vizia_core/views/
toggle_button.rs1use crate::prelude::*;
2
3pub struct ToggleButton {
5 on_toggle: Option<Box<dyn Fn(&mut EventContext)>>,
6}
7
8impl ToggleButton {
9 pub fn new<V: View>(
11 cx: &mut Context,
12 checked: impl Res<bool>,
13 content: impl Fn(&mut Context) -> Handle<V> + 'static,
14 ) -> Handle<Self> {
15 Self { on_toggle: None }
16 .build(cx, |cx| {
17 (content)(cx).hoverable(false);
18 })
19 .role(Role::Button)
20 .navigable(true)
21 .checkable(true) .checked(checked)
23 }
24
25 pub fn with_contents<V1: View, V2: View>(
27 cx: &mut Context,
28 checked: impl Res<bool> + Copy + 'static,
29 content_unchecked: impl Fn(&mut Context) -> Handle<V1> + 'static,
30 content_checked: impl Fn(&mut Context) -> Handle<V2> + 'static,
31 ) -> Handle<Self> {
32 Self { on_toggle: None }
33 .build(cx, move |cx| {
34 checked.set_or_bind(cx, move |cx, checked| {
35 if checked.get_value(cx) {
36 (content_checked)(cx).hoverable(false);
37 } else {
38 (content_unchecked)(cx).hoverable(false);
39 }
40 });
41 })
42 .role(Role::Button)
43 .navigable(true)
44 .checkable(true) .checked(checked)
46 }
47}
48
49impl View for ToggleButton {
50 fn element(&self) -> Option<&'static str> {
51 Some("toggle-button")
52 }
53
54 fn event(&mut self, cx: &mut EventContext, event: &mut Event) {
55 event.map(|window_event, meta| match window_event {
56 WindowEvent::PressDown { mouse } => {
57 if *mouse {
58 cx.capture()
59 }
60 cx.focus();
61 }
62
63 WindowEvent::Press { mouse } => {
64 let over = if *mouse { cx.mouse().left.pressed } else { cx.focused() };
65 if over == cx.current() && meta.target == cx.current() && !cx.is_disabled() {
66 if let Some(callback) = &self.on_toggle {
67 (callback)(cx);
68 }
69 }
70 }
71
72 WindowEvent::MouseUp(button) if *button == MouseButton::Left => {
73 cx.release();
74 }
75
76 WindowEvent::ActionRequest(action) => match action.action {
77 Action::Click => {
78 if let Some(callback) = &self.on_toggle {
79 (callback)(cx);
80 }
81 }
82
83 _ => {}
84 },
85
86 _ => {}
87 });
88 }
89}
90
91impl Handle<'_, ToggleButton> {
92 pub fn on_toggle(self, callback: impl Fn(&mut EventContext) + 'static) -> Self {
94 self.modify(|toggle_button| toggle_button.on_toggle = Some(Box::new(callback)))
95 }
96}