Wizard: fix layout & text problems

This commit is contained in:
Ilya Kirillov
2020-04-07 16:30:28 +03:00
parent c313916044
commit c1f40907db
13 changed files with 99 additions and 69 deletions
@@ -1,36 +1,36 @@
generator.title=Kotlin (Experimental Wizard)
error.nothing.selected=Neither module nor source set is selected
project.preview=Preview
error.nothing.selected=No module is selected. Select module or source set to configure.
project.preview=Project Structure
additional.buildsystem.settings.kotlin.runtime=Kotlin Runtime
additional.buildsystem.settings.project.jdk=Project JDK
additional.buildsystem.settings.artifact.coordinates=Artifact Coordinates
module.dependencies.module.dependencies=Module dependencies
module.dependencies.add.module.dependency=Add module dependency
module.dependencies.remove.module.dependency=Remove module dependency
module.dependencies.add.module.dependency=Add Module Dependency
module.dependencies.remove.module.dependency=Remove Module Dependency
editor.modules.add=Add {0}
editor.modules.remove.selected.module=Do you want to remove selected {0}
editor.modules.remove.selected.submodules=This will also remove all submodules.
editor.modules.remove.selected.no.undone=This action cannot be undone.
editor.modules.remove.selected.question=Remove selected {0}?
editor.modules.remove.selected.module=Do you want to remove {0} module with all submodules?
editor.modules.remove.selected.target=Do you want to remove {0} target?
editor.modules.remove.selected.question=Remove {0}
editor.modules.remove.selected.remove=Remove
editor.modules.remove.selected.cancel=Cancel
editor.modules.remove.tooltip=Remove {0}
editor.modules.project=Project
editor.modules.add.module=Add a module to the project
editor.modules.no.modules=No modules created
editor.modules.no.modules=No modules created
module.settings.name=Name
module.settings.name.same.as.project=[The same as the project name]
module.settings.name.can.not.be.modified=[Can not be modified]
module.settings.name.same.as.project=<The same as the project name>
module.settings.name.can.not.be.modified=<Can not be modified>
module.settings.name.module.name=Module name
module.settings.template=Template
module.settings.template.none=None
version.provider.downloading.kotlin.version=Downloading Kotlin version
module.settings.dependencies.empty=There is no module dependencies
module.settings.dependencies.empty=No module dependencies added.
module.settings.dependencies.empty.suggest.add=Add module dependency
@@ -32,7 +32,7 @@ class TextFieldComponent(
fun disable(@Nls message: String) {
cachedValueWhenDisabled = getUiValue()
uiComponent.isEditable = false
uiComponent.foreground = UIUtil.getLabelFontColor(UIUtil.FontColor.BRIGHTER)
uiComponent.foreground = UIUtil.getLabelDisabledForeground()
isDisabled = true
updateUiValue(message)
}
@@ -38,7 +38,7 @@ class BuildSystemTypeSettingComponent(
BuildSystemPlugin::type.reference,
context
), Disposable {
override val forceLabelCenteringOffset: Int? = 2
override val forceLabelCenteringOffset: Int? = 3
private val buttons by lazy(LazyThreadSafetyMode.NONE) {
read { setting.type.values.filter { setting.type.filter(this, reference, it) }.map(::BuildSystemChooseButton) }
}
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting.createSettingC
import java.awt.Cursor
import java.awt.event.MouseAdapter
import java.awt.event.MouseEvent
import javax.swing.BorderFactory
import javax.swing.JComponent
class FirstWizardStepComponent(ideWizard: IdeWizard) : WizardStepComponent(ideWizard.context) {
@@ -200,10 +201,15 @@ private class KotlinRuntimeComponentComponent(ideWizard: IdeWizard) : TitledComp
@Suppress("SpellCheckingInspection")
private class HideableSection(text: String, private var component: JComponent) : BorderLayoutPanel() {
private val titledSeparator = TitledSeparator(text)
private val contentPanel = borderPanel {
addBorder(JBUI.Borders.emptyLeft(20))
}
private var isExpanded = false
init {
titledSeparator.label.cursor = Cursor(Cursor.HAND_CURSOR)
addToTop(titledSeparator)
addToCenter(contentPanel)
updateComponent(component)
titledSeparator.addMouseListener(object : MouseAdapter() {
override fun mouseReleased(e: MouseEvent) = update(!isExpanded)
@@ -217,15 +223,14 @@ private class HideableSection(text: String, private var component: JComponent) :
private fun updateComponent(newComponent: JComponent) {
component = newComponent
removeAll()
addToTop(titledSeparator)
addToCenter(newComponent)
contentPanel.removeAll()
contentPanel.addToCenter(newComponent)
update(isExpanded)
}
private fun update(isExpanded: Boolean) {
this.isExpanded = isExpanded
component.isVisible = isExpanded
contentPanel.isVisible = isExpanded
titledSeparator.label.icon = if (isExpanded) AllIcons.General.ArrowDown else AllIcons.General.ArrowRight
}
}
@@ -1,6 +1,8 @@
package org.jetbrains.kotlin.tools.projectWizard.wizard.ui.firstStep
import com.intellij.openapi.util.SystemInfo
import com.intellij.ui.ScrollPaneFactory
import com.intellij.ui.components.JBLabel
import com.intellij.util.ui.JBUI
import com.intellij.util.ui.UIUtil
import org.jetbrains.kotlin.tools.projectWizard.core.Context
@@ -71,10 +73,19 @@ class ProjectTemplateSettingComponent(
}
class TemplateDescriptionComponent : Component() {
private val descriptionLabel = label("") {
fontColor = UIUtil.FontColor.BRIGHTER
private val descriptionLabel = JBLabel().apply {
preferredSize = Dimension(preferredSize.width, 45)
verticalAlignment = SwingConstants.TOP
isFocusable = false
foreground = UIUtil.getContextHelpForeground()
// taken from com.intellij.openapi.ui.panel.ComponentPanelBuilder.createCommentComponent
if (SystemInfo.isMac) {
val font = component.font
val size = font.size2D
val smallFont = font.deriveFont(size - 2.0f)
this.font = smallFont
}
}
fun setTemplate(template: ProjectTemplate) {
@@ -18,12 +18,13 @@ import org.jetbrains.kotlin.utils.addToStdlib.safeAs
import java.awt.Dimension
import javax.swing.Icon
import javax.swing.JPanel
import kotlin.reflect.KFunction0
class ModuleDependenciesComponent(
context: Context
) : TitledComponent(context) {
override val title: String = KotlinNewProjectWizardUIBundle.message("module.dependencies.module.dependencies")
private val dependenciesList = ModuleDependenciesList()
private val dependenciesList = ModuleDependenciesList(::possibleDependencies)
override val forceLabelCenteringOffset: Int? = 4
override val additionalComponentPadding: Int = 1
override val maximumWidth: Int = 500
@@ -102,9 +103,21 @@ private class AddModulesPopUp(
}
}
private class ModuleDependenciesList : AbstractSingleSelectableListWithIcon<Module>() {
private class ModuleDependenciesList(getDependencies: () -> List<Module>) : AbstractSingleSelectableListWithIcon<Module>() {
init {
setEmptyText(KotlinNewProjectWizardUIBundle.message("module.settings.dependencies.empty"))
emptyText.apply {
clear()
appendText(KotlinNewProjectWizardUIBundle.message("module.settings.dependencies.empty"))
appendSecondaryText(
KotlinNewProjectWizardUIBundle.message("module.settings.dependencies.empty.suggest.add"),
SimpleTextAttributes.LINK_ATTRIBUTES
) {
AddModulesPopUp.create(
getDependencies(),
::addDependency
).showInCenterOf(this@ModuleDependenciesList)
}
}
}
override fun ColoredListCellRenderer<Module>.render(value: Module) {
@@ -1,5 +1,6 @@
package org.jetbrains.kotlin.tools.projectWizard.wizard.ui.secondStep
import com.intellij.ui.components.JBLabel
import com.intellij.ui.components.JBTextField
import com.intellij.ui.layout.panel
import com.intellij.util.ui.JBUI
@@ -131,9 +132,9 @@ private class ModuleTemplateComponent(
}.asSubComponent()
override val forceLabelCenteringOffset: Int? = 4
private val templateDescriptionLabel = label("") {
fontColor = UIUtil.FontColor.BRIGHTER
addBorder(JBUI.Borders.empty(4, 4))
private val templateDescriptionLabel = JBLabel().apply {
foreground = UIUtil.getContextHelpForeground()
addBorder(JBUI.Borders.empty(2, 4))
}
override fun onInit() {
@@ -143,6 +144,7 @@ private class ModuleTemplateComponent(
private fun changeTemplateDescription(template: Template?) {
templateDescriptionLabel.text = template?.description
templateDescriptionLabel.isVisible = template?.description != null
}
override val component = borderPanel {
@@ -1,14 +0,0 @@
package org.jetbrains.kotlin.tools.projectWizard.wizard.ui.secondStep
import org.jetbrains.kotlin.tools.projectWizard.wizard.KotlinNewProjectWizardUIBundle
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.Component
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.PanelWithStatusText
import java.awt.BorderLayout
class NothingSelectedComponent : Component() {
override val component = PanelWithStatusText(
BorderLayout(),
KotlinNewProjectWizardUIBundle.message("error.nothing.selected"),
isStatusTextVisible = true
)
}
@@ -7,6 +7,7 @@ import org.jetbrains.kotlin.tools.projectWizard.core.entity.ValidationResult
import org.jetbrains.kotlin.tools.projectWizard.settings.DisplayableSettingItem
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.Module
import org.jetbrains.kotlin.tools.projectWizard.wizard.IdeWizard
import org.jetbrains.kotlin.tools.projectWizard.wizard.KotlinNewProjectWizardUIBundle
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.*
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.secondStep.modulesEditor.ModulesEditorComponent
import java.awt.BorderLayout
@@ -64,10 +65,14 @@ class ModuleSettingsSubStep(
) : SubStep(wizard.context) {
private val moduleSettingsComponent =
ModuleSettingsComponent(wizard.context, uiEditorUsagesStats).asSubComponent()
private val nothingSelectedComponent = NothingSelectedComponent().asSubComponent()
private val nothingSelected = PanelWithStatusText(
BorderLayout(),
KotlinNewProjectWizardUIBundle.message("error.nothing.selected"),
isStatusTextVisible = true
)
private val panel = customPanel {
add(nothingSelectedComponent.component, BorderLayout.CENTER)
add(nothingSelected, BorderLayout.CENTER)
}
var selectedNode: DisplayableSettingItem? = null
@@ -80,10 +85,10 @@ class ModuleSettingsSubStep(
private fun changeComponent() {
panel.removeAll()
val component = when (selectedNode) {
is Module -> moduleSettingsComponent
else -> nothingSelectedComponent
is Module -> moduleSettingsComponent.component
else -> nothingSelected
}
panel.add(component.component, BorderLayout.CENTER)
panel.add(component, BorderLayout.CENTER)
panel.updateUI()
}
@@ -56,6 +56,9 @@ class ModulesEditorComponent(
override fun onInit() {
super.onInit()
updateModel()
if (editable) {
value?.firstOrNull()?.let(tree::selectModule)
}
}
fun updateModel() {
@@ -67,7 +67,7 @@ class ModulesEditorToolbarDecorator(
null -> ""
}
text = KotlinNewProjectWizardUIBundle.message("editor.modules.add", moduleKindTextToAdd)
text = KotlinNewProjectWizardUIBundle.message("editor.modules.add", moduleKindTextToAdd.capitalize())
}
event.presentation.isEnabled
}
@@ -77,12 +77,14 @@ class ModulesEditorToolbarDecorator(
if (Messages.showOkCancelDialog(
tree,
buildString {
appendln(KotlinNewProjectWizardUIBundle.message("editor.modules.remove.selected.module", moduleKindText))
val moduleName = selectedModule?.name!!
appendln(KotlinNewProjectWizardUIBundle.message("editor.modules.remove.selected.module", moduleName))
if (tree.selectedSettingItem.safeAs<Module>()?.kind != ModuleKind.target) {
appendln(KotlinNewProjectWizardUIBundle.message("editor.modules.remove.selected.submodules"))
appendln(KotlinNewProjectWizardUIBundle.message("editor.modules.remove.selected.module", moduleName))
} else {
appendln(KotlinNewProjectWizardUIBundle.message("editor.modules.remove.selected.target", moduleName))
}
appendln()
appendln(KotlinNewProjectWizardUIBundle.message("editor.modules.remove.selected.no.undone"))
},
KotlinNewProjectWizardUIBundle.message("editor.modules.remove.selected.question", moduleKindText),
KotlinNewProjectWizardUIBundle.message("editor.modules.remove.selected.remove"),
@@ -98,7 +100,7 @@ class ModulesEditorToolbarDecorator(
isEnabled = tree.selectedSettingItem is Module
text = KotlinNewProjectWizardUIBundle.message(
"editor.modules.remove.tooltip",
selectedModuleKindText?.let { " $it" }.orEmpty()
selectedModuleKindText?.let { " ${it.capitalize()}" }.orEmpty()
)
}
event.presentation.isEnabled
@@ -108,8 +110,11 @@ class ModulesEditorToolbarDecorator(
setMoveUpAction(null)
}
private val selectedModule
get() = tree.selectedSettingItem.safeAs<Module>()
private val selectedModuleKindText
get() = tree.selectedSettingItem.safeAs<Module>()?.kindText
get() = selectedModule?.kindText
fun createToolPanel(): JComponent = toolbarDecorator
.createPanelWithPopupHandler(tree)
@@ -80,7 +80,7 @@ open class TitledComponentsList(
var lastLabel: SpringLayout.Constraints? = null
var lastComponent: SpringLayout.Constraints? = null
for (data in componentsWithLabels) {
for ((index, data) in componentsWithLabels.withIndex()) {
val (label, component) = data
label.x = xPanelPadding.asSpring()
component.x = label[SpringLayout.EAST] + xGap
@@ -99,7 +99,7 @@ open class TitledComponentsList(
}
if (stretchY) {
constraints()[SpringLayout.SOUTH] = lastComponent!![SpringLayout.SOUTH] + yGap
constraints()[SpringLayout.SOUTH] = lastComponent!![SpringLayout.SOUTH]
}
}
@@ -1,6 +1,6 @@
buildsystem.type.gradle.groovy=Gradle Groovy
buildsystem.type.gradle.kotlin=Gradle Kotlin
buildsystem.type.intellij=IntelliJ
buildsystem.type.intellij=IntelliJ build system
buildsystem.type.maven=Maven
error.template.not.found=Template with an id {0} is not found
@@ -21,7 +21,7 @@ module.kind.module=Module
module.kind.mpp.module=MPP Module
module.kind.target=Target
plugin.buildsystem.setting.type=Build System
plugin.buildsystem.setting.type=Build system
plugin.buildsystem.setting.type.error.wrong.project.kind={0} cannot be generated using {1}
plugin.kotlin.downloading.kotlin.versions=Downloading list of Kotlin versions
@@ -47,7 +47,7 @@ plugin.structure.setting.version=Version
plugin.android.setting.sdk=Android SDK
validation.should.not.be.blank={0} should not be blank
validation.should.not.be.blank=Specify {0}
validation.identifier={0} should consist only of letters, digits{1}
validation.identifier.additional.symbols=, and symbols: {0}
validation.file.should.exists=File for {0} should exists
@@ -69,14 +69,14 @@ module.name.with.name=Module name {0}
module.configurator.js=JS for Browser
module.configurator.android=Android
module.configurator.android.setting.android.plugin=Android Plugin
module.configurator.android.setting.android.plugin=Android plugin
module.configurator.android.setting.android.plugin.application=Android Application
module.configurator.android.setting.android.plugin.library=Android
module.configurator.common=Common
module.configurator.jvm=JVM
module.configurator.jvm.setting.target.jvm.version=Target JVM Version
module.configurator.jvm.setting.target.jvm.version=Target JVM version
module.configurator.jvm.setting.java.support=Java language support
module.configurator.mpp=Multiplatform
@@ -86,40 +86,40 @@ module.configurator.ios.requires.xcode=Requires Xcode
module.configurator.js.browser=Browser
module.configurator.js.node=Node.js
module.configurator.tests.setting.framework=Test Framework
module.configurator.tests.setting.framework=Test framework
module.configurator.tests.setting.framework.junit4=JUnit 4
module.configurator.tests.setting.framework.junit5=JUnit 5
module.configurator.tests.setting.framework.test.ng=Test NG
module.configurator.tests.setting.framework.test.ng=TestNG
module.configurator.tests.setting.framework.js=JavaScript
module.configurator.tests.setting.framework.common=common
module.configurator.native.for.current.system=Your system
project.template.empty.singleplatform.title=Backend Application
project.template.empty.singleplatform.description=Create a backend application with Kotlin/JVM.
project.template.empty.singleplatform.description=Backend application with Kotlin/JVM.
project.template.empty.mpp.title=Multiplatform Application
project.template.empty.mpp.description=Create applications for different platforms that support sharing common code.
project.template.empty.mpp.description=Applications for different platforms that support sharing common code.
project.template.empty.jvm.console.title=Console Application
project.template.empty.jvm.console.description=Create a console application with Kotlin/JVM. Use it for prototyping or testing purposes.
project.template.empty.jvm.console.description=Console application with Kotlin/JVM. Use it for prototyping or testing purposes.
project.template.mpp.lib.title=Multiplatform Library
project.template.mpp.lib.description=Create a library for sharing common code among different platforms.
project.template.mpp.lib.description=Library for sharing common code among different platforms.
project.template.full.stack.title=Full-Stack Web Application
project.template.full.stack.description=Create a fully-functional web application using Kotlin/JS for the frontend and Kotlin/JVM for the backend.
project.template.full.stack.description=Fully-functional web application using Kotlin/JS for the frontend and Kotlin/JVM for the backend.
project.template.native.console.title=Native Application
project.template.native.console.description=Create an application with Kotlin/Native that works as a standalone application under a specific platform.
project.template.native.console.description=Application with Kotlin/Native that works as a standalone application under a specific platform.
project.template.frontend.title=Frontend Application
project.template.frontend.description=Create a frontend application with Kotlin/JS if you already have a backend.
project.template.frontend.description=Frontend application with Kotlin/JS if you already have a backend.
project.template.mpp.mobile.title=Multiplatform Mobile Application
project.template.mpp.mobile.description=Create mobile applications for iOS and Android with Kotlin Multiplatform Mobile, which supports sharing common code between platforms.
project.template.mpp.mobile.description=Mobile applications for iOS and Android with Kotlin Multiplatform Mobile, which supports sharing common code between platforms.
project.template.mpp.mobile.lib.title=Multiplatform Mobile Library
project.template.mpp.mobile.lib.description=Create a library that supports sharing code between iOS and Android.
project.template.mpp.mobile.lib.description=Library that supports sharing code between iOS and Android.
module.template.console.jvm.title=Console Application