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.ZigToolchain
|
||||||
import com.falsepattern.zigbrains.project.toolchain.base.resolve
|
import com.falsepattern.zigbrains.project.toolchain.base.resolve
|
||||||
import com.falsepattern.zigbrains.project.toolchain.base.toRef
|
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.UUIDMapSerializable
|
||||||
import com.falsepattern.zigbrains.shared.UUIDStorage
|
import com.falsepattern.zigbrains.shared.UUIDStorage
|
||||||
import com.intellij.openapi.components.*
|
import com.intellij.openapi.components.*
|
||||||
|
@ -38,25 +35,20 @@ import com.intellij.openapi.components.*
|
||||||
name = "ZigToolchainList",
|
name = "ZigToolchainList",
|
||||||
storages = [Storage("zigbrains.xml")]
|
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 serialize(value: ZigToolchain) = value.toRef()
|
||||||
override fun deserialize(value: ZigToolchain.Ref) = value.resolve()
|
override fun deserialize(value: ZigToolchain.Ref) = value.resolve()
|
||||||
override fun getStorage(state: MyState) = state.toolchains
|
override fun getStorage(state: MyState) = state.toolchains
|
||||||
override fun updateStorage(state: MyState, storage: ToolchainStorage) = state.copy(toolchains = storage)
|
override fun updateStorage(state: MyState, storage: ToolchainStorage) = state.copy(toolchains = storage)
|
||||||
|
|
||||||
data class MyState(
|
data class MyState(@JvmField val toolchains: ToolchainStorage = emptyMap())
|
||||||
@JvmField
|
|
||||||
val toolchains: ToolchainStorage = emptyMap(),
|
|
||||||
)
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun getInstance(): IZigToolchainListService = service<ZigToolchainListService>()
|
fun getInstance(): ZigToolchainListService = service<ZigToolchainListService>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline val zigToolchainList: IZigToolchainListService get() = ZigToolchainListService.getInstance()
|
inline val zigToolchainList: ZigToolchainListService get() = ZigToolchainListService.getInstance()
|
||||||
|
|
||||||
sealed interface IZigToolchainListService: ChangeTrackingStorage, AccessibleStorage<ZigToolchain>, IterableStorage<ZigToolchain>
|
|
||||||
|
|
||||||
private typealias ToolchainStorage = UUIDStorage<ZigToolchain.Ref>
|
private typealias ToolchainStorage = UUIDStorage<ZigToolchain.Ref>
|
||||||
|
|
|
@ -22,7 +22,6 @@
|
||||||
|
|
||||||
package com.falsepattern.zigbrains.project.toolchain.base
|
package com.falsepattern.zigbrains.project.toolchain.base
|
||||||
|
|
||||||
import com.falsepattern.zigbrains.project.toolchain.ZigToolchainListService
|
|
||||||
import com.falsepattern.zigbrains.project.toolchain.zigToolchainList
|
import com.falsepattern.zigbrains.project.toolchain.zigToolchainList
|
||||||
import com.intellij.openapi.ui.NamedConfigurable
|
import com.intellij.openapi.ui.NamedConfigurable
|
||||||
import com.intellij.openapi.util.NlsContexts
|
import com.intellij.openapi.util.NlsContexts
|
||||||
|
@ -39,19 +38,21 @@ abstract class ZigToolchainConfigurable<T: ZigToolchain>(
|
||||||
zigToolchainList[uuid] = value
|
zigToolchainList[uuid] = value
|
||||||
field = value
|
field = value
|
||||||
}
|
}
|
||||||
private var myView: ZigToolchainPanel<T>? = null
|
private var myViews: List<ZigToolchainPanel<T>> = emptyList()
|
||||||
|
|
||||||
abstract fun createPanel(): ZigToolchainPanel<T>
|
abstract fun createPanel(): ZigToolchainPanel<T>
|
||||||
|
|
||||||
override fun createOptionsPanel(): JComponent? {
|
override fun createOptionsPanel(): JComponent? {
|
||||||
var view = myView
|
var views = myViews
|
||||||
if (view == null) {
|
if (views.isEmpty()) {
|
||||||
view = createPanel()
|
views = ArrayList<ZigToolchainPanel<T>>()
|
||||||
view.reset(toolchain)
|
views.add(createPanel())
|
||||||
myView = view
|
views.addAll(createZigToolchainExtensionPanels())
|
||||||
|
views.forEach { it.reset(toolchain) }
|
||||||
|
myViews = views
|
||||||
}
|
}
|
||||||
return panel {
|
return panel {
|
||||||
view.attach(this)
|
views.forEach { it.attach(this@panel) }
|
||||||
}.withMinimumWidth(20)
|
}.withMinimumWidth(20)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,20 +69,20 @@ abstract class ZigToolchainConfigurable<T: ZigToolchain>(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isModified(): Boolean {
|
override fun isModified(): Boolean {
|
||||||
return myView?.isModified(toolchain) == true
|
return myViews.any { it.isModified(toolchain) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun apply() {
|
override fun apply() {
|
||||||
myView?.apply(toolchain)?.let { toolchain = it }
|
toolchain = myViews.fold(toolchain) { tc, view -> view.apply(tc) ?: tc }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun reset() {
|
override fun reset() {
|
||||||
myView?.reset(toolchain)
|
myViews.forEach { it.reset(toolchain) }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun disposeUIResources() {
|
override fun disposeUIResources() {
|
||||||
myView?.dispose()
|
myViews.forEach { it.dispose() }
|
||||||
myView = null
|
myViews = emptyList()
|
||||||
super.disposeUIResources()
|
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
|
package com.falsepattern.zigbrains.project.toolchain.base
|
||||||
|
|
||||||
import com.falsepattern.zigbrains.ZigBrainsBundle
|
|
||||||
import com.intellij.openapi.Disposable
|
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.dsl.builder.Panel
|
||||||
import com.intellij.ui.util.preferredHeight
|
|
||||||
import java.awt.Dimension
|
|
||||||
|
|
||||||
abstract class ZigToolchainPanel<T: ZigToolchain>: Disposable {
|
interface ZigToolchainPanel<T: ZigToolchain>: Disposable {
|
||||||
private val nameField = JBTextField(25)
|
fun attach(p: Panel)
|
||||||
|
fun isModified(toolchain: T): Boolean
|
||||||
protected var nameFieldValue: String?
|
/**
|
||||||
get() = nameField.text.ifBlank { null }
|
* Returned object must be the exact same class as the provided one.
|
||||||
set(value) {nameField.text = value ?: ""}
|
*/
|
||||||
|
fun apply(toolchain: T): T?
|
||||||
open fun attach(p: Panel): Unit = with(p) {
|
fun reset(toolchain: T)
|
||||||
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)
|
|
||||||
}
|
}
|
|
@ -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
|
package com.falsepattern.zigbrains.project.toolchain.local
|
||||||
|
|
||||||
import com.falsepattern.zigbrains.ZigBrainsBundle
|
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.coroutine.withEDTContext
|
||||||
import com.falsepattern.zigbrains.shared.zigCoroutineScope
|
import com.falsepattern.zigbrains.shared.zigCoroutineScope
|
||||||
import com.intellij.openapi.Disposable
|
|
||||||
import com.intellij.openapi.application.ModalityState
|
import com.intellij.openapi.application.ModalityState
|
||||||
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory
|
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory
|
||||||
import com.intellij.openapi.util.Disposer
|
import com.intellij.openapi.util.Disposer
|
||||||
|
@ -35,7 +34,6 @@ import com.intellij.ui.DocumentAdapter
|
||||||
import com.intellij.ui.JBColor
|
import com.intellij.ui.JBColor
|
||||||
import com.intellij.ui.components.JBCheckBox
|
import com.intellij.ui.components.JBCheckBox
|
||||||
import com.intellij.ui.components.JBTextArea
|
import com.intellij.ui.components.JBTextArea
|
||||||
import com.intellij.ui.components.JBTextField
|
|
||||||
import com.intellij.ui.components.textFieldWithBrowseButton
|
import com.intellij.ui.components.textFieldWithBrowseButton
|
||||||
import com.intellij.ui.dsl.builder.AlignX
|
import com.intellij.ui.dsl.builder.AlignX
|
||||||
import com.intellij.ui.dsl.builder.Panel
|
import com.intellij.ui.dsl.builder.Panel
|
||||||
|
@ -46,7 +44,7 @@ import kotlinx.coroutines.launch
|
||||||
import javax.swing.event.DocumentEvent
|
import javax.swing.event.DocumentEvent
|
||||||
import kotlin.io.path.pathString
|
import kotlin.io.path.pathString
|
||||||
|
|
||||||
class LocalZigToolchainPanel() : ZigToolchainPanel<LocalZigToolchain>() {
|
class LocalZigToolchainPanel() : ZigToolchainPanelBase<LocalZigToolchain>() {
|
||||||
private val pathToToolchain = textFieldWithBrowseButton(
|
private val pathToToolchain = textFieldWithBrowseButton(
|
||||||
null,
|
null,
|
||||||
FileChooserDescriptorFactory.createSingleFolderDescriptor().withTitle(ZigBrainsBundle.message("dialog.title.zig-toolchain"))
|
FileChooserDescriptorFactory.createSingleFolderDescriptor().withTitle(ZigBrainsBundle.message("dialog.title.zig-toolchain"))
|
||||||
|
|
Loading…
Add table
Reference in a new issue