set_menus.rs

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