makepad_widgets/
fold_header.rs

1use crate::{
2    makepad_derive_widget::*,
3    makepad_draw::*,
4    widget::*,
5    fold_button::*
6};
7
8live_design!{
9    FoldHeaderBase = {{FoldHeader}} {}
10}
11
12#[derive(Live)]
13pub struct FoldHeader {
14    #[rust] draw_state: DrawStateWrap<DrawState>,
15    #[rust] rect_size: f64,
16    #[rust] area: Area,
17    #[live] header: WidgetRef,
18    #[live] body: WidgetRef,
19    #[animator] animator: Animator,
20
21    #[live] opened: f64,
22    #[layout] layout: Layout,
23    #[walk] walk: Walk,
24    #[live] body_walk: Walk,
25}
26
27impl LiveHook for FoldHeader{
28    fn before_live_design(cx:&mut Cx){
29        register_widget!(cx,FoldHeader)
30    }
31}
32
33#[derive(Clone)]
34enum DrawState {
35    DrawHeader,
36    DrawBody
37}
38
39impl Widget for FoldHeader {
40    fn handle_widget_event_with(
41        &mut self,
42        cx: &mut Cx,
43        event: &Event,
44        dispatch_action: &mut dyn FnMut(&mut Cx, WidgetActionItem)
45    ) {
46        if self.animator_handle_event(cx, event).must_redraw() {
47            if self.animator.is_track_animating(cx, id!(open)) {
48                self.area.redraw(cx);
49            }
50        };
51        
52        for item in self.header.handle_widget_event(cx, event) {
53            if item.widget_uid == self.header.widget(id!(fold_button)).widget_uid(){
54                match item.action.cast() {
55                    FoldButtonAction::Opening => {
56                        self.animator_play(cx, id!(open.on))
57                    }
58                    FoldButtonAction::Closing => {
59                        self.animator_play(cx, id!(open.off))
60                    }
61                    _ => ()
62                }
63            }
64            dispatch_action(cx, item)
65        }
66        
67        self.body.handle_widget_event_with(cx, event, dispatch_action);
68    }
69    
70    fn redraw(&mut self, cx: &mut Cx) {
71        self.header.redraw(cx);
72        self.body.redraw(cx);
73    }
74    
75    fn walk(&mut self, _cx:&mut Cx) -> Walk {self.walk}
76
77    fn find_widgets(&mut self, path: &[LiveId], cached: WidgetCache, results: &mut WidgetSet) {
78        self.header.find_widgets(path, cached, results);
79        self.body.find_widgets(path, cached, results);
80    }
81    
82    fn draw_walk_widget(&mut self, cx: &mut Cx2d, walk: Walk) -> WidgetDraw {
83        if self.draw_state.begin(cx, DrawState::DrawHeader) {
84            cx.begin_turtle(walk, self.layout);
85        }
86        if let Some(DrawState::DrawHeader) = self.draw_state.get() {
87            self.header.draw_widget(cx) ?;
88            cx.begin_turtle(
89                self.body_walk,
90                Layout::flow_down()
91                .with_scroll(dvec2(0.0, self.rect_size * (1.0 - self.opened)))
92            );
93            self.draw_state.set(DrawState::DrawBody);
94        }
95        if let Some(DrawState::DrawBody) = self.draw_state.get() {
96            self.body.draw_widget(cx) ?;
97            self.rect_size = cx.turtle().used().y;
98            cx.end_turtle();
99            cx.end_turtle_with_area(&mut self.area);
100            self.draw_state.end();
101        }
102        WidgetDraw::done()
103    }
104}
105
106#[derive(Clone, WidgetAction)]
107pub enum FoldHeaderAction {
108    Opening,
109    Closing,
110    None
111}