makepad_widgets/
slide_panel.rs1use 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 self.frame.handle_event(cx, event, scope);
62 self.widget_match_event(cx, event, scope);
63 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 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