tuix_widgets/popups/popup.rs
1use crate::common::*;
2
3
4#[derive(Debug, Clone, PartialEq)]
5pub enum PopupEvent {
6 OpenAtCursor,
7 Open,
8 Close,
9 Switch,
10}
11
12pub struct Popup {
13 open: bool,
14}
15
16impl Popup {
17 pub fn new() -> Self {
18 Self { open: false }
19 }
20}
21
22impl Widget for Popup {
23 type Ret = Entity;
24 type Data = ();
25 fn on_build(&mut self, state: &mut State, entity: Entity) -> Self::Ret {
26
27
28 entity.add_listener(state, |popup: &mut Self, state, entity, event| {
29 if let Some(window_event) = event.message.downcast() {
30 match window_event {
31 WindowEvent::MouseDown(_) => {
32 if popup.open {
33 if event.origin != entity {
34 if !entity.is_over(state) {
35 entity.emit(state, PopupEvent::Close);
36
37 }
38 }
39 }
40 }
41
42 WindowEvent::KeyDown(code, _) => {
43 if popup.open {
44 if *code == Code::Escape {
45 entity.emit(state, PopupEvent::Close);
46 }
47 }
48 }
49
50 _=> {}
51 }
52 }
53 });
54
55 entity
56 .set_focusable(state, false)
57 .set_element(state, "popup")
58 .set_overflow(state, Overflow::Visible)
59 .set_position_type(state, PositionType::SelfDirected)
60 .set_opacity(state, 0.0)
61
62 }
63
64 fn on_event(&mut self, state: &mut State, entity: Entity, event: &mut Event) {
65 if let Some(popup_event) = event.message.downcast::<PopupEvent>() {
66 match popup_event {
67
68 PopupEvent::OpenAtCursor => {
69
70 let cursor_x = state.mouse.cursorx;
71 let cursor_y = state.mouse.cursory;
72
73 let width = state.data.get_width(entity);
74 let height = state.data.get_height(entity);
75
76 let right_edge = cursor_x + width;
77 let bottom_edge = cursor_y + height;
78
79 let window_width = state.data.get_width(Entity::root());
80 let window_height = state.data.get_height(Entity::root());
81
82 let mut new_posx = if right_edge > window_width {
83 cursor_x - width
84 } else {
85 cursor_x
86 };
87
88 let mut new_posy = if bottom_edge > window_height {
89 window_height - height
90 } else {
91 cursor_y
92 };
93
94 if new_posx < 0.0 {
95 new_posx = 0.0;
96 }
97
98 if new_posy < 0.0 {
99 new_posy = 0.0;
100 }
101
102 entity.set_left(state, Pixels(new_posx)).set_top(state, Pixels(new_posy));
103
104 self.open = true;
105 //state.capture(entity);
106 entity.set_opacity(state, 1.0);
107
108 }
109
110 PopupEvent::Open => {
111 self.open = true;
112 //state.capture(entity);
113 entity.set_opacity(state, 1.0);
114 }
115
116 PopupEvent::Close => {
117 self.open = false;
118 //state.release(entity);
119 entity.set_opacity(state, 0.0);
120 }
121
122 PopupEvent::Switch => {
123 if self.open {
124 self.open = false;
125 //state.release(entity);
126 entity.set_opacity(state, 0.0);
127 } else {
128 self.open = true;
129 //state.capture(entity);
130 entity.set_opacity(state, 1.0);
131 }
132 }
133 }
134 }
135
136 /*
137 if let Some(window_event) = event.message.downcast::<WindowEvent>() {
138 match window_event {
139 WindowEvent::MouseCaptureOutEvent => {
140 println!("Received mouse capture out from {}", event.target);
141 //println!("Hide");
142 // state
143 // .style
144 // .opacity
145 // .play_animation(self.container, self.fade_out_animation);
146 //entity.emit(state, PopupEvent::Close);
147 //entity.set_opacity(state, 0.0);
148 // if event.target != entity {
149 // state.capture(entity);
150 // }
151 }
152
153 WindowEvent::MouseCaptureEvent => {
154 //println!("Show");
155 // state
156 // .style
157 // .opacity
158 // .play_animation(self.container, self.fade_in_animation);
159 //entity.emit(state, PopupEvent::Open);
160 //entity.set_opacity(state, 1.0);
161 // Shouldn't need to do this but it's required for some reason. TODO: Investigate
162 //self.container.set_z_order(state, 1);
163 }
164
165 WindowEvent::MouseDown(button) => {
166 println!("Receive mouse button down");
167 if event.origin != entity {
168 if !entity.is_over(state) {
169 entity.emit(state, PopupEvent::Close);
170
171 } else {
172 state.insert_event(
173 Event::new(WindowEvent::MouseDown(*button))
174 .target(state.hovered)
175 .origin(entity)
176 .propagate(Propagation::Up),
177 );
178 }
179 }
180
181 }
182
183 WindowEvent::MouseUp(button) => match button {
184 MouseButton::Left => {
185 if event.origin != entity {
186 if state.mouse.left.pressed == state.hovered {
187 // if !self.open {
188 // //state.capture(entity);
189 // } else {
190 // // println!("Release");
191 // // state.release(entity);
192 // }
193
194 state.insert_event(
195 Event::new(WindowEvent::MouseUp(*button))
196 .target(state.hovered)
197 .origin(entity)
198 .propagate(Propagation::Up),
199 );
200 }
201 }
202 }
203
204 _ => {}
205 },
206
207 WindowEvent::MouseScroll(x,y) => {
208 if event.origin != entity {
209 state.insert_event(
210 Event::new(WindowEvent::MouseScroll(*x,*y))
211 .target(state.hovered)
212 .origin(entity)
213 .propagate(Propagation::Up),
214 );
215 }
216 }
217
218 WindowEvent::MouseMove(x,y) => {
219 if event.origin != entity {
220 state.insert_event(
221 Event::new(WindowEvent::MouseMove(*x,*y))
222 .target(state.hovered)
223 .origin(entity)
224 .propagate(Propagation::Up),
225 );
226 }
227 }
228
229 WindowEvent::KeyDown(code, _) => match code {
230 Code::Escape => {
231 state.insert_event(Event::new(PopupEvent::Close).target(entity));
232 }
233
234 _ => {}
235 },
236
237 _ => {}
238 }
239 }
240 */
241 }
242}