Wizard: rework build system component
This commit is contained in:
+16
@@ -0,0 +1,16 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.tools.projectWizard.wizard.ui.firstStep
|
||||||
|
|
||||||
|
import com.intellij.openapi.actionSystem.ActionGroup
|
||||||
|
import com.intellij.openapi.actionSystem.impl.ActionToolbarImpl
|
||||||
|
|
||||||
|
// needed for <=192 to work correctly
|
||||||
|
abstract class ActionToolbarImplWrapper(
|
||||||
|
place: String,
|
||||||
|
actionGroup: ActionGroup,
|
||||||
|
horizontal: Boolean
|
||||||
|
) : ActionToolbarImpl(place, actionGroup, horizontal)
|
||||||
+17
@@ -0,0 +1,17 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.tools.projectWizard.wizard.ui.firstStep
|
||||||
|
|
||||||
|
import com.intellij.openapi.actionSystem.ActionGroup
|
||||||
|
import com.intellij.openapi.actionSystem.impl.ActionToolbarImpl
|
||||||
|
import com.intellij.openapi.keymap.ex.KeymapManagerEx
|
||||||
|
|
||||||
|
// needed for <=192 to work correctly
|
||||||
|
abstract class ActionToolbarImplWrapper(
|
||||||
|
place: String,
|
||||||
|
actionGroup: ActionGroup,
|
||||||
|
horizontal: Boolean
|
||||||
|
) : ActionToolbarImpl(place, actionGroup, horizontal, KeymapManagerEx.getInstanceEx())
|
||||||
+17
@@ -0,0 +1,17 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.tools.projectWizard.wizard.ui.firstStep
|
||||||
|
|
||||||
|
import com.intellij.openapi.actionSystem.ActionGroup
|
||||||
|
import com.intellij.openapi.actionSystem.impl.ActionToolbarImpl
|
||||||
|
import com.intellij.openapi.keymap.ex.KeymapManagerEx
|
||||||
|
|
||||||
|
// needed for <=192 to work correctly
|
||||||
|
abstract class ActionToolbarImplWrapper(
|
||||||
|
place: String,
|
||||||
|
actionGroup: ActionGroup,
|
||||||
|
horizontal: Boolean
|
||||||
|
) : ActionToolbarImpl(place, actionGroup, horizontal, KeymapManagerEx.getInstanceEx())
|
||||||
+72
-131
@@ -1,35 +1,29 @@
|
|||||||
package org.jetbrains.kotlin.tools.projectWizard.wizard.ui.firstStep
|
package org.jetbrains.kotlin.tools.projectWizard.wizard.ui.firstStep
|
||||||
|
|
||||||
import com.intellij.ide.ui.UISettings
|
import com.intellij.icons.AllIcons
|
||||||
import com.intellij.openapi.Disposable
|
import com.intellij.openapi.actionSystem.*
|
||||||
import com.intellij.openapi.actionSystem.ex.ActionButtonLook
|
import com.intellij.openapi.actionSystem.ex.ActionButtonLook
|
||||||
import com.intellij.ui.layout.panel
|
import com.intellij.openapi.actionSystem.impl.ActionButton
|
||||||
import com.intellij.util.ui.JBInsets
|
import com.intellij.openapi.actionSystem.impl.ActionButtonWithText
|
||||||
import com.intellij.util.ui.JBUI
|
import com.intellij.openapi.actionSystem.impl.ActionToolbarImpl
|
||||||
import com.intellij.util.ui.UIUtil
|
import com.intellij.openapi.util.Disposer
|
||||||
import com.intellij.util.ui.UIUtilities
|
import icons.GradleIcons
|
||||||
|
import icons.OpenapiIcons
|
||||||
|
import org.jetbrains.kotlin.idea.KotlinIcons
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.core.Context
|
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.ValidationResult
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.core.entity.isSpecificError
|
import org.jetbrains.kotlin.tools.projectWizard.core.entity.isSpecificError
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.core.entity.settings.DropDownSettingType
|
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.core.entity.settings.reference
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.BuildSystemPlugin
|
import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.BuildSystemPlugin
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.BuildSystemType
|
import org.jetbrains.kotlin.tools.projectWizard.plugins.buildSystem.BuildSystemType
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.KotlinPlugin
|
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting.IdeaBasedComponentValidator
|
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting.IdeaBasedComponentValidator
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting.SettingComponent
|
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting.SettingComponent
|
||||||
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting.ValidationIndicator
|
import org.jetbrains.kotlin.tools.projectWizard.wizard.ui.setting.ValidationIndicator
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
import java.awt.Cursor
|
|
||||||
import java.awt.Dimension
|
import java.awt.Dimension
|
||||||
import java.awt.Graphics
|
import java.awt.Insets
|
||||||
import java.awt.Rectangle
|
|
||||||
import java.awt.event.MouseAdapter
|
|
||||||
import java.awt.event.MouseEvent
|
|
||||||
import javax.swing.JComponent
|
import javax.swing.JComponent
|
||||||
import javax.swing.SwingConstants
|
|
||||||
import javax.swing.SwingUtilities
|
|
||||||
|
|
||||||
|
|
||||||
class BuildSystemTypeSettingComponent(
|
class BuildSystemTypeSettingComponent(
|
||||||
@@ -37,24 +31,18 @@ class BuildSystemTypeSettingComponent(
|
|||||||
) : SettingComponent<BuildSystemType, DropDownSettingType<BuildSystemType>>(
|
) : SettingComponent<BuildSystemType, DropDownSettingType<BuildSystemType>>(
|
||||||
BuildSystemPlugin::type.reference,
|
BuildSystemPlugin::type.reference,
|
||||||
context
|
context
|
||||||
), Disposable {
|
) {
|
||||||
override val forceLabelCenteringOffset: Int? = 3
|
|
||||||
private val buttons by lazy(LazyThreadSafetyMode.NONE) {
|
private val toolbar by lazy(LazyThreadSafetyMode.NONE) {
|
||||||
read { setting.type.values.filter { setting.type.filter(this, reference, it) }.map(::BuildSystemChooseButton) }
|
val buildSystemTypes = read { setting.type.values.filter { setting.type.filter(this, reference, it) } }
|
||||||
|
val actionGroup = DefaultActionGroup(buildSystemTypes.map(::BuildSystemTypeAction))
|
||||||
|
BuildSystemToolbar(ActionPlaces.UNKNOWN, actionGroup, true)
|
||||||
}
|
}
|
||||||
override val component = panel {
|
override val component: JComponent by lazy(LazyThreadSafetyMode.NONE) {
|
||||||
row {
|
toolbar
|
||||||
buttons.forEach { button -> button(growX) }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override val validationIndicator: ValidationIndicator = IdeaBasedComponentValidator(this, component)
|
override val validationIndicator: ValidationIndicator = IdeaBasedComponentValidator(Disposer.newDisposable(), component)
|
||||||
|
|
||||||
override fun onInit() {
|
|
||||||
super.onInit()
|
|
||||||
updateButtonsValidationState()
|
|
||||||
updateButtons()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun navigateTo(error: ValidationResult.ValidationError) {
|
override fun navigateTo(error: ValidationResult.ValidationError) {
|
||||||
if (validationIndicator.validationState.isSpecificError(error)) {
|
if (validationIndicator.validationState.isSpecificError(error)) {
|
||||||
@@ -62,117 +50,70 @@ class BuildSystemTypeSettingComponent(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onValueUpdated(reference: SettingReference<*, *>?) {
|
|
||||||
super.onValueUpdated(reference)
|
|
||||||
if (reference == BuildSystemPlugin::type.reference) {
|
|
||||||
updateButtons()
|
|
||||||
}
|
|
||||||
if (reference == KotlinPlugin::projectKind.reference) {
|
|
||||||
updateButtonsValidationState()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun updateButtonsValidationState() {
|
|
||||||
buttons.forEach(BuildSystemChooseButton::updateValidationState)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun validateBuildSystem(buildSystem: BuildSystemType) = read {
|
private fun validateBuildSystem(buildSystem: BuildSystemType) = read {
|
||||||
setting.validator.validate(this, buildSystem)
|
setting.validator.validate(this, buildSystem)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateButtons() {
|
private inner class BuildSystemTypeAction(
|
||||||
buttons.forEach(BuildSystemChooseButton::updateSelectedBuildSystem)
|
val buildSystemType: BuildSystemType
|
||||||
|
) : ToggleAction(buildSystemType.text, null, buildSystemType.icon) {
|
||||||
|
override fun isSelected(e: AnActionEvent): Boolean = value == buildSystemType
|
||||||
|
|
||||||
|
override fun setSelected(e: AnActionEvent, state: Boolean) {
|
||||||
|
if (state) {
|
||||||
|
value = buildSystemType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun update(e: AnActionEvent) {
|
||||||
|
super.update(e)
|
||||||
|
val validationResult = validateBuildSystem(buildSystemType)
|
||||||
|
e.presentation.isEnabled = validationResult.isOk
|
||||||
|
e.presentation.description = validationResult.safeAs<ValidationResult.ValidationError>()?.messages?.firstOrNull()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun dispose() {}
|
private inner class BuildSystemToolbar(
|
||||||
|
place: String,
|
||||||
|
actionGroup: ActionGroup,
|
||||||
|
horizontal: Boolean
|
||||||
|
) : ActionToolbarImplWrapper(place, actionGroup, horizontal) {
|
||||||
|
override fun createToolbarButton(
|
||||||
|
action: AnAction,
|
||||||
|
look: ActionButtonLook?,
|
||||||
|
place: String,
|
||||||
|
presentation: Presentation,
|
||||||
|
minimumSize: Dimension
|
||||||
|
): ActionButton = BuildSystemChooseButton(action as BuildSystemTypeAction, presentation, place, minimumSize)
|
||||||
|
}
|
||||||
|
|
||||||
private inner class BuildSystemChooseButton(private val buildSystemType: BuildSystemType) : JComponent() {
|
private inner class BuildSystemChooseButton(
|
||||||
private val look = ActionButtonLook.SYSTEM_LOOK
|
action: BuildSystemTypeAction,
|
||||||
|
presentation: Presentation,
|
||||||
init {
|
place: String?,
|
||||||
font = UIUtil.getLabelFont()
|
minimumSize: Dimension
|
||||||
preferredSize = Dimension(preferredSize.width, BUTTON_HEIGHT)
|
) : ActionButtonWithText(action, presentation, place, minimumSize) {
|
||||||
minimumSize = Dimension(minimumSize.width, BUTTON_HEIGHT)
|
override fun getInsets(): Insets = super.getInsets().apply {
|
||||||
cursor = Cursor(Cursor.HAND_CURSOR)
|
right += left
|
||||||
addMouseListener(object : MouseAdapter() {
|
left = 0
|
||||||
override fun mouseClicked(e: MouseEvent?) = modify {
|
|
||||||
if (isValidBuildSystem) {
|
|
||||||
BuildSystemPlugin::type.reference.setValue(buildSystemType)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun mouseEntered(e: MouseEvent?) {
|
|
||||||
hovered = true
|
|
||||||
repaint()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun mouseExited(e: MouseEvent?) {
|
|
||||||
hovered = false
|
|
||||||
repaint()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateSelectedBuildSystem() {
|
override fun getPreferredSize(): Dimension {
|
||||||
val currentBuildSystem = read { BuildSystemPlugin::type.settingValue }
|
val old = super.getPreferredSize()
|
||||||
selected = currentBuildSystem == buildSystemType
|
return Dimension(old.width + LEFT_RIGHT_PADDING * 2, old.height + TOP_BOTTOM_PADDING * 2)
|
||||||
repaint()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateValidationState() {
|
|
||||||
val validationResult = validateBuildSystem(buildSystemType)
|
|
||||||
isValidBuildSystem = validationResult.isOk
|
|
||||||
cursor = Cursor(if (isValidBuildSystem) Cursor.HAND_CURSOR else Cursor.DEFAULT_CURSOR)
|
|
||||||
toolTipText = validationResult.safeAs<ValidationResult.ValidationError>()
|
|
||||||
?.messages
|
|
||||||
?.firstOrNull()
|
|
||||||
?.takeUnless { isSelectedAndInvalid }
|
|
||||||
repaint()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// mostly copied from com.intellij.openapi.actionSystem.impl.ActionButtonWithText.paintComponent
|
|
||||||
override fun paintComponent(g: Graphics) {
|
|
||||||
UISettings.setupAntialiasing(g)
|
|
||||||
|
|
||||||
val fm = getFontMetrics(font)
|
|
||||||
val viewRect = Rectangle(size)
|
|
||||||
JBInsets.removeFrom(viewRect, insets)
|
|
||||||
|
|
||||||
val iconRect = Rectangle()
|
|
||||||
val textRect = Rectangle()
|
|
||||||
val text = SwingUtilities.layoutCompoundLabel(
|
|
||||||
this, fm, buildSystemType.text, null,
|
|
||||||
SwingConstants.CENTER, SwingConstants.CENTER,
|
|
||||||
SwingConstants.CENTER, SwingConstants.TRAILING,
|
|
||||||
viewRect, iconRect, textRect, 0
|
|
||||||
)
|
|
||||||
|
|
||||||
look.paintLookBackground(g, viewRect, bgColor())
|
|
||||||
|
|
||||||
g.color = if (isValidBuildSystem) foreground else UIUtil.getInactiveTextColor()
|
|
||||||
UIUtilities.drawStringUnderlineCharAt(
|
|
||||||
this, g, text, -1,
|
|
||||||
textRect.x, textRect.y + fm.ascent
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun bgColor() = when {
|
|
||||||
selected -> JBUI.CurrentTheme.ActionButton.pressedBackground()
|
|
||||||
hovered -> JBUI.CurrentTheme.ActionButton.hoverBackground()
|
|
||||||
else -> background
|
|
||||||
}
|
|
||||||
|
|
||||||
private var selected: Boolean = false
|
|
||||||
private var hovered: Boolean = false
|
|
||||||
private var isValidBuildSystem: Boolean = true
|
|
||||||
|
|
||||||
private val isSelectedAndInvalid
|
|
||||||
get() = selected && !isValidBuildSystem
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val BUTTON_HEIGHT = 25
|
private const val LEFT_RIGHT_PADDING = 10
|
||||||
|
private const val TOP_BOTTOM_PADDING = 4
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val BuildSystemType.icon
|
||||||
|
get() = when (this) {
|
||||||
|
BuildSystemType.GradleKotlinDsl -> KotlinIcons.GRADLE_SCRIPT
|
||||||
|
BuildSystemType.GradleGroovyDsl -> GradleIcons.Gradle
|
||||||
|
BuildSystemType.Maven -> OpenapiIcons.RepositoryLibraryLogo
|
||||||
|
BuildSystemType.Jps -> AllIcons.Nodes.Module
|
||||||
|
}
|
||||||
+2
-1
@@ -1,6 +1,7 @@
|
|||||||
buildsystem.type.gradle.groovy=Gradle Groovy
|
buildsystem.type.gradle.groovy=Gradle Groovy
|
||||||
buildsystem.type.gradle.kotlin=Gradle Kotlin
|
buildsystem.type.gradle.kotlin=Gradle Kotlin
|
||||||
buildsystem.type.intellij=IntelliJ build system
|
buildsystem.type.intellij=IntelliJ
|
||||||
|
buildsystem.type.intellij.full=IntelliJ build system
|
||||||
buildsystem.type.maven=Maven
|
buildsystem.type.maven=Maven
|
||||||
|
|
||||||
error.template.not.found=Template with an id {0} is not found
|
error.template.not.found=Template with an id {0} is not found
|
||||||
|
|||||||
+6
-3
@@ -45,7 +45,7 @@ abstract class BuildSystemPlugin(context: Context) : Plugin(context) {
|
|||||||
KotlinNewProjectWizardBundle.message(
|
KotlinNewProjectWizardBundle.message(
|
||||||
"plugin.buildsystem.setting.type.error.wrong.project.kind",
|
"plugin.buildsystem.setting.type.error.wrong.project.kind",
|
||||||
projectKind,
|
projectKind,
|
||||||
buildSystemType.text
|
buildSystemType.fullText
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
} else ValidationResult.OK
|
} else ValidationResult.OK
|
||||||
@@ -122,10 +122,13 @@ data class BuildFileData(
|
|||||||
@NonNls val buildFileName: String
|
@NonNls val buildFileName: String
|
||||||
)
|
)
|
||||||
|
|
||||||
enum class BuildSystemType(@Nls override val text: String) : DisplayableSettingItem {
|
enum class BuildSystemType(@Nls override val text: String, val fullText: String = text) : DisplayableSettingItem {
|
||||||
GradleKotlinDsl(KotlinNewProjectWizardBundle.message("buildsystem.type.gradle.kotlin")),
|
GradleKotlinDsl(KotlinNewProjectWizardBundle.message("buildsystem.type.gradle.kotlin")),
|
||||||
GradleGroovyDsl(KotlinNewProjectWizardBundle.message("buildsystem.type.gradle.groovy")),
|
GradleGroovyDsl(KotlinNewProjectWizardBundle.message("buildsystem.type.gradle.groovy")),
|
||||||
Jps(KotlinNewProjectWizardBundle.message("buildsystem.type.intellij")),
|
Jps(
|
||||||
|
KotlinNewProjectWizardBundle.message("buildsystem.type.intellij"),
|
||||||
|
KotlinNewProjectWizardBundle.message("buildsystem.type.intellij.full")
|
||||||
|
),
|
||||||
Maven(KotlinNewProjectWizardBundle.message("buildsystem.type.maven"))
|
Maven(KotlinNewProjectWizardBundle.message("buildsystem.type.maven"))
|
||||||
|
|
||||||
;
|
;
|
||||||
|
|||||||
Reference in New Issue
Block a user