1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
|
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.kotlin.tools.projectWizard.wizard.ui
import com.intellij.icons.AllIcons
import com.intellij.openapi.actionSystem.DefaultActionGroup
import com.intellij.openapi.progress.ProgressManager
import com.intellij.openapi.util.NlsContexts
import com.intellij.openapi.util.NlsSafe
import com.intellij.openapi.util.ThrowableComputable
import com.intellij.ui.ColorUtil
import com.intellij.ui.PopupHandler
import com.intellij.ui.SimpleTextAttributes
import com.intellij.ui.ToolbarDecorator
import com.intellij.ui.components.JBLabel
import com.intellij.ui.components.JBTextField
import com.intellij.util.ui.StartupUiUtil
import com.intellij.util.ui.components.BorderLayoutPanel
import org.jetbrains.annotations.Nls
import org.jetbrains.kotlin.idea.KotlinIcons
import org.jetbrains.kotlin.tools.projectWizard.core.entity.ValidationResult
import org.jetbrains.kotlin.tools.projectWizard.moduleConfigurators.*
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.ModuleSubType
import org.jetbrains.kotlin.tools.projectWizard.plugins.kotlin.ModuleType
import org.jetbrains.kotlin.tools.projectWizard.settings.DisplayableSettingItem
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.Module
import org.jetbrains.kotlin.tools.projectWizard.settings.buildsystem.ModuleKind
import java.awt.BorderLayout
import java.awt.Font
import java.awt.LayoutManager
import javax.swing.*
import javax.swing.border.Border
import javax.swing.event.DocumentEvent
import javax.swing.event.DocumentListener
internal inline fun label(@NlsContexts.Label text: String, bold: Boolean = false, init: JBLabel.() -> Unit = {}) = JBLabel().apply {
font = StartupUiUtil.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 borderPanel(init: BorderLayoutPanel.() -> Unit = {}) = BorderLayoutPanel().apply(init)
fun textField(@Nls defaultValue: String?, onUpdated: (value: String) -> Unit) =
JBTextField(defaultValue)
.withOnUpdatedListener(onUpdated)
fun <F : JTextField> F.withOnUpdatedListener(onUpdated: (value: String) -> Unit) = apply {
document.addDocumentListener(object : DocumentListener {
override fun insertUpdate(e: DocumentEvent?) = onUpdated(this@apply.text)
override fun removeUpdate(e: DocumentEvent?) = onUpdated(this@apply.text)
override fun changedUpdate(e: DocumentEvent?) = onUpdated(this@apply.text)
})
}
@NlsSafe
internal fun String.asHtml() = "<html><body>$this</body></html>"
@Nls
fun ValidationResult.ValidationError.asHtml() = when (messages.size) {
0 -> ""
1 -> messages.single()
else -> {
val errorsList = messages.joinToString(separator = "") { "<li>${it}</li>" }
"<ul>$errorsList</ul>".asHtml()
}
}
val ModuleType.icon: Icon
get() = when (this) {
ModuleType.jvm -> KotlinIcons.Wizard.JVM
ModuleType.js -> KotlinIcons.Wizard.JS
ModuleType.native -> KotlinIcons.Wizard.NATIVE
ModuleType.common -> KotlinIcons.SMALL_LOGO
ModuleType.android -> KotlinIcons.Wizard.ANDROID
}
val Module.icon: Icon
get() = configurator.icon
val ModuleSubType.icon: Icon
get() = when (this) {
ModuleSubType.jvm -> KotlinIcons.Wizard.JVM
ModuleSubType.js -> KotlinIcons.Wizard.JS
ModuleSubType.android, ModuleSubType.androidNativeArm32, ModuleSubType.androidNativeArm64 -> KotlinIcons.Wizard.ANDROID
ModuleSubType.iosArm32, ModuleSubType.iosArm64, ModuleSubType.iosX64, ModuleSubType.ios -> KotlinIcons.Wizard.IOS
ModuleSubType.linuxArm32Hfp, ModuleSubType.linuxMips32, ModuleSubType.linuxMipsel32, ModuleSubType.linuxX64 ->
KotlinIcons.Wizard.LINUX
ModuleSubType.macosX64 -> KotlinIcons.Wizard.MAC_OS
ModuleSubType.mingwX64, ModuleSubType.mingwX86 -> KotlinIcons.Wizard.WINDOWS
ModuleSubType.common -> KotlinIcons.SMALL_LOGO
}
val ModuleKind.icon: Icon
get() = when (this) {
ModuleKind.multiplatform -> KotlinIcons.MPP
ModuleKind.singlePlatformJsBrowser -> KotlinIcons.Wizard.JS
ModuleKind.singlePlatformJsNode -> KotlinIcons.Wizard.NODE_JS
ModuleKind.singlePlatformJvm -> KotlinIcons.Wizard.JVM
ModuleKind.target -> AllIcons.Nodes.Module
ModuleKind.singlePlatformAndroid -> KotlinIcons.Wizard.ANDROID
}
val ModuleConfigurator.icon: Icon
get() = when (this) {
is JsBrowserTargetConfigurator, MppLibJsBrowserTargetConfigurator -> KotlinIcons.Wizard.WEB
is JsNodeTargetConfigurator -> KotlinIcons.Wizard.NODE_JS
is IOSSinglePlatformModuleConfigurator -> KotlinIcons.Wizard.IOS
is SimpleTargetConfigurator -> moduleSubType.icon
is TargetConfigurator -> moduleType.icon
else -> moduleKind.icon
}
fun ToolbarDecorator.createPanelWithPopupHandler(popupTarget: JComponent) = createPanel().apply toolbarApply@{
val actionGroup = DefaultActionGroup().apply {
ToolbarDecorator.findAddButton(this@toolbarApply)?.let(this::add)
ToolbarDecorator.findRemoveButton(this@toolbarApply)?.let(this::add)
}
PopupHandler.installPopupMenu(
popupTarget,
actionGroup,
"ToolbarDecoratorPopup"
)
}
fun <C : JComponent> C.addBorder(border: Border): C = apply {
this.border = BorderFactory.createCompoundBorder(border, this.border)
}
fun <T> runWithProgressBar(@Nls title: String, action: () -> T): T =
ProgressManager.getInstance().runProcessWithProgressSynchronously(
ThrowableComputable<T, Exception> { action() },
title,
true,
null
)
val DisplayableSettingItem.fullTextHtml
get() = buildString {
append(text)
greyText?.let { grey ->
append(" ")
append("""<span style="color:${ColorUtil.toHtmlColor(SimpleTextAttributes.GRAYED_ATTRIBUTES.fgColor)};">""")
append(grey)
append("</span>")
}
}.asHtml()
object UIConstants {
const val PADDING = 8
}
|