makepad_widgets/
fold_header.rs1use crate::{
2 makepad_derive_widget::*,
3 makepad_draw::*,
4 widget::*,
5 fold_button::*
6};
7
8live_design!{
9 link widgets;
10 use link::theme::*;
11
12 pub FoldHeaderBase = {{FoldHeader}} {}
13 pub FoldHeader = <FoldHeaderBase> {
14 width: Fill, height: Fit,
15 body_walk: { width: Fill, height: Fit}
16
17 flow: Down,
18
19 animator: {
20 active = {
21 default: on
22 off = {
23 from: {all: Forward {duration: 0.2}}
24 ease: ExpDecay {d1: 0.96, d2: 0.97}
25 redraw: true
26 apply: {
27 opened: [{time: 0.0, value: 1.0}, {time: 1.0, value: 0.0}]
28 }
29 }
30 on = {
31 from: {all: Forward {duration: 0.2}}
32 ease: ExpDecay {d1: 0.98, d2: 0.95}
33 redraw: true
34 apply: {
35 opened: [{time: 0.0, value: 0.0}, {time: 1.0, value: 1.0}]
36 }
37 }
38 }
39 }
40 }
41
42}
43
44#[derive(Live, LiveHook, Widget)]
45pub struct FoldHeader {
46 #[rust] draw_state: DrawStateWrap<DrawState>,
47 #[rust] rect_size: f64,
48 #[rust] area: Area,
49 #[find] #[redraw] #[live] header: WidgetRef,
50 #[find] #[redraw] #[live] body: WidgetRef,
51 #[animator] animator: Animator,
52
53 #[live] opened: f64,
54 #[layout] layout: Layout,
55 #[walk] walk: Walk,
56 #[live] body_walk: Walk,
57}
58
59#[derive(Clone)]
60enum DrawState {
61 DrawHeader,
62 DrawBody
63}
64
65impl Widget for FoldHeader {
66 fn handle_event(&mut self, cx: &mut Cx, event: &Event, scope: &mut Scope) {
67 if self.animator_handle_event(cx, event).must_redraw() {
68 if self.animator.is_track_animating(cx, id!(active)) {
69 self.area.redraw(cx);
70 }
71 };
72
73 self.header.handle_event(cx, event, scope);
74
75 if let Event::Actions(actions) = event{
76 match actions.find_widget_action(self.header.widget(id!(fold_button)).widget_uid()).cast() {
77 FoldButtonAction::Opening => {
78 self.animator_play(cx, id!(active.on))
79 }
80 FoldButtonAction::Closing => {
81 self.animator_play(cx, id!(active.off))
82 }
83 _ => ()
84 }
85 }
86 }
87
88
89 fn draw_walk(&mut self, cx: &mut Cx2d, scope:&mut Scope, walk: Walk) -> DrawStep {
90 if self.draw_state.begin(cx, DrawState::DrawHeader) {
91 cx.begin_turtle(walk, self.layout);
92 }
93 if let Some(DrawState::DrawHeader) = self.draw_state.get() {
94 let walk = self.header.walk(cx);
95 self.header.draw_walk(cx, scope, walk) ?;
96 cx.begin_turtle(
97 self.body_walk,
98 Layout::flow_down()
99 .with_scroll(dvec2(0.0, self.rect_size * (1.0 - self.opened)))
100 );
101 self.draw_state.set(DrawState::DrawBody);
102 }
103 if let Some(DrawState::DrawBody) = self.draw_state.get() {
104 let walk = self.body.walk(cx);
105 self.body.draw_walk(cx, scope, walk) ?;
106 self.rect_size = cx.turtle().used().y;
107 cx.end_turtle();
108 cx.end_turtle_with_area(&mut self.area);
109 self.draw_state.end();
110 }
111 DrawStep::done()
112 }
113}
114
115#[derive(Clone, DefaultNone)]
116pub enum FoldHeaderAction {
117 Opening,
118 Closing,
119 None
120}