From ba6b3190463d3a2476f1eea33ba0bd68bfb125f2 Mon Sep 17 00:00:00 2001 From: Michael Angerman <1809991+stormasm@users.noreply.github.com> Date: Thu, 22 Feb 2024 09:51:40 -0800 Subject: [PATCH] Add an app_menu to Storybook which enables quitting with `cmd-q` (#8166) I really think storybook is a cool standalone app but there are some usability issues that are getting in the way of making this a fun tool to use. Currently it is not easy to gracefully exit out of storybook. In fact even trying to Ctrl-c out of storybook seems currently broken to me... So the only real way to exit out of storybook is to kill the process after a Ctrl-z. This PR attempts to make this much easier by adding a simple app_menu with a menu item called quit along with the ability to *Cmd-q* out of storybook as well... Both the menu item quit and *Cmd-q* gracefully exit storybook. There are still a bunch of issues with storybook which I plan on addressing in future PR's but this is a start and something that to me is the highest priority to make storybook more functional and easy to use moving forward. One of my longer term goals of storybook is to have it be a nice stand alone application similar to [Loungy](https://github.com/MatthiasGrandl/Loungy) which can be used as a nice tutorial application for how to develop a real world *gpui* app. For that reason I added a *assets/keymaps/storybook.json* file as well. --- assets/keymaps/storybook.json | 23 +++++++++++++++++++++++ crates/storybook/src/actions.rs | 2 ++ crates/storybook/src/app_menus.rs | 10 ++++++++++ crates/storybook/src/storybook.rs | 26 +++++++++++++++++++++++++- 4 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 assets/keymaps/storybook.json create mode 100644 crates/storybook/src/actions.rs create mode 100644 crates/storybook/src/app_menus.rs diff --git a/assets/keymaps/storybook.json b/assets/keymaps/storybook.json new file mode 100644 index 0000000000..658a9d67bd --- /dev/null +++ b/assets/keymaps/storybook.json @@ -0,0 +1,23 @@ +[ + // Standard macOS bindings + { + "bindings": { + "up": "menu::SelectPrev", + "pageup": "menu::SelectFirst", + "shift-pageup": "menu::SelectFirst", + "ctrl-p": "menu::SelectPrev", + "down": "menu::SelectNext", + "pagedown": "menu::SelectLast", + "shift-pagedown": "menu::SelectFirst", + "ctrl-n": "menu::SelectNext", + "cmd-up": "menu::SelectFirst", + "cmd-down": "menu::SelectLast", + "enter": "menu::Confirm", + "ctrl-enter": "menu::ShowContextMenu", + "cmd-enter": "menu::SecondaryConfirm", + "escape": "menu::Cancel", + "ctrl-c": "menu::Cancel", + "cmd-q": "storybook::Quit" + } + } +] diff --git a/crates/storybook/src/actions.rs b/crates/storybook/src/actions.rs new file mode 100644 index 0000000000..03ee5b580c --- /dev/null +++ b/crates/storybook/src/actions.rs @@ -0,0 +1,2 @@ +use gpui::actions; +actions!(storybook, [Quit]); diff --git a/crates/storybook/src/app_menus.rs b/crates/storybook/src/app_menus.rs new file mode 100644 index 0000000000..14c5e073ad --- /dev/null +++ b/crates/storybook/src/app_menus.rs @@ -0,0 +1,10 @@ +use gpui::{Menu, MenuItem}; + +pub fn app_menus() -> Vec> { + use crate::actions::Quit; + + vec![Menu { + name: "Storybook", + items: vec![MenuItem::action("Quit", Quit)], + }] +} diff --git a/crates/storybook/src/storybook.rs b/crates/storybook/src/storybook.rs index efbd46665c..74bca38209 100644 --- a/crates/storybook/src/storybook.rs +++ b/crates/storybook/src/storybook.rs @@ -1,3 +1,5 @@ +mod actions; +mod app_menus; mod assets; mod stories; mod story_selector; @@ -9,14 +11,16 @@ use gpui::{ WindowOptions, }; use log::LevelFilter; -use settings::{default_settings, Settings, SettingsStore}; +use settings::{default_settings, KeymapFile, Settings, SettingsStore}; use simplelog::SimpleLogger; use strum::IntoEnumIterator; use theme::{ThemeRegistry, ThemeSettings}; use ui::prelude::*; +use crate::app_menus::app_menus; use crate::assets::Assets; use crate::story_selector::{ComponentStory, StorySelector}; +use actions::Quit; pub use indoc::indoc; #[derive(Parser)] @@ -37,6 +41,7 @@ fn main() { SimpleLogger::init(LevelFilter::Info, Default::default()).expect("could not initialize logger"); + menu::init(); let args = Args::parse(); let story_selector = args.story.clone().unwrap_or_else(|| { @@ -78,6 +83,9 @@ fn main() { language::init(cx); editor::init(cx); + init(cx); + load_storybook_keymap(cx); + cx.set_menus(app_menus()); let _window = cx.open_window( WindowOptions { @@ -133,3 +141,19 @@ fn load_embedded_fonts(cx: &AppContext) -> gpui::Result<()> { cx.text_system().add_fonts(embedded_fonts) } + +fn load_storybook_keymap(cx: &mut AppContext) { + KeymapFile::load_asset("keymaps/storybook.json", cx).unwrap(); +} + +pub fn init(cx: &mut AppContext) { + cx.on_action(quit); +} + +fn quit(_: &Quit, cx: &mut AppContext) { + cx.spawn(|cx| async move { + cx.update(|cx| cx.quit())?; + anyhow::Ok(()) + }) + .detach_and_log_err(cx); +}