Make view::scroll public

This commit is contained in:
Alexandre Bury 2019-10-08 15:33:33 -07:00
parent 5bf6f952d1
commit 22886859dd
11 changed files with 116 additions and 35 deletions

View File

@ -87,6 +87,7 @@ pub mod logger;
pub mod menu;
pub mod theme;
pub mod vec;
#[macro_use]
pub mod views;
// This probably doesn't need to be public?

View File

@ -51,13 +51,9 @@ mod view_trait;
// Helper bases
mod boxable;
mod identifiable;
#[cfg(feature = "unstable_scroll")]
#[macro_use]
pub mod scroll;
#[cfg(not(feature = "unstable_scroll"))]
#[allow(dead_code)]
pub(crate) mod scroll;
mod scroll_base;
mod scrollable;

View File

@ -24,6 +24,36 @@ pub trait Scroller {
fn get_scroller(&self) -> &Core;
}
/// Implements the `Scroller` trait for any type.
#[macro_export]
macro_rules! impl_scroller {
($class:ident :: $core:ident) => {
impl $crate::view::scroll::Scroller for $class {
fn get_scroller_mut(
&mut self,
) -> &mut $crate::view::scroll::Core {
&mut self.$core
}
fn get_scroller(&self) -> &$crate::view::scroll::Core {
&self.$core
}
}
};
($class:ident < $($args:tt),* > :: $core:ident) => {
impl <$( $args ),* > $crate::view::scroll::Scroller for $class<$($args),*> {
fn get_scroller_mut(
&mut self,
) -> &mut $crate::view::scroll::Core {
&mut self.$core
}
fn get_scroller(&self) -> &$crate::view::scroll::Core {
&self.$core
}
}
};
}
/// Core system for scrolling views.
///
/// This is the lowest-level element handling scroll logic.

View File

@ -19,6 +19,7 @@
//!
//! [`ScrollView`](crate::views::ScrollView) may be an easier way to add scrolling to an existing view.
#[macro_use]
mod core;
mod raw;
@ -48,10 +49,33 @@ impl Default for ScrollStrategy {
///
/// Example:
///
/// ```rust,ignore
/// ```
/// use cursive::{Printer, Vec2, Rect};
/// use cursive::event::{Event, EventResult};
/// use cursive::view::{View, scroll};
///
/// struct MyView {
/// core: scroll::Core,
/// }
///
/// cursive::impl_scroller!(MyView::core);
///
/// impl MyView {
/// fn inner_on_event(&mut self, event: Event) -> EventResult {
/// EventResult::Ignored
/// }
///
/// fn inner_important_area(&self, size: Vec2) -> Rect {
/// Rect::from_size((0,0), size)
/// }
/// }
///
/// impl View for MyView {
/// # fn draw(&self, printer: &Printer) {}
/// fn on_event(&mut self, event: Event) -> EventResult {
/// scroll::on_event(self, event, Self::inner_on_event, Self::inner_important_area)
/// }
/// }
/// ```
pub fn on_event<T, OnEvent, ImportantArea>(
scroller: &mut T,

View File

@ -23,12 +23,13 @@ impl SizeCache {
/// Returns `true` if `self` is still valid for the given `request`.
pub fn accept(self, request: usize) -> bool {
if request < self.value {
false
} else if request == self.value {
true
} else {
!self.constrained
match (request, self.value) {
// Request a smaller size than last time? Hell no!
(r, v) if r < v => false,
// Request exactly what we had last time? Sure!
(r, v) if r == v => true,
// Request more than we had last time? Maybe?
_ => !self.constrained,
}
}

View File

@ -1,6 +1,6 @@
use crate::event::{Event, EventResult};
use crate::view::{View, ViewWrapper};
use crate::{Printer, With};
use crate::Printer;
/// Wrapper around another view that can be enabled/disabled at will.
///

View File

@ -34,15 +34,7 @@ pub struct MenuPopup {
// The `scroll::Scroller` trait is used to weave the borrow phases.
//
// TODO: use some macro to auto-generate this.
impl scroll::Scroller for MenuPopup {
fn get_scroller(&self) -> &scroll::Core {
&self.scroll_core
}
fn get_scroller_mut(&mut self) -> &mut scroll::Core {
&mut self.scroll_core
}
}
impl_scroller!(MenuPopup::scroll_core);
impl MenuPopup {
/// Creates a new `MenuPopup` using the given menu tree.

View File

@ -1,6 +1,22 @@
//! Various views to use when creating the layout.
/// A macro to help with creating toggleable views.
///
/// # Examples
///
/// ```
/// struct MyView {
/// enabled: bool,
/// }
///
/// impl MyView {
/// cursive::impl_enabled!(self.enabled);
/// }
///
/// let view = MyView { enabled: true };
/// assert!(view.is_enabled());
/// ```
#[macro_export]
macro_rules! impl_enabled {
(self.$x:ident) => {
@ -15,6 +31,7 @@ macro_rules! impl_enabled {
///
/// Chainable variant.
pub fn disabled(self) -> Self {
use $crate::traits::With as _;
self.with(Self::disable)
}

View File

@ -11,17 +11,7 @@ pub struct ScrollView<V> {
core: scroll::Core,
}
impl<V> scroll::Scroller for ScrollView<V>
where
V: View,
{
fn get_scroller(&self) -> &scroll::Core {
&self.core
}
fn get_scroller_mut(&mut self) -> &mut scroll::Core {
&mut self.core
}
}
impl_scroller!(ScrollView<V>::core);
impl<V> ScrollView<V>
where

View File

@ -10,6 +10,21 @@ use crate::{Cursive, Printer};
use std::rc::Rc;
/// A horizontal or vertical slider.
///
/// # Examples
///
/// ```
/// use cursive::views::{Dialog, SliderView};
///
/// let slider_view = SliderView::horizontal(10)
/// .on_change(|s, n| if n == 5 {
/// s.add_layer(Dialog::info("5! Pick 5!"));
/// })
/// .on_enter(|s, n| match n {
/// 5 => s.add_layer(Dialog::info("You did it!")),
/// n => s.add_layer(Dialog::info(format!("Why {}? Why not 5?", n))),
/// });
/// ```
pub struct SliderView {
orientation: Orientation,
on_change: Option<Rc<dyn Fn(&mut Cursive, usize)>>,
@ -24,6 +39,8 @@ impl SliderView {
///
/// The view will have a fixed length of `max_value`,
/// with one tick per block.
///
/// The actual range of values for this slider is `[0, max_value - 1]`.
pub fn new(orientation: Orientation, max_value: usize) -> Self {
SliderView {
orientation,

View File

@ -16,6 +16,19 @@ use unicode_width::UnicodeWidthStr;
/// A `TextArea` will attempt to grow vertically and horizontally
/// dependent on the content. Wrap it in a `BoxView` to
/// constrain its size.
///
/// # Examples
///
/// ```
/// use cursive::traits::{Boxable, Identifiable};
/// use cursive::views::TextArea;
///
/// let text_area = TextArea::new()
/// .content("Write description here...")
/// .with_id("text_area")
/// .fixed_width(30)
/// .min_height(5);
/// ```
pub struct TextArea {
// TODO: use a smarter data structure (rope?)
content: String,