zaplib/
menu.rs

1//! Defining native menus.
2
3use crate::*;
4
5impl Cx {
6    pub const COMMAND_QUIT: CommandId = location_hash!();
7    pub const COMMAND_UNDO: CommandId = location_hash!();
8    pub const COMMAND_REDO: CommandId = location_hash!();
9    pub const COMMAND_CUT: CommandId = location_hash!();
10    pub const COMMAND_COPY: CommandId = location_hash!();
11    pub const COMMAND_PASTE: CommandId = location_hash!();
12    pub const COMMAND_ZOOM_IN: CommandId = location_hash!();
13    pub const COMMAND_ZOOM_OUT: CommandId = location_hash!();
14    pub const COMMAND_MINIMIZE: CommandId = location_hash!();
15    pub const COMMAND_ZOOM: CommandId = location_hash!();
16    pub const COMMAND_SELECT_ALL: CommandId = location_hash!();
17
18    pub fn command_default_keymap(&mut self) {
19        Cx::COMMAND_QUIT.set_key(self, KeyCode::KeyQ);
20        Cx::COMMAND_UNDO.set_key(self, KeyCode::KeyZ);
21        Cx::COMMAND_REDO.set_key_shift(self, KeyCode::KeyZ);
22        Cx::COMMAND_CUT.set_key(self, KeyCode::KeyX);
23        Cx::COMMAND_COPY.set_key(self, KeyCode::KeyC);
24        Cx::COMMAND_PASTE.set_key(self, KeyCode::KeyV);
25        Cx::COMMAND_SELECT_ALL.set_key(self, KeyCode::KeyA);
26        Cx::COMMAND_ZOOM_OUT.set_key(self, KeyCode::Minus);
27        Cx::COMMAND_ZOOM_IN.set_key(self, KeyCode::Equals);
28        Cx::COMMAND_MINIMIZE.set_key(self, KeyCode::KeyM);
29    }
30}
31
32/// An alias over LocationHash so we have a semantic type
33/// but can change the underlying implementation whenever.
34/// See [`Event::Command`].
35pub type CommandId = LocationHash;
36
37impl CommandId {
38    pub fn set_enabled(&self, cx: &mut Cx, enabled: bool) {
39        let mut s = if let Some(s) = cx.command_settings.get(self) { *s } else { CxCommandSetting::default() };
40        s.enabled = enabled;
41        cx.command_settings.insert(*self, s);
42    }
43
44    pub fn set_key(&self, cx: &mut Cx, key_code: KeyCode) {
45        let mut s = if let Some(s) = cx.command_settings.get(self) { *s } else { CxCommandSetting::default() };
46        s.shift = false;
47        s.key_code = key_code;
48        cx.command_settings.insert(*self, s);
49    }
50
51    pub fn set_key_shift(&self, cx: &mut Cx, key_code: KeyCode) {
52        let mut s = if let Some(s) = cx.command_settings.get(self) { *s } else { CxCommandSetting::default() };
53        s.shift = true;
54        s.key_code = key_code;
55        cx.command_settings.insert(*self, s);
56    }
57}
58
59/// Represents a single menu, as well as all menus (recursively).
60#[derive(PartialEq, Clone)]
61pub enum Menu {
62    Main { items: Vec<Menu> },
63    Item { name: String, command: CommandId },
64    Sub { name: String, items: Vec<Menu> },
65    Line,
66}
67
68impl Menu {
69    pub fn main(items: Vec<Menu>) -> Menu {
70        Menu::Main { items }
71    }
72
73    pub fn sub(name: &str, items: Vec<Menu>) -> Menu {
74        Menu::Sub { name: name.to_string(), items }
75    }
76
77    pub fn line() -> Menu {
78        Menu::Line
79    }
80
81    pub fn item(name: &str, command: CommandId) -> Menu {
82        Menu::Item { name: name.to_string(), command }
83    }
84}