use dyn any for widget_id example
use fltk::{prelude::*, *};
use std::collections::HashMap;
use std::sync::Mutex;
+use std::any::Any;
lazy_static::lazy_static! {
- static ref WIDGET_MAP: Mutex<HashMap<&'static str, widget::Widget>> = Mutex::new(HashMap::default());
+ static ref WIDGET_MAP: Mutex<HashMap<&'static str, Box<dyn Any + Send + Sync + 'static>>> = Mutex::new(HashMap::default());
}
pub trait WidgetId<W>
@@ -18,13 +19,13 @@ where
impl<W> WidgetId<W> for W
where
- W: WidgetExt,
+ W: WidgetExt + Send + Sync + Clone + 'static,
{
fn set_id(&mut self, id: &'static str) {
WIDGET_MAP
.lock()
.unwrap()
- .insert(id, unsafe { self.into_widget() });
+ .insert(id, Box::new(self.clone()));
}
fn with_id(mut self, id: &'static str) -> Self {
self.set_id(id);
@@ -32,9 +33,9 @@ where
}
}
-pub fn from_id(id: &'static str) -> Option<widget::Widget> {
+pub fn from_id<T: 'static + Clone>(id: &'static str) -> Option<T> {
if let Some(w) = WIDGET_MAP.lock().unwrap().get(&id) {
- Some(w.clone())
+ w.downcast_ref::<T>().map(|w| (*w).clone())
} else {
None
}
@@ -66,7 +67,7 @@ struct Counter {
// For calls inside a closure
fn increment_by(step: i32) {
- if let Some(mut frame) = from_id("my_frame") {
+ let mut frame: frame::Frame = from_id("my_frame").unwrap();
let state = app::GlobalState::<Counter>::get();
let count = state.with(move |c| {
c.count += step;
@@ -74,19 +75,17 @@ fn increment_by(step: i32) {
});
frame.set_label(&count.to_string());
}
-}
// To pass a function object directly!
fn increment(_w: &mut impl WidgetExt) {
- if let Some(mut frame) = from_id("my_frame") {
+ let mut frame: frame::Frame = from_id("my_frame").unwrap();
let state = app::GlobalState::<Counter>::get();
- let count = state.with(move |c| {
+ let count = state.with(|c| {
c.count += 1;
c.count
});
frame.set_label(&count.to_string());
}
-}
fn main() {
let counter = Counter { count: 0 };
