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
// Callback Store // Callback Cache using fn() Enumerations for storing closures // // 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 at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. use crate::core::point::Point; use std::collections::HashMap; /// Index for mouse entered callback, used by `Widget` internally. Refers to a /// ```CallbackTypes::SingleCallback``` callback. pub const CALLBACK_MOUSE_ENTERED: u32 = 1; /// Index for mouse exited callback, used by `Widget` internally. Refers to a /// ```CallbackTypes::SingleCallback``` callback. pub const CALLBACK_MOUSE_EXITED: u32 = 2; /// Index for mouse scrolled callback, used by `Widget` internally. Refers to a /// ```CallbackTypes::PointCallback``` callback. pub const CALLBACK_MOUSE_SCROLLED: u32 = 3; /// Index for mouse moved callback, used by `Widget` internally. Refers to a /// ```CallbackTypes::PointCallback``` callback. pub const CALLBACK_MOUSE_MOVED: u32 = 4; pub type SingleCallback = Box<Fn(i32) -> ()>; pub type PointCallback = Box<Fn(i32, Point) -> ()>; /// This is an enumerated type that is used to store numerous variations of callbacks that can /// be used within the `Widget` system. This is written such that the `CallbackTypes` enum /// can be added to/extended as necessary. pub enum CallbackTypes { /// Callback that only supplies its widget ID. SingleCallback { callback: SingleCallback }, /// Callback that supplies its widget ID and a `Point` on the screen within the `Widget`. PointCallback { callback: PointCallback }, } /// This is the `CallbackStore` that is used to store a list of `CallbackTypes` that are /// triggered when an action occurs on a `Widget`. pub struct CallbackStore { callbacks: HashMap<u32, CallbackTypes>, } /// The actual class implementation of the `CallbackStore`. This is primarily stored within the /// `Widget` class, and its usage looks something similar to the following code: /// /// ``` /// # use pushrod::core::callbacks::*; /// # use pushrod::core::point::*; /// # fn main() { /// let mut cs = CallbackStore::new(); /// /// cs.put(CALLBACK_MOUSE_MOVED, /// CallbackTypes::PointCallback { callback: Box::new(|widget_id, point| { /// eprintln!("Callback for widget {} resulted in point at {} x {}", /// widget_id, point.x, point.y); /// }) /// }); /// /// // And, to call the callback to run it: /// /// match cs.get(CALLBACK_MOUSE_MOVED) { /// CallbackTypes::PointCallback { callback } => /// callback(12, Point { x: 16, y: 24 }), /// _ => eprintln!("Unsupported callback for ID {}!", CALLBACK_MOUSE_MOVED), /// } /// # } /// ``` /// /// This is an example of how it would be used in the `Widget` callbacks. User-specified /// callbacks will likely be much simpler than this. impl CallbackStore { pub fn new() -> Self { Self { callbacks: HashMap::new(), } } pub fn put(&mut self, id: u32, func: CallbackTypes) { self.callbacks.insert(id, func); } pub fn get(&mut self, id: u32) -> &CallbackTypes { if self.callbacks.contains_key(&id) { &self.callbacks[&id] } else { self.put(id, CallbackTypes::SingleCallback { callback: Box::new(|_arg| { }) }); &self.callbacks[&id] } } }