set_menus.rs

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