1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
use std::fmt;
use crate::event::{MouseButton, MouseButtons};
use crate::menu_item::MenuItemKind;
use crate::{AreaId, ItemId, MenuItem};
/// The structure of a popup menu.
pub struct PopupMenu {
area_id: AreaId,
pub(super) menu: Vec<MenuItem>,
/// The default item in the menu.
pub(super) default: Option<u32>,
/// Mouse buttons which will be accepted to open the menu.
pub(super) open_menu: MouseButtons,
}
impl PopupMenu {
/// Construct a new empt popup menu.
pub(super) fn new(area_id: AreaId) -> Self {
Self {
area_id,
menu: Vec::new(),
default: None,
open_menu: MouseButtons::RIGHT,
}
}
/// Specify a collection of mouse buttons which will be accepted to open the
/// context menu.
///
/// By default this is [`MouseButton::Right`].
///
/// # Examples
///
/// ```
/// use winctx::CreateWindow;
/// use winctx::event::MouseButton;
///
/// let mut window = CreateWindow::new("se.tedro.Example");;
/// let area = window.new_area();
///
/// let menu = area.popup_menu().open_menu([MouseButton::Left, MouseButton::Right]);
/// menu.push_entry("Example Application");
/// menu.push_separator();
/// menu.push_entry("Exit...");
/// ```
pub fn open_menu<I>(&mut self, buttons: I) -> &mut Self
where
I: IntoIterator<Item = MouseButton>,
{
self.open_menu = MouseButtons::from_iter(buttons);
self
}
/// Construct a menu entry.
///
/// The `default` parameter indicates whether the entry shoudl be
/// highlighted.
///
/// This returns a token which can be matched against the token returned in
/// [`Event::MenuItemClicked`].
///
/// [`Event::MenuItemClicked`]: crate::Event::MenuItemClicked
///
/// # Examples
///
/// ```
/// use winctx::CreateWindow;
///
/// let mut window = CreateWindow::new("se.tedro.Example");;
/// let area = window.new_area();
///
/// let menu = area.popup_menu();
/// menu.push_entry("Example Application");
/// menu.push_separator();
/// menu.push_entry("Exit...");
/// ```
pub fn push_entry<T>(&mut self, text: T) -> &mut MenuItem
where
T: fmt::Display,
{
let menu_id = ItemId::new(self.area_id.id(), self.menu.len() as u32);
self.menu.push(MenuItem::new(
menu_id,
MenuItemKind::String {
text: text.to_string(),
},
));
self.menu.last_mut().unwrap()
}
/// Construct a menu separator.
///
/// # Examples
///
/// ```no_run
/// use winctx::CreateWindow;
///
/// let mut window = CreateWindow::new("se.tedro.Example");;
/// let area = window.new_area();
///
/// let menu = area.popup_menu();
/// menu.push_separator();
/// ```
pub fn push_separator(&mut self) -> &mut MenuItem {
let menu_id = ItemId::new(self.area_id.id(), self.menu.len() as u32);
self.menu
.push(MenuItem::new(menu_id, MenuItemKind::Separator));
self.menu.last_mut().unwrap()
}
/// Set the default item in the menu.
///
/// # Examples
///
/// ```no_run
/// use winctx::CreateWindow;
///
/// let mut window = CreateWindow::new("se.tedro.Example");
/// let area = window.new_area();
///
/// let menu = area.popup_menu();
/// let first = menu.push_entry("Example Application").id();
/// menu.push_separator();
/// menu.push_entry("Exit...");
/// menu.set_default(first);
/// ```
pub fn set_default(&mut self, menu_item_id: ItemId) {
if self.area_id == menu_item_id.area_id() {
self.default = Some(menu_item_id.id());
}
}
}