makepad_widgets/
fold_button.rs1use crate::{
2 makepad_derive_widget::*,
3 makepad_draw::*,
4 widget::*,
5};
6
7live_design!{
8 FoldButtonBase = {{FoldButton}} {}
9}
10
11#[derive(Live)]
12pub struct FoldButton {
13 #[animator] animator: Animator,
14
15 #[live] draw_bg: DrawQuad,
16 #[live] abs_size: DVec2,
17 #[live] abs_offset: DVec2,
18 #[walk] walk: Walk,
19}
20
21impl LiveHook for FoldButton{
22 fn before_live_design(cx:&mut Cx){
23 register_widget!(cx,FoldButton)
24 }
25}
26
27#[derive(Clone, WidgetAction)]
28pub enum FoldButtonAction {
29 None,
30 Opening,
31 Closing,
32 Animating(f64)
33}
34
35impl FoldButton {
36
37 pub fn handle_event_with(
38 &mut self,
39 cx: &mut Cx,
40 event: &Event,
41 dispatch_action: &mut dyn FnMut(&mut Cx, FoldButtonAction),
42 ) {
43 if self.animator_handle_event(cx, event).is_animating() {
44 if self.animator.is_track_animating(cx, id!(open)) {
45 let mut value = [0.0];
46 self.draw_bg.get_instance(cx, id!(open),&mut value);
47 dispatch_action(cx, FoldButtonAction::Animating(value[0] as f64))
48 }
49 };
50
51 match event.hits(cx, self.draw_bg.area()) {
52 Hit::FingerDown(_fe) => {
53 if self.animator_in_state(cx, id!(open.yes)) {
54 self.animator_play(cx, id!(open.no));
55 dispatch_action(cx, FoldButtonAction::Closing)
56 }
57 else {
58 self.animator_play(cx, id!(open.yes));
59 dispatch_action(cx, FoldButtonAction::Opening)
60 }
61 self.animator_play(cx, id!(hover.on));
62 },
63 Hit::FingerHoverIn(_) => {
64 cx.set_cursor(MouseCursor::Hand);
65 self.animator_play(cx, id!(hover.on));
66 }
67 Hit::FingerHoverOut(_) => {
68 self.animator_play(cx, id!(hover.off));
69 }
70 Hit::FingerUp(fe) => if fe.is_over {
71 if fe.device.has_hovers() {
72 self.animator_play(cx, id!(hover.on));
73 }
74 else{
75 self.animator_play(cx, id!(hover.off));
76 }
77 }
78 else {
79 self.animator_play(cx, id!(hover.off));
80 }
81 _ => ()
82 };
83 }
84
85 pub fn set_is_open(&mut self, cx: &mut Cx, is_open: bool, animate: Animate) {
86 self.animator_toggle(cx, is_open, animate, id!(open.yes), id!(open.no))
87 }
88
89 pub fn draw_walk(&mut self, cx: &mut Cx2d, walk: Walk) {
90 self.draw_bg.draw_walk(cx, walk);
91 }
92
93 pub fn area(&mut self)->Area{
94 self.draw_bg.area()
95 }
96
97 pub fn draw_abs(&mut self, cx: &mut Cx2d, pos: DVec2, fade: f64) {
98 self.draw_bg.apply_over(cx, live!{fade: (fade)});
99 self.draw_bg.draw_abs(cx, Rect {
100 pos: pos + self.abs_offset,
101 size: self.abs_size
102 });
103 }
104}
105
106impl Widget for FoldButton {
107 fn redraw(&mut self, cx: &mut Cx) {
108 self.draw_bg.redraw(cx);
109 }
110
111 fn handle_widget_event_with(&mut self, cx: &mut Cx, event: &Event, dispatch_action: &mut dyn FnMut(&mut Cx, WidgetActionItem)) {
112 let uid = self.widget_uid();
113 self.handle_event_with(cx, event, &mut | cx, action | {
114 dispatch_action(cx, WidgetActionItem::new(action.into(), uid))
115 });
116 }
117
118 fn walk(&mut self, _cx:&mut Cx) -> Walk {self.walk}
119
120 fn draw_walk_widget(&mut self, cx: &mut Cx2d, walk: Walk) -> WidgetDraw {
121 self.draw_walk(cx, walk);
122 WidgetDraw::done()
123 }
124}
125
126
127#[derive(Clone, Debug, PartialEq, WidgetRef)]
128pub struct FoldButtonRef(WidgetRef);
129
130impl FoldButtonRef {
131
132 pub fn opening(&self, actions:&WidgetActions) -> bool {
133 if let Some(item) = actions.find_single_action(self.widget_uid()) {
134 if let FoldButtonAction::Opening = item.action() {
135 return true
136 }
137 }
138 false
139 }
140
141 pub fn closing(&self, actions:&WidgetActions) -> bool {
142 if let Some(item) = actions.find_single_action(self.widget_uid()) {
143 if let FoldButtonAction::Closing = item.action() {
144 return true
145 }
146 }
147 false
148 }
149
150 pub fn animating(&self, actions:&WidgetActions) -> Option<f64> {
151 if let Some(item) = actions.find_single_action(self.widget_uid()) {
152 if let FoldButtonAction::Animating(v) = item.action() {
153 return Some(v)
154 }
155 }
156 None
157 }
158}
159