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::*,
  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(gpui::white())
 16            .size_full()
 17            .justify_center()
 18            .items_center()
 19            .text_xl()
 20            .text_color(gpui::black())
 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
 32        // by the `MenuItem::action` in the menu bar
 33        cx.on_action(quit);
 34        cx.on_action(toggle_check);
 35        // Add menu items
 36        set_app_menus(cx);
 37        cx.open_window(WindowOptions::default(), |_, cx| cx.new(|_| SetMenus {}))
 38            .unwrap();
 39    });
 40}
 41
 42#[cfg(not(target_family = "wasm"))]
 43fn main() {
 44    run_example();
 45}
 46
 47#[cfg(target_family = "wasm")]
 48#[wasm_bindgen::prelude::wasm_bindgen(start)]
 49pub fn start() {
 50    gpui_platform::web_init();
 51    run_example();
 52}
 53
 54#[derive(PartialEq)]
 55enum ViewMode {
 56    List,
 57    Grid,
 58}
 59
 60impl ViewMode {
 61    fn toggle(&mut self) {
 62        *self = match self {
 63            ViewMode::List => ViewMode::Grid,
 64            ViewMode::Grid => ViewMode::List,
 65        }
 66    }
 67}
 68
 69impl Into<SharedString> for ViewMode {
 70    fn into(self) -> SharedString {
 71        match self {
 72            ViewMode::List => "List",
 73            ViewMode::Grid => "Grid",
 74        }
 75        .into()
 76    }
 77}
 78
 79struct AppState {
 80    view_mode: ViewMode,
 81}
 82
 83impl AppState {
 84    fn new() -> Self {
 85        Self {
 86            view_mode: ViewMode::List,
 87        }
 88    }
 89}
 90
 91impl Global for AppState {}
 92
 93fn set_app_menus(cx: &mut App) {
 94    let app_state = cx.global::<AppState>();
 95    cx.set_menus([Menu::new("set_menus").items([
 96        MenuItem::os_submenu("Services", SystemMenuType::Services),
 97        MenuItem::separator(),
 98        MenuItem::action("Disabled Item", gpui::NoAction).disabled(true),
 99        MenuItem::submenu(Menu::new("Disabled Submenu").disabled(true)),
100        MenuItem::separator(),
101        MenuItem::action("List Mode", ToggleCheck).checked(app_state.view_mode == ViewMode::List),
102        MenuItem::submenu(
103            Menu::new("Mode").items([
104                MenuItem::action(ViewMode::List, ToggleCheck)
105                    .checked(app_state.view_mode == ViewMode::List),
106                MenuItem::action(ViewMode::Grid, ToggleCheck)
107                    .checked(app_state.view_mode == ViewMode::Grid),
108            ]),
109        ),
110        MenuItem::separator(),
111        MenuItem::action("Quit", Quit),
112    ])]);
113}
114
115// Associate actions using the `actions!` macro (or `Action` derive macro)
116actions!(set_menus, [Quit, ToggleCheck]);
117
118// Define the quit function that is registered with the App
119fn quit(_: &Quit, cx: &mut App) {
120    println!("Gracefully quitting the application...");
121    cx.quit();
122}
123
124fn toggle_check(_: &ToggleCheck, cx: &mut App) {
125    let app_state = cx.global_mut::<AppState>();
126    app_state.view_mode.toggle();
127    set_app_menus(cx);
128}