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}