use crate::axis::*;
use crate::scrollbar::*;
use wrflib::*;
#[derive(Default)]
pub struct ScrollView {
pub view: View,
pub scroll_h: Option<ScrollBar>,
pub scroll_v: Option<ScrollBar>,
}
impl ScrollView {
#[must_use]
pub fn new_standard_hv() -> Self {
Self {
scroll_h: Some(ScrollBar::default()),
scroll_v: Some(ScrollBar::default().with_smoothing(0.15)),
..Self::default()
}
}
#[must_use]
pub fn with_scroll_h(self, s: ScrollBar) -> Self {
Self { scroll_h: Some(s), ..self }
}
#[must_use]
pub fn with_scroll_v(self, s: ScrollBar) -> Self {
Self { scroll_v: Some(s), ..self }
}
pub fn begin_view(&mut self, cx: &mut Cx, layout_size: LayoutSize) {
self.view.begin_view(cx, layout_size);
}
pub fn handle(&mut self, cx: &mut Cx, event: &mut Event) -> bool {
let mut ret_h = ScrollBarEvent::None;
let mut ret_v = ScrollBarEvent::None;
if let Some(scroll_h) = &mut self.scroll_h {
ret_h = scroll_h.handle(cx, event);
}
if let Some(scroll_v) = &mut self.scroll_v {
ret_v = scroll_v.handle(cx, event);
}
if let Some(view_id) = self.view.view_id {
match ret_h {
ScrollBarEvent::None => (),
ScrollBarEvent::Scroll { scroll_pos, .. } => {
cx.set_view_scroll_x(view_id, scroll_pos);
}
_ => (),
};
match ret_v {
ScrollBarEvent::None => (),
ScrollBarEvent::Scroll { scroll_pos, .. } => {
cx.set_view_scroll_y(view_id, scroll_pos);
}
_ => (),
};
ret_h != ScrollBarEvent::None || ret_v != ScrollBarEvent::None
} else {
false
}
}
pub fn get_scroll_pos(&self, cx: &Cx) -> Vec2 {
self.view.get_scroll_pos(cx)
}
pub fn set_scroll_pos(&mut self, cx: &mut Cx, pos: Vec2) -> bool {
let view_id = self.view.view_id.unwrap();
let mut changed = false;
if let Some(scroll_h) = &mut self.scroll_h {
if scroll_h.set_scroll_pos(cx, pos.x) {
let scroll_pos = scroll_h.get_scroll_pos();
cx.set_view_scroll_x(view_id, scroll_pos);
changed = true;
}
}
if let Some(scroll_v) = &mut self.scroll_v {
if scroll_v.set_scroll_pos(cx, pos.y) {
let scroll_pos = scroll_v.get_scroll_pos();
cx.set_view_scroll_y(view_id, scroll_pos);
changed = true;
}
}
changed
}
pub fn set_scroll_view_total(&mut self, cx: &mut Cx, view_total: Vec2) {
if let Some(scroll_h) = &mut self.scroll_h {
scroll_h.set_scroll_view_total(cx, view_total.x)
}
if let Some(scroll_v) = &mut self.scroll_v {
scroll_v.set_scroll_view_total(cx, view_total.y)
}
}
pub fn get_scroll_view_total(&mut self) -> Vec2 {
Vec2 {
x: if let Some(scroll_h) = &mut self.scroll_h { scroll_h.get_scroll_view_total() } else { 0. },
y: if let Some(scroll_v) = &mut self.scroll_v { scroll_v.get_scroll_view_total() } else { 0. },
}
}
pub fn scroll_into_view(&mut self, cx: &mut Cx, rect: Rect) {
if let Some(scroll_h) = &mut self.scroll_h {
scroll_h.scroll_into_view(cx, rect.pos.x, rect.size.x, true);
}
if let Some(scroll_v) = &mut self.scroll_v {
scroll_v.scroll_into_view(cx, rect.pos.y, rect.size.y, true);
}
}
pub fn scroll_into_view_no_smooth(&mut self, cx: &mut Cx, rect: Rect) {
if let Some(scroll_h) = &mut self.scroll_h {
scroll_h.scroll_into_view(cx, rect.pos.x, rect.size.x, false);
}
if let Some(scroll_v) = &mut self.scroll_v {
scroll_v.scroll_into_view(cx, rect.pos.y, rect.size.y, false);
}
}
pub fn scroll_into_view_abs(&mut self, cx: &mut Cx, rect: Rect) {
let self_rect = self.get_rect(cx);
if let Some(scroll_h) = &mut self.scroll_h {
scroll_h.scroll_into_view(cx, rect.pos.x - self_rect.pos.x, rect.size.x, true);
}
if let Some(scroll_v) = &mut self.scroll_v {
scroll_v.scroll_into_view(cx, rect.pos.y - self_rect.pos.y, rect.size.y, true);
}
}
pub fn set_scroll_target(&mut self, cx: &mut Cx, pos: Vec2) {
if let Some(scroll_h) = &mut self.scroll_h {
scroll_h.set_scroll_target(cx, pos.x);
}
if let Some(scroll_v) = &mut self.scroll_v {
scroll_v.set_scroll_target(cx, pos.y);
}
}
pub fn end_view(&mut self, cx: &mut Cx) -> Area {
let view_total = cx.get_box_bounds();
let mut rect_now = cx.get_box_rect();
if rect_now.size.y.is_nan() {
rect_now.size.y = view_total.y;
}
if rect_now.size.x.is_nan() {
rect_now.size.x = view_total.x;
}
let view_id = self.view.view_id.unwrap();
if let Some(scroll_h) = &mut self.scroll_h {
let scroll_pos = scroll_h.draw(cx, Axis::Horizontal, self.view.area(), rect_now, view_total);
cx.set_view_scroll_x(view_id, scroll_pos);
}
if let Some(scroll_v) = &mut self.scroll_v {
let scroll_pos = scroll_v.draw(cx, Axis::Vertical, self.view.area(), rect_now, view_total);
cx.set_view_scroll_y(view_id, scroll_pos);
}
self.view.end_view(cx)
}
pub fn get_rect(&mut self, cx: &Cx) -> Rect {
self.view.get_rect(cx)
}
pub fn area(&self) -> Area {
self.view.area()
}
}