diff --git a/crates/ui-egui/src/app.rs b/crates/ui-egui/src/app.rs index f0513520b..0267dd769 100644 --- a/crates/ui-egui/src/app.rs +++ b/crates/ui-egui/src/app.rs @@ -272,6 +272,10 @@ impl FigApp { // The shortcuts panel belongs to the canvas; it doesn't hang over the home screen // (cleared after the home widgets, which may have just asked for it). self.ui.shortcuts_panel = false; + // The keymap runs with the canvas; here the one shortcut that still applies is read directly. + if ctx.input_mut(|i| i.consume_key(egui::Modifiers::COMMAND, egui::Key::Comma)) { + self.run("app.preferences", serde_json::json!({})); + } dialogs::keys(self, &ctx); dialogs::show(self, &ctx); updates_ui::show(self, &ctx); diff --git a/crates/ui-egui/src/home.rs b/crates/ui-egui/src/home.rs index 9587c6623..d5babe72a 100644 --- a/crates/ui-egui/src/home.rs +++ b/crates/ui-egui/src/home.rs @@ -190,8 +190,8 @@ fn dropped(app: &mut FigApp, ctx: &egui::Context) { } } -/// Draw the Home sidebar: app icon and wordmark, file/template search (Escape clears it) -/// and section tabs; choosing a section clears the file query. +/// Draw the Home sidebar: app icon and wordmark, file/template search (Escape clears it), section +/// tabs (choosing one clears the file query) and Preferences at the bottom. fn sidebar(app: &mut FigApp, ui: &mut Ui, t: &Tokens, left: Rect) { let mut y = left.min.y + 20.0; crate::theme::paint_app_icon(ui, Rect::from_min_size(pos2(left.min.x + 12.0, y - 4.0), vec2(32.0, 32.0))); @@ -229,6 +229,26 @@ fn sidebar(app: &mut FigApp, ui: &mut Ui, t: &Tokens, left: Rect) { } y += 34.0; } + let pref_y = (left.max.y - 44.0).max(y + 12.0); + if pref_y > y + 12.0 { + ui.painter().line_segment([pos2(left.min.x + 12.0, pref_y - 6.0), pos2(left.max.x - 12.0, pref_y - 6.0)], Stroke::new(1.0, t.border)); + } + let r = Rect::from_min_size(pos2(left.min.x + 8.0, pref_y), vec2(SIDEBAR - 16.0, 32.0)); + let mut resp = ui.interact(r, ui.scope_id().with("home_preferences"), Sense::click()); + let current = app.ui.preferences; + a11y::button(&resp, tr("Preferences")); + if current || resp.hovered() { + ui.painter().rect_filled(r, CornerRadius::same(5), if current { t.selected_row } else { t.hover }); + } + focus_ring(ui, t, r, &resp, 5); + icons::paint(ui.painter(), Rect::from_min_size(pos2(r.min.x + 10.0, r.center().y - 8.0), vec2(16.0, 16.0)), Icon::Adjust, t.icon); + ui.painter().text(pos2(r.min.x + 36.0, r.center().y), Align2::LEFT_CENTER, tr("Preferences"), regular(12.0), t.text); + let key_label = figcraft_engine::keymap::display("Cmd+,", crate::shortcuts::platform()); + ui.painter().text(pos2(r.max.x - 8.0, r.center().y), Align2::RIGHT_CENTER, &key_label, regular(11.0), t.text_secondary); + resp = resp.on_hover_text(format!("{} ({})", tr("Preferences"), key_label)); + if resp.clicked() { + app.ui.preferences = !app.ui.preferences; + } } fn file_matches(name: &str, location: &str, query: &str) -> bool { diff --git a/crates/ui-egui/src/home_tests.rs b/crates/ui-egui/src/home_tests.rs index dcbbb3b6f..dfe3a0a7e 100644 --- a/crates/ui-egui/src/home_tests.rs +++ b/crates/ui-egui/src/home_tests.rs @@ -917,3 +917,34 @@ fn a_jam_file_is_a_document_open_and_drops_take() { assert!(crate::open::opens(path) && crate::open::is_document(path), "{name}"); } } + +/// The Preferences dialog can be opened and toggled from the home screen via +/// the `Cmd/Ctrl + ,` shortcut as well as by clicking Preferences in the sidebar. +#[test] +fn home_screen_preferences_shortcut_and_sidebar_access() { + let mut u = first_run(); + u.app.ui.home = true; + u.frame(vec![]); + assert!(!u.app.ui.preferences); + + // Ctrl/Cmd + Comma opens Preferences on the Home screen. + u.frame(vec![ + Event::Key { key: Key::Comma, physical_key: None, pressed: true, repeat: false, modifiers: Modifiers::COMMAND }, + Event::Key { key: Key::Comma, physical_key: None, pressed: false, repeat: false, modifiers: Modifiers::COMMAND }, + ]); + assert!(u.app.ui.preferences, "Ctrl/Cmd+, should open Preferences from the Home screen"); + + // Escape closes Preferences. + press(&mut u, Key::Escape); + assert!(!u.app.ui.preferences, "Escape should close Preferences"); + + // Clicking Preferences in the sidebar opens Preferences. + let s = shapes(&mut u); + click(&mut u, text_center(&s, "Preferences")); + assert!(u.app.ui.preferences, "Clicking Preferences in sidebar should open Preferences"); + + // Clicking it again toggles it closed. + let s = shapes(&mut u); + click(&mut u, text_center(&s, "Preferences")); + assert!(!u.app.ui.preferences, "Clicking Preferences in sidebar again should close it"); +}