mirror of
https://github.com/FliegendeWurst/cursive.git
synced 2024-11-23 17:35:00 +00:00
Make view::scroll public
This commit is contained in:
parent
5bf6f952d1
commit
22886859dd
@ -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?
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
///
|
||||
|
@ -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.
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user