diff --git a/src/view/mod.rs b/src/view/mod.rs index 380fcde..3aebdc4 100644 --- a/src/view/mod.rs +++ b/src/view/mod.rs @@ -64,7 +64,8 @@ pub use self::identifiable::Identifiable; pub use self::into_boxed_view::IntoBoxedView; pub use self::margins::Margins; pub use self::position::{Offset, Position}; -pub use self::scroll_base::{ScrollBase, ScrollStrategy}; +pub use self::scroll::ScrollStrategy; +pub use self::scroll_base::ScrollBase; pub use self::scrollable::Scrollable; pub use self::size_cache::SizeCache; pub use self::size_constraint::SizeConstraint; diff --git a/src/view/scroll.rs b/src/view/scroll/core.rs similarity index 90% rename from src/view/scroll.rs rename to src/view/scroll/core.rs index eada83c..8b0131b 100644 --- a/src/view/scroll.rs +++ b/src/view/scroll/core.rs @@ -1,8 +1,3 @@ -//! Core mechanisms to implement scrolling. -//! -//! This module defines [`ScrollCore`](crate::view::scroll::ScrollCore) and related traits. -//! -//! [`ScrollView`](crate::views::ScrollView) may be an easier way to add scrolling to an existing view. use std::cmp::min; use crate::direction::{Direction, Orientation}; @@ -11,118 +6,13 @@ use crate::printer::Printer; use crate::rect::Rect; use crate::theme::ColorStyle; use crate::vec::Vec2; -use crate::view::{ScrollStrategy, Selector, SizeCache, View}; +use crate::view::{ScrollStrategy, Selector, SizeCache}; use crate::with::With; use crate::XY; -/// Inner implementation for `ScrollCore::on_event` -pub trait InnerOnEvent { - /// Performs `View::on_event()` - fn on_event(&mut self, event: Event) -> EventResult; - - /// Performs `View::important_area()` - fn important_area(&self, size: Vec2) -> Rect; -} - -impl<'a, V: View> InnerOnEvent for &'a mut V { - fn on_event(&mut self, event: Event) -> EventResult { - ::on_event(self, event) - } - fn important_area(&self, size: Vec2) -> Rect { - ::important_area(self, size) - } -} - -/// Inner implementation for `ScrollCore::draw()` -pub trait InnerDraw { - /// Performs `View::draw()` - fn draw(&self, printer: &Printer<'_, '_>); -} - -impl<'a, V: View> InnerDraw for &'a V { - fn draw(&self, printer: &Printer<'_, '_>) { - ::draw(self, printer); - } -} - -/// Inner implementation for `ScrollCore::InnerLayout()` -pub trait InnerLayout { - /// Performs `View::layout()` - fn layout(&mut self, size: Vec2); - /// Performs `View::needs_relayout()` - fn needs_relayout(&self) -> bool; - /// Performs `View::required_size()` - fn required_size(&mut self, constraint: Vec2) -> Vec2; -} - -struct Layout2Sizes<'a, I> { - inner: &'a mut I, -} - -impl<'a, I: InnerLayout> InnerSizes for Layout2Sizes<'a, I> { - fn needs_relayout(&self) -> bool { - self.inner.needs_relayout() - } - fn required_size(&mut self, constraint: Vec2) -> Vec2 { - self.inner.required_size(constraint) - } -} - -impl<'a, V: View> InnerLayout for &'a mut V { - fn layout(&mut self, size: Vec2) { - ::layout(self, size); - } - fn needs_relayout(&self) -> bool { - ::needs_relayout(self) - } - fn required_size(&mut self, constraint: Vec2) -> Vec2 { - ::required_size(self, constraint) - } -} - -/// Inner implementation for `ScrollCore::required_size()` -pub trait InnerRequiredSize { - /// Performs `View::needs_relayout()` - fn needs_relayout(&self) -> bool; - /// Performs `View::required_size()` - fn required_size(&mut self, constraint: Vec2) -> Vec2; -} - -impl InnerRequiredSize for &mut V { - fn needs_relayout(&self) -> bool { - ::needs_relayout(self) - } - fn required_size(&mut self, constraint: Vec2) -> Vec2 { - ::required_size(self, constraint) - } -} - -struct Required2Sizes<'a, I> { - inner: &'a mut I, -} - -impl<'a, I: InnerRequiredSize> InnerSizes for Required2Sizes<'a, I> { - fn needs_relayout(&self) -> bool { - self.inner.needs_relayout() - } - fn required_size(&mut self, constraint: Vec2) -> Vec2 { - self.inner.required_size(constraint) - } -} - -trait InnerSizes { - fn needs_relayout(&self) -> bool; - fn required_size(&mut self, constraint: Vec2) -> Vec2; -} - -impl InnerSizes for &mut I { - fn needs_relayout(&self) -> bool { - ::needs_relayout(self) - } - fn required_size(&mut self, constraint: Vec2) -> Vec2 { - ::required_size(self, constraint) - } -} +use crate::view::scroll::{ + InnerDraw, InnerLayout, InnerOnEvent, InnerRequiredSize, +}; /// Core system for scrolling views. /// @@ -853,3 +743,34 @@ impl ScrollCore { } } } + +struct Layout2Sizes<'a, I> { + inner: &'a mut I, +} + +trait InnerSizes { + fn needs_relayout(&self) -> bool; + fn required_size(&mut self, constraint: Vec2) -> Vec2; +} + +impl<'a, I: InnerLayout> InnerSizes for Layout2Sizes<'a, I> { + fn needs_relayout(&self) -> bool { + self.inner.needs_relayout() + } + fn required_size(&mut self, constraint: Vec2) -> Vec2 { + self.inner.required_size(constraint) + } +} + +struct Required2Sizes<'a, I> { + inner: &'a mut I, +} + +impl<'a, I: InnerRequiredSize> InnerSizes for Required2Sizes<'a, I> { + fn needs_relayout(&self) -> bool { + self.inner.needs_relayout() + } + fn required_size(&mut self, constraint: Vec2) -> Vec2 { + self.inner.required_size(constraint) + } +} diff --git a/src/view/scroll/mod.rs b/src/view/scroll/mod.rs new file mode 100644 index 0000000..0bcb3d8 --- /dev/null +++ b/src/view/scroll/mod.rs @@ -0,0 +1,30 @@ +//! Core mechanisms to implement scrolling. +//! +//! This module defines [`ScrollCore`](crate::view::scroll::ScrollCore) and related traits. +//! +//! [`ScrollView`](crate::views::ScrollView) may be an easier way to add scrolling to an existing view. + +mod core; +mod traits; + +pub use self::core::ScrollCore; +pub use self::traits::{ + InnerDraw, InnerLayout, InnerOnEvent, InnerRequiredSize, +}; + +/// Defines the scrolling behaviour on content or size change +#[derive(Debug)] +pub enum ScrollStrategy { + /// Keeps the same row number + KeepRow, + /// Sticks to the top. + StickToTop, + /// Sticks to the bottom of the view. + StickToBottom, +} + +impl Default for ScrollStrategy { + fn default() -> Self { + ScrollStrategy::KeepRow + } +} diff --git a/src/view/scroll/strategy.rs b/src/view/scroll/strategy.rs new file mode 100644 index 0000000..e69de29 diff --git a/src/view/scroll/traits.rs b/src/view/scroll/traits.rs new file mode 100644 index 0000000..37946b0 --- /dev/null +++ b/src/view/scroll/traits.rs @@ -0,0 +1,75 @@ +use crate::event::{Event, EventResult}; +use crate::printer::Printer; +use crate::rect::Rect; + +use crate::vec::Vec2; +use crate::view::View; + +/// Inner implementation for `ScrollCore::on_event` +pub trait InnerOnEvent { + /// Performs `View::on_event()` + fn on_event(&mut self, event: Event) -> EventResult; + + /// Performs `View::important_area()` + fn important_area(&self, size: Vec2) -> Rect; +} + +impl<'a, V: View> InnerOnEvent for &'a mut V { + fn on_event(&mut self, event: Event) -> EventResult { + ::on_event(self, event) + } + fn important_area(&self, size: Vec2) -> Rect { + ::important_area(self, size) + } +} + +/// Inner implementation for `ScrollCore::draw()` +pub trait InnerDraw { + /// Performs `View::draw()` + fn draw(&self, printer: &Printer<'_, '_>); +} + +impl<'a, V: View> InnerDraw for &'a V { + fn draw(&self, printer: &Printer<'_, '_>) { + ::draw(self, printer); + } +} + +/// Inner implementation for `ScrollCore::InnerLayout()` +pub trait InnerLayout { + /// Performs `View::layout()` + fn layout(&mut self, size: Vec2); + /// Performs `View::needs_relayout()` + fn needs_relayout(&self) -> bool; + /// Performs `View::required_size()` + fn required_size(&mut self, constraint: Vec2) -> Vec2; +} + +impl<'a, V: View> InnerLayout for &'a mut V { + fn layout(&mut self, size: Vec2) { + ::layout(self, size); + } + fn needs_relayout(&self) -> bool { + ::needs_relayout(self) + } + fn required_size(&mut self, constraint: Vec2) -> Vec2 { + ::required_size(self, constraint) + } +} + +/// Inner implementation for `ScrollCore::required_size()` +pub trait InnerRequiredSize { + /// Performs `View::needs_relayout()` + fn needs_relayout(&self) -> bool; + /// Performs `View::required_size()` + fn required_size(&mut self, constraint: Vec2) -> Vec2; +} + +impl InnerRequiredSize for &mut V { + fn needs_relayout(&self) -> bool { + ::needs_relayout(self) + } + fn required_size(&mut self, constraint: Vec2) -> Vec2 { + ::required_size(self, constraint) + } +} diff --git a/src/view/scroll_base.rs b/src/view/scroll_base.rs index d183db4..4b17c9c 100644 --- a/src/view/scroll_base.rs +++ b/src/view/scroll_base.rs @@ -35,23 +35,6 @@ pub struct ScrollBase { pub thumb_grab: Option, } -/// Defines the scrolling behaviour on content or size change -#[derive(Debug)] -pub enum ScrollStrategy { - /// Keeps the same row number - KeepRow, - /// Sticks to the top. - StickToTop, - /// Sticks to the bottom of the view. - StickToBottom, -} - -impl Default for ScrollStrategy { - fn default() -> Self { - ScrollStrategy::KeepRow - } -} - impl ScrollBase { /// Creates a new, uninitialized scrollbar. pub fn new() -> Self {