Wizard: fix layout
This commit is contained in:
+2
@@ -70,6 +70,8 @@ abstract class DynamicComponent(private val context: Context) : Component() {
|
||||
}
|
||||
|
||||
abstract class TitledComponent(context: Context) : DynamicComponent(context) {
|
||||
open val needCentering: Boolean = true
|
||||
open val maximumWidth: Int? = null
|
||||
abstract val title: String?
|
||||
open fun shouldBeShow(): Boolean = true
|
||||
}
|
||||
|
||||
+28
-12
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.*
|
||||
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.secondStep.modulesEditor.ModulesEditorComponent
|
||||
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting.TitledComponentsList
|
||||
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting.createSettingComponent
|
||||
import java.awt.Cursor
|
||||
import java.awt.event.MouseAdapter
|
||||
import java.awt.event.MouseEvent
|
||||
import javax.swing.JComponent
|
||||
@@ -52,7 +53,9 @@ class ProjectSettingsComponent(ideWizard: IdeWizard) : DynamicComponent(ideWizar
|
||||
projectTemplateComponent,
|
||||
buildSystemSetting
|
||||
),
|
||||
context
|
||||
context,
|
||||
stretchY = true,
|
||||
useBigYGap = true
|
||||
).asSubComponent()
|
||||
|
||||
override val component: JComponent by lazy(LazyThreadSafetyMode.NONE) {
|
||||
@@ -63,8 +66,6 @@ class ProjectSettingsComponent(ideWizard: IdeWizard) : DynamicComponent(ideWizar
|
||||
row {
|
||||
buildSystemAdditionalSettingsComponent.component(growX)
|
||||
}
|
||||
}.apply {
|
||||
border = JBUI.Borders.empty(10)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,10 +153,24 @@ private class PomSettingsComponent(context: Context) : TitledComponentsList(
|
||||
StructurePlugin::artifactId.reference.createSettingComponent(context),
|
||||
StructurePlugin::version.reference.createSettingComponent(context)
|
||||
),
|
||||
context
|
||||
context,
|
||||
stretchY = true
|
||||
)
|
||||
|
||||
class KotlinJpsRuntimeComponent(ideWizard: IdeWizard) : DynamicComponent(ideWizard.context) {
|
||||
private val componentList = TitledComponentsList(
|
||||
listOf(
|
||||
JdkComponent(ideWizard),
|
||||
KotlinRuntimeComponentComponent(ideWizard)
|
||||
),
|
||||
ideWizard.context,
|
||||
stretchY = true
|
||||
).asSubComponent()
|
||||
|
||||
override val component: JComponent = componentList.component
|
||||
}
|
||||
|
||||
private class JdkComponent(ideWizard: IdeWizard) : TitledComponent(ideWizard.context) {
|
||||
private val javaModuleBuilder = JavaModuleBuilder()
|
||||
private val jdkComboBox = JdkComboBox(
|
||||
ProjectSdksModel().apply { reset(null) },
|
||||
@@ -166,14 +181,14 @@ class KotlinJpsRuntimeComponent(ideWizard: IdeWizard) : DynamicComponent(ideWiza
|
||||
ideWizard.jpsData.jdk = selectedJdk
|
||||
}
|
||||
}
|
||||
override val component: JComponent = panel {
|
||||
row("Project JDK:") {
|
||||
borderPanel { addToCenter(jdkComboBox) }.addBorder(JBUI.Borders.empty(0, 7))(growX)
|
||||
}
|
||||
row("Kotlin Runtime:") {
|
||||
ideWizard.jpsData.libraryOptionsPanel.simplePanel(growX)
|
||||
}
|
||||
}
|
||||
|
||||
override val title: String = "Project JDK"
|
||||
override val component: JComponent = jdkComboBox
|
||||
}
|
||||
|
||||
private class KotlinRuntimeComponentComponent(ideWizard: IdeWizard) : TitledComponent(ideWizard.context) {
|
||||
override val title: String = "Kotlin Runtime"
|
||||
override val component: JComponent = ideWizard.jpsData.libraryOptionsPanel.simplePanel
|
||||
}
|
||||
|
||||
@Suppress("SpellCheckingInspection")
|
||||
@@ -182,6 +197,7 @@ private class HideableSection(text: String, private var component: JComponent) :
|
||||
private var isExpanded = false
|
||||
|
||||
init {
|
||||
titledSeparator.label.cursor = Cursor(Cursor.HAND_CURSOR)
|
||||
updateComponent(component)
|
||||
titledSeparator.addMouseListener(object : MouseAdapter() {
|
||||
override fun mouseReleased(e: MouseEvent) = update(!isExpanded)
|
||||
|
||||
+2
-2
@@ -13,7 +13,6 @@ 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.JComponent
|
||||
|
||||
class ProjectTemplateSettingComponent(
|
||||
@@ -23,6 +22,7 @@ class ProjectTemplateSettingComponent(
|
||||
context
|
||||
) {
|
||||
override val validationIndicator: ValidationIndicator? get() = null
|
||||
override val needCentering: Boolean = false
|
||||
private val templateDescriptionComponent = TemplateDescriptionComponent().asSubComponent()
|
||||
|
||||
private val list = ImmutableSingleSelectableListWithIcon(
|
||||
@@ -37,7 +37,7 @@ class ProjectTemplateSettingComponent(
|
||||
|
||||
override val component: JComponent = borderPanel {
|
||||
addToCenter(borderPanel { addToCenter(list) }.addBorder(JBUI.Borders.empty(0,/*left*/ 3, 0, /*right*/ 3)))
|
||||
addToBottom(templateDescriptionComponent.component.addBorder(JBUI.Borders.empty(/*top*/5,/*left*/ 3, 0, 0)))
|
||||
addToBottom(templateDescriptionComponent.component.addBorder(JBUI.Borders.empty(/*top*/8,/*left*/ 3, /*bottom*/10, 0)))
|
||||
}
|
||||
|
||||
private fun applySelectedTemplate() = modify {
|
||||
|
||||
+4
@@ -7,6 +7,7 @@ import com.intellij.ui.ColoredListCellRenderer
|
||||
import com.intellij.ui.SimpleTextAttributes
|
||||
import com.intellij.ui.ToolbarDecorator
|
||||
import com.intellij.ui.popup.PopupFactoryImpl
|
||||
import com.intellij.util.ui.JBUI
|
||||
import org.jetbrains.kotlin.tools.projectWizard.core.Context
|
||||
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.KotlinPlugin
|
||||
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.withAllSubModules
|
||||
@@ -22,6 +23,8 @@ class ModuleDependenciesComponent(
|
||||
) : TitledComponent(context) {
|
||||
override val title: String = "Module dependencies"
|
||||
private val dependenciesList = ModuleDependenciesList()
|
||||
override val needCentering: Boolean = false
|
||||
override val maximumWidth: Int = 500
|
||||
|
||||
private val toolbarDecorator: ToolbarDecorator = ToolbarDecorator.createDecorator(dependenciesList).apply {
|
||||
setToolbarPosition(ActionToolbarPosition.BOTTOM)
|
||||
@@ -72,6 +75,7 @@ class ModuleDependenciesComponent(
|
||||
|
||||
override val component: JPanel = toolbarDecorator.createPanelWithPopupHandler(dependenciesList).apply {
|
||||
preferredSize = Dimension(preferredSize.width, 200)
|
||||
addBorder(JBUI.Borders.empty(0, 3))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-6
@@ -1,6 +1,5 @@
|
||||
package org.jetbrains.kotlin.tools.projectWizard.wizard.ui.secondStep
|
||||
|
||||
import com.intellij.util.ui.JBUI
|
||||
import org.jetbrains.kotlin.idea.projectWizard.UiEditorUsageStats
|
||||
import org.jetbrains.kotlin.tools.projectWizard.core.Context
|
||||
import org.jetbrains.kotlin.tools.projectWizard.core.Reader
|
||||
@@ -15,7 +14,6 @@ import org.jetbrains.kotlin.tools.projectWizard.templates.Template
|
||||
import org.jetbrains.kotlin.tools.projectWizard.templates.settings
|
||||
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.DynamicComponent
|
||||
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.TitledComponent
|
||||
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.borderPanel
|
||||
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.components.DropDownComponent
|
||||
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.components.TextFieldComponent
|
||||
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting.TitledComponentsList
|
||||
@@ -29,10 +27,7 @@ class ModuleSettingsComponent(
|
||||
private val settingsList = TitledComponentsList(emptyList(), context).asSubComponent()
|
||||
private val moduleDependenciesComponent = ModuleDependenciesComponent(context)
|
||||
|
||||
override val component: JComponent = borderPanel {
|
||||
addToCenter(settingsList.component)
|
||||
border = JBUI.Borders.empty(20)
|
||||
}
|
||||
override val component: JComponent = settingsList.component
|
||||
|
||||
var module: Module? = null
|
||||
set(value) {
|
||||
|
||||
+5
@@ -1,5 +1,6 @@
|
||||
package org.jetbrains.kotlin.tools.projectWizard.wizard.ui.secondStep
|
||||
|
||||
import com.intellij.util.ui.JBUI
|
||||
import org.jetbrains.kotlin.idea.projectWizard.UiEditorUsageStats
|
||||
import org.jetbrains.kotlin.tools.projectWizard.core.Context
|
||||
import org.jetbrains.kotlin.tools.projectWizard.core.entity.ValidationResult
|
||||
@@ -9,6 +10,10 @@ import org.jetbrains.kotlin.tools.projectWizard.wizard.IdeWizard
|
||||
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.*
|
||||
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.secondStep.modulesEditor.ModulesEditorComponent
|
||||
import java.awt.BorderLayout
|
||||
import java.awt.Dimension
|
||||
import javax.swing.Box
|
||||
import javax.swing.BoxLayout
|
||||
import javax.swing.JPanel
|
||||
|
||||
class SecondStepWizardComponent(
|
||||
wizard: IdeWizard,
|
||||
|
||||
+93
-20
@@ -1,20 +1,24 @@
|
||||
package org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting
|
||||
|
||||
import com.intellij.ui.layout.panel
|
||||
import com.intellij.util.ui.components.BorderLayoutPanel
|
||||
import org.jetbrains.kotlin.tools.projectWizard.core.Context
|
||||
import org.jetbrains.kotlin.tools.projectWizard.core.entity.ValidationResult
|
||||
import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.SettingReference
|
||||
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.DynamicComponent
|
||||
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.FocusableComponent
|
||||
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.TitledComponent
|
||||
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.*
|
||||
import javax.swing.JComponent
|
||||
import javax.swing.Spring
|
||||
import javax.swing.SpringLayout
|
||||
|
||||
open class TitledComponentsList(
|
||||
private var components: List<TitledComponent>,
|
||||
private val context: Context
|
||||
context: Context,
|
||||
private val stretchY: Boolean = false,
|
||||
private val globalMaxWidth: Int? = null,
|
||||
useBigYGap: Boolean = false,
|
||||
) : DynamicComponent(context) {
|
||||
private val ui = BorderLayoutPanel()
|
||||
|
||||
private val yGap = if (useBigYGap) yGapBig else yGapSmall
|
||||
|
||||
init {
|
||||
ui.addToCenter(createComponentsPanel(components))
|
||||
}
|
||||
@@ -37,23 +41,92 @@ open class TitledComponentsList(
|
||||
ui.addToCenter(createComponentsPanel(newComponents))
|
||||
}
|
||||
|
||||
private fun createComponentsPanel(components: List<TitledComponent>) = customPanel(SpringLayout()) {
|
||||
if (components.isEmpty()) return@customPanel
|
||||
val layout = this.layout as SpringLayout
|
||||
|
||||
fun setSettings(settings: List<SettingReference<*, *>>) {
|
||||
setComponents(
|
||||
settings.map { setting ->
|
||||
DefaultSettingComponent.create(setting, context, needLabel = false)
|
||||
fun JComponent.constraints() = layout.getConstraints(this)
|
||||
|
||||
val componentsWithLabels = components.mapNotNull { component ->
|
||||
if (!component.shouldBeShow()) return@mapNotNull null
|
||||
val label = label(component.title?.let { "$it:" }.orEmpty())
|
||||
TitledComponentData(
|
||||
label.also { add(it) }.constraints(),
|
||||
component.component.also { add(it) }.constraints(),
|
||||
component.needCentering,
|
||||
component.maximumWidth
|
||||
)
|
||||
}
|
||||
|
||||
fun TitledComponentData.centerConstraint() =
|
||||
if (needCentering) component.height * .5f - label.height * .5f
|
||||
else 4.asSpring()
|
||||
|
||||
val labelWidth = componentsWithLabels.fold(componentsWithLabels.first().label.width) { spring, row ->
|
||||
Spring.max(spring, row.label.width)
|
||||
}
|
||||
|
||||
componentsWithLabels.forEach { (label, component, _, componentMaxWidth) ->
|
||||
label.width = labelWidth
|
||||
val maxWidth = componentMaxWidth ?: globalMaxWidth
|
||||
if (maxWidth == null) {
|
||||
component[SpringLayout.EAST] = layout.getConstraint(SpringLayout.EAST, this) - xPanelPadding.asSpring()
|
||||
} else {
|
||||
component.width = maxWidth.asSpring()
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
var lastLabel: SpringLayout.Constraints? = null
|
||||
var lastComponent: SpringLayout.Constraints? = null
|
||||
|
||||
for (data in componentsWithLabels) {
|
||||
val (label, component) = data
|
||||
label.x = xPanelPadding.asSpring()
|
||||
component.x = label[SpringLayout.EAST] + xGap
|
||||
|
||||
if (lastComponent != null && lastLabel != null) {
|
||||
val constraint = lastComponent[SpringLayout.SOUTH] + yGap
|
||||
label.y = constraint + data.centerConstraint()
|
||||
component.y = constraint
|
||||
} else {
|
||||
label.y = data.centerConstraint() + yPanelPadding
|
||||
component.y = yPanelPadding.asSpring()
|
||||
}
|
||||
|
||||
lastLabel = label
|
||||
lastComponent = component
|
||||
}
|
||||
|
||||
if (stretchY) {
|
||||
constraints()[SpringLayout.SOUTH] = lastComponent!![SpringLayout.SOUTH] + yGap
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private fun createComponentsPanel(components: List<TitledComponent>) = panel {
|
||||
components.forEach { component ->
|
||||
if (!component.shouldBeShow()) return@forEach
|
||||
row(component.title?.let { "$it:" }.orEmpty()) {
|
||||
component.component(growX)
|
||||
}
|
||||
}
|
||||
}
|
||||
private const val xGap = 5
|
||||
private const val yGapSmall = 6
|
||||
private const val yGapBig = 12
|
||||
private const val xPanelPadding = 16
|
||||
private const val yPanelPadding = 16
|
||||
}
|
||||
}
|
||||
|
||||
private data class TitledComponentData(
|
||||
val label: SpringLayout.Constraints,
|
||||
val component: SpringLayout.Constraints,
|
||||
val needCentering: Boolean,
|
||||
val maximumWidth: Int?,
|
||||
)
|
||||
}
|
||||
|
||||
private operator fun Spring.plus(other: Spring) = Spring.sum(this, other)
|
||||
private operator fun Spring.plus(gap: Int) = Spring.sum(this, Spring.constant(gap))
|
||||
private operator fun Spring.minus(other: Spring) = this + Spring.minus(other)
|
||||
private operator fun Spring.unaryMinus() = Spring.minus(this)
|
||||
private operator fun Spring.times(by: Float) = Spring.scale(this, by)
|
||||
private fun Int.asSpring() = Spring.constant(this)
|
||||
private operator fun SpringLayout.Constraints.get(edgeName: String) = getConstraint(edgeName)
|
||||
private operator fun SpringLayout.Constraints.set(edgeName: String, spring: Spring) {
|
||||
setConstraint(edgeName, spring)
|
||||
}
|
||||
|
||||
|
||||
|
||||
+2
-2
@@ -35,12 +35,12 @@ import javax.swing.event.DocumentEvent
|
||||
import javax.swing.event.DocumentListener
|
||||
|
||||
internal inline fun label(text: String, bold: Boolean = false, init: JBLabel.() -> Unit = {}) = JBLabel().apply {
|
||||
font = UIUtil.getButtonFont().deriveFont(if (bold) Font.BOLD else Font.PLAIN)
|
||||
font = UIUtil.getLabelFont().deriveFont(if (bold) Font.BOLD else Font.PLAIN)
|
||||
this.text = text
|
||||
init()
|
||||
}
|
||||
|
||||
inline fun customPanel(layout: LayoutManager = BorderLayout(), init: JPanel.() -> Unit = {}) = JPanel(layout).apply(init)
|
||||
inline fun customPanel(layout: LayoutManager? = BorderLayout(), init: JPanel.() -> Unit = {}) = JPanel(layout).apply(init)
|
||||
|
||||
inline fun borderPanel(init: BorderLayoutPanel.() -> Unit = {}) = BorderLayoutPanel().apply(init)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user