diff --git a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/TitleBarView.kt b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/TitleBarView.kt index e1e2ea1a9..d2a1fa36d 100644 --- a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/TitleBarView.kt +++ b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/TitleBarView.kt @@ -32,9 +32,11 @@ fun DecoratedWindowScope.TitleBarView() { Row(Modifier.align(Alignment.Start)) { Dropdown(Modifier.height(30.dp), menuContent = { MainViewModel.views.forEach { - selectableItem(MainViewModel.currentView == it, { - MainViewModel.currentView = it - }) { + selectableItem( + selected = MainViewModel.currentView == it, + onClick = { + MainViewModel.currentView = it + }) { Row( horizontalArrangement = Arrangement.spacedBy(4.dp), verticalAlignment = Alignment.CenterVertically, diff --git a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/Dropdowns.kt b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/Dropdowns.kt index a2f2c5221..a42bc7c44 100644 --- a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/Dropdowns.kt +++ b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/Dropdowns.kt @@ -14,6 +14,7 @@ import org.jetbrains.jewel.ui.Outline import org.jetbrains.jewel.ui.component.Dropdown import org.jetbrains.jewel.ui.component.Text import org.jetbrains.jewel.ui.component.separator +import org.jetbrains.jewel.ui.component.styling.DropdownStyle @Composable @View(title = "Dropdowns", position = 3) @@ -110,5 +111,64 @@ fun Dropdowns() { ) { Text(selected) } + Dropdown( + menuContent = { + items.forEach { + if (it == "---") { + separator() + } else { + selectableItem( + iconResource = dropdownIcons.random(), + iconClass = DropdownStyle::class.java, + selected = false, + onClick = { } + ) { + Text(it) + } + } + } + submenu(submenu = { + items.forEach { + if (it == "---") { + separator() + } else { + selectableItem( + iconResource = dropdownIcons.random(), + iconClass = DropdownStyle::class.java, + selected = false, + onClick = { } + ) { + Text(it) + } + } + } + separator() + submenu(submenu = { + items.forEach { + if (it == "---") { + separator() + } else { + selectableItem( + iconResource = dropdownIcons.random(), + iconClass = DropdownStyle::class.java, + selected = false, + onClick = { } + ) { + Text(it) + } + } + } + }) { + Text("Submenu2") + } + }) { + Text("Submenu") + } + }, + ) { + Text("With icons") + } } } + +private val dropdownIcons = listOf("icons/search.svg", "icons/close.svg", null) \ No newline at end of file diff --git a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/Links.kt b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/Links.kt index 42e892752..6a4dead2e 100644 --- a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/Links.kt +++ b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/view/component/Links.kt @@ -43,9 +43,11 @@ fun Links() { if (it == "---") { separator() } else { - selectableItem(selected == it, { - selected = it - }) { + selectableItem( + selected = selected == it, + onClick = { + selected = it + }) { Text(it) } } diff --git a/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Menu.kt b/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Menu.kt index 8ae86fc24..ac00bc6f5 100644 --- a/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Menu.kt +++ b/ui/src/main/kotlin/org/jetbrains/jewel/ui/component/Menu.kt @@ -162,21 +162,7 @@ internal fun MenuContent( ) { Column(Modifier.verticalScroll(scrollState).padding(style.metrics.contentPadding)) { items.forEach { - //todo here Fab wip move this in showMenuItem or we lose the background color tint - Row(horizontalArrangement = Arrangement.spacedBy(style.metrics.iconGap)) { - if (anyIconItem) { - val (iconResource, iconClass) = when (it) { - is MenuSelectableItem -> it.iconResource to it.iconClass - else -> null to this::class.java - } - if (iconResource != null) { - Icon(resource = iconResource, contentDescription = null, iconClass = iconClass) - } else { - Box(modifier = Modifier.size(style.metrics.iconSize)) - } - } - } - ShowMenuItem(it) + ShowMenuItem(it, anyIconItem, anyKeyBinding) } } @@ -190,18 +176,26 @@ internal fun MenuContent( } @Composable -private fun ShowMenuItem(item: MenuItem) { +private fun ShowMenuItem(item: MenuItem, iconGap: Boolean = false, keybindingGap: Boolean = false) { when (item) { is MenuSelectableItem -> MenuItem( selected = item.isSelected, onClick = item.onClick, enabled = item.isEnabled, + iconGap = iconGap, + keybindingGap = keybindingGap, + iconResource = item.iconResource, + iconClass = item.iconClass, + keybinding = item.keybinding, content = item.content, ) is SubmenuItem -> MenuSubmenuItem( enabled = item.isEnabled, submenu = item.submenu, + iconGap = iconGap, + iconResource = item.iconResource, + iconClass = item.iconClass, content = item.content, ) @@ -349,6 +343,11 @@ internal fun MenuItem( onClick: () -> Unit, modifier: Modifier = Modifier, enabled: Boolean = true, + iconResource: String?, + iconClass: Class<*>, + keybinding: Set?, + iconGap: Boolean, + keybindingGap: Boolean, interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, style: MenuStyle = JewelTheme.menuStyle, content: @Composable () -> Unit, @@ -414,21 +413,37 @@ internal fun MenuItem( ) { val backgroundColor by itemColors.backgroundFor(itemState) - Box( - Modifier.fillMaxWidth() + Row( + modifier = Modifier.fillMaxWidth() .drawItemBackground(itemMetrics, backgroundColor) .padding(itemMetrics.contentPadding), + horizontalArrangement = Arrangement.spacedBy(4.dp) ) { + if (iconGap) { + if (iconResource != null) { + Icon(resource = iconResource, contentDescription = null, iconClass = iconClass) + } else { + Box(modifier = Modifier.size(16.dp)) // todo 16 dp move to style.metrics.iconSize + } + } content() + if (keybindingGap) { + val keybindingText = keybinding?.joinToString("+") { it.toString() } ?: "" + Text(keybindingText) + } } } } } + @Composable public fun MenuSubmenuItem( modifier: Modifier = Modifier, enabled: Boolean = true, + iconGap: Boolean, + iconResource: String?, + iconClass: Class<*>, interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, style: MenuStyle = JewelTheme.menuStyle, submenu: MenuScope.() -> Unit, @@ -493,6 +508,13 @@ public fun MenuSubmenuItem( Modifier.fillMaxWidth().padding(menuMetrics.itemMetrics.contentPadding), verticalAlignment = Alignment.CenterVertically, ) { + if (iconGap) { + if (iconResource != null) { + Icon(resource = iconResource, iconClass = iconClass, contentDescription = "") + } else { + Box(Modifier.size(16.dp)) //todo move to style.metrics.iconSize + } + } Box(Modifier.weight(1f)) { content() } val chevronPainter by style.icons.submenuChevron.getPainter(Stateful(itemState))