modular toolchain config
This commit is contained in:
parent
ab20a57e9e
commit
137977f691
6 changed files with 112 additions and 51 deletions
|
@ -26,9 +26,6 @@ import com.falsepattern.zigbrains.project.toolchain.ZigToolchainListService.MySt
|
|||
import com.falsepattern.zigbrains.project.toolchain.base.ZigToolchain
|
||||
import com.falsepattern.zigbrains.project.toolchain.base.resolve
|
||||
import com.falsepattern.zigbrains.project.toolchain.base.toRef
|
||||
import com.falsepattern.zigbrains.shared.AccessibleStorage
|
||||
import com.falsepattern.zigbrains.shared.ChangeTrackingStorage
|
||||
import com.falsepattern.zigbrains.shared.IterableStorage
|
||||
import com.falsepattern.zigbrains.shared.UUIDMapSerializable
|
||||
import com.falsepattern.zigbrains.shared.UUIDStorage
|
||||
import com.intellij.openapi.components.*
|
||||
|
@ -38,25 +35,20 @@ import com.intellij.openapi.components.*
|
|||
name = "ZigToolchainList",
|
||||
storages = [Storage("zigbrains.xml")]
|
||||
)
|
||||
class ZigToolchainListService: UUIDMapSerializable.Converting<ZigToolchain, ZigToolchain.Ref, MyState>(MyState()), IZigToolchainListService {
|
||||
class ZigToolchainListService: UUIDMapSerializable.Converting<ZigToolchain, ZigToolchain.Ref, MyState>(MyState()) {
|
||||
override fun serialize(value: ZigToolchain) = value.toRef()
|
||||
override fun deserialize(value: ZigToolchain.Ref) = value.resolve()
|
||||
override fun getStorage(state: MyState) = state.toolchains
|
||||
override fun updateStorage(state: MyState, storage: ToolchainStorage) = state.copy(toolchains = storage)
|
||||
|
||||
data class MyState(
|
||||
@JvmField
|
||||
val toolchains: ToolchainStorage = emptyMap(),
|
||||
)
|
||||
data class MyState(@JvmField val toolchains: ToolchainStorage = emptyMap())
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun getInstance(): IZigToolchainListService = service<ZigToolchainListService>()
|
||||
fun getInstance(): ZigToolchainListService = service<ZigToolchainListService>()
|
||||
}
|
||||
}
|
||||
|
||||
inline val zigToolchainList: IZigToolchainListService get() = ZigToolchainListService.getInstance()
|
||||
|
||||
sealed interface IZigToolchainListService: ChangeTrackingStorage, AccessibleStorage<ZigToolchain>, IterableStorage<ZigToolchain>
|
||||
inline val zigToolchainList: ZigToolchainListService get() = ZigToolchainListService.getInstance()
|
||||
|
||||
private typealias ToolchainStorage = UUIDStorage<ZigToolchain.Ref>
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
|
||||
package com.falsepattern.zigbrains.project.toolchain.base
|
||||
|
||||
import com.falsepattern.zigbrains.project.toolchain.ZigToolchainListService
|
||||
import com.falsepattern.zigbrains.project.toolchain.zigToolchainList
|
||||
import com.intellij.openapi.ui.NamedConfigurable
|
||||
import com.intellij.openapi.util.NlsContexts
|
||||
|
@ -39,19 +38,21 @@ abstract class ZigToolchainConfigurable<T: ZigToolchain>(
|
|||
zigToolchainList[uuid] = value
|
||||
field = value
|
||||
}
|
||||
private var myView: ZigToolchainPanel<T>? = null
|
||||
private var myViews: List<ZigToolchainPanel<T>> = emptyList()
|
||||
|
||||
abstract fun createPanel(): ZigToolchainPanel<T>
|
||||
|
||||
override fun createOptionsPanel(): JComponent? {
|
||||
var view = myView
|
||||
if (view == null) {
|
||||
view = createPanel()
|
||||
view.reset(toolchain)
|
||||
myView = view
|
||||
var views = myViews
|
||||
if (views.isEmpty()) {
|
||||
views = ArrayList<ZigToolchainPanel<T>>()
|
||||
views.add(createPanel())
|
||||
views.addAll(createZigToolchainExtensionPanels())
|
||||
views.forEach { it.reset(toolchain) }
|
||||
myViews = views
|
||||
}
|
||||
return panel {
|
||||
view.attach(this)
|
||||
views.forEach { it.attach(this@panel) }
|
||||
}.withMinimumWidth(20)
|
||||
}
|
||||
|
||||
|
@ -68,20 +69,20 @@ abstract class ZigToolchainConfigurable<T: ZigToolchain>(
|
|||
}
|
||||
|
||||
override fun isModified(): Boolean {
|
||||
return myView?.isModified(toolchain) == true
|
||||
return myViews.any { it.isModified(toolchain) }
|
||||
}
|
||||
|
||||
override fun apply() {
|
||||
myView?.apply(toolchain)?.let { toolchain = it }
|
||||
toolchain = myViews.fold(toolchain) { tc, view -> view.apply(tc) ?: tc }
|
||||
}
|
||||
|
||||
override fun reset() {
|
||||
myView?.reset(toolchain)
|
||||
myViews.forEach { it.reset(toolchain) }
|
||||
}
|
||||
|
||||
override fun disposeUIResources() {
|
||||
myView?.dispose()
|
||||
myView = null
|
||||
myViews.forEach { it.dispose() }
|
||||
myViews = emptyList()
|
||||
super.disposeUIResources()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* This file is part of ZigBrains.
|
||||
*
|
||||
* Copyright (C) 2023-2025 FalsePattern
|
||||
* All Rights Reserved
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* ZigBrains is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, only version 3 of the License.
|
||||
*
|
||||
* ZigBrains is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with ZigBrains. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.falsepattern.zigbrains.project.toolchain.base
|
||||
|
||||
import com.intellij.openapi.extensions.ExtensionPointName
|
||||
|
||||
private val EXTENSION_POINT_NAME = ExtensionPointName.create<ZigToolchainExtensionsProvider>("com.falsepattern.zigbrains.toolchainExtensionsProvider")
|
||||
|
||||
internal interface ZigToolchainExtensionsProvider {
|
||||
fun <T : ZigToolchain> createExtensionPanel(): ZigToolchainPanel<T>?
|
||||
val index: Int
|
||||
}
|
||||
|
||||
fun <T: ZigToolchain> createZigToolchainExtensionPanels(): List<ZigToolchainPanel<T>> {
|
||||
return EXTENSION_POINT_NAME.extensionList.sortedBy{ it.index }.mapNotNull {
|
||||
it.createExtensionPanel()
|
||||
}
|
||||
}
|
|
@ -22,29 +22,15 @@
|
|||
|
||||
package com.falsepattern.zigbrains.project.toolchain.base
|
||||
|
||||
import com.falsepattern.zigbrains.ZigBrainsBundle
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.ui.components.JBTextField
|
||||
import com.intellij.ui.dsl.builder.AlignX
|
||||
import com.intellij.ui.dsl.builder.Panel
|
||||
import com.intellij.ui.util.preferredHeight
|
||||
import java.awt.Dimension
|
||||
|
||||
abstract class ZigToolchainPanel<T: ZigToolchain>: Disposable {
|
||||
private val nameField = JBTextField(25)
|
||||
|
||||
protected var nameFieldValue: String?
|
||||
get() = nameField.text.ifBlank { null }
|
||||
set(value) {nameField.text = value ?: ""}
|
||||
|
||||
open fun attach(p: Panel): Unit = with(p) {
|
||||
row(ZigBrainsBundle.message("settings.toolchain.base.name.label")) {
|
||||
cell(nameField).resizableColumn().align(AlignX.FILL)
|
||||
}
|
||||
separator()
|
||||
}
|
||||
|
||||
abstract fun isModified(toolchain: T): Boolean
|
||||
abstract fun apply(toolchain: T): T?
|
||||
abstract fun reset(toolchain: T)
|
||||
interface ZigToolchainPanel<T: ZigToolchain>: Disposable {
|
||||
fun attach(p: Panel)
|
||||
fun isModified(toolchain: T): Boolean
|
||||
/**
|
||||
* Returned object must be the exact same class as the provided one.
|
||||
*/
|
||||
fun apply(toolchain: T): T?
|
||||
fun reset(toolchain: T)
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* This file is part of ZigBrains.
|
||||
*
|
||||
* Copyright (C) 2023-2025 FalsePattern
|
||||
* All Rights Reserved
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* ZigBrains is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, only version 3 of the License.
|
||||
*
|
||||
* ZigBrains is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with ZigBrains. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.falsepattern.zigbrains.project.toolchain.base
|
||||
|
||||
import com.falsepattern.zigbrains.ZigBrainsBundle
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.ui.components.JBTextField
|
||||
import com.intellij.ui.dsl.builder.AlignX
|
||||
import com.intellij.ui.dsl.builder.Panel
|
||||
import com.intellij.ui.util.preferredHeight
|
||||
import java.awt.Dimension
|
||||
|
||||
abstract class ZigToolchainPanelBase<T: ZigToolchain>: ZigToolchainPanel<T> {
|
||||
private val nameField = JBTextField(25)
|
||||
|
||||
protected var nameFieldValue: String?
|
||||
get() = nameField.text.ifBlank { null }
|
||||
set(value) {nameField.text = value ?: ""}
|
||||
|
||||
override fun attach(p: Panel): Unit = with(p) {
|
||||
row(ZigBrainsBundle.message("settings.toolchain.base.name.label")) {
|
||||
cell(nameField).resizableColumn().align(AlignX.FILL)
|
||||
}
|
||||
separator()
|
||||
}
|
||||
}
|
|
@ -23,10 +23,9 @@
|
|||
package com.falsepattern.zigbrains.project.toolchain.local
|
||||
|
||||
import com.falsepattern.zigbrains.ZigBrainsBundle
|
||||
import com.falsepattern.zigbrains.project.toolchain.base.ZigToolchainPanel
|
||||
import com.falsepattern.zigbrains.project.toolchain.base.ZigToolchainPanelBase
|
||||
import com.falsepattern.zigbrains.shared.coroutine.withEDTContext
|
||||
import com.falsepattern.zigbrains.shared.zigCoroutineScope
|
||||
import com.intellij.openapi.Disposable
|
||||
import com.intellij.openapi.application.ModalityState
|
||||
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory
|
||||
import com.intellij.openapi.util.Disposer
|
||||
|
@ -35,7 +34,6 @@ import com.intellij.ui.DocumentAdapter
|
|||
import com.intellij.ui.JBColor
|
||||
import com.intellij.ui.components.JBCheckBox
|
||||
import com.intellij.ui.components.JBTextArea
|
||||
import com.intellij.ui.components.JBTextField
|
||||
import com.intellij.ui.components.textFieldWithBrowseButton
|
||||
import com.intellij.ui.dsl.builder.AlignX
|
||||
import com.intellij.ui.dsl.builder.Panel
|
||||
|
@ -46,7 +44,7 @@ import kotlinx.coroutines.launch
|
|||
import javax.swing.event.DocumentEvent
|
||||
import kotlin.io.path.pathString
|
||||
|
||||
class LocalZigToolchainPanel() : ZigToolchainPanel<LocalZigToolchain>() {
|
||||
class LocalZigToolchainPanel() : ZigToolchainPanelBase<LocalZigToolchain>() {
|
||||
private val pathToToolchain = textFieldWithBrowseButton(
|
||||
null,
|
||||
FileChooserDescriptorFactory.createSingleFolderDescriptor().withTitle(ZigBrainsBundle.message("dialog.title.zig-toolchain"))
|
||||
|
|
Loading…
Add table
Reference in a new issue