From 37bd70621cb36b9751935428a510bb2428e0ea8c Mon Sep 17 00:00:00 2001 From: Ivan Morgillo Date: Mon, 19 Aug 2024 19:12:56 +0200 Subject: [PATCH] Iterate on keyboard shortcuts (#549) * add keyboardShortcut to ViewInfo Signed-off-by: Ivan Morgillo * make keybindings UI fairly multiplatform Signed-off-by: Ivan Morgillo * iterate on KeyBinding.forCurrentOs() reference: https://github.com/JetBrains/jewel/pull/549#discussion_r1721339123 Signed-off-by: Ivan Morgillo --------- Signed-off-by: Ivan Morgillo --- .../jewel/samples/standalone/view/TitleBarView.kt | 6 +++--- .../standalone/view/component/Dropdowns.kt | 2 +- .../samples/standalone/viewmodel/MainViewModel.kt | 3 +++ .../samples/standalone/viewmodel/ViewInfo.kt | 15 +++++++++++++++ .../org/jetbrains/jewel/ui/component/Menu.kt | 15 ++++++++++----- 5 files changed, 32 insertions(+), 9 deletions(-) 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 609f04bc7..5bcedb06f 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 @@ -12,6 +12,7 @@ import androidx.compose.ui.unit.dp import org.jetbrains.jewel.samples.standalone.IntUiThemes import org.jetbrains.jewel.samples.standalone.StandaloneSampleIcons import org.jetbrains.jewel.samples.standalone.viewmodel.MainViewModel +import org.jetbrains.jewel.samples.standalone.viewmodel.forCurrentOs import org.jetbrains.jewel.ui.component.Dropdown import org.jetbrains.jewel.ui.component.Icon import org.jetbrains.jewel.ui.component.IconButton @@ -32,9 +33,8 @@ fun DecoratedWindowScope.TitleBarView() { MainViewModel.views.forEach { selectableItem( selected = MainViewModel.currentView == it, - onClick = { - MainViewModel.currentView = it - }, + onClick = { MainViewModel.currentView = it }, + keybinding = it.keyboardShortcut?.forCurrentOs(), ) { Row( horizontalArrangement = Arrangement.spacedBy(4.dp), 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 5d738a3c3..c21fc7421 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 @@ -190,4 +190,4 @@ fun Dropdowns() { } private val dropdownIconsSample = listOf(AllIconsKeys.Actions.Find, AllIconsKeys.Actions.Close, null) -private val dropdownKeybindingsSample = setOf('A', 'B', '↑', '→', '␡') +private val dropdownKeybindingsSample = setOf("A", "B", "↑", "→", "␡") diff --git a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/viewmodel/MainViewModel.kt b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/viewmodel/MainViewModel.kt index 54f957a08..e7449031e 100644 --- a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/viewmodel/MainViewModel.kt +++ b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/viewmodel/MainViewModel.kt @@ -38,16 +38,19 @@ private val mainMenuItems = ViewInfo( title = "Welcome", iconKey = StandaloneSampleIcons.welcome, + keyboardShortcut = KeyBinding(macOs = setOf("⌥", "W"), windows = setOf("Alt", "W")), content = { WelcomeView() }, ), ViewInfo( title = "Components", iconKey = StandaloneSampleIcons.componentsMenu, + keyboardShortcut = KeyBinding(macOs = setOf("⌥", "C"), windows = setOf("Alt", "C")), content = { ComponentsView() }, ), ViewInfo( title = "Markdown", iconKey = StandaloneSampleIcons.markdown, + keyboardShortcut = KeyBinding(macOs = setOf("⌥", "M"), windows = setOf("Alt", "M"), linux = setOf("Alt", "M")), content = { MarkdownDemo() }, ), ) diff --git a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/viewmodel/ViewInfo.kt b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/viewmodel/ViewInfo.kt index 713e9d64a..dd3dd94c8 100644 --- a/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/viewmodel/ViewInfo.kt +++ b/samples/standalone/src/main/kotlin/org/jetbrains/jewel/samples/standalone/viewmodel/ViewInfo.kt @@ -2,9 +2,24 @@ package org.jetbrains.jewel.samples.standalone.viewmodel import androidx.compose.runtime.Composable import org.jetbrains.jewel.ui.icon.IconKey +import org.jetbrains.skiko.hostOs + +data class KeyBinding( + val macOs: Set = emptySet(), + val windows: Set = emptySet(), + val linux: Set = emptySet(), +) + +fun KeyBinding.forCurrentOs(): Set = + when { + hostOs.isMacOS -> macOs + hostOs.isLinux -> linux + else -> windows + } data class ViewInfo( val title: String, val iconKey: IconKey, + val keyboardShortcut: KeyBinding? = null, val content: @Composable () -> Unit, ) 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 d07adba21..17ebace00 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 @@ -84,6 +84,7 @@ import org.jetbrains.jewel.ui.component.styling.MenuStyle import org.jetbrains.jewel.ui.icon.IconKey import org.jetbrains.jewel.ui.painter.hints.Stateful import org.jetbrains.jewel.ui.theme.menuStyle +import org.jetbrains.skiko.hostOs @Composable public fun PopupMenu( @@ -222,7 +223,7 @@ public interface MenuScope { selected: Boolean, iconKey: IconKey? = null, iconClass: Class<*>? = iconKey?.let { it::class.java }, - keybinding: Set? = null, + keybinding: Set? = null, onClick: () -> Unit, enabled: Boolean = true, content: @Composable () -> Unit, @@ -275,7 +276,7 @@ private fun (MenuScope.() -> Unit).asList() = selected: Boolean, iconKey: IconKey?, iconClass: Class<*>?, - keybinding: Set?, + keybinding: Set?, onClick: () -> Unit, enabled: Boolean, content: @Composable () -> Unit, @@ -319,7 +320,7 @@ private data class MenuSelectableItem( val isEnabled: Boolean, val iconKey: IconKey?, val iconClass: Class<*>?, - val keybinding: Set?, + val keybinding: Set?, val onClick: () -> Unit = {}, override val content: @Composable () -> Unit, ) : MenuItem @@ -360,7 +361,7 @@ internal fun MenuItem( enabled: Boolean = true, iconKey: IconKey?, iconClass: Class<*>?, - keybinding: Set?, + keybinding: Set?, canShowIcon: Boolean, canShowKeybinding: Boolean, interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, @@ -459,7 +460,11 @@ internal fun MenuItem( if (canShowKeybinding) { val keybindingText = remember(keybinding) { - keybinding?.joinToString("") { it.toString() }.orEmpty() + if(hostOs.isMacOS) { + keybinding?.joinToString(" ") { it }.orEmpty() + } else { + keybinding?.joinToString(" + ") { it }.orEmpty() + } } Text( modifier = Modifier.padding(style.metrics.itemMetrics.keybindingsPadding),