From 74d9c911bdeaa5bc06e19590e613cee715736ec7 Mon Sep 17 00:00:00 2001 From: Keavon Chambers Date: Thu, 4 Dec 2025 22:04:37 -0800 Subject: [PATCH] Fix ShortcutLabel drawing of consecutive key labels --- .gitignore | 1 + .../messages/input_mapper/input_mappings.rs | 1 + .../widgets/labels/ShortcutLabel.svelte | 67 +++++++++++++------ .../components/window/workspace/Panel.svelte | 4 +- .../window/workspace/Workspace.svelte | 2 +- 5 files changed, 50 insertions(+), 25 deletions(-) diff --git a/.gitignore b/.gitignore index 8f569654..f410829a 100644 --- a/.gitignore +++ b/.gitignore @@ -9,5 +9,6 @@ profile.json.gz flamegraph.svg .idea/ .direnv +.DS_Store hierarchical_message_system_tree.txt hierarchical_message_system_tree.html diff --git a/editor/src/messages/input_mapper/input_mappings.rs b/editor/src/messages/input_mapper/input_mappings.rs index 8bc699b7..d8c4a045 100644 --- a/editor/src/messages/input_mapper/input_mappings.rs +++ b/editor/src/messages/input_mapper/input_mappings.rs @@ -411,6 +411,7 @@ pub fn input_mappings() -> Mapping { entry!(KeyDown(Equal); modifiers=[Accel], action_dispatch=NavigationMessage::CanvasZoomIncrease { center_on_mouse: false }), entry!(KeyDown(Minus); modifiers=[Accel], action_dispatch=NavigationMessage::CanvasZoomDecrease { center_on_mouse: false }), entry!(WheelScroll; modifiers=[Control], action_dispatch=NavigationMessage::CanvasZoomMouseWheel), + entry!(WheelScroll; modifiers=[Command], action_dispatch=NavigationMessage::CanvasZoomMouseWheel), entry!(WheelScroll; modifiers=[Shift], action_dispatch=NavigationMessage::CanvasPanMouseWheel { use_y_as_x: true }), entry!(WheelScroll; action_dispatch=NavigationMessage::CanvasPanMouseWheel { use_y_as_x: false }), entry!(KeyDown(PageUp); modifiers=[Shift], action_dispatch=NavigationMessage::CanvasPanByViewportFraction { delta: DVec2::new(1., 0.) }), diff --git a/frontend/src/components/widgets/labels/ShortcutLabel.svelte b/frontend/src/components/widgets/labels/ShortcutLabel.svelte index 4aee14b6..d634f4df 100644 --- a/frontend/src/components/widgets/labels/ShortcutLabel.svelte +++ b/frontend/src/components/widgets/labels/ShortcutLabel.svelte @@ -9,8 +9,8 @@ export let shortcut: ActionShortcut; - function keyTextOrIconList(keyGroup: LabeledShortcut): { label?: string; icon?: IconName; mouseMotion?: MouseMotion }[] { - const list = keyGroup.map((labeledKeyOrMouseMotion) => { + function keyTextOrIconList(keyGroup: LabeledShortcut): ({ label?: string; icon?: IconName }[] | { mouseMotion?: MouseMotion }[])[] { + const list = keyGroup.map((labeledKeyOrMouseMotion): { label?: string; icon?: IconName; mouseMotion?: MouseMotion } => { // Use a mouse icon if it's a mouse motion instead of a key if (typeof labeledKeyOrMouseMotion === "string") return { mouseMotion: labeledKeyOrMouseMotion }; @@ -33,11 +33,25 @@ }); // Consolidate consecutive labels into a concatenated single label - const consolidatedList: typeof list = []; - list.forEach((item) => { - const lastItem = consolidatedList[consolidatedList.length - 1]; - if (item.label && lastItem?.label) lastItem.label += " " + item.label; - else consolidatedList.push(item); + const consolidatedList: ReturnType = []; + list.forEach((currentItem) => { + const lastGroup = consolidatedList.length > 0 ? consolidatedList[consolidatedList.length - 1] : undefined; + const lastItem = lastGroup !== undefined ? lastGroup[lastGroup.length - 1] : undefined; + + // If current and last are both labels, concatenate both within their existing label + if (currentItem.label && lastItem && "label" in lastItem && lastItem.label) { + lastItem.label += " " + currentItem.label; + return; + } + + // If current and last are both of the same group type (both icons/labels, or both mouseMotion), join them within their existing + if (lastItem && (((currentItem.label || currentItem.icon) && ("label" in lastItem || "icon" in lastItem)) || (currentItem.mouseMotion && "mouseMotion" in lastItem))) { + lastGroup?.push(currentItem); + return; + } + + // Otherwise, start a new group with the first item of its group type + consolidatedList.push([currentItem]); }); return consolidatedList; } @@ -73,32 +87,38 @@ } } - function mouseHintIcon(input?: MouseMotion): IconName { + function mouseHintIcon(input: MouseMotion): IconName { return `MouseHint${input}` as IconName; } - {#each keyTextOrIconList(shortcut.shortcut) as { label, icon, mouseMotion }} - {#if label} + {#each keyTextOrIconList(shortcut.shortcut) as group} + {#if "label" in group[0] || "icon" in group[0]}
- {label} -
- {:else if icon} -
- -
- {:else if mouseMotion} -
- + {#each group as item} + {#if "label" in item && item.label} + {item.label} + {:else if "icon" in item && item.icon} + + {/if} + {/each}
{/if} + {#if "mouseMotion" in group[0]} + {#each group as item} + {#if "mouseMotion" in item && item.mouseMotion} +
+ +
+ {/if} + {/each} + {/if} {/each}