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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
use self::{common::StatusFlags, keyselector::events::KeySelectorEvents};
use super::{events::ModalWindowMethods, Flags, Window};
use crate::prelude::*;
use std::ops::{Deref, DerefMut};
#[repr(C)]
pub struct ModalWindow<T: Sized> {
base: Window,
result: Option<T>,
}
impl<T> Deref for ModalWindow<T> {
type Target = Window;
fn deref(&self) -> &Self::Target {
&self.base
}
}
impl<T> DerefMut for ModalWindow<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.base
}
}
impl<T> ModalWindow<T> {
/// Creates a new Modal Window with the specified title, layout, and flags.
/// The window type is set be the one associated with the current theme and the background to `Normal` by default.
///
/// A Modal Window does not have an implicit close button
/// as exiting has to be done from either `exit(...)` or `exit_with(...)` methods.
///
/// # Parameters
/// * `title` - The title of the window
/// * `layout` - The layout of the window (position and size)
/// * `flags` - The initialization flags for the window
pub fn new(title: &str, layout: Layout, flags: Flags) -> Self {
// a Modal Window does not have an implicit close button
// as exiting has to be done from either exit(...) or exit_with(...) method.
Self {
base: Window::internal_create(
title,
layout,
flags | Flags::NoCloseButton,
None,
window::Background::Normal,
StatusFlags::ModalWindow | StatusFlags::ThemeType,
),
result: None,
}
}
/// Creates a new Modal Window with the specified title, layout, flags and background.
/// The background can be one of `Normal`, `Error`, `Warning` or `Notification`.
/// The window type is set be the one associated with the current theme.
///
/// A Modal Window does not have an implicit close button
/// as exiting has to be done from either `exit(...)` or `exit_with(...)` methods.
///
/// # Parameters
/// * `title` - The title of the window
/// * `layout` - The layout of the window (position and size)
/// * `flags` - The initialization flags for the window
/// * `background` - The background of the window (Normal, Error, Warning, Notification)
pub fn with_background(title: &str, layout: Layout, flags: Flags, background: window::Background) -> Self {
// a Modal Window does not have an implicit close button
// as exiting has to be done from either exit(...) or exit_with(...) method.
Self {
base: Window::internal_create(
title,
layout,
flags | Flags::NoCloseButton,
None,
background,
StatusFlags::ModalWindow | StatusFlags::ThemeType,
),
result: None,
}
}
/// Creates a new Modal Window with the specified title, layout, flags, window type and background.
/// The window type can be one of `Classic`, `Rounded` or `Panel`.
/// The background can be one of `Normal`, `Error`, `Warning` or `Notification`.
///
/// A Modal Window does not have an implicit close button
/// as exiting has to be done from either `exit(...)` or `exit_with(...)` methods.
///
/// # Parameters
/// * `title` - The title of the window
/// * `layout` - The layout of the window (position and size)
/// * `flags` - The initialization flags for the window
/// * `window_type` - The type of the window (Classic, Rounded, Panel)
/// * `background` - The background of the window (Normal, Error, Warning, Notification)
pub fn with_type(title: &str, layout: Layout, flags: Flags, window_type: window::Type, background: window::Background) -> Self {
// a Modal Window does not have an implicit close button
// as exiting has to be done from either exit(...) or exit_with(...) method.
Self {
base: Window::internal_create(
title,
layout,
flags | Flags::NoCloseButton,
Some(window_type),
background,
StatusFlags::ModalWindow,
),
result: None,
}
}
/// Displays the modal window and runs its event loop.
/// This method will block until the window is closed, either by calling `exit_with`
/// or `exit` methods.
/// Returns an `Option<T>` containing the result set by `exit_with` method,
/// or `None` if the window was closed using the `exit` method or if it was cancelled.
pub fn show<U>(object: U) -> Option<T>
where
U: Control + WindowControl + ModalWindowMethods<T> + 'static,
U: DerefMut<Target = ModalWindow<T>>,
{
let handle = RuntimeManager::get().add_modal_window(object);
// safety check - if we did not manage to add the window
if handle.is_none() {
return None;
}
// run the loop (the method will determine if it runs in a modal way or not)
RuntimeManager::get().run();
// the loop has ended , lets grab the results
if let Some(obj) = RuntimeManager::get().get_control_mut(handle) {
// move the result
return obj.result.take();
}
None
}
}
impl<T: 'static> Control for ModalWindow<T> {}
impl<T> OnThemeChanged for ModalWindow<T> {}
impl<T> GenericMenuEvents for ModalWindow<T> {}
impl<T> AppBarEvents for ModalWindow<T> {}
impl<T> DesktopEvents for ModalWindow<T> {}
impl<T> ToolBarEvents for ModalWindow<T> {}
impl<T> WindowEvents for ModalWindow<T> {}
impl<T> GenericCommandBarEvents for ModalWindow<T> {}
impl<T> CheckBoxEvents for ModalWindow<T> {}
impl<T> RadioBoxEvents for ModalWindow<T> {}
impl<T> PasswordEvents for ModalWindow<T> {}
impl<T> KeySelectorEvents for ModalWindow<T> {}
impl<T> TextFieldEvents for ModalWindow<T> {}
impl<T> RichTextFieldEvents for ModalWindow<T> {}
impl<T> ButtonEvents for ModalWindow<T> {}
impl<T> ToggleButtonEvents for ModalWindow<T> {}
impl<T> ColorPickerEvents for ModalWindow<T> {}
impl<T> CharPickerEvents for ModalWindow<T> {}
impl<T> ComboBoxEvents for ModalWindow<T> {}
impl<T> DatePickerEvents for ModalWindow<T> {}
impl<T> TimePickerEvents for ModalWindow<T> {}
impl<T> ListBoxEvents for ModalWindow<T> {}
impl<T> CustomEvents for ModalWindow<T> {}
impl<T> GenericSelectorEvents for ModalWindow<T> {}
impl<T> GenericDropDownListEvents for ModalWindow<T> {}
impl<T> GenericNumericSelectorEvents for ModalWindow<T> {}
impl<T> GenericListViewEvents for ModalWindow<T> {}
impl<T> GenericTreeViewEvents for ModalWindow<T> {}
impl<T> GenericBackgroundTaskEvents for ModalWindow<T> {}
impl<T> GenericGraphViewEvents for ModalWindow<T> {}
impl<T> OnDefaultAction for ModalWindow<T> {}
impl<T> WindowControl for ModalWindow<T> {}
impl<T> OnExpand for ModalWindow<T> {}
impl<T> ThreeStateBoxEvents for ModalWindow<T> {}
impl<T> OnSiblingSelected for ModalWindow<T> {}
impl<T> PathFinderEvents for ModalWindow<T> {}
impl<T> TimerEvents for ModalWindow<T> {}
impl<T> MarkdownEvents for ModalWindow<T> {}
impl<T> AccordionEvents for ModalWindow<T> {}
impl<T> TabEvents for ModalWindow<T> {}
// events routed to base window
impl<T> OnFocus for ModalWindow<T> {
fn on_focus(&mut self) {
OnFocus::on_focus(&mut self.base);
}
fn on_lose_focus(&mut self) {
OnFocus::on_lose_focus(&mut self.base);
}
}
impl<T> OnPaint for ModalWindow<T> {
fn on_paint(&self, surface: &mut Surface, theme: &Theme) {
OnPaint::on_paint(&self.base, surface, theme);
}
}
impl<T> OnResize for ModalWindow<T> {
fn on_resize(&mut self, old_size: Size, new_size: Size) {
OnResize::on_resize(&mut self.base, old_size, new_size);
}
}
impl<T: 'static> OnKeyPressed for ModalWindow<T> {
fn on_key_pressed(&mut self, key: Key, character: char) -> EventProcessStatus {
if !self.base.is_in_resize_mode() {
match key.value() {
key!("Enter") => {
if let Some(interface) = self.interface_mut() {
WindowEvents::on_accept(interface);
}
EventProcessStatus::Processed
}
key!("Escape") => {
if let Some(interface) = self.interface_mut() {
let result = WindowEvents::on_cancel(interface);
if result == ActionRequest::Allow {
// force the exit with None
self.exit();
} else {
// clean the result
self.result = None;
RuntimeManager::get().cancel_exit_from_execution_loop();
}
}
EventProcessStatus::Processed
}
_ => OnKeyPressed::on_key_pressed(&mut self.base, key, character),
}
} else {
OnKeyPressed::on_key_pressed(&mut self.base, key, character)
}
}
}
impl<T> OnMouseEvent for ModalWindow<T> {
fn on_mouse_event(&mut self, event: &MouseEvent) -> EventProcessStatus {
OnMouseEvent::on_mouse_event(&mut self.base, event)
}
}
impl<T> OnWindowRegistered for ModalWindow<T> {
fn on_registered(&mut self) {
self.base.on_registered();
}
}
impl<T: 'static> ModalWindowMethods<T> for ModalWindow<T> {
fn show(self) -> Option<T> {
// do nothing
None
}
fn exit_with(&mut self, result: T) {
self.result = Some(result);
RuntimeManager::get().exit_execution_loop();
}
fn exit(&mut self) {
self.result = None;
RuntimeManager::get().exit_execution_loop();
}
fn close(&mut self) {
self.exit();
}
}