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
// Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License in the LICENSE-APACHE file or at: // https://www.apache.org/licenses/LICENSE-2.0 //! Event handling //! //! Event handling uses *event* messages, passed from the parent into a widget, //! with responses passed back to the parent. This model is simpler than that //! commonly used by GUI frameworks: widgets do not need a pointer to their //! parent and any result is pushed back up the call stack. The model allows //! type-safety while allowing user-defined result types. use std::fmt::Debug; use crate::TkWidget; use crate::macros::NoResponse; use crate::widget::Core; /// Input actions: these are high-level messages aimed at specific widgets. #[derive(Debug)] pub enum Action { /// An `Entry` has been activated. Activate, /// A button has been clicked. ButtonClick, /// A window has been asked to close. Close, } /* /// Input events: these are low-level messages where the destination widget is /// unknown. /// /// TODO: probably just re-export `winit::Event`, maybe behind a feature flag. #[derive(Debug)] pub type Event = (); */ /// No message /// /// All response message types should implement `From<NoResponse>`. /// This can be done conveniently with the /// [`derive(NoResponse)`](../macros/index.html#the-derivenoresponse-macro) macro. #[derive(Debug)] pub struct NoResponse; /// General GUI event responses #[derive(Debug, NoResponse)] pub enum GuiResponse { /// No action None, /// Close the window Close, /// Exit (close all windows) Exit, } /// Mark explicitly ignored events. /// /// This is an error, meaning somehow an event has been sent to a widget which /// does not support events of that type. /// It is safe to ignore this error, but this function panics in debug builds. pub fn err_unhandled<M: Debug, R: From<NoResponse>>(m: M) -> R { debug_assert!(false, "handle_action: event not handled by widget: {:?}", m); println!("handle_action: event not handled by widget: {:?}", m); NoResponse.into() } /// Notify of an incorrect widget number. /// /// This is an error, meaning somehow an event has been sent to a /// widget number which is not a child of the initial window/widget. /// It is safe to ignore this error, but this function panics in debug builds. pub fn err_num<R: From<NoResponse>>() -> R { debug_assert!(false, "handle_action: bad widget number"); println!("handle_action: bad widget number"); NoResponse.into() } /// Event-handling aspect of a widget. /// /// This is a companion trait to [`Widget`]. It can (optionally) be implemented /// by the `derive(Widget)` macro, or can be implemented manually. /// /// [`Widget`]: crate::Widget pub trait Handler: Core { /// Type of message returned by this handler. /// /// This mechanism allows type-safe handling of user-defined responses to handled actions. /// For example, a user may define a control panel where each button returns a unique code, /// or a configuration editor may return a full copy of the new configuration on completion. type Response: From<NoResponse>; /// Handle a high-level event directed at the widget identified by `number`, /// and return a user-defined msg. fn handle_action(&mut self, tk: &TkWidget, action: Action, number: u32) -> Self::Response; }