From a98e40768c13c4cbeed1aa047e162b6d025026b9 Mon Sep 17 00:00:00 2001 From: Manos Pitsidianakis Date: Sun, 26 Mar 2023 15:12:47 +0300 Subject: [PATCH] Show editor tool shortcuts in shortcut popover --- src/editor.rs | 3 +- src/editor/shortcuts.rs | 142 ++++++++++++++++++++--------- src/editor/tools/panning.rs | 77 ++++++++-------- src/themes/custom-widgets.css | 30 ++++++ src/themes/paperwhite/_common.scss | 22 +---- src/themes/paperwhite/gtk.css | 8 +- src/window.rs | 3 + 7 files changed, 180 insertions(+), 105 deletions(-) diff --git a/src/editor.rs b/src/editor.rs index 4a5038a..2f626fd 100644 --- a/src/editor.rs +++ b/src/editor.rs @@ -73,7 +73,7 @@ pub struct EditorInner { lock: Cell<(Option, tools::constraints::Lock)>, snap: Cell<(Option, tools::constraints::Snap)>, precision: Cell<(Option, tools::constraints::Precision)>, - shortcuts: Rc>>, + shortcuts: shortcuts::Shortcuts, shortcut_status: gtk::Box, } @@ -89,6 +89,7 @@ impl ObjectImpl for EditorInner { self.parent_constructed(obj); self.lock_guidelines.set(false); self.setup_shortcuts(obj); + self.shortcuts.rebuild(); self.show_glyph_guidelines.set(true); self.show_project_guidelines.set(true); self.show_metrics_guidelines.set(true); diff --git a/src/editor/shortcuts.rs b/src/editor/shortcuts.rs index af91b66..f371e1a 100644 --- a/src/editor/shortcuts.rs +++ b/src/editor/shortcuts.rs @@ -56,7 +56,7 @@ impl EditorInner { pub fn setup_shortcuts(&self, obj: &Editor) { { use Editor as A; - let mut sh = self.shortcuts.borrow_mut(); + let mut sh = self.shortcuts.entries.borrow_mut(); sh.push(ShortcutAction::new( "preview".into(), Shortcut::empty().char('`'), @@ -246,53 +246,13 @@ impl EditorInner { self.shortcut_status .set_orientation(gtk::Orientation::Horizontal); self.shortcut_status.set_visible(true); - let grid = gtk::FlowBox::builder() - .expand(false) - .visible(true) - .sensitive(false) - .can_focus(true) - .column_spacing(5) - .margin(10) - .row_spacing(5) - .build(); - let btn = gtk::Button::builder() - .label("⏶") - .visible(true) - .focus_on_click(false) - .tooltip_text("shortcuts") - .relief(gtk::ReliefStyle::None) - .halign(gtk::Align::Center) - .valign(gtk::Align::Center) - .build(); - btn.style_context().add_class("shortcuts-more"); - self.shortcut_status.pack_end(&btn, false, false, 1); - for s in sh.iter() { - let b = gtk::Box::builder() - .expand(false) - .visible(true) - .sensitive(true) - .build(); - b.pack_start(s.desc_label(), false, false, 1); - b.pack_end(&s.shortcut().label(), false, false, 1); - grid.add(&b); - } - let pop = gtk::Popover::builder() - .expand(false) - .visible(false) - .sensitive(true) - .modal(true) - .position(gtk::PositionType::Bottom) - .child(&grid) - .relative_to(&btn) - .build(); - btn.connect_clicked(clone!(@strong pop => move |_| { - pop.popup(); - })); + self.shortcut_status + .pack_end(&self.shortcuts, false, false, 1); } let ctrl = gtk::EventControllerKey::new(obj); ctrl.connect_key_pressed( - clone!(@weak self.action_group as group, @weak self.shortcuts as shortcuts => @default-return false, move |_self, keyval, _, modifier_type: gdk::ModifierType| { + clone!(@weak self.action_group as group, @weak self.shortcuts.entries as shortcuts => @default-return false, move |_self, keyval, _, modifier_type: gdk::ModifierType| { use gtk::gdk::keys::Key; let key = Key::from(keyval); @@ -304,7 +264,7 @@ impl EditorInner { }), ); ctrl.connect_key_released( - clone!(@weak self.action_group as group, @weak self.shortcuts as shortcuts => move |_self, keyval, _, modifier_type: gdk::ModifierType| { + clone!(@weak self.action_group as group, @weak self.shortcuts.entries as shortcuts => move |_self, keyval, _, modifier_type: gdk::ModifierType| { use gtk::gdk::keys::Key; let key = Key::from(keyval); @@ -315,3 +275,95 @@ impl EditorInner { self.ctrl.set(ctrl).unwrap(); } } + +#[derive(Debug, Default)] +pub struct ShortcutsInner { + pub list: gtk::FlowBox, + pub btn: gtk::Button, + pub entries: Rc>>, +} + +impl ShortcutsInner { + pub fn rebuild(&self) { + for c in self.list.children() { + self.list.remove(&c); + } + for s in self.entries.borrow().iter() { + let b = gtk::Box::builder() + .expand(false) + .visible(true) + .sensitive(true) + .build(); + b.pack_start(s.desc_label(), false, false, 1); + b.pack_end(&s.shortcut().label(), false, false, 1); + b.show_all(); + self.list.add(&b); + } + } +} + +#[glib::object_subclass] +impl ObjectSubclass for ShortcutsInner { + const NAME: &'static str = "Shortcuts"; + type Type = Shortcuts; + type ParentType = gtk::Bin; +} + +impl ObjectImpl for ShortcutsInner { + fn constructed(&self, obj: &Self::Type) { + self.parent_constructed(obj); + self.btn.set_label("⏶"); + self.btn.set_visible(true); + self.btn.set_focus_on_click(false); + self.btn.set_tooltip_text(Some("shortcuts")); + self.btn.set_relief(gtk::ReliefStyle::None); + self.btn.set_halign(gtk::Align::Center); + self.btn.set_valign(gtk::Align::Center); + self.btn.style_context().add_class("shortcuts-more"); + obj.add(&self.btn); + self.list.set_expand(false); + self.list.set_visible(true); + self.list.set_sensitive(false); + self.list.set_can_focus(true); + self.list.set_margin(10); + self.list.set_column_spacing(0); + self.list.set_row_spacing(0); + self.list.set_max_children_per_line(4); + self.list.set_min_children_per_line(2); + let pop = gtk::Popover::builder() + .expand(false) + .visible(false) + .sensitive(true) + .modal(true) + .position(gtk::PositionType::Bottom) + .child(&self.list) + .relative_to(&self.btn) + .build(); + self.btn.connect_clicked(clone!(@strong pop => move |_| { + pop.popup(); + })); + obj.set_visible(true); + } +} + +impl WidgetImpl for ShortcutsInner {} +impl ContainerImpl for ShortcutsInner {} +impl BinImpl for ShortcutsInner {} + +glib::wrapper! { + pub struct Shortcuts(ObjectSubclass) + @extends gtk::Widget, gtk::Container, gtk::Bin; +} + +impl std::ops::Deref for Shortcuts { + type Target = ShortcutsInner; + fn deref(&self) -> &Self::Target { + self.imp() + } +} + +impl Default for Shortcuts { + fn default() -> Self { + glib::Object::new(&[]).unwrap() + } +} diff --git a/src/editor/tools/panning.rs b/src/editor/tools/panning.rs index 0f37efa..89c261c 100644 --- a/src/editor/tools/panning.rs +++ b/src/editor/tools/panning.rs @@ -1110,43 +1110,46 @@ impl PanningToolInner { view.viewport.set_cursor("crosshair"); })); view.action_group.add_action(&pan_action); - let mut sh = view.shortcuts.borrow_mut(); - sh.push(ShortcutAction::new( - "move".into(), - Shortcut::empty().shift().char('G'), - Box::new(|group| { - group.activate_action(PanningTool::MOVE_ACTION, None); - true - }), - None, - )); - sh.push(ShortcutAction::new( - "scale".into(), - Shortcut::empty().shift().char('S'), - Box::new(|group| { - group.activate_action(PanningTool::SCALE_ACTION, None); - true - }), - None, - )); - sh.push(ShortcutAction::new( - "rotate".into(), - Shortcut::empty().shift().char('R'), - Box::new(|group| { - group.activate_action(PanningTool::ROTATE_ACTION, None); - true - }), - None, - )); - sh.push(ShortcutAction::new( - "pan".into(), - Shortcut::empty().shift().char('P'), - Box::new(|group| { - group.activate_action(PanningTool::PAN_ACTION, None); - true - }), - None, - )); + { + let mut sh = view.shortcuts.entries.borrow_mut(); + sh.push(ShortcutAction::new( + "move".into(), + Shortcut::empty().shift().char('G'), + Box::new(|group| { + group.activate_action(PanningTool::MOVE_ACTION, None); + true + }), + None, + )); + sh.push(ShortcutAction::new( + "scale".into(), + Shortcut::empty().shift().char('S'), + Box::new(|group| { + group.activate_action(PanningTool::SCALE_ACTION, None); + true + }), + None, + )); + sh.push(ShortcutAction::new( + "rotate".into(), + Shortcut::empty().shift().char('R'), + Box::new(|group| { + group.activate_action(PanningTool::ROTATE_ACTION, None); + true + }), + None, + )); + sh.push(ShortcutAction::new( + "pan".into(), + Shortcut::empty().shift().char('P'), + Box::new(|group| { + group.activate_action(PanningTool::PAN_ACTION, None); + true + }), + None, + )); + } + view.shortcuts.rebuild(); } } diff --git a/src/themes/custom-widgets.css b/src/themes/custom-widgets.css index 5a8224d..55982cd 100644 --- a/src/themes/custom-widgets.css +++ b/src/themes/custom-widgets.css @@ -101,3 +101,33 @@ menu separator label, menuitem separator label { font-size: 9pt; font-family: mono; } + +.welcome-banner { + border: 0.1rem ridge @borders; + padding: 1rem 2rem; +} + +.shortcut-kbd { + background-color: @theme_bg_color; + border-radius: 0.3rem; + border: 0.1rem solid @borders; + border-bottom-width: 0.2rem; + box-shadow: 0rem 0.2rem 0.2rem 0rem rgba(0, 0, 0, 0.2), 0rem 0.2rem 0.2rem 0rem rgba(255, 255, 255, 0.7); + font-size: 0.85rem; + padding: 0.2rem 0.4rem; + font-family: monospace; +} + +button.text-button.shortcuts-more { + min-height: 0; + min-width: 0; + padding: 0 .5ex; +} + +button.text-button.shortcuts-more { + border-color: @borders; +} + +button:hover.text-button.shortcuts-more label { + color: @theme_text_color; +} diff --git a/src/themes/paperwhite/_common.scss b/src/themes/paperwhite/_common.scss index 8e142ca..6e1b0e6 100644 --- a/src/themes/paperwhite/_common.scss +++ b/src/themes/paperwhite/_common.scss @@ -4948,32 +4948,20 @@ statusbar { .shortcut-kbd { background-color: #fff; - border-radius: 3px; - border: 1px solid #b4b4b4; - box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2), 0 2px 0 0 rgba(255, 255, 255, 0.7) inset; + border-color: #b4b4b4; color: #333; - font-size: 0.85em; - padding: 2px 4px; - font-family: monospace; -} - -button.text-button.shortcuts-more { - min-height: 0; - min-width: 0; - padding: 0 .5ex; } button.text-button.shortcuts-more label { - border:1px solid darkgray; + border: 0.1rem solid darkgray; color: #555; - box-shadow:none; + box-shadow: none; padding: 0; - margin:0; + margin: 0; } button:hover.text-button.shortcuts-more label { - color:black; - box-shadow: -1px 1px; + color: black; } #layers { diff --git a/src/themes/paperwhite/gtk.css b/src/themes/paperwhite/gtk.css index 96c574c..3c2f2f6 100644 --- a/src/themes/paperwhite/gtk.css +++ b/src/themes/paperwhite/gtk.css @@ -1970,13 +1970,11 @@ box.workspace { border: none; margin: 0; } statusbar { background: #DDDDDD; border-top: 1px solid black; } -.shortcut-kbd { background-color: #fff; border-radius: 3px; border: 1px solid #b4b4b4; box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2), 0 2px 0 0 rgba(255, 255, 255, 0.7) inset; color: #333; font-size: 0.85em; padding: 2px 4px; font-family: monospace; } +.shortcut-kbd { background-color: #fff; border-color: #b4b4b4; color: #333; } -button.text-button.shortcuts-more { min-height: 0; min-width: 0; padding: 0 .5ex; } +button.text-button.shortcuts-more label { border: 0.1rem solid darkgray; color: #555; box-shadow: none; padding: 0; margin: 0; } -button.text-button.shortcuts-more label { border: 1px solid darkgray; color: #555; box-shadow: none; padding: 0; margin: 0; } - -button:hover.text-button.shortcuts-more label { color: black; box-shadow: -1px 1px; } +button:hover.text-button.shortcuts-more label { color: black; } #layers { background: white; border: 1px solid black; padding: 5px; border-bottom-right-radius: 4px; } diff --git a/src/window.rs b/src/window.rs index 0026b66..6a3603d 100644 --- a/src/window.rs +++ b/src/window.rs @@ -397,6 +397,9 @@ impl WindowInner { impl WindowInner { fn setup_welcome_banner(&self, obj: &Window) { + self.welcome_banner + .style_context() + .add_class("welcome-banner"); let title_label = gtk::Label::builder() .label(crate::APPLICATION_NAME) .visible(true)