makepad_widgets/
slide_panel.rs

1use crate::{
2    makepad_derive_widget::*,
3    makepad_draw::*,
4    view::*,
5    widget::*,
6    WidgetMatchEvent,
7    WindowAction,
8};
9
10live_design!{
11    link widgets
12    pub SlidePanelBase = {{SlidePanel}} {}
13    pub SlidePanel = <SlidePanelBase>{
14        animator: {
15            active = {
16                default: off,
17                on = {
18                    redraw: true,
19                    from: {
20                        all: Forward {duration: 0.5}
21                    }
22                    ease: InQuad
23                    apply: {
24                        active: 0.0
25                    }
26                }
27                                
28                off = {
29                    redraw: true,
30                    from: {
31                        all: Forward {duration: 0.5}
32                    }
33                    ease: OutQuad
34                    apply: {
35                        active: 1.0
36                    }
37                }
38            }
39        }
40    }
41}
42
43#[derive(Live, LiveHook, Widget)]
44pub struct SlidePanel {
45    #[deref] frame: View,
46    #[animator] animator: Animator,
47    #[live] active: f64,
48    #[live] side: SlideSide,
49    #[rust] screen_width: f64,
50    #[rust] next_frame: NextFrame
51}
52
53#[derive(Clone, DefaultNone)]
54pub enum SlidePanelAction {
55    None,
56}
57
58impl Widget for SlidePanel {
59    fn handle_event(&mut self, cx: &mut Cx, event: &Event, scope: &mut Scope) {
60        //let uid = self.widget_uid();
61        self.frame.handle_event(cx, event, scope);
62        self.widget_match_event(cx, event, scope);
63        // lets handle mousedown, setfocus
64        if self.animator_handle_event(cx, event).must_redraw() {
65            self.frame.redraw(cx);
66        }
67        
68        match event {
69            Event::NextFrame(ne) if ne.set.contains(&self.next_frame) => {
70                self.frame.redraw(cx);
71            }
72            _ => ()
73        }
74    }
75    
76    fn draw_walk(&mut self, cx: &mut Cx2d, scope:&mut Scope, mut walk: Walk) -> DrawStep {
77        // we need to make this thing work with a 
78        let rect = cx.peek_walk_turtle(walk);
79        match self.side{
80            SlideSide::Top=>{
81                walk.abs_pos = Some(dvec2(0.0, -rect.size.y * self.active));
82            }
83            SlideSide::Left=>{
84                walk.abs_pos = Some(dvec2(-rect.size.x * self.active, 0.0));
85            }
86            SlideSide::Right => {
87                walk.abs_pos = Some(dvec2(self.screen_width - rect.size.x + rect.size.x * self.active, 0.0));
88            }
89        }
90        self.frame.draw_walk(cx, scope, walk)
91    }
92}
93
94impl WidgetMatchEvent for SlidePanel {
95    fn handle_actions(&mut self, cx: &mut Cx, actions: &Actions, _scope: &mut Scope) {
96        for action in actions {
97            if let WindowAction::WindowGeomChange(ce) = action.as_widget_action().cast() {
98                self.screen_width = ce.new_geom.inner_size.x;
99                self.redraw(cx);
100            }
101        }
102    }
103}
104
105#[derive(Live, LiveHook)]
106#[live_ignore]
107pub enum SlideSide{
108    #[pick] Left,
109    Right,
110    Top
111}
112
113impl SlidePanel {
114
115    pub fn open(&mut self, cx: &mut Cx) {
116        self.frame.redraw(cx);
117    }
118    
119    pub fn close(&mut self, cx: &mut Cx) {
120        self.frame.redraw(cx);
121    }
122    
123    pub fn redraw(&mut self, cx: &mut Cx) {
124        self.frame.redraw(cx);
125    }
126}
127
128impl SlidePanelRef {
129    pub fn close(&self, cx: &mut Cx) {
130        if let Some(mut inner) = self.borrow_mut() {
131            inner.animator_play(cx, id!(active.off))
132        }
133    }
134    pub fn open(&self, cx: &mut Cx) {
135        if let Some(mut inner) = self.borrow_mut() {
136            inner.animator_play(cx, id!(active.on))
137        }
138    }
139    pub fn toggle(&self, cx: &mut Cx) {
140        if let Some(mut inner) = self.borrow_mut() {
141            if inner.animator_in_state(cx, id!(active.on)){
142                inner.animator_play(cx, id!(active.on))
143            }
144            else{
145                inner.animator_play(cx, id!(active.off))
146            }
147        }
148    }
149    pub fn is_animating(&self, cx: &mut Cx) -> bool {
150        if let Some(inner) = self.borrow() {
151            inner.animator.is_track_animating(cx, id!(active))
152        } else {
153            false
154        }
155    }
156}
157
158impl SlidePanelSet {
159    pub fn close(&self, cx: &mut Cx) {
160        for item in self.iter() {
161            item.close(cx);
162        }
163    }
164    pub fn open(&self, cx: &mut Cx) {
165        for item in self.iter() {
166            item.open(cx);
167        }
168    }
169}
170