{
261 | /// Creates a unconsumed event, initialized with `val`.
262 | pub fn new(val: T) -> Self {
263 | ConsumableEvent(Rc::new(ConsumableEventInner { marker: RefCell::new(true), data: val }))
264 | }
265 |
266 | /// Returns the event data as long as **both** the following conditions are satisfied:
267 | /// 1. The event hasn't been consumed yet.
268 | /// 2. The predicate returns true.
269 | ///
270 | /// The point of the predicate is to let the caller see if the event actually applies
271 | /// to them before consuming needlessly.
272 | pub fn with(&self, mut pred: P) -> Option<&T>
273 | where
274 | P: FnMut(&T) -> bool,
275 | {
276 | let mut is_consumed = self.0.marker.borrow_mut();
277 | if *is_consumed && pred(&self.0.data) {
278 | *is_consumed = false;
279 | Some(&self.0.data)
280 | } else {
281 | None
282 | }
283 | }
284 |
285 | /// Returns the inner event data regardless of consumption.
286 | #[inline(always)]
287 | pub fn get(&self) -> &T {
288 | &self.0.data
289 | }
290 | }
291 |
292 | impl Clone for ConsumableEvent {
293 | fn clone(&self) -> Self {
294 | ConsumableEvent(self.0.clone())
295 | }
296 | }
297 |
298 | /// An event related to the window, e.g. input.
299 | #[derive(Event, Debug, Clone, PartialEq)]
300 | pub enum WindowEvent {
301 | /// The user pressed a mouse button.
302 | #[event_key(mouse_press)]
303 | MousePress(ConsumableEvent<(AbsolutePoint, MouseButton, KeyModifiers)>),
304 | /// The user released a mouse button.
305 | /// This event complements `MousePress`, which means it realistically can only
306 | /// be emitted after `MousePress` has been emitted.
307 | #[event_key(mouse_release)]
308 | MouseRelease(ConsumableEvent<(AbsolutePoint, MouseButton, KeyModifiers)>),
309 | /// The user moved the cursor.
310 | #[event_key(mouse_move)]
311 | MouseMove(ConsumableEvent<(AbsolutePoint, KeyModifiers)>),
312 | /// Emitted when a text input is received.
313 | #[event_key(text_input)]
314 | TextInput(ConsumableEvent),
315 | /// Emitted when a key is pressed.
316 | #[event_key(key_press)]
317 | KeyPress(ConsumableEvent<(KeyInput, KeyModifiers)>),
318 | /// Emitted when a key is released.
319 | #[event_key(key_release)]
320 | KeyRelease(ConsumableEvent<(KeyInput, KeyModifiers)>),
321 | /// Emitted immediately before an event which is capable of changing focus.
322 | /// If implementing a focus-able widget, to handle this event, simply clear
323 | /// the local "focused" flag (which should ideally be stored as `draw::state::InteractionState`).
324 | #[event_key(clear_focus)]
325 | ClearFocus,
326 | }
327 |
328 | // Most of these are copied from `winit`.
329 | // We can't reuse the `winit` types because `winit` is an optional dependency (app feature).
330 |
331 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
332 | pub struct KeyModifiers {
333 | pub shift: bool,
334 | pub ctrl: bool,
335 | pub alt: bool,
336 | pub logo: bool,
337 | }
338 |
339 | /// Button on a mouse.
340 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
341 | pub enum MouseButton {
342 | Left,
343 | Middle,
344 | Right,
345 | }
346 |
347 | // Previously: `std::mem::transmute::(virtual_key)`.
348 | // Now: `virtual_key.into()`.
349 | // :)
350 | macro_rules! keyboard_enum {
351 | ($name:ident as $other:ty {
352 | $($v:ident),*$(,)?
353 | }) => {
354 | #[doc = "Key on a keyboard."]
355 | #[repr(u32)]
356 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
357 | pub enum $name {
358 | $($v),*
359 | }
360 |
361 | #[cfg(feature = "app")]
362 | impl From<$other> for $name {
363 | fn from(other: $other) -> $name {
364 | match other {
365 | $(<$other>::$v => $name::$v),*
366 | }
367 | }
368 | }
369 |
370 | #[cfg(feature = "app")]
371 | impl Into<$other> for $name {
372 | fn into(self) -> $other {
373 | match self {
374 | $($name::$v => <$other>::$v),*
375 | }
376 | }
377 | }
378 | };
379 | }
380 |
381 | keyboard_enum! {
382 | KeyInput as glutin::event::VirtualKeyCode {
383 | Key1,
384 | Key2,
385 | Key3,
386 | Key4,
387 | Key5,
388 | Key6,
389 | Key7,
390 | Key8,
391 | Key9,
392 | Key0,
393 | A,
394 | B,
395 | C,
396 | D,
397 | E,
398 | F,
399 | G,
400 | H,
401 | I,
402 | J,
403 | K,
404 | L,
405 | M,
406 | N,
407 | O,
408 | P,
409 | Q,
410 | R,
411 | S,
412 | T,
413 | U,
414 | V,
415 | W,
416 | X,
417 | Y,
418 | Z,
419 | Escape,
420 | F1,
421 | F2,
422 | F3,
423 | F4,
424 | F5,
425 | F6,
426 | F7,
427 | F8,
428 | F9,
429 | F10,
430 | F11,
431 | F12,
432 | F13,
433 | F14,
434 | F15,
435 | F16,
436 | F17,
437 | F18,
438 | F19,
439 | F20,
440 | F21,
441 | F22,
442 | F23,
443 | F24,
444 | Snapshot,
445 | Scroll,
446 | Pause,
447 | Insert,
448 | Home,
449 | Delete,
450 | End,
451 | PageDown,
452 | PageUp,
453 | Left,
454 | Up,
455 | Right,
456 | Down,
457 | Back,
458 | Return,
459 | Space,
460 | Compose,
461 | Caret,
462 | Numlock,
463 | Numpad0,
464 | Numpad1,
465 | Numpad2,
466 | Numpad3,
467 | Numpad4,
468 | Numpad5,
469 | Numpad6,
470 | Numpad7,
471 | Numpad8,
472 | Numpad9,
473 | AbntC1,
474 | AbntC2,
475 | Add,
476 | Apostrophe,
477 | Apps,
478 | At,
479 | Ax,
480 | Backslash,
481 | Calculator,
482 | Capital,
483 | Colon,
484 | Comma,
485 | Convert,
486 | Decimal,
487 | Divide,
488 | Equals,
489 | Grave,
490 | Kana,
491 | Kanji,
492 | LAlt,
493 | LBracket,
494 | LControl,
495 | LShift,
496 | LWin,
497 | Mail,
498 | MediaSelect,
499 | MediaStop,
500 | Minus,
501 | Multiply,
502 | Mute,
503 | MyComputer,
504 | NavigateForward,
505 | NavigateBackward,
506 | NextTrack,
507 | NoConvert,
508 | NumpadComma,
509 | NumpadEnter,
510 | NumpadEquals,
511 | OEM102,
512 | Period,
513 | PlayPause,
514 | Power,
515 | PrevTrack,
516 | RAlt,
517 | RBracket,
518 | RControl,
519 | RShift,
520 | RWin,
521 | Semicolon,
522 | Slash,
523 | Sleep,
524 | Stop,
525 | Subtract,
526 | Sysrq,
527 | Tab,
528 | Underline,
529 | Unlabeled,
530 | VolumeDown,
531 | VolumeUp,
532 | Wake,
533 | WebBack,
534 | WebFavorites,
535 | WebForward,
536 | WebHome,
537 | WebRefresh,
538 | WebSearch,
539 | WebStop,
540 | Yen,
541 | Copy,
542 | Paste,
543 | Cut,
544 | }
545 | }
546 |
547 | /// Information about a parent layout with a queue which receives updated rectangles.
548 | #[derive(Debug)]
549 | pub struct WidgetLayoutEventsInner {
550 | pub id: u64,
551 | pub evq: reclutch::event::bidir_single::Secondary,
552 | }
553 |
554 | /// Helper layout over `WidgetLayoutEventsInner`; optionally stores information about a parent layout.
555 | #[derive(Default, Debug)]
556 | pub struct WidgetLayoutEvents(Option);
557 |
558 | impl WidgetLayoutEvents {
559 | /// Creates `WidgetLayoutEvents` not connected to any layout.
560 | /// This means all the getters will return `None`.
561 | pub fn new() -> Self {
562 | Default::default()
563 | }
564 |
565 | /// Creates `WidgetLayoutEvents` from the given layout information.
566 | pub fn from_layout(layout: WidgetLayoutEventsInner) -> Self {
567 | WidgetLayoutEvents(Some(layout))
568 | }
569 |
570 | /// Possibly returns the inner associated layout ID.
571 | pub fn id(&self) -> Option {
572 | self.0.as_ref().map(|inner| inner.id)
573 | }
574 |
575 | /// Possibly updates the layout information.
576 | pub fn update(&mut self, layout: impl Into