Wizard: place all settings of first step into one setting list

This commit is contained in:
Ilya Kirillov
2020-03-13 15:43:46 +03:00
parent 586b044235
commit cbfe05efc8
8 changed files with 71 additions and 125 deletions
@@ -24,7 +24,7 @@ class BuildSystemTypeSettingComponent(
override val uiComponent: DropDownComponent<BuildSystemType> = DropDownComponent(
context,
setting.type.values,
labelText = "Build System",
labelText = null,
filter = { value -> read { setting.type.filter(this, reference, value) } },
validator = setting.validator,
iconProvider = BuildSystemType::icon,
@@ -1,111 +1,27 @@
package org.jetbrains.kotlin.tools.projectWizard.wizard.ui.firstStep
import TemplateTag
import com.intellij.ide.plugins.newui.VerticalLayout
import com.intellij.util.ui.JBUI
import org.jetbrains.kotlin.tools.projectWizard.core.Context
import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.SettingReference
import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.reference
import org.jetbrains.kotlin.tools.projectWizard.plugins.StructurePlugin
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.KotlinPlugin
import org.jetbrains.kotlin.tools.projectWizard.plugins.projectTemplates.ProjectTemplatesPlugin
import org.jetbrains.kotlin.tools.projectWizard.plugins.projectTemplates.applyProjectTemplate
import org.jetbrains.kotlin.tools.projectWizard.projectTemplates.ProjectTemplate
import org.jetbrains.kotlin.tools.projectWizard.wizard.IdeWizard
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.*
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting.PathSettingComponent
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.WizardStepComponent
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting.SettingsList
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting.StringSettingComponent
import java.awt.BorderLayout
import javax.swing.Box
import javax.swing.BoxLayout
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting.createSettingComponent
import javax.swing.JComponent
import java.awt.Component as AwtComponent
class FirstWizardStepComponent(wizard: IdeWizard) : WizardStepComponent(wizard.context) {
private val context = wizard.context
private val projectTemplateComponent = ProjectTemplateSettingComponent(context).asSubComponent()
private val buildSystemSetting = BuildSystemTypeSettingComponent(context).asSubComponent()
private val nameAndLocationComponent = SettingsList(
listOf(
StructurePlugin::name.reference,
StructurePlugin::projectPath.reference
StructurePlugin::name.reference.createSettingComponent(context),
StructurePlugin::projectPath.reference.createSettingComponent(context),
projectTemplateComponent,
buildSystemSetting
),
wizard.context
).asSubComponent()
private val buildSystemSubStep = BuildSystemSubStep(wizard.context).asSubComponent()
private val templatesSubStep = TemplatesSubStep(wizard.context).asSubComponent()
override val component: JComponent = panel {
add(nameAndLocationComponent.component, BorderLayout.CENTER)
add(buildSystemSubStep.component, BorderLayout.SOUTH)
}
override val component: JComponent = nameAndLocationComponent.component
}
class BuildSystemSubStep(context: Context) : SubStep(context) {
private val buildSystemSetting = BuildSystemTypeSettingComponent(context).asSubComponent()
override fun buildContent(): JComponent = panel {
add(buildSystemSetting.component, BorderLayout.CENTER)
}
}
class TemplatesSubStep(context: Context) : SubStep(context) {
private val projectTemplateSettingComponent =
ProjectTemplateSettingComponent(context) { projectTemplate ->
templateDescriptionComponent.setTemplate(projectTemplate)
}.asSubComponent()
private val templateDescriptionComponent = TemplateDescriptionComponent().asSubComponent()
override fun buildContent(): JComponent = panel {
add(projectTemplateSettingComponent.component, BorderLayout.CENTER)
add(templateDescriptionComponent.component, BorderLayout.SOUTH)
}
override fun onInit() {
super.onInit()
applySelectedTemplate()
}
private fun applySelectedTemplate() {
modify {
val selectedProjectTemplate = projectTemplateSettingComponent.value ?: return@modify
applyProjectTemplate(selectedProjectTemplate)
}
}
override fun onValueUpdated(reference: SettingReference<*, *>?) {
super.onValueUpdated(reference)
if (reference == ProjectTemplatesPlugin::template.reference) {
applySelectedTemplate()
}
}
}
class TemplateDescriptionComponent : Component() {
private val tagsPanel = panel {
layout = BoxLayout(this, BoxLayout.X_AXIS)
alignmentX = AwtComponent.LEFT_ALIGNMENT
alignmentY = AwtComponent.TOP_ALIGNMENT
border = JBUI.Borders.emptyBottom(6)
}
private val descriptionPanel = DescriptionPanel()
fun setTemplate(template: ProjectTemplate) {
addTagsToPanel(template.tags)
descriptionPanel.updateText(template.htmlDescription)
}
private fun addTagsToPanel(tags: List<TemplateTag>) {
tagsPanel.removeAll()
for (tag in tags) {
tagsPanel.add(TemplateTagUIComponent(tag))
tagsPanel.add(Box.createHorizontalStrut(6))
}
tagsPanel.updateUI()
}
override val component: JComponent = panel {
bordered()
add(tagsPanel, BorderLayout.NORTH)
add(descriptionPanel, BorderLayout.CENTER)
}
}
@@ -1,25 +1,28 @@
package org.jetbrains.kotlin.tools.projectWizard.wizard.ui.firstStep
import com.intellij.util.ui.JBUI
import com.intellij.util.ui.UIUtil
import org.jetbrains.kotlin.tools.projectWizard.core.Context
import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.DropDownSettingType
import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.SettingReference
import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.reference
import org.jetbrains.kotlin.tools.projectWizard.plugins.projectTemplates.ProjectTemplatesPlugin
import org.jetbrains.kotlin.tools.projectWizard.plugins.projectTemplates.applyProjectTemplate
import org.jetbrains.kotlin.tools.projectWizard.projectTemplates.ProjectTemplate
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.*
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting.SettingComponent
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting.ValidationIndicator
import java.awt.BorderLayout
import javax.swing.BorderFactory
import javax.swing.JComponent
class ProjectTemplateSettingComponent(
context: Context,
private val onSelected: (ProjectTemplate) -> Unit
context: Context
) : SettingComponent<ProjectTemplate, DropDownSettingType<ProjectTemplate>>(
ProjectTemplatesPlugin::template.reference,
context
) {
override val validationIndicator: ValidationIndicator? get() = null
private val templateDescriptionComponent = TemplateDescriptionComponent().asSubComponent()
private val list = ImmutableSingleSelectableListWithIcon(
setting.type.values,
@@ -27,33 +30,47 @@ class ProjectTemplateSettingComponent(
icon = value.projectKind.icon
append(value.title)
},
onValueSelected = {
onValueSelected(it!!)
}
).apply {
border = BorderFactory.createEmptyBorder(
UiConstants.GAP_BORDER_SIZE,
UiConstants.GAP_BORDER_SIZE,
UiConstants.GAP_BORDER_SIZE,
UiConstants.GAP_BORDER_SIZE
onValueSelected = { value = it }
).bordered(needTopEmptyBorder = false, needInnerEmptyBorder = false, needBottomEmptyBorder = false)
override val component: JComponent = panel {
add(list, BorderLayout.CENTER)
add(
templateDescriptionComponent.component.withBorder(JBUI.Borders.emptyTop(5)),
BorderLayout.SOUTH
)
}
private fun onValueSelected(selected: ProjectTemplate) {
value = selected
onSelected(selected)
private fun applySelectedTemplate() = modify {
value?.let(::applyProjectTemplate)
}
override val component: JComponent = panel {
bordered(needTopEmptyBorder = false, needInnerEmptyBorder = false)
add(list, BorderLayout.CENTER)
override fun onValueUpdated(reference: SettingReference<*, *>?) {
super.onValueUpdated(reference)
if (reference == ProjectTemplatesPlugin::template.reference) {
applySelectedTemplate()
value?.let(templateDescriptionComponent::setTemplate)
}
}
override fun onInit() {
super.onInit()
if (setting.type.values.isNotEmpty()) {
list.selectedIndex = 0
onValueSelected(setting.type.values.first())
value = setting.type.values.firstOrNull()
}
}
}
class TemplateDescriptionComponent : Component() {
private val descriptionLabel = label("").apply {
fontColor = UIUtil.FontColor.BRIGHTER
}
fun setTemplate(template: ProjectTemplate) {
descriptionLabel.text = template.htmlDescription
}
override val component: JComponent = descriptionLabel
}
@@ -59,6 +59,9 @@ object DefaultSettingComponent {
}
}
fun <V : Any, T : SettingType<V>> SettingReference<V, T>.createSettingComponent(context: Context) =
DefaultSettingComponent.create(this, context, needLabel = false)
class VersionSettingComponent(
reference: SettingReference<Version, VersionSettingType>,
context: Context
@@ -14,15 +14,13 @@ interface ErrorAwareComponent {
}
class SettingsList(
settings: List<SettingReference<*, *>>,
private var settingComponents: List<SettingComponent<*, *>>,
private val context: Context
) : DynamicComponent(context), ErrorAwareComponent {
private val ui = BorderLayoutPanel()
private var settingComponents: List<SettingComponent<*, *>> = emptyList()
init {
setSettings(settings)
setSettingComponents(settingComponents)
}
override val component get() = ui
@@ -32,11 +30,9 @@ class SettingsList(
settingComponents.forEach { it.onInit() }
}
fun setSettings(settings: List<SettingReference<*, *>>) {
private fun setSettingComponents(settingComponents: List<SettingComponent<*, *>>) {
this.settingComponents = settingComponents
ui.removeAll()
settingComponents = settings.map { setting ->
DefaultSettingComponent.create(setting, context, needLabel = false)
}
ui.addToCenter(panel {
settingComponents.forEach { settingComponent ->
settingComponent.onInit()
@@ -47,6 +43,15 @@ class SettingsList(
})
}
fun setSettings(settings: List<SettingReference<*, *>>) {
setSettingComponents(
settings.map { setting ->
DefaultSettingComponent.create(setting, context, needLabel = false)
}
)
}
override fun findComponentWithError(error: ValidationResult.ValidationError) = read {
settingComponents.firstOrNull { component ->
val value = component.value ?: return@firstOrNull false
@@ -31,6 +31,7 @@ import javax.swing.BorderFactory
import javax.swing.Icon
import javax.swing.JComponent
import javax.swing.JPanel
import javax.swing.border.Border
import javax.swing.event.DocumentEvent
import javax.swing.event.DocumentListener
@@ -170,6 +171,10 @@ fun <C : JComponent> C.bordered(
)
}
fun <C : JComponent> C.withBorder(border: Border): C = apply {
this.border = BorderFactory.createCompoundBorder(border, this.border)
}
class TemplateTagUIComponent(tag: TemplateTag) : TagComponent(tag.text) {
override fun isInClickableArea(pt: Point?) = false
@@ -12,7 +12,7 @@ import org.jetbrains.kotlin.tools.projectWizard.settings.version.Version
import java.nio.file.Paths
class StructurePlugin(context: Context) : Plugin(context) {
val projectPath by pathSetting("Root path", GenerationPhase.PROJECT_GENERATION) {
val projectPath by pathSetting("Location", GenerationPhase.PROJECT_GENERATION) {
defaultValue = value(Paths.get("."))
}
val name by stringSetting("Name", GenerationPhase.PROJECT_GENERATION)
@@ -9,7 +9,7 @@ import org.jetbrains.kotlin.tools.projectWizard.projectTemplates.ProjectTemplate
class ProjectTemplatesPlugin(context: Context) : Plugin(context) {
val template by dropDownSetting<ProjectTemplate>(
"Template",
"Project template",
GenerationPhase.INIT_TEMPLATE,
parser = valueParserM { _, _ ->
Failure(ParseError("Project templates is not supported in yaml for now"))