set_menus.rs

  1#![cfg_attr(target_family = "wasm", no_main)]
  2
  3use gpui::{
  4    App, Context, Global, Menu, MenuItem, SharedString, SystemMenuType, Window, WindowOptions,
  5    actions, div, prelude::*, rgb,
  6};
  7use gpui_platform::application;
  8
  9struct SetMenus;
 10
 11impl Render for SetMenus {
 12    fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
 13        div()
 14            .flex()
 15            .bg(rgb(0x2e7d32))
 16            .size_full()
 17            .justify_center()
 18            .items_center()
 19            .text_xl()
 20            .text_color(rgb(0xffffff))
 21            .child("Set Menus Example")
 22    }
 23}
 24
 25fn run_example() {
 26    application().run(|cx: &mut App| {
 27        cx.set_global(AppState::new());
 28
 29        // Bring the menu bar to the foreground (so you can see the menu bar)
 30        cx.activate(true);
 31        // Register the `quit` function so it can be referenced by the `MenuItem::action` in the menu bar
 32        cx.on_action(quit);
 33        cx.on_action(toggle_check);
 34        // Add menu items
 35        set_app_menus(cx);
 36        cx.open_window(WindowOptions::default(), |_, cx| cx.new(|_| SetMenus {}))
 37            .unwrap();
 38    });
 39}
 40
 41#[cfg(not(target_family = "wasm"))]
 42fn main() {
 43    run_example();
 44}
 45
 46#[cfg(target_family = "wasm")]
 47#[wasm_bindgen::prelude::wasm_bindgen(start)]
 48pub fn start() {
 49    gpui_platform::web_init();
 50    run_example();
 51}
 52
 53#[derive(PartialEq)]
 54enum ViewMode {
 55    List,
 56    Grid,
 57}
 58
 59impl ViewMode {
 60    fn toggle(&mut self) {
 61        *self = match self {
 62            ViewMode::List => ViewMode::Grid,
 63            ViewMode::Grid => ViewMode::List,
 64        }
 65    }
 66}
 67
 68impl Into<SharedString> for ViewMode {
 69    fn into(self) -> SharedString {
 70        match self {
 71            ViewMode::List => "List",
 72            ViewMode::Grid => "Grid",
 73        }
 74        .into()
 75    }
 76}
 77
 78struct AppState {
 79    view_mode: ViewMode,
 80}
 81
 82impl AppState {
 83    fn new() -> Self {
 84        Self {
 85            view_mode: ViewMode::List,
 86        }
 87    }
 88}
 89
 90impl Global for AppState {}
 91
 92fn set_app_menus(cx: &mut App) {
 93    let app_state = cx.global::<AppState>();
 94    cx.set_menus(vec![Menu {
 95        name: "set_menus".into(),
 96        items: vec![
 97            MenuItem::os_submenu("Services", SystemMenuType::Services),
 98            MenuItem::separator(),
 99            MenuItem::action(ViewMode::List, ToggleCheck)
100                .checked(app_state.view_mode == ViewMode::List),
101            MenuItem::action(ViewMode::Grid, ToggleCheck)
102                .checked(app_state.view_mode == ViewMode::Grid),
103            MenuItem::separator(),
104            MenuItem::action("Quit", Quit),
105        ],
106    }]);
107}
108
109// Associate actions using the `actions!` macro (or `Action` derive macro)
110actions!(set_menus, [Quit, ToggleCheck]);
111
112// Define the quit function that is registered with the App
113fn quit(_: &Quit, cx: &mut App) {
114    println!("Gracefully quitting the application . . .");
115    cx.quit();
116}
117
118fn toggle_check(_: &ToggleCheck, cx: &mut App) {
119    let app_state = cx.global_mut::<AppState>();
120    app_state.view_mode.toggle();
121    set_app_menus(cx);
122}