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}