1use crate::cx::*;
2use std::any::TypeId;
3use std::collections::HashMap;
4
5#[derive(Clone, Debug, PartialEq, Default)]
6pub struct KeyModifiers {
7 pub shift: bool,
8 pub control: bool,
9 pub alt: bool,
10 pub logo: bool
11}
12
13#[derive(Clone, Default, Debug, PartialEq)]
14pub struct FingerDownEvent {
15 pub window_id: usize,
16 pub abs: Vec2,
17 pub rel: Vec2,
18 pub rect: Rect,
19 pub digit: usize,
20 pub tap_count: u32,
21 pub handled: bool,
22 pub is_touch: bool,
23 pub modifiers: KeyModifiers,
24 pub time: f64
25}
26
27#[derive(Clone, Default, Debug, PartialEq)]
28pub struct FingerMoveEvent {
29 pub window_id: usize,
30 pub abs: Vec2,
31 pub abs_start: Vec2,
32 pub rel: Vec2,
33 pub rel_start: Vec2,
34 pub rect: Rect,
35 pub is_over: bool,
36 pub digit: usize,
37 pub is_touch: bool,
38 pub modifiers: KeyModifiers,
39 pub time: f64
40}
41
42impl FingerMoveEvent {
43 pub fn move_distance(&self) -> f32 {
44 ((self.abs_start.x - self.abs.x).powf(2.) + (self.abs_start.y - self.abs.y).powf(2.)).sqrt()
45 }
46}
47
48#[derive(Clone, Default, Debug, PartialEq)]
49pub struct FingerUpEvent {
50 pub window_id: usize,
51 pub abs: Vec2,
52 pub abs_start: Vec2,
53 pub rel: Vec2,
54 pub rel_start: Vec2,
55 pub rect: Rect,
56 pub digit: usize,
57 pub is_over: bool,
58 pub is_touch: bool,
59 pub modifiers: KeyModifiers,
60 pub time: f64
61}
62
63#[derive(Clone, Debug, PartialEq)]
64pub enum HoverState {
65 In,
66 Over,
67 Out
68}
69
70impl Default for HoverState {
71 fn default() -> HoverState {
72 HoverState::Over
73 }
74}
75
76#[derive(Clone, Default, Debug, PartialEq)]
77pub struct FingerHoverEvent {
78 pub window_id: usize,
79 pub abs: Vec2,
80 pub rel: Vec2,
81 pub rect: Rect,
82 pub any_down: bool,
83 pub handled: bool,
84 pub hover_state: HoverState,
85 pub modifiers: KeyModifiers,
86 pub time: f64
87}
88
89#[derive(Clone, Default, Debug, PartialEq)]
90pub struct FingerScrollEvent {
91 pub window_id: usize,
92 pub abs: Vec2,
93 pub rel: Vec2,
94 pub rect: Rect,
95 pub scroll: Vec2,
96 pub is_wheel: bool,
97 pub handled: bool,
98 pub modifiers: KeyModifiers,
99 pub time: f64
100}
101
102#[derive(Clone, Default, Debug, PartialEq)]
103pub struct WindowGeomChangeEvent {
104 pub window_id: usize,
105 pub old_geom: WindowGeom,
106 pub new_geom: WindowGeom,
107}
108
109#[derive(Clone, Default, Debug, PartialEq)]
110pub struct WindowMovedEvent {
111 pub window_id: usize,
112 pub old_pos: Vec2,
113 pub new_pos: Vec2,
114}
115
116#[derive(Clone, Default, Debug, PartialEq)]
117pub struct AnimateEvent {
118 pub frame: u64,
119 pub time: f64
120}
121
122#[derive(Clone, Default, Debug, PartialEq)]
123pub struct FrameEvent {
124 pub frame: u64,
125 pub time: f64
126}
127
128#[derive(Clone, Default, Debug)]
129pub struct RedrawEvent {
130 pub area: Area
131}
132
133#[derive(Clone, Debug, PartialEq)]
134pub struct FileReadEvent {
135 pub read_id: u64,
136 pub data: Result<Vec<u8>, String>
137}
138
139#[derive(Clone, Debug, PartialEq)]
140pub struct TimerEvent {
141 pub timer_id: u64
142}
143
144#[derive(Clone, Debug, PartialEq)]
145pub struct SignalEvent {
146 pub signals: HashMap<Signal, Vec<StatusId>>
147}
148
149#[derive(Clone, Debug, PartialEq)]
150pub struct FileWriteEvent {
151 id: u64,
152 error: Option<String>
153}
154
155#[derive(Clone, Debug, PartialEq)]
156pub struct KeyEvent {
157 pub key_code: KeyCode,
158 pub is_repeat: bool,
160 pub modifiers: KeyModifiers,
161 pub time: f64
162}
163
164#[derive(Clone, Debug, PartialEq)]
165pub struct KeyFocusEvent {
166 pub prev: Area,
167 pub focus: Area,
168}
169
170#[derive(Clone, Debug, PartialEq)]
171pub struct TextInputEvent {
172 pub input: String,
173 pub replace_last: bool,
174 pub was_paste: bool
175}
176
177#[derive(Clone, Debug, PartialEq)]
178pub struct TextCopyEvent {
179 pub response: Option<String>
180}
181
182#[derive(Clone, Debug, PartialEq)]
183pub struct WindowCloseRequestedEvent {
184 pub window_id: usize,
185 pub accept_close: bool
186}
187
188#[derive(Clone, Debug, PartialEq)]
189pub struct WindowClosedEvent {
190 pub window_id: usize
191}
192
193#[derive(Clone, Debug, PartialEq)]
194pub struct WindowResizeLoopEvent {
195 pub was_started: bool,
196 pub window_id: usize
197}
198
199#[derive(Clone, Debug, PartialEq)]
200pub enum WindowDragQueryResponse {
201 NoAnswer,
202 Client,
203 Caption,
204 SysMenu, }
206
207#[derive(Clone, Debug, PartialEq)]
208pub struct WindowDragQueryEvent {
209 pub window_id: usize,
210 pub abs: Vec2,
211 pub response: WindowDragQueryResponse,
212}
213
214#[derive(Clone, Debug, PartialEq)]
215pub enum Event {
216 None,
217 Construct,
218 Destruct,
219 Draw,
220 Paint,
221 AppFocus,
222 AppFocusLost,
223 AnimEnded(AnimateEvent),
224 Animate(AnimateEvent),
225 Frame(FrameEvent),
226 WindowSetHoverCursor(MouseCursor),
227 WindowDragQuery(WindowDragQueryEvent),
228 WindowCloseRequested(WindowCloseRequestedEvent),
229 WindowClosed(WindowClosedEvent),
230 WindowGeomChange(WindowGeomChangeEvent),
231 WindowResizeLoop(WindowResizeLoopEvent),
232 FingerDown(FingerDownEvent),
233 FingerMove(FingerMoveEvent),
234 FingerHover(FingerHoverEvent),
235 FingerUp(FingerUpEvent),
236 FingerScroll(FingerScrollEvent),
237 FileRead(FileReadEvent),
238 FileWrite(FileWriteEvent),
239 Timer(TimerEvent),
240 Signal(SignalEvent),
241 Command(CommandId),
242 KeyFocus(KeyFocusEvent),
243 KeyFocusLost(KeyFocusEvent),
244 KeyDown(KeyEvent),
245 KeyUp(KeyEvent),
246 TextInput(TextInputEvent),
247 TextCopy(TextCopyEvent)
248}
249
250impl Default for Event {
251 fn default() -> Event {
252 Event::None
253 }
254}
255
256pub enum HitTouch {
257 Single,
258 Multi
259}
260
261#[derive(Clone, Debug, Default)]
262pub struct HitOpt {
263 pub use_multi_touch: bool,
264 pub margin: Option<Margin>,
265}
266
267impl Event {
268
269 pub fn hits(&mut self, cx: &mut Cx, area: Area, opt: HitOpt) -> Event {
270 match self {
271 Event::KeyFocus(kf) => {
272 if area == kf.prev {
273 return Event::KeyFocusLost(kf.clone())
274 }
275 else if area == kf.focus {
276 return Event::KeyFocus(kf.clone())
277 }
278 },
279 Event::KeyDown(_) => {
280 if area == cx.key_focus {
281 return self.clone();
282 }
283 },
284 Event::KeyUp(_) => {
285 if area == cx.key_focus {
286 return self.clone();
287 }
288 },
289 Event::TextInput(_) => {
290 if area == cx.key_focus {
291 return self.clone();
292 }
293 },
294 Event::TextCopy(_) => {
295 if area == cx.key_focus {
296 return Event::TextCopy(
297 TextCopyEvent {response: None}
298 );
299 }
300 },
301 Event::Animate(_) => {
302 for anim in &cx.playing_anim_areas {
303 if anim.area == area {
304 return self.clone()
305 }
306 }
307 },
308 Event::Frame(_) => {
309 for frame_area in &cx._frame_callbacks {
310 if *frame_area == area {
311 return self.clone()
312 }
313 }
314 },
315 Event::AnimEnded(_) => {
316 for anim in &cx.ended_anim_areas {
317 if anim.area == area {
318 return self.clone()
319 }
320 }
321 },
322 Event::FingerScroll(fe) => {
323 let rect = area.get_rect(&cx);
324 if !fe.handled && rect.contains_with_margin(fe.abs.x, fe.abs.y, &opt.margin) {
325 return Event::FingerScroll(FingerScrollEvent {
327 rel: Vec2 {x: fe.abs.x - rect.x, y: fe.abs.y - rect.y},
328 rect: rect,
329 ..fe.clone()
330 })
331 }
332 },
333 Event::FingerHover(fe) => {
334 let rect = area.get_rect(&cx);
335
336 if cx._finger_over_last_area == area {
337 let mut any_down = false;
338 for fin_area in &cx.captured_fingers {
339 if *fin_area == area {
340 any_down = true;
341 break;
342 }
343 }
344 if !fe.handled && rect.contains_with_margin(fe.abs.x, fe.abs.y, &opt.margin) {
345 fe.handled = true;
346 if let HoverState::Out = fe.hover_state {
347 }
349 else {
350 cx.finger_over_last_area = area;
351 }
352 return Event::FingerHover(FingerHoverEvent {
353 rel: area.abs_to_rel(cx, fe.abs),
354 rect: rect,
355 any_down:any_down,
356 ..fe.clone()
357 })
358 }
359 else {
360 return Event::FingerHover(FingerHoverEvent {
362 rel: area.abs_to_rel(cx, fe.abs),
363 rect: rect,
364 any_down:any_down,
365 hover_state: HoverState::Out,
366 ..fe.clone()
367 })
368 }
369 }
370 else {
371 if !fe.handled && rect.contains_with_margin(fe.abs.x, fe.abs.y, &opt.margin) {
372 let mut any_down = false;
373 for fin_area in &cx.captured_fingers {
374 if *fin_area == area {
375 any_down = true;
376 break;
377 }
378 }
379 cx.finger_over_last_area = area;
380 fe.handled = true;
381 return Event::FingerHover(FingerHoverEvent {
383 rel: area.abs_to_rel(cx, fe.abs),
384 rect: rect,
385 any_down:any_down,
386 hover_state: HoverState::In,
387 ..fe.clone()
388 })
389 }
390 }
391 },
392 Event::FingerMove(fe) => {
393 if cx.captured_fingers[fe.digit] == area {
395 let abs_start = cx.finger_down_abs_start[fe.digit];
396 let rel_start = cx.finger_down_rel_start[fe.digit];
397 let rect = area.get_rect(&cx);
398 return Event::FingerMove(FingerMoveEvent {
399 abs_start: abs_start,
400 rel: area.abs_to_rel(cx, fe.abs),
401 rel_start: rel_start,
402 rect: rect,
403 is_over: rect.contains_with_margin(fe.abs.x, fe.abs.y, &opt.margin),
404 ..fe.clone()
405 })
406 }
407 },
408 Event::FingerDown(fe) => {
409 if !fe.handled {
410 let rect = area.get_rect(&cx);
411 if rect.contains_with_margin(fe.abs.x, fe.abs.y, &opt.margin) {
412 if !opt.use_multi_touch {
414 for fin_area in &cx.captured_fingers {
415 if *fin_area == area {
416 return Event::None;
417 }
418 }
419 }
420 cx.captured_fingers[fe.digit] = area;
421 let rel = area.abs_to_rel(cx, fe.abs);
422 cx.finger_down_abs_start[fe.digit] = fe.abs;
423 cx.finger_down_rel_start[fe.digit] = rel;
424 fe.handled = true;
425 return Event::FingerDown(FingerDownEvent {
426 rel: rel,
427 rect: rect,
428 ..fe.clone()
429 })
430 }
431 }
432 },
433 Event::FingerUp(fe) => {
434 if cx.captured_fingers[fe.digit] == area {
435 cx.captured_fingers[fe.digit] = Area::Empty;
436 let abs_start = cx.finger_down_abs_start[fe.digit];
437 let rel_start = cx.finger_down_rel_start[fe.digit];
438 let rect = area.get_rect(&cx);
439 return Event::FingerUp(FingerUpEvent {
440 is_over: rect.contains(fe.abs.x, fe.abs.y),
441 abs_start: abs_start,
442 rel_start: rel_start,
443 rel: area.abs_to_rel(cx, fe.abs),
444 rect: rect,
445 ..fe.clone()
446 })
447 }
448 },
449 _ => ()
450 };
451 return Event::None;
452 }
453}
454
455#[derive(Hash, Eq, PartialEq, Clone, Copy, Debug, Default)]
456pub struct Signal {
457 pub signal_id: usize
458}
459
460impl Signal {
461 pub fn empty() -> Signal {
462 Signal {
463 signal_id: 0
464 }
465 }
466
467 pub fn is_empty(&self) -> bool {
468 self.signal_id == 0
469 }
470
471 pub fn send(&self, cx:&mut Cx, status:StatusId){
472 cx.send_signal(*self, status);
473 }
474
475 pub fn post(&self, status:StatusId){
476 Cx::post_signal(*self, status);
477 }
478}
479
480
481#[derive(PartialEq, Copy, Clone, Hash, Eq, Debug)]
485pub struct StatusId(pub TypeId);
486
487impl Into<StatusId> for UniqueId {
488 fn into(self) -> StatusId {StatusId(self.0)}
489}
490
491
492
493
494
495
496#[derive(Clone, Debug, Default)]
497pub struct FileRead {
498 pub path: String,
499 pub read_id: u64
500}
501
502impl FileRead {
503 pub fn is_pending(&self) -> bool {
504 self.read_id != 0
505 }
506
507 pub fn resolve_utf8<'a>(&mut self, fr: &'a FileReadEvent) -> Option<Result<&'a str,String>> {
508 if fr.read_id == self.read_id {
509 self.read_id = 0;
510 if let Ok(str_data) = &fr.data {
511 if let Ok(utf8_string) = std::str::from_utf8(&str_data) {
512 return Some(Ok(utf8_string))
513 }
514 else {
515 return Some(Err(format!("can't parse file as utf8 {}", self.path)))
516 }
517 }
518 else if let Err(err) = &fr.data {
519 return Some(Err(format!("can't load file as utf8 {} {}", self.path, err)))
520 }
521 }
522 return None
523 }
524}
525
526#[derive(Clone, Debug, Default)]
527pub struct Timer {
528 pub timer_id: u64
529}
530
531impl Timer {
532 pub fn empty() -> Timer {
533 Timer {
534 timer_id: 0,
535 }
536 }
537
538 pub fn is_empty(&self) -> bool {
539 self.timer_id == 0
540 }
541
542 pub fn is_timer(&mut self, te: &TimerEvent) -> bool {
543 te.timer_id == self.timer_id
544 }
545}
546
547impl Event {
548 pub fn set_handled(&mut self, set: bool) {
549 match self {
550 Event::FingerHover(fe) => {
551 fe.handled = set;
552 },
553 Event::FingerScroll(fe) => {
554 fe.handled = set;
555 },
556 Event::FingerDown(fe) => {
557 fe.handled = set;
558 },
559 _ => ()
560 }
561 }
562
563 pub fn handled(&self) -> bool {
564 match self {
565 Event::FingerHover(fe) => {
566 fe.handled
567 },
568 Event::FingerScroll(fe) => {
569 fe.handled
570 },
571 Event::FingerDown(fe) => {
572 fe.handled
573 },
574
575 _ => false
576 }
577 }
578
579
580}
581
582#[derive(Clone, Copy, PartialEq, Debug)]
584pub enum KeyCode {
585 Escape,
586
587 Backtick,
588 Key0,
589 Key1,
590 Key2,
591 Key3,
592 Key4,
593 Key5,
594 Key6,
595 Key7,
596 Key8,
597 Key9,
598 Minus,
599 Equals,
600
601 Backspace,
602 Tab,
603
604 KeyQ,
605 KeyW,
606 KeyE,
607 KeyR,
608 KeyT,
609 KeyY,
610 KeyU,
611 KeyI,
612 KeyO,
613 KeyP,
614 LBracket,
615 RBracket,
616 Return,
617
618 KeyA,
619 KeyS,
620 KeyD,
621 KeyF,
622 KeyG,
623 KeyH,
624 KeyJ,
625 KeyK,
626 KeyL,
627 Semicolon,
628 Quote,
629 Backslash,
630
631 KeyZ,
632 KeyX,
633 KeyC,
634 KeyV,
635 KeyB,
636 KeyN,
637 KeyM,
638 Comma,
639 Period,
640 Slash,
641
642 Control,
643 Alt,
644 Shift,
645 Logo,
646
647 Space,
653 Capslock,
654 F1,
655 F2,
656 F3,
657 F4,
658 F5,
659 F6,
660 F7,
661 F8,
662 F9,
663 F10,
664 F11,
665 F12,
666
667 PrintScreen,
668 Scrolllock,
669 Pause,
670
671 Insert,
672 Delete,
673 Home,
674 End,
675 PageUp,
676 PageDown,
677
678 Numpad0,
679 Numpad1,
680 Numpad2,
681 Numpad3,
682 Numpad4,
683 Numpad5,
684 Numpad6,
685 Numpad7,
686 Numpad8,
687 Numpad9,
688
689 NumpadEquals,
690 NumpadSubtract,
691 NumpadAdd,
692 NumpadDecimal,
693 NumpadMultiply,
694 NumpadDivide,
695 Numlock,
696 NumpadEnter,
697
698 ArrowUp,
699 ArrowDown,
700 ArrowLeft,
701 ArrowRight,
702
703 Unknown
704}
705
706impl Default for KeyCode{
707 fn default()->Self{KeyCode::Unknown}
708}