makepad_widgets/
window_menu.rs1use crate::{
3 makepad_derive_widget::*,
4 makepad_draw::*,
5 widget::*,
6};
7use std::collections::HashMap;
8
9live_design!{
10 link widgets;
11 use link::theme::*;
12 use makepad_draw::shader::std::*;
13
14 pub WindowMenuBase = {{WindowMenu}}{
15 }
16
17 pub WindowMenu = <WindowMenuBase> { height: 0, width: 0, }
18}
19
20#[derive(Clone, Debug, Live, LiveHook)]
21#[live_ignore]
22pub enum WindowMenuItem {
23 #[pick {items: vec![]}]
24 Main{items:Vec<LiveId>},
25 #[live {name:"Unknown".to_string(), shift: false, key:KeyCode::Unknown, enabled:true }]
26 Item{
27 name: String,
28 shift: bool,
29 key: KeyCode,
30 enabled: bool
31 },
32 #[live {name:"Unknown".to_string(), items:vec![] }]
33 Sub{
34 name:String,
35 items:Vec<LiveId>
36 },
37 #[live]
38 Line
39}
40
41#[derive(Live, Widget)]
42pub struct WindowMenu{
43 #[walk] walk: Walk,
44 #[redraw] #[rust] area: Area,
45 #[layout] layout: Layout,
46 #[rust] menu_items: HashMap<LiveId, WindowMenuItem>,
47}
48
49#[derive(Clone, DefaultNone)]
50pub enum WindowMenuAction {
51 Command(LiveId),
52 None
53}
54
55
56impl LiveHook for WindowMenu {
57 fn apply_value_instance(&mut self, cx: &mut Cx, apply: &mut Apply, index: usize, nodes: &[LiveNode]) -> usize {
58 let id = nodes[index].id;
59 match apply.from {
60 ApplyFrom::NewFromDoc {..} | ApplyFrom::UpdateFromDoc {..} => {
61 if nodes[index].origin.has_prop_type(LivePropType::Instance) {
62 if nodes[index].value.is_enum() {
63 let mut dock_item = WindowMenuItem::new(cx);
64 let index = dock_item.apply(cx, apply, index, nodes);
65 self.menu_items.insert(id, dock_item);
66 return index;
67 }
68 }
69 else {
70 cx.apply_error_no_matching_field(live_error_origin!(), index, nodes);
71 }
72 }
73 _ => ()
74 }
75 nodes.skip_node(index)
76 }
77
78 fn after_new_from_doc(&mut self, _cx: &mut Cx) {
79 #[cfg(target_os="macos")]{
81 fn recur_menu(command:LiveId,menu_items:&HashMap<LiveId, WindowMenuItem>)->MacosMenu{
83
84 if let Some(item) = menu_items.get(&command){
85 match item.clone(){
86 WindowMenuItem::Main{items}=>{
87 let mut out = Vec::new();
88 for item in items{
89 out.push(recur_menu(item, menu_items));
90 }
91 return MacosMenu::Main{items:out}
92 }
93 WindowMenuItem::Item{name, shift, key, enabled}=>{
94 return MacosMenu::Item{
95 command,
96 name,
97 shift,
98 key,
99 enabled
100 }
101 }
102 WindowMenuItem::Sub{name, items}=>{
103 let mut out = Vec::new();
104 for item in items{
105 out.push(recur_menu(item, menu_items));
106 }
107 return MacosMenu::Sub{name, items:out}
108 }
109 WindowMenuItem::Line=>{
110 return MacosMenu::Line
111 }
112 }
113 }
114 else{
115 log!("Menu cannot find item {}", command);
116 MacosMenu::Line
117 }
118 }
119 let menu = recur_menu(live_id!(main), &self.menu_items);
120 _cx.update_macos_menu(menu)
121 }
122 }
123
124}
125
126
127impl Widget for WindowMenu {
128
129 fn handle_event(&mut self, cx: &mut Cx, event: &Event, _scope:&mut Scope) {
130 match event{
131 Event::MacosMenuCommand(item)=>{
132 if *item == live_id!(quit){
133 cx.quit();
134 }
135 }
136 _=>()
137 }
138 }
139
140 fn draw_walk(&mut self, _cx: &mut Cx2d, _scope:&mut Scope, _walk: Walk) -> DrawStep {
141 DrawStep::done()
142 }
143}
144
145impl WindowMenuRef {
146 pub fn command(&self) -> Option<LiveId> {
147 if let Some(mut _dock) = self.borrow_mut() {
148
149 }
150 None
151 }
152}
153