Skip to content

Commit 810ce40

Browse files
authored
Restyle and refactor shortcut labels to send hints bar and welcome screen layouts from Rust (#3447)
* Restyle UserInputLabel and refactor its usages to have all input its data sent from Rust * Replace the welcome screen quick buttons with ones sent by backend * Add the ShortcutLabel widget to the backend * Replace hints bar with a backend-controlled layout; show mouse icons in place of mouse labels
1 parent 6ed42d0 commit 810ce40

File tree

78 files changed

+980
-996
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

78 files changed

+980
-996
lines changed

desktop/wrapper/src/utils.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ pub(crate) mod menu {
33
use base64::engine::Engine;
44
use base64::engine::general_purpose::STANDARD as BASE64;
55

6-
use graphite_editor::messages::input_mapper::utility_types::input_keyboard::{Key, LayoutKey, LayoutKeysGroup};
7-
use graphite_editor::messages::input_mapper::utility_types::misc::ActionKeys;
6+
use graphite_editor::messages::input_mapper::utility_types::input_keyboard::{Key, LabeledKey, LabeledShortcut};
7+
use graphite_editor::messages::input_mapper::utility_types::misc::ActionShortcut;
88
use graphite_editor::messages::layout::LayoutMessage;
99
use graphite_editor::messages::tool::tool_messages::tool_prelude::{LayoutGroup, LayoutTarget, MenuListEntry, SubLayout, Widget, WidgetId};
1010

@@ -84,7 +84,7 @@ pub(crate) mod menu {
8484
}
8585

8686
let shortcut = match shortcut_keys {
87-
Some(ActionKeys::Keys(LayoutKeysGroup(keys))) => convert_layout_keys_to_shortcut(keys),
87+
Some(ActionShortcut::Shortcut(LabeledShortcut(shortcut))) => convert_labeled_keys_to_shortcut(shortcut),
8888
_ => None,
8989
};
9090

@@ -126,11 +126,11 @@ pub(crate) mod menu {
126126
items
127127
}
128128

129-
fn convert_layout_keys_to_shortcut(layout_keys: &Vec<LayoutKey>) -> Option<Shortcut> {
129+
fn convert_labeled_keys_to_shortcut(labeled_keys: &Vec<LabeledKey>) -> Option<Shortcut> {
130130
let mut key: Option<KeyCode> = None;
131131
let mut modifiers = Modifiers::default();
132-
for layout_key in layout_keys {
133-
match layout_key.key() {
132+
for labeled_key in labeled_keys {
133+
match labeled_key.key() {
134134
Key::Shift => modifiers |= Modifiers::SHIFT,
135135
Key::Control => modifiers |= Modifiers::CONTROL,
136136
Key::Alt => modifiers |= Modifiers::ALT,

editor/src/messages/frontend/frontend_message.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ use crate::messages::portfolio::document::node_graph::utility_types::{
77
use crate::messages::portfolio::document::utility_types::nodes::{JsRawBuffer, LayerPanelEntry, RawBuffer};
88
use crate::messages::portfolio::document::utility_types::wires::{WirePath, WirePathUpdate};
99
use crate::messages::prelude::*;
10-
use crate::messages::tool::utility_types::HintData;
1110
use glam::IVec2;
1211
use graph_craft::document::NodeId;
1312
use graphene_std::raster::Image;
@@ -257,10 +256,6 @@ pub enum FrontendMessage {
257256
UpdateGraphFadeArtwork {
258257
percentage: f64,
259258
},
260-
UpdateInputHints {
261-
#[serde(rename = "hintData")]
262-
hint_data: HintData,
263-
},
264259
UpdateLayersPanelControlBarLeftLayout {
265260
#[serde(rename = "layoutTarget")]
266261
layout_target: LayoutTarget,
@@ -335,6 +330,16 @@ pub enum FrontendMessage {
335330
#[serde(rename = "wirePath")]
336331
wire_path: Option<WirePath>,
337332
},
333+
UpdateWelcomeScreenButtonsLayout {
334+
#[serde(rename = "layoutTarget")]
335+
layout_target: LayoutTarget,
336+
diff: Vec<WidgetDiff>,
337+
},
338+
UpdateStatusBarHintsLayout {
339+
#[serde(rename = "layoutTarget")]
340+
layout_target: LayoutTarget,
341+
diff: Vec<WidgetDiff>,
342+
},
338343
UpdateWorkingColorsLayout {
339344
#[serde(rename = "layoutTarget")]
340345
layout_target: LayoutTarget,

editor/src/messages/input_mapper/utility_types/input_keyboard.rs

Lines changed: 87 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,18 @@ use bitflags::bitflags;
44
use std::fmt::{self, Display, Formatter};
55
use std::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign};
66

7+
// ===========
8+
// StorageType
9+
// ===========
10+
711
// TODO: Increase size of type
812
/// Edit this to specify the storage type used.
913
pub type StorageType = u128;
1014

15+
// =========
16+
// KeyStates
17+
// =========
18+
1119
// Base-2 logarithm of the storage type used to represents how many bits you need to fully address every bit in that storage type
1220
const STORAGE_SIZE: u32 = (std::mem::size_of::<StorageType>() * 8).trailing_zeros();
1321
const STORAGE_SIZE_BITS: usize = 1 << STORAGE_SIZE;
@@ -23,11 +31,19 @@ pub fn all_required_modifiers_pressed(keyboard_state: &KeyStates, modifiers: &Ke
2331
all_modifiers_without_pressed_modifiers.is_empty()
2432
}
2533

34+
// ===========
35+
// KeyPosition
36+
// ===========
37+
2638
pub enum KeyPosition {
2739
Pressed,
2840
Released,
2941
}
3042

43+
// ============
44+
// ModifierKeys
45+
// ============
46+
3147
bitflags! {
3248
#[derive(Clone, Copy, Debug, PartialEq, Eq, Default, serde::Serialize, serde::Deserialize)]
3349
#[repr(transparent)]
@@ -40,6 +56,10 @@ bitflags! {
4056
}
4157
}
4258

59+
// ===
60+
// Key
61+
// ===
62+
4363
// Currently this is mostly based on the JS `KeyboardEvent.code` list: <https://www.w3.org/TR/uievents-code/>
4464
// But in the future, especially once users can customize keyboard mappings, we should deviate more from this so we have actual symbols
4565
// like `+` (which doesn't exist because it's the shifted version of `=` on the US keyboard, after which these scan codes are named).
@@ -198,14 +218,19 @@ pub enum Key {
198218

199219
// Other keys that aren't part of the W3C spec
200220
//
201-
/// "Cmd" on Mac (not present on other platforms)
221+
/// "Cmd" on Mac (not present on other platforms).
202222
Command,
203-
/// "Ctrl" on Windows/Linux, "Cmd" on Mac
223+
/// "Ctrl" on Windows/Linux, "Cmd" on Mac.
204224
Accel,
225+
/// Left mouse button click (LMB).
205226
MouseLeft,
227+
/// Right mouse button click (RMB).
206228
MouseRight,
229+
/// Middle mouse button click (MMB).
207230
MouseMiddle,
231+
/// Mouse backward navigation button (typically on the side of the mouse).
208232
MouseBack,
233+
/// Mouse forward navigation button (typically on the side of the mouse).
209234
MouseForward,
210235

211236
// Fake keys for displaying special labels in the UI
@@ -225,11 +250,11 @@ impl fmt::Display for Key {
225250

226251
// Writing system keys
227252
const DIGIT_PREFIX: &str = "Digit";
228-
if key_name.len() == DIGIT_PREFIX.len() + 1 && &key_name[0..DIGIT_PREFIX.len()] == "Digit" {
253+
if key_name.len() == DIGIT_PREFIX.len() + 1 && &key_name[0..DIGIT_PREFIX.len()] == DIGIT_PREFIX {
229254
return write!(f, "{}", key_name.chars().skip(DIGIT_PREFIX.len()).collect::<String>());
230255
}
231256
const KEY_PREFIX: &str = "Key";
232-
if key_name.len() == KEY_PREFIX.len() + 1 && &key_name[0..KEY_PREFIX.len()] == "Key" {
257+
if key_name.len() == KEY_PREFIX.len() + 1 && &key_name[0..KEY_PREFIX.len()] == KEY_PREFIX {
233258
return write!(f, "{}", key_name.chars().skip(KEY_PREFIX.len()).collect::<String>());
234259
}
235260

@@ -313,26 +338,12 @@ impl fmt::Display for Key {
313338
}
314339
}
315340

316-
impl From<Key> for LayoutKey {
317-
fn from(key: Key) -> Self {
318-
Self { key, label: key.to_string() }
319-
}
320-
}
321-
322-
#[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize, specta::Type)]
323-
pub struct LayoutKey {
324-
key: Key,
325-
label: String,
326-
}
327-
328-
impl LayoutKey {
329-
pub fn key(&self) -> Key {
330-
self.key
331-
}
332-
}
333-
334341
pub const NUMBER_OF_KEYS: usize = Key::_KeysVariantCount as usize - 1;
335342

343+
// =========
344+
// KeysGroup
345+
// =========
346+
336347
/// Only `Key`s that exist on a physical keyboard should be used.
337348
#[derive(Debug, Clone, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
338349
pub struct KeysGroup(pub Vec<Key>);
@@ -365,22 +376,26 @@ impl fmt::Display for KeysGroup {
365376
}
366377
}
367378

368-
impl From<KeysGroup> for String {
369-
fn from(keys: KeysGroup) -> Self {
370-
let layout_keys: LayoutKeysGroup = keys.into();
371-
serde_json::to_string(&layout_keys).expect("Failed to serialize KeysGroup")
372-
}
373-
}
379+
// ==========
380+
// LabeledKey
381+
// ==========
374382

375-
#[derive(Debug, Clone, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize, specta::Type)]
376-
pub struct LayoutKeysGroup(pub Vec<LayoutKey>);
383+
#[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize, specta::Type)]
384+
pub struct LabeledKey {
385+
key: Key,
386+
label: String,
387+
}
377388

378-
impl From<KeysGroup> for LayoutKeysGroup {
379-
fn from(keys_group: KeysGroup) -> Self {
380-
Self(keys_group.0.into_iter().map(|key| key.into()).collect())
389+
impl LabeledKey {
390+
pub fn key(&self) -> Key {
391+
self.key
381392
}
382393
}
383394

395+
// ===========
396+
// MouseMotion
397+
// ===========
398+
384399
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize, specta::Type)]
385400
pub enum MouseMotion {
386401
None,
@@ -397,6 +412,45 @@ pub enum MouseMotion {
397412
MmbDrag,
398413
}
399414

415+
// =======================
416+
// LabeledKeyOrMouseMotion
417+
// =======================
418+
419+
#[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize, specta::Type)]
420+
#[serde(untagged)]
421+
pub enum LabeledKeyOrMouseMotion {
422+
Key(LabeledKey),
423+
MouseMotion(MouseMotion),
424+
}
425+
426+
impl From<Key> for LabeledKeyOrMouseMotion {
427+
fn from(key: Key) -> Self {
428+
match key {
429+
Key::MouseLeft => Self::MouseMotion(MouseMotion::Lmb),
430+
Key::MouseRight => Self::MouseMotion(MouseMotion::Rmb),
431+
Key::MouseMiddle => Self::MouseMotion(MouseMotion::Mmb),
432+
_ => Self::Key(LabeledKey { key, label: key.to_string() }),
433+
}
434+
}
435+
}
436+
437+
// ===============
438+
// LabeledShortcut
439+
// ===============
440+
441+
#[derive(Debug, Clone, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize, specta::Type)]
442+
pub struct LabeledShortcut(pub Vec<LabeledKeyOrMouseMotion>);
443+
444+
impl From<KeysGroup> for LabeledShortcut {
445+
fn from(keys_group: KeysGroup) -> Self {
446+
Self(keys_group.0.into_iter().map(|key| key.into()).collect())
447+
}
448+
}
449+
450+
// =========
451+
// BitVector
452+
// =========
453+
400454
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
401455
pub struct BitVector<const LENGTH: usize>([StorageType; LENGTH]);
402456

editor/src/messages/input_mapper/utility_types/macros.rs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,14 +117,23 @@ macro_rules! mapping {
117117
}};
118118
}
119119

120-
/// Constructs an `ActionKeys` macro with a certain `Action` variant, conveniently wrapped in `Some()`.
121-
macro_rules! action_keys {
120+
/// Constructs an `ActionShortcut` macro with a certain `Action` variant, conveniently wrapped in `Some()`.
121+
macro_rules! action_shortcut {
122122
($action:expr_2021) => {
123-
Some(crate::messages::input_mapper::utility_types::misc::ActionKeys::Action($action.into()))
123+
Some(crate::messages::input_mapper::utility_types::misc::ActionShortcut::Action($action.into()))
124124
};
125125
}
126126

127-
pub(crate) use action_keys;
127+
macro_rules! action_shortcut_manual {
128+
($($keys:expr),*) => {
129+
Some(crate::messages::input_mapper::utility_types::misc::ActionShortcut::Shortcut(
130+
crate::messages::input_mapper::utility_types::input_keyboard::LabeledShortcut(vec![$($keys.into()),*]).into(),
131+
))
132+
};
133+
}
134+
135+
pub(crate) use action_shortcut;
136+
pub(crate) use action_shortcut_manual;
128137
pub(crate) use entry;
129138
pub(crate) use mapping;
130139
pub(crate) use modifiers;

editor/src/messages/input_mapper/utility_types/misc.rs

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use super::input_keyboard::{KeysGroup, LayoutKeysGroup, all_required_modifiers_pressed};
1+
use super::input_keyboard::{KeysGroup, LabeledShortcut, all_required_modifiers_pressed};
22
use crate::messages::input_mapper::key_mapping::MappingVariant;
33
use crate::messages::input_mapper::utility_types::input_keyboard::{KeyStates, NUMBER_OF_KEYS};
44
use crate::messages::input_mapper::utility_types::input_mouse::NUMBER_OF_MOUSE_BUTTONS;
@@ -128,28 +128,24 @@ pub struct MappingEntry {
128128
}
129129

130130
#[derive(Debug, Clone, Eq, PartialEq, serde::Serialize, serde::Deserialize, specta::Type)]
131-
pub enum ActionKeys {
131+
pub enum ActionShortcut {
132132
Action(MessageDiscriminant),
133-
#[serde(rename = "keys")]
134-
Keys(LayoutKeysGroup),
133+
#[serde(rename = "shortcut")]
134+
Shortcut(LabeledShortcut),
135135
}
136136

137-
impl ActionKeys {
138-
pub fn to_keys(&mut self, action_input_mapping: &impl Fn(&MessageDiscriminant) -> Option<KeysGroup>) -> String {
137+
impl ActionShortcut {
138+
pub fn realize_shortcut(&mut self, action_input_mapping: &impl Fn(&MessageDiscriminant) -> Option<KeysGroup>) {
139139
match self {
140140
Self::Action(action) => {
141141
if let Some(keys) = action_input_mapping(action) {
142-
let description = keys.to_string();
143-
*self = Self::Keys(keys.into());
144-
description
142+
*self = Self::Shortcut(keys.into());
145143
} else {
146-
*self = Self::Keys(KeysGroup::default().into());
147-
String::new()
144+
*self = Self::Shortcut(KeysGroup::default().into());
148145
}
149146
}
150-
Self::Keys(keys) => {
151-
warn!("Calling `.to_keys()` on a `ActionKeys::Keys` is a mistake/bug. Keys are: {keys:?}.");
152-
String::new()
147+
Self::Shortcut(shortcut) => {
148+
warn!("Calling `.to_keys()` on a `ActionShortcut::Shortcut` is a mistake/bug. Shortcut is: {shortcut:?}.");
153149
}
154150
}
155151
}

editor/src/messages/layout/layout_message.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ pub enum LayoutMessage {
1212
layout: Layout,
1313
layout_target: LayoutTarget,
1414
},
15+
DestroyLayout {
16+
layout_target: LayoutTarget,
17+
},
1518
WidgetValueCommit {
1619
layout_target: LayoutTarget,
1720
widget_id: WidgetId,

editor/src/messages/layout/layout_message_handler.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@ impl MessageHandler<LayoutMessage, LayoutMessageContext<'_>> for LayoutMessageHa
3939
LayoutMessage::SendLayout { layout, layout_target } => {
4040
self.diff_and_send_layout_to_frontend(layout_target, layout, responses, action_input_mapping);
4141
}
42+
LayoutMessage::DestroyLayout { layout_target } => {
43+
if let Some(layout) = self.layouts.get_mut(layout_target as usize) {
44+
*layout = Default::default();
45+
}
46+
}
4247
LayoutMessage::WidgetValueCommit { layout_target, widget_id, value } => {
4348
self.handle_widget_callback(layout_target, widget_id, value, WidgetValueAction::Commit, responses);
4449
}
@@ -78,7 +83,7 @@ impl LayoutMessageHandler {
7883
LayoutGroup::Section { layout, .. } => {
7984
stack.extend(layout.iter().enumerate().map(|(index, val)| ([widget_path.as_slice(), &[index]].concat(), val)));
8085
}
81-
LayoutGroup::Table { rows } => {
86+
LayoutGroup::Table { rows, .. } => {
8287
for (row_index, row) in rows.iter().enumerate() {
8388
for (cell_index, cell) in row.iter().enumerate() {
8489
// Return if this is the correct ID
@@ -310,6 +315,7 @@ impl LayoutMessageHandler {
310315
responses.add(callback_message);
311316
}
312317
Widget::ImageLabel(_) => {}
318+
Widget::ShortcutLabel(_) => {}
313319
Widget::IconLabel(_) => {}
314320
Widget::NodeCatalog(node_type_input) => match action {
315321
WidgetValueAction::Commit => {
@@ -509,8 +515,10 @@ impl LayoutMessageHandler {
509515
LayoutTarget::MenuBar => FrontendMessage::UpdateMenuBarLayout { layout_target, diff },
510516
LayoutTarget::NodeGraphControlBar => FrontendMessage::UpdateNodeGraphControlBarLayout { layout_target, diff },
511517
LayoutTarget::PropertiesPanel => FrontendMessage::UpdatePropertiesPanelLayout { layout_target, diff },
518+
LayoutTarget::StatusBarHints => FrontendMessage::UpdateStatusBarHintsLayout { layout_target, diff },
512519
LayoutTarget::ToolOptions => FrontendMessage::UpdateToolOptionsLayout { layout_target, diff },
513520
LayoutTarget::ToolShelf => FrontendMessage::UpdateToolShelfLayout { layout_target, diff },
521+
LayoutTarget::WelcomeScreenButtons => FrontendMessage::UpdateWelcomeScreenButtonsLayout { layout_target, diff },
514522
LayoutTarget::WorkingColors => FrontendMessage::UpdateWorkingColorsLayout { layout_target, diff },
515523

516524
LayoutTarget::LayoutTargetLength => panic!("`LayoutTargetLength` is not a valid Layout Target and is used for array indexing"),

0 commit comments

Comments
 (0)