mirror of
https://github.com/FliegendeWurst/cursive.git
synced 2024-11-23 17:35:00 +00:00
Add some documentation to the view::scroll module
This commit is contained in:
parent
976cb99bdb
commit
babc038e36
@ -12,6 +12,9 @@ repository = "https://github.com/gyscos/cursive"
|
|||||||
version = "0.12.1-alpha.0"
|
version = "0.12.1-alpha.0"
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
|
[package.metadata.docs.rs]
|
||||||
|
features = ["unstable_scroll"]
|
||||||
|
|
||||||
[badges.travis-ci]
|
[badges.travis-ci]
|
||||||
repository = "gyscos/cursive"
|
repository = "gyscos/cursive"
|
||||||
|
|
||||||
|
@ -26,7 +26,11 @@ pub trait Scroller {
|
|||||||
|
|
||||||
/// Core system for scrolling views.
|
/// Core system for scrolling views.
|
||||||
///
|
///
|
||||||
/// See also [`ScrollView`](crate::views::ScrollView).
|
/// This is the lowest-level element handling scroll logic.
|
||||||
|
///
|
||||||
|
/// Higher-level abstractions are probably what you're after.
|
||||||
|
///
|
||||||
|
/// In particular, see also [`ScrollView`](crate::views::ScrollView).
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Core {
|
pub struct Core {
|
||||||
/// This is the size the child thinks we're giving him.
|
/// This is the size the child thinks we're giving him.
|
||||||
@ -93,7 +97,8 @@ impl Core {
|
|||||||
|
|
||||||
/// Returns a sub-printer ready to draw the content.
|
/// Returns a sub-printer ready to draw the content.
|
||||||
pub fn sub_printer<'a, 'b>(
|
pub fn sub_printer<'a, 'b>(
|
||||||
&self, printer: &Printer<'a, 'b>,
|
&self,
|
||||||
|
printer: &Printer<'a, 'b>,
|
||||||
) -> Printer<'a, 'b> {
|
) -> Printer<'a, 'b> {
|
||||||
// Draw scrollbar?
|
// Draw scrollbar?
|
||||||
let scrolling = self.is_scrolling();
|
let scrolling = self.is_scrolling();
|
||||||
@ -180,7 +185,9 @@ impl Core {
|
|||||||
|
|
||||||
/// Handle an event after processing by the content.
|
/// Handle an event after processing by the content.
|
||||||
pub fn on_inner_event(
|
pub fn on_inner_event(
|
||||||
&mut self, event: Event, inner_result: EventResult,
|
&mut self,
|
||||||
|
event: Event,
|
||||||
|
inner_result: EventResult,
|
||||||
important_area: Rect,
|
important_area: Rect,
|
||||||
) -> EventResult {
|
) -> EventResult {
|
||||||
match inner_result {
|
match inner_result {
|
||||||
@ -358,7 +365,9 @@ impl Core {
|
|||||||
|
|
||||||
/// Performs `View::call_on_any()`
|
/// Performs `View::call_on_any()`
|
||||||
pub fn call_on_any<'a, F>(
|
pub fn call_on_any<'a, F>(
|
||||||
&mut self, selector: &Selector<'_>, cb: AnyCb<'a>,
|
&mut self,
|
||||||
|
selector: &Selector<'_>,
|
||||||
|
cb: AnyCb<'a>,
|
||||||
inner_call_on_any: F,
|
inner_call_on_any: F,
|
||||||
) where
|
) where
|
||||||
F: FnOnce(&Selector, AnyCb),
|
F: FnOnce(&Selector, AnyCb),
|
||||||
@ -368,7 +377,9 @@ impl Core {
|
|||||||
|
|
||||||
/// Performs `View::focus_view()`
|
/// Performs `View::focus_view()`
|
||||||
pub fn focus_view<F>(
|
pub fn focus_view<F>(
|
||||||
&mut self, selector: &Selector<'_>, inner_focus_view: F,
|
&mut self,
|
||||||
|
selector: &Selector<'_>,
|
||||||
|
inner_focus_view: F,
|
||||||
) -> Result<(), ()>
|
) -> Result<(), ()>
|
||||||
where
|
where
|
||||||
F: FnOnce(&Selector) -> Result<(), ()>,
|
F: FnOnce(&Selector) -> Result<(), ()>,
|
||||||
@ -402,7 +413,8 @@ impl Core {
|
|||||||
|
|
||||||
/// Sets the padding between content and scrollbar.
|
/// Sets the padding between content and scrollbar.
|
||||||
pub fn set_scrollbar_padding<V: Into<Vec2>>(
|
pub fn set_scrollbar_padding<V: Into<Vec2>>(
|
||||||
&mut self, scrollbar_padding: V,
|
&mut self,
|
||||||
|
scrollbar_padding: V,
|
||||||
) {
|
) {
|
||||||
self.scrollbar_padding = scrollbar_padding.into();
|
self.scrollbar_padding = scrollbar_padding.into();
|
||||||
}
|
}
|
||||||
@ -411,7 +423,8 @@ impl Core {
|
|||||||
///
|
///
|
||||||
/// Chainable variant.
|
/// Chainable variant.
|
||||||
pub fn scrollbar_padding<V: Into<Vec2>>(
|
pub fn scrollbar_padding<V: Into<Vec2>>(
|
||||||
self, scrollbar_padding: V,
|
self,
|
||||||
|
scrollbar_padding: V,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
self.with(|s| s.set_scrollbar_padding(scrollbar_padding))
|
self.with(|s| s.set_scrollbar_padding(scrollbar_padding))
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,21 @@
|
|||||||
//! Core mechanisms to implement scrolling.
|
//! Core mechanisms to implement scrolling.
|
||||||
//!
|
//!
|
||||||
//! *This module is still unstable and may go through breaking changes.*
|
//! *This module is still unstable and may go through breaking changes.*
|
||||||
|
//! In addition, it is private unless you enable the `unstable_scroll` feature.
|
||||||
//!
|
//!
|
||||||
//! This module defines [`Core`](crate::view::scroll::Core) and related traits.
|
//! This modules defines:
|
||||||
|
//!
|
||||||
|
//! * [`scroll::Core`](crate::view::scroll::Core): stores the state variables
|
||||||
|
//! required to handle scrolling. Any view that needs to implement scrolling
|
||||||
|
//! should embed a `scroll::Core`.
|
||||||
|
//! * [`scroll::Scroller`](crate::view::scroll::Scroller): a trait for
|
||||||
|
//! something that embeds a such a `scroll::Core`.
|
||||||
|
//! * Some free functions to help implement the usual `View` trait for a type
|
||||||
|
//! implementing `scroll::Scroller`.
|
||||||
|
//! Some methods, like `View::call_on_any`, are not affected by scrolling
|
||||||
|
//! and are not covered here.
|
||||||
|
//! * The functions defined here will usually take a reference to the
|
||||||
|
//! `Scroller` object, as well as closures to implement the "inner view".
|
||||||
//!
|
//!
|
||||||
//! [`ScrollView`](crate::views::ScrollView) may be an easier way to add scrolling to an existing view.
|
//! [`ScrollView`](crate::views::ScrollView) may be an easier way to add scrolling to an existing view.
|
||||||
|
|
||||||
@ -41,7 +54,9 @@ impl Default for ScrollStrategy {
|
|||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub fn on_event<T, OnEvent, ImportantArea>(
|
pub fn on_event<T, OnEvent, ImportantArea>(
|
||||||
scroller: &mut T, event: Event, on_event: OnEvent,
|
scroller: &mut T,
|
||||||
|
event: Event,
|
||||||
|
on_event: OnEvent,
|
||||||
important_area: ImportantArea,
|
important_area: ImportantArea,
|
||||||
) -> EventResult
|
) -> EventResult
|
||||||
where
|
where
|
||||||
@ -60,7 +75,9 @@ where
|
|||||||
|
|
||||||
/// Performs `View::important_area` on a `scroll::Scroller`.
|
/// Performs `View::important_area` on a `scroll::Scroller`.
|
||||||
pub fn important_area<T, ImportantArea>(
|
pub fn important_area<T, ImportantArea>(
|
||||||
scroller: &T, size: Vec2, mut important_area: ImportantArea,
|
scroller: &T,
|
||||||
|
size: Vec2,
|
||||||
|
mut important_area: ImportantArea,
|
||||||
) -> Rect
|
) -> Rect
|
||||||
where
|
where
|
||||||
T: Scroller,
|
T: Scroller,
|
||||||
@ -79,7 +96,10 @@ where
|
|||||||
|
|
||||||
/// Performs `View::layout` on a `scroll::Scroller`.
|
/// Performs `View::layout` on a `scroll::Scroller`.
|
||||||
pub fn layout<T, Layout, RequiredSize>(
|
pub fn layout<T, Layout, RequiredSize>(
|
||||||
scroller: &mut T, size: Vec2, needs_relayout: bool, layout: Layout,
|
scroller: &mut T,
|
||||||
|
size: Vec2,
|
||||||
|
needs_relayout: bool,
|
||||||
|
layout: Layout,
|
||||||
required_size: RequiredSize,
|
required_size: RequiredSize,
|
||||||
) where
|
) where
|
||||||
T: Scroller,
|
T: Scroller,
|
||||||
@ -98,7 +118,9 @@ pub fn layout<T, Layout, RequiredSize>(
|
|||||||
|
|
||||||
/// Performs `View::required_size` on a `scroll::Scroller`.
|
/// Performs `View::required_size` on a `scroll::Scroller`.
|
||||||
pub fn required_size<T, RequiredSize>(
|
pub fn required_size<T, RequiredSize>(
|
||||||
scroller: &mut T, size: Vec2, needs_relayout: bool,
|
scroller: &mut T,
|
||||||
|
size: Vec2,
|
||||||
|
needs_relayout: bool,
|
||||||
required_size: RequiredSize,
|
required_size: RequiredSize,
|
||||||
) -> Vec2
|
) -> Vec2
|
||||||
where
|
where
|
||||||
@ -127,7 +149,9 @@ where
|
|||||||
///
|
///
|
||||||
/// This is an alternative to `scroll::draw()` when you just need to print individual lines.
|
/// This is an alternative to `scroll::draw()` when you just need to print individual lines.
|
||||||
pub fn draw_lines<T, LineDrawer>(
|
pub fn draw_lines<T, LineDrawer>(
|
||||||
scroller: &T, printer: &Printer, mut line_drawer: LineDrawer,
|
scroller: &T,
|
||||||
|
printer: &Printer,
|
||||||
|
mut line_drawer: LineDrawer,
|
||||||
) where
|
) where
|
||||||
T: Scroller,
|
T: Scroller,
|
||||||
LineDrawer: FnMut(&T, &Printer, usize),
|
LineDrawer: FnMut(&T, &Printer, usize),
|
||||||
@ -146,8 +170,11 @@ pub fn draw_lines<T, LineDrawer>(
|
|||||||
///
|
///
|
||||||
/// `left_border` will be called for each row to draw the left border for the given line number.
|
/// `left_border` will be called for each row to draw the left border for the given line number.
|
||||||
pub fn draw_frame<T, LeftBorder, TopBorder, RightBorder, BottomBorder>(
|
pub fn draw_frame<T, LeftBorder, TopBorder, RightBorder, BottomBorder>(
|
||||||
scroller: &T, printer: &Printer, mut left_border: LeftBorder,
|
scroller: &T,
|
||||||
mut top_border: TopBorder, mut right_border: RightBorder,
|
printer: &Printer,
|
||||||
|
mut left_border: LeftBorder,
|
||||||
|
mut top_border: TopBorder,
|
||||||
|
mut right_border: RightBorder,
|
||||||
mut bottom_border: BottomBorder,
|
mut bottom_border: BottomBorder,
|
||||||
) where
|
) where
|
||||||
T: Scroller,
|
T: Scroller,
|
||||||
@ -197,7 +224,9 @@ pub fn draw_frame<T, LeftBorder, TopBorder, RightBorder, BottomBorder>(
|
|||||||
///
|
///
|
||||||
/// It will print a box with the appropriate `├`, `┤` and so on.
|
/// It will print a box with the appropriate `├`, `┤` and so on.
|
||||||
pub fn draw_box_frame<T, IsHDelim, IsVDelim>(
|
pub fn draw_box_frame<T, IsHDelim, IsVDelim>(
|
||||||
scroller: &T, printer: &Printer, is_h_delim: IsHDelim,
|
scroller: &T,
|
||||||
|
printer: &Printer,
|
||||||
|
is_h_delim: IsHDelim,
|
||||||
is_v_delim: IsVDelim,
|
is_v_delim: IsVDelim,
|
||||||
) where
|
) where
|
||||||
T: Scroller,
|
T: Scroller,
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
//! Low-level implementation of the `View` trait using a `scroll::Core`.
|
||||||
|
//!
|
||||||
|
//! Most functions take a generic `Model` class, and various closures to get
|
||||||
|
//! the required things from this model.
|
||||||
use crate::event::{Event, EventResult};
|
use crate::event::{Event, EventResult};
|
||||||
use crate::rect::Rect;
|
use crate::rect::Rect;
|
||||||
use crate::view::scroll;
|
use crate::view::scroll;
|
||||||
@ -5,8 +9,11 @@ use crate::xy::XY;
|
|||||||
use crate::Printer;
|
use crate::Printer;
|
||||||
use crate::Vec2;
|
use crate::Vec2;
|
||||||
|
|
||||||
|
/// Implements `View::draw` over the `model`.
|
||||||
pub fn draw<Model, GetScroller, Draw>(
|
pub fn draw<Model, GetScroller, Draw>(
|
||||||
printer: &Printer, model: &Model, mut get_scroller: GetScroller,
|
printer: &Printer,
|
||||||
|
model: &Model,
|
||||||
|
mut get_scroller: GetScroller,
|
||||||
inner_draw: Draw,
|
inner_draw: Draw,
|
||||||
) where
|
) where
|
||||||
Model: ?Sized,
|
Model: ?Sized,
|
||||||
@ -17,9 +24,20 @@ pub fn draw<Model, GetScroller, Draw>(
|
|||||||
inner_draw(model, &printer);
|
inner_draw(model, &printer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Intermediate method to get the size requirements of a view.
|
||||||
|
///
|
||||||
|
/// Assumes we are already scrolling on the axis designated by `scrolling`.
|
||||||
|
///
|
||||||
|
/// `strict` means the result will never be bigger than the constraint.
|
||||||
|
///
|
||||||
|
/// Returns (Inner size, Outer size, New scrolling)
|
||||||
fn sizes_when_scrolling<Model, GetScroller, RequiredSize>(
|
fn sizes_when_scrolling<Model, GetScroller, RequiredSize>(
|
||||||
constraint: Vec2, scrollable: XY<bool>, strict: bool, model: &mut Model,
|
constraint: Vec2,
|
||||||
get_scroller: &mut GetScroller, required_size: &mut RequiredSize,
|
scrolling: XY<bool>,
|
||||||
|
strict: bool,
|
||||||
|
model: &mut Model,
|
||||||
|
get_scroller: &mut GetScroller,
|
||||||
|
required_size: &mut RequiredSize,
|
||||||
) -> (Vec2, Vec2, XY<bool>)
|
) -> (Vec2, Vec2, XY<bool>)
|
||||||
where
|
where
|
||||||
Model: ?Sized,
|
Model: ?Sized,
|
||||||
@ -27,7 +45,7 @@ where
|
|||||||
RequiredSize: FnMut(&mut Model, Vec2) -> Vec2,
|
RequiredSize: FnMut(&mut Model, Vec2) -> Vec2,
|
||||||
{
|
{
|
||||||
// This is the size taken by the scrollbars.
|
// This is the size taken by the scrollbars.
|
||||||
let scrollbar_size = scrollable.swap().select_or(
|
let scrollbar_size = scrolling.swap().select_or(
|
||||||
get_scroller(model).get_scrollbar_padding() + (1, 1),
|
get_scroller(model).get_scrollbar_padding() + (1, 1),
|
||||||
Vec2::zero(),
|
Vec2::zero(),
|
||||||
);
|
);
|
||||||
@ -56,14 +74,21 @@ where
|
|||||||
.is_enabled()
|
.is_enabled()
|
||||||
.select_or(inner_size, size.saturating_sub(scrollbar_size));
|
.select_or(inner_size, size.saturating_sub(scrollbar_size));
|
||||||
|
|
||||||
let new_scrollable = inner_size.zip_map(size, |i, s| i > s);
|
let new_scrolling = inner_size.zip_map(size, |i, s| i > s);
|
||||||
|
|
||||||
(inner_size, size, new_scrollable)
|
(inner_size, size, new_scrolling)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the size requirement of the view.
|
||||||
|
///
|
||||||
|
/// Returns (Inner size, Outer size)
|
||||||
fn sizes<Model, GetScroller, RequiredSize>(
|
fn sizes<Model, GetScroller, RequiredSize>(
|
||||||
constraint: Vec2, strict: bool, needs_relayout: bool, model: &mut Model,
|
constraint: Vec2,
|
||||||
get_scroller: &mut GetScroller, required_size: &mut RequiredSize,
|
strict: bool,
|
||||||
|
needs_relayout: bool,
|
||||||
|
model: &mut Model,
|
||||||
|
get_scroller: &mut GetScroller,
|
||||||
|
required_size: &mut RequiredSize,
|
||||||
) -> (Vec2, Vec2)
|
) -> (Vec2, Vec2)
|
||||||
where
|
where
|
||||||
Model: ?Sized,
|
Model: ?Sized,
|
||||||
@ -77,7 +102,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Attempt 1: try without scrollbars
|
// Attempt 1: try without scrollbars
|
||||||
let (inner_size, size, scrollable) = sizes_when_scrolling(
|
let (inner_size, size, scrolling) = sizes_when_scrolling(
|
||||||
constraint,
|
constraint,
|
||||||
XY::new(false, false),
|
XY::new(false, false),
|
||||||
strict,
|
strict,
|
||||||
@ -87,18 +112,18 @@ where
|
|||||||
);
|
);
|
||||||
|
|
||||||
// If we need to add scrollbars, the available size will change.
|
// If we need to add scrollbars, the available size will change.
|
||||||
if scrollable.any() && get_scroller(model).get_show_scrollbars() {
|
if scrolling.any() && get_scroller(model).get_show_scrollbars() {
|
||||||
// Attempt 2: he wants to scroll? Sure!
|
// Attempt 2: he wants to scroll? Sure!
|
||||||
// Try again with some space for the scrollbar.
|
// Try again with some space for the scrollbar.
|
||||||
let (inner_size, size, new_scrollable) = sizes_when_scrolling(
|
let (inner_size, size, new_scrolling) = sizes_when_scrolling(
|
||||||
constraint,
|
constraint,
|
||||||
scrollable,
|
scrolling,
|
||||||
strict,
|
strict,
|
||||||
model,
|
model,
|
||||||
get_scroller,
|
get_scroller,
|
||||||
required_size,
|
required_size,
|
||||||
);
|
);
|
||||||
if scrollable == new_scrollable {
|
if scrolling == new_scrolling {
|
||||||
// Yup, scrolling did it. We're good to go now.
|
// Yup, scrolling did it. We're good to go now.
|
||||||
(inner_size, size)
|
(inner_size, size)
|
||||||
} else {
|
} else {
|
||||||
@ -106,7 +131,7 @@ where
|
|||||||
// There is no end to this!
|
// There is no end to this!
|
||||||
let (inner_size, size, _) = sizes_when_scrolling(
|
let (inner_size, size, _) = sizes_when_scrolling(
|
||||||
constraint,
|
constraint,
|
||||||
new_scrollable,
|
new_scrolling,
|
||||||
strict,
|
strict,
|
||||||
model,
|
model,
|
||||||
get_scroller,
|
get_scroller,
|
||||||
@ -124,9 +149,13 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Implements `View::layout` on the given model.
|
||||||
pub fn layout<Model, GetScroller, RequiredSize, Layout>(
|
pub fn layout<Model, GetScroller, RequiredSize, Layout>(
|
||||||
size: Vec2, needs_relayout: bool, model: &mut Model,
|
size: Vec2,
|
||||||
mut get_scroller: GetScroller, mut required_size: RequiredSize,
|
needs_relayout: bool,
|
||||||
|
model: &mut Model,
|
||||||
|
mut get_scroller: GetScroller,
|
||||||
|
mut required_size: RequiredSize,
|
||||||
mut layout: Layout,
|
mut layout: Layout,
|
||||||
) where
|
) where
|
||||||
Model: ?Sized,
|
Model: ?Sized,
|
||||||
@ -154,9 +183,13 @@ pub fn layout<Model, GetScroller, RequiredSize, Layout>(
|
|||||||
get_scroller(model).update_offset();
|
get_scroller(model).update_offset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Implements `View::required_size` on the given model.
|
||||||
pub fn required_size<Model, GetScroller, RequiredSize>(
|
pub fn required_size<Model, GetScroller, RequiredSize>(
|
||||||
constraint: Vec2, needs_relayout: bool, model: &mut Model,
|
constraint: Vec2,
|
||||||
mut get_scroller: GetScroller, mut required_size: RequiredSize,
|
needs_relayout: bool,
|
||||||
|
model: &mut Model,
|
||||||
|
mut get_scroller: GetScroller,
|
||||||
|
mut required_size: RequiredSize,
|
||||||
) -> Vec2
|
) -> Vec2
|
||||||
where
|
where
|
||||||
Model: ?Sized,
|
Model: ?Sized,
|
||||||
@ -175,9 +208,13 @@ where
|
|||||||
size
|
size
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Implements `View::on_event` on the given model.
|
||||||
pub fn on_event<Model, GetScroller, OnEvent, ImportantArea>(
|
pub fn on_event<Model, GetScroller, OnEvent, ImportantArea>(
|
||||||
event: Event, model: &mut Model, mut get_scroller: GetScroller,
|
event: Event,
|
||||||
mut on_event: OnEvent, mut important_area: ImportantArea,
|
model: &mut Model,
|
||||||
|
mut get_scroller: GetScroller,
|
||||||
|
mut on_event: OnEvent,
|
||||||
|
mut important_area: ImportantArea,
|
||||||
) -> EventResult
|
) -> EventResult
|
||||||
where
|
where
|
||||||
Model: ?Sized,
|
Model: ?Sized,
|
||||||
|
Loading…
Reference in New Issue
Block a user