Wizard: group project templates into the categories on the first step

#KT-39700 fixed
This commit is contained in:
Ilya Kirillov
2020-06-18 20:40:23 +03:00
parent bfedeed2c1
commit 11a680d7d8
4 changed files with 107 additions and 15 deletions
@@ -0,0 +1,85 @@
/*
* 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
import com.intellij.ui.ColoredListCellRenderer
import com.intellij.ui.SeparatorWithText
import com.intellij.ui.components.JBList
import java.awt.Component
import javax.swing.JList
import javax.swing.ListCellRenderer
class ListWithSeparators<V>(
private val groups: List<ListGroup<V>>,
render: ColoredListCellRenderer<V>.(V) -> Unit,
onValueSelected: (V?) -> Unit
) : JBList<V>() {
private val values: List<V> = groups.flatMap { it.values }
@OptIn(ExperimentalStdlibApi::class)
private val elementIndexToPreviousSeparator: Map<Int, ListGroup<V>> = groups
.scan(0) { startElement, group -> startElement + group.values.size }
.dropLast(1)
.mapIndexed { groupIndex, startElement -> startElement to groups[groupIndex] }
.toMap()
private fun updateValues(newValues: List<V>) {
setModel(createDefaultListModel(newValues))
if (newValues.isNotEmpty()) {
selectedIndex = 0
}
}
init {
updateValues(values)
selectionModel.addListSelectionListener { e ->
if (e.valueIsAdjusting) return@addListSelectionListener
val selectedValue = when (selectedIndex) {
-1 -> null
else -> this.model.getElementAt(selectedIndex)
}
onValueSelected(selectedValue)
}
cellRenderer = object : ListCellRenderer<V> {
val separator = SeparatorWithText()
private val simpleRenderer = object : ColoredListCellRenderer<V>() {
public override fun customizeCellRenderer(
list: JList<out V>,
value: V?,
index: Int,
selected: Boolean,
hasFocus: Boolean
) {
render(value ?: return)
}
}
override fun getListCellRendererComponent(
list: JList<out V>?,
value: V,
index: Int,
isSelected: Boolean,
cellHasFocus: Boolean
): Component {
return borderPanel {
background = this@ListWithSeparators.background
elementIndexToPreviousSeparator[index]?.let { group ->
addToTop(separator.apply { caption = group.title })
}
addToCenter(simpleRenderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus))
}
}
}
}
data class ListGroup<V>(
val title: String,
val values: List<V>
)
}
@@ -1,6 +1,7 @@
package org.jetbrains.kotlin.tools.projectWizard.wizard.ui.firstStep
import com.intellij.ui.ScrollPaneFactory
import com.intellij.ui.SeparatorWithText
import com.intellij.util.ui.JBUI
import org.jetbrains.kotlin.idea.KotlinIcons
import org.jetbrains.kotlin.tools.projectWizard.core.Context
@@ -27,9 +28,15 @@ class ProjectTemplateSettingComponent(
override val forceLabelCenteringOffset: Int? = 4
private val templateDescriptionComponent = TemplateDescriptionComponent().asSubComponent()
private val list = ImmutableSingleSelectableListWithIcon(
setting.type.values,
renderValue = { value ->
private val templateGroups = setting.type.values
.groupBy { it.projectKind }
.map { (group, templates) ->
ListWithSeparators.ListGroup(group.text, templates)
}
private val list = ListWithSeparators(
templateGroups,
render = { value ->
icon = value.icon
append(value.title)
},
@@ -69,7 +76,7 @@ class ProjectTemplateSettingComponent(
}
companion object {
private const val HEIGHT = 230
private const val HEIGHT = 310
}
}