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}