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
use Basalt;
use std::sync::Arc;
use super::bin::{KeepAlive,Bin,BinStyle};
use parking_lot::Mutex;
use std::thread;
use input::*;
impl KeepAlive for CheckBox {}
pub struct CheckBox {
pub basalt: Arc<Basalt>,
pub inner_box: Arc<Bin>,
pub outer_box: Arc<Bin>,
checked: Mutex<bool>,
on_change: Mutex<Vec<Arc<dyn Fn(bool) + Send + Sync>>>,
}
impl CheckBox {
pub fn is_checked(&self) -> bool {
*self.checked.lock()
}
pub fn set(&self, check: bool) {
*self.checked.lock() = check;
self.update(Some(check));
self.call_on_change(Some(check));
}
pub fn check(&self) {
self.set(true);
}
pub fn uncheck(&self) {
self.set(false);
}
pub fn toggle(&self) {
let mut checked = self.checked.lock();
*checked = !*checked;
self.update(Some(*checked));
self.call_on_change(Some(*checked));
}
pub fn on_change(&self, func: Arc<dyn Fn(bool) + Send + Sync>) {
self.on_change.lock().push(func);
}
fn call_on_change(&self, checked_op: Option<bool>) {
let checked = match checked_op {
Some(some) => some,
None => self.is_checked()
};
let on_change = self.on_change.lock().clone().into_iter();
thread::spawn(move || {
for func in on_change {
func(checked);
}
});
}
fn update(&self, checked_op: Option<bool>) {
let checked = match checked_op {
Some(some) => some,
None => self.is_checked()
};
self.inner_box.style_update(BinStyle {
hidden: Some(!checked),
.. self.inner_box.style_copy()
});
}
pub fn new(basalt: Arc<Basalt>) -> Arc<Self> {
let mut bins = basalt.interface_ref().new_bins(2);
let checkbox = Arc::new(CheckBox {
basalt: basalt,
inner_box: bins.pop().unwrap(),
outer_box: bins.pop().unwrap(),
checked: Mutex::new(false),
on_change: Mutex::new(Vec::new()),
});
checkbox.outer_box.add_child(checkbox.inner_box.clone());
let checkbox_wk = Arc::downgrade(&checkbox);
checkbox.outer_box.on_mouse_press(MouseButton::Left, Arc::new(move |_, _| {
match checkbox_wk.upgrade() {
Some(checkbox) => checkbox.toggle(),
None => return
}
}));
checkbox
}
}