makepad_widget/
scrollview.rs

1use makepad_render::*;
2use crate::scrollbar::*;
3
4#[derive(Clone)]
5pub struct ScrollView{
6    pub view:View,
7    pub scroll_h:Option<ScrollBar>,
8    pub scroll_v:Option<ScrollBar>,
9}
10
11impl ScrollView{
12
13    pub fn proto(cx: &mut Cx) -> Self {
14        Self {
15            view: View::proto(cx),
16            scroll_h: Some(ScrollBar::proto(cx)),
17            scroll_v: Some(ScrollBar {
18                smoothing: Some(0.15),
19                ..ScrollBar::proto(cx)
20            }),
21        }
22    }
23    
24    pub fn proto_no_scroll(cx: &mut Cx) -> Self {
25        Self {
26            view: View::proto(cx),
27            scroll_h: None,
28            scroll_v: None
29        }
30    }
31    
32    pub fn begin_view(&mut self, cx: &mut Cx, layout: Layout) -> ViewRedraw {
33        self.view.begin_view(cx, layout)
34    }
35    
36    pub fn view_will_redraw(&mut self, cx: &mut Cx)->bool{
37        self.view.view_will_redraw(cx)
38    }
39    
40    pub fn handle_scroll_bars(&mut self, cx: &mut Cx, event: &mut Event) -> bool {
41        let mut ret_h = ScrollBarEvent::None;
42        let mut ret_v = ScrollBarEvent::None;
43        
44        if let Some(scroll_h) = &mut self.scroll_h {
45            ret_h = scroll_h.handle_scroll_bar(cx, event);
46        }
47        if let Some(scroll_v) = &mut self.scroll_v {
48            ret_v = scroll_v.handle_scroll_bar(cx, event);
49        }
50        match ret_h {
51            ScrollBarEvent::None => (),
52            ScrollBarEvent::Scroll {scroll_pos, ..} => {
53                cx.set_view_scroll_x(self.view.view_id.unwrap(), scroll_pos);
54            },
55            _ => ()
56        };
57        match ret_v {
58            ScrollBarEvent::None => (),
59            ScrollBarEvent::Scroll {scroll_pos, ..} => {
60                cx.set_view_scroll_y(self.view.view_id.unwrap(), scroll_pos);
61            },
62            _ => ()
63        };
64        ret_h != ScrollBarEvent::None || ret_v != ScrollBarEvent::None
65    }
66    
67    pub fn get_scroll_pos(&self, cx: &Cx) -> Vec2 {
68        if let Some(view_id) = self.view.view_id {
69            let cxview = &cx.views[view_id];
70            cxview.unsnapped_scroll
71        }
72        else {
73            Vec2::default()
74        }
75    }
76    
77    pub fn set_scroll_pos(&mut self, cx: &mut Cx, pos: Vec2) -> bool {
78        let view_id = self.view.view_id.unwrap();
79        //let view_area = Area::DrawList(DrawListArea{draw_list_id:draw_list_id, redraw_id:cx.redraw_id});
80        let mut changed = false;
81        if let Some(scroll_h) = &mut self.scroll_h {
82            if scroll_h.set_scroll_pos(cx, pos.x) {
83                let scroll_pos = scroll_h.get_scroll_pos();
84                cx.set_view_scroll_x(view_id, scroll_pos);
85                changed = true;
86            }
87        }
88        if let Some(scroll_v) = &mut self.scroll_v {
89            if scroll_v.set_scroll_pos(cx, pos.y) {
90                let scroll_pos = scroll_v.get_scroll_pos();
91                cx.set_view_scroll_y(view_id, scroll_pos);
92                changed = true;
93            }
94        }
95        changed
96    }
97    
98    pub fn set_scroll_view_total(&mut self, cx: &mut Cx, view_total: Vec2) {
99        if let Some(scroll_h) = &mut self.scroll_h {
100            scroll_h.set_scroll_view_total(cx, view_total.x)
101        }
102        if let Some(scroll_v) = &mut self.scroll_v {
103            scroll_v.set_scroll_view_total(cx, view_total.y)
104        }
105    }
106    
107    pub fn get_scroll_view_total(&mut self) -> Vec2 {
108        Vec2 {
109            x: if let Some(scroll_h) = &mut self.scroll_h {
110                scroll_h.get_scroll_view_total()
111            }else {0.},
112            y: if let Some(scroll_v) = &mut self.scroll_v {
113                scroll_v.get_scroll_view_total()
114            }else {0.}
115        }
116    }
117    
118    pub fn scroll_into_view(&mut self, cx: &mut Cx, rect: Rect) {
119        if let Some(scroll_h) = &mut self.scroll_h {
120            scroll_h.scroll_into_view(cx, rect.x, rect.w);
121        }
122        if let Some(scroll_v) = &mut self.scroll_v {
123            scroll_v.scroll_into_view(cx, rect.y, rect.h);
124        }
125    }
126    
127    pub fn scroll_into_view_abs(&mut self, cx: &mut Cx, rect: Rect) {
128        let self_rect = self.get_rect(cx); 
129        if let Some(scroll_h) = &mut self.scroll_h {
130            scroll_h.scroll_into_view(cx, rect.x - self_rect.x, rect.w);
131        }
132        if let Some(scroll_v) = &mut self.scroll_v {
133            scroll_v.scroll_into_view(cx, rect.y  - self_rect.y, rect.h);
134        }
135    }
136    
137    pub fn set_scroll_target(&mut self, cx: &mut Cx, pos: Vec2) {
138        if let Some(scroll_h) = &mut self.scroll_h {
139            scroll_h.set_scroll_target(cx, pos.x);
140        }
141        if let Some(scroll_v) = &mut self.scroll_v {
142            scroll_v.set_scroll_target(cx, pos.y);
143        }
144    }
145    
146    pub fn end_view(&mut self, cx: &mut Cx) -> Area {
147
148        let view_id = self.view.view_id.unwrap();
149        let view_area = Area::View(ViewArea {view_id: view_id, redraw_id: cx.redraw_id});
150        
151        // lets ask the turtle our actual bounds
152        let view_total = cx.get_turtle_bounds();
153        let mut rect_now = cx.get_turtle_rect();
154        if rect_now.h.is_nan() {
155            rect_now.h = view_total.y;
156        }
157        if rect_now.w.is_nan() {
158            rect_now.w = view_total.x;
159        }
160        
161        if let Some(scroll_h) = &mut self.scroll_h {
162            let scroll_pos = scroll_h.draw_scroll_bar(cx, Axis::Horizontal, view_area, rect_now, view_total);
163            cx.set_view_scroll_x(view_id, scroll_pos);
164        }
165        if let Some(scroll_v) = &mut self.scroll_v {
166            //println!("SET SCROLLBAR {} {}", rect_now.h, view_total.y);
167            let scroll_pos = scroll_v.draw_scroll_bar(cx, Axis::Vertical, view_area, rect_now, view_total);
168            cx.set_view_scroll_y(view_id, scroll_pos);
169        }
170        
171        let rect = cx.end_turtle(view_area);
172        let cxview = &mut cx.views[view_id];
173        cxview.rect = rect;
174        cx.view_stack.pop();
175        
176        return view_area
177    }
178    
179    pub fn get_rect(&mut self, cx: &Cx) -> Rect {
180        self.view.get_rect(cx)
181    }
182    
183    
184    pub fn redraw_view_area(&self, cx: &mut Cx) {
185        self.view.redraw_view_area(cx)
186    }
187    
188    pub fn get_view_area(&self, cx: &Cx) -> Area {
189        self.view.get_view_area(cx)
190    }
191}