mirror of
https://github.com/FliegendeWurst/cursive.git
synced 2024-11-23 17:35:00 +00:00
Add AnyCb type alias
This commit is contained in:
parent
8c00b171c0
commit
39babacbf5
15
src/event.rs
15
src/event.rs
@ -17,6 +17,7 @@ use Cursive;
|
|||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use vec::Vec2;
|
use vec::Vec2;
|
||||||
|
use std::any::Any;
|
||||||
|
|
||||||
/// Callback is a function that can be triggered by an event.
|
/// Callback is a function that can be triggered by an event.
|
||||||
/// It has a mutable access to the cursive root.
|
/// It has a mutable access to the cursive root.
|
||||||
@ -24,6 +25,9 @@ use vec::Vec2;
|
|||||||
pub struct Callback(Rc<Box<Fn(&mut Cursive)>>);
|
pub struct Callback(Rc<Box<Fn(&mut Cursive)>>);
|
||||||
// TODO: remove the Box when Box<T: Sized> -> Rc<T> is possible
|
// TODO: remove the Box when Box<T: Sized> -> Rc<T> is possible
|
||||||
|
|
||||||
|
/// A boxed callback that can be run on `&mut Any`.
|
||||||
|
pub type AnyCb<'a> = Box<FnMut(&mut Any) + 'a>;
|
||||||
|
|
||||||
impl Callback {
|
impl Callback {
|
||||||
/// Wraps the given function into a `Callback` object.
|
/// Wraps the given function into a `Callback` object.
|
||||||
pub fn from_fn<F>(f: F) -> Self
|
pub fn from_fn<F>(f: F) -> Self
|
||||||
@ -343,6 +347,17 @@ impl Event {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a mutable reference to the position of the mouse/
|
||||||
|
///
|
||||||
|
/// Returns `None` if `self` is not a mouse event.
|
||||||
|
pub fn mouse_position_mut(&mut self) -> Option<&mut Vec2> {
|
||||||
|
if let Event::Mouse { ref mut position, .. } = *self {
|
||||||
|
Some(position)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Update `self` with the given offset.
|
/// Update `self` with the given offset.
|
||||||
///
|
///
|
||||||
/// If `self` is a mouse event, adds `top_left` to its offset.
|
/// If `self` is a mouse event, adds `top_left` to its offset.
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use Printer;
|
use Printer;
|
||||||
use direction::Direction;
|
use direction::Direction;
|
||||||
use event::{Event, EventResult};
|
use event::{AnyCb, Event, EventResult};
|
||||||
use rect::Rect;
|
use rect::Rect;
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
use vec::Vec2;
|
use vec::Vec2;
|
||||||
@ -73,7 +73,7 @@ pub trait View: Any + AnyView {
|
|||||||
/// If the selector doesn't find a match, the closure will not be run.
|
/// If the selector doesn't find a match, the closure will not be run.
|
||||||
///
|
///
|
||||||
/// Default implementation is a no-op.
|
/// Default implementation is a no-op.
|
||||||
fn call_on_any<'a>(&mut self, _: &Selector, _: Box<FnMut(&mut Any) + 'a>) {
|
fn call_on_any<'a>(&mut self, _: &Selector, _: AnyCb<'a>) {
|
||||||
// TODO: FnMut -> FnOnce once it works
|
// TODO: FnMut -> FnOnce once it works
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use Printer;
|
use Printer;
|
||||||
use direction::Direction;
|
use direction::Direction;
|
||||||
use event::{Event, EventResult};
|
use event::{AnyCb, Event, EventResult};
|
||||||
use rect::Rect;
|
use rect::Rect;
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
use vec::Vec2;
|
use vec::Vec2;
|
||||||
@ -79,7 +79,7 @@ pub trait ViewWrapper: 'static {
|
|||||||
|
|
||||||
/// Wraps the `find` method.
|
/// Wraps the `find` method.
|
||||||
fn wrap_call_on_any<'a>(
|
fn wrap_call_on_any<'a>(
|
||||||
&mut self, selector: &Selector, callback: Box<FnMut(&mut Any) + 'a>
|
&mut self, selector: &Selector, callback: AnyCb<'a>
|
||||||
) {
|
) {
|
||||||
self.with_view_mut(|v| v.call_on_any(selector, callback));
|
self.with_view_mut(|v| v.call_on_any(selector, callback));
|
||||||
}
|
}
|
||||||
@ -92,8 +92,7 @@ pub trait ViewWrapper: 'static {
|
|||||||
|
|
||||||
/// Wraps the `needs_relayout` method.
|
/// Wraps the `needs_relayout` method.
|
||||||
fn wrap_needs_relayout(&self) -> bool {
|
fn wrap_needs_relayout(&self) -> bool {
|
||||||
self.with_view(|v| v.needs_relayout())
|
self.with_view(|v| v.needs_relayout()).unwrap_or(true)
|
||||||
.unwrap_or(true)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Wraps the `important_area` method.
|
/// Wraps the `important_area` method.
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
use Printer;
|
use Printer;
|
||||||
use With;
|
use With;
|
||||||
use direction::Direction;
|
use direction::Direction;
|
||||||
use event::{Event, EventResult};
|
use event::{AnyCb, Event, EventResult};
|
||||||
|
use rect::Rect;
|
||||||
use vec::Vec2;
|
use vec::Vec2;
|
||||||
use view::View;
|
use view::{Selector, View};
|
||||||
|
|
||||||
/// A blank view that forwards calls to closures.
|
/// A blank view that forwards calls to closures.
|
||||||
///
|
///
|
||||||
@ -17,6 +18,9 @@ pub struct Canvas<T> {
|
|||||||
layout: Box<FnMut(&mut T, Vec2)>,
|
layout: Box<FnMut(&mut T, Vec2)>,
|
||||||
take_focus: Box<FnMut(&mut T, Direction) -> bool>,
|
take_focus: Box<FnMut(&mut T, Direction) -> bool>,
|
||||||
needs_relayout: Box<Fn(&T) -> bool>,
|
needs_relayout: Box<Fn(&T) -> bool>,
|
||||||
|
focus_view: Box<FnMut(&mut T, &Selector) -> Result<(), ()>>,
|
||||||
|
call_on_any: Box<for<'a> FnMut(&mut T, &Selector, AnyCb<'a>)>,
|
||||||
|
important_area: Box<Fn(&T, Vec2) -> Rect>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: 'static + View> Canvas<T> {
|
impl<T: 'static + View> Canvas<T> {
|
||||||
@ -31,6 +35,9 @@ impl<T: 'static + View> Canvas<T> {
|
|||||||
.with_layout(T::layout)
|
.with_layout(T::layout)
|
||||||
.with_take_focus(T::take_focus)
|
.with_take_focus(T::take_focus)
|
||||||
.with_needs_relayout(T::needs_relayout)
|
.with_needs_relayout(T::needs_relayout)
|
||||||
|
.with_focus_view(T::focus_view)
|
||||||
|
.with_call_on_any(T::call_on_any)
|
||||||
|
.with_important_area(T::important_area)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,6 +62,11 @@ impl<T> Canvas<T> {
|
|||||||
layout: Box::new(|_, _| ()),
|
layout: Box::new(|_, _| ()),
|
||||||
take_focus: Box::new(|_, _| false),
|
take_focus: Box::new(|_, _| false),
|
||||||
needs_relayout: Box::new(|_| true),
|
needs_relayout: Box::new(|_| true),
|
||||||
|
focus_view: Box::new(|_, _| Err(())),
|
||||||
|
call_on_any: Box::new(|_, _, _| ()),
|
||||||
|
important_area: Box::new(|_, size| {
|
||||||
|
Rect::from_corners((0, 0), size)
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,6 +182,60 @@ impl<T> Canvas<T> {
|
|||||||
{
|
{
|
||||||
self.with(|s| s.set_needs_relayout(f))
|
self.with(|s| s.set_needs_relayout(f))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sets the closure for `call_on_any()`.
|
||||||
|
pub fn set_call_on_any<F>(&mut self, f: F)
|
||||||
|
where
|
||||||
|
F: 'static + for<'a> FnMut(&mut T, &Selector, AnyCb<'a>),
|
||||||
|
{
|
||||||
|
self.call_on_any = Box::new(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the closure for `call_on_any()`.
|
||||||
|
///
|
||||||
|
/// Chainable variant.
|
||||||
|
pub fn with_call_on_any<F>(self, f: F) -> Self
|
||||||
|
where
|
||||||
|
F: 'static + for<'a> FnMut(&mut T, &Selector, AnyCb<'a>),
|
||||||
|
{
|
||||||
|
self.with(|s| s.set_call_on_any(f))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the closure for `important_area()`.
|
||||||
|
pub fn set_important_area<F>(&mut self, f: F)
|
||||||
|
where
|
||||||
|
F: 'static + Fn(&T, Vec2) -> Rect,
|
||||||
|
{
|
||||||
|
self.important_area = Box::new(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the closure for `important_area()`.
|
||||||
|
///
|
||||||
|
/// Chainable variant.
|
||||||
|
pub fn with_important_area<F>(self, f: F) -> Self
|
||||||
|
where
|
||||||
|
F: 'static + Fn(&T, Vec2) -> Rect,
|
||||||
|
{
|
||||||
|
self.with(|s| s.set_important_area(f))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the closure for `focus_view()`.
|
||||||
|
pub fn set_focus_view<F>(&mut self, f: F)
|
||||||
|
where
|
||||||
|
F: 'static + FnMut(&mut T, &Selector) -> Result<(), ()>,
|
||||||
|
{
|
||||||
|
self.focus_view = Box::new(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the closure for `focus_view()`.
|
||||||
|
///
|
||||||
|
/// Chainable variant.
|
||||||
|
pub fn with_focus_view<F>(self, f: F) -> Self
|
||||||
|
where
|
||||||
|
F: 'static + FnMut(&mut T, &Selector) -> Result<(), ()>,
|
||||||
|
{
|
||||||
|
self.with(|s| s.set_focus_view(f))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: 'static> View for Canvas<T> {
|
impl<T: 'static> View for Canvas<T> {
|
||||||
@ -192,4 +258,20 @@ impl<T: 'static> View for Canvas<T> {
|
|||||||
fn take_focus(&mut self, source: Direction) -> bool {
|
fn take_focus(&mut self, source: Direction) -> bool {
|
||||||
(self.take_focus)(&mut self.state, source)
|
(self.take_focus)(&mut self.state, source)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn needs_relayout(&self) -> bool {
|
||||||
|
(self.needs_relayout)(&self.state)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn focus_view(&mut self, selector: &Selector) -> Result<(), ()> {
|
||||||
|
(self.focus_view)(&mut self.state, selector)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn important_area(&self, view_size: Vec2) -> Rect {
|
||||||
|
(self.important_area)(&self.state, view_size)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn call_on_any<'a>(&mut self, selector: &Selector, cb: AnyCb<'a>) {
|
||||||
|
(self.call_on_any)(&mut self.state, selector, cb);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,9 +3,8 @@ use Printer;
|
|||||||
use With;
|
use With;
|
||||||
use align::*;
|
use align::*;
|
||||||
use direction::Direction;
|
use direction::Direction;
|
||||||
use event::*;
|
use event::{AnyCb, Event, EventResult, Key};
|
||||||
use rect::Rect;
|
use rect::Rect;
|
||||||
use std::any::Any;
|
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::cmp::max;
|
use std::cmp::max;
|
||||||
use theme::ColorStyle;
|
use theme::ColorStyle;
|
||||||
@ -249,11 +248,7 @@ impl Dialog {
|
|||||||
pub fn buttons_mut<'a>(
|
pub fn buttons_mut<'a>(
|
||||||
&'a mut self
|
&'a mut self
|
||||||
) -> Box<'a + Iterator<Item = &'a mut Button>> {
|
) -> Box<'a + Iterator<Item = &'a mut Button>> {
|
||||||
Box::new(
|
Box::new(self.buttons.iter_mut().map(|b| &mut b.button.view))
|
||||||
self.buttons
|
|
||||||
.iter_mut()
|
|
||||||
.map(|b| &mut b.button.view),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns currently focused element
|
/// Returns currently focused element
|
||||||
@ -566,9 +561,7 @@ impl View for Dialog {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call_on_any<'a>(
|
fn call_on_any<'a>(&mut self, selector: &Selector, callback: AnyCb<'a>) {
|
||||||
&mut self, selector: &Selector, callback: Box<FnMut(&mut Any) + 'a>
|
|
||||||
) {
|
|
||||||
self.content.call_on_any(selector, callback);
|
self.content.call_on_any(selector, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,9 +2,8 @@ use Printer;
|
|||||||
use With;
|
use With;
|
||||||
use XY;
|
use XY;
|
||||||
use direction;
|
use direction;
|
||||||
use event::{Event, EventResult, Key};
|
use event::{AnyCb, Event, EventResult, Key};
|
||||||
use rect::Rect;
|
use rect::Rect;
|
||||||
use std::any::Any;
|
|
||||||
use std::cmp::min;
|
use std::cmp::min;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use vec::Vec2;
|
use vec::Vec2;
|
||||||
@ -81,10 +80,8 @@ impl<'a, T: Deref<Target = Child>, I: Iterator<Item = T>> Iterator
|
|||||||
|
|
||||||
// eprintln!("Available: {}", self.available);
|
// eprintln!("Available: {}", self.available);
|
||||||
|
|
||||||
let length = min(
|
let length =
|
||||||
self.available,
|
min(self.available, *child.size.get(self.orientation));
|
||||||
*child.size.get(self.orientation),
|
|
||||||
);
|
|
||||||
|
|
||||||
// Allocated width
|
// Allocated width
|
||||||
self.available = self.available.saturating_sub(length);
|
self.available = self.available.saturating_sub(length);
|
||||||
@ -175,9 +172,7 @@ impl LinearLayout {
|
|||||||
|
|
||||||
/// Returns a mutable reference to a child.
|
/// Returns a mutable reference to a child.
|
||||||
pub fn get_child_mut(&mut self, i: usize) -> Option<&mut View> {
|
pub fn get_child_mut(&mut self, i: usize) -> Option<&mut View> {
|
||||||
self.children
|
self.children.get_mut(i).map(|child| &mut *child.view)
|
||||||
.get_mut(i)
|
|
||||||
.map(|child| &mut *child.view)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the cache can be used, return the cached size.
|
// If the cache can be used, return the cached size.
|
||||||
@ -226,27 +221,21 @@ impl LinearLayout {
|
|||||||
} else {
|
} else {
|
||||||
self.children.len()
|
self.children.len()
|
||||||
};
|
};
|
||||||
Box::new(
|
Box::new(self.children[..end].iter_mut().enumerate().rev())
|
||||||
self.children[..end]
|
|
||||||
.iter_mut()
|
|
||||||
.enumerate()
|
|
||||||
.rev(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn move_focus(&mut self, source: direction::Direction) -> EventResult {
|
fn move_focus(&mut self, source: direction::Direction) -> EventResult {
|
||||||
let i = if let Some(i) = source.relative(self.orientation).and_then(
|
let i = if let Some(i) =
|
||||||
|rel| {
|
source.relative(self.orientation).and_then(|rel| {
|
||||||
// The iterator starts at the focused element.
|
// The iterator starts at the focused element.
|
||||||
// We don't want that one.
|
// We don't want that one.
|
||||||
self.iter_mut(true, rel)
|
self.iter_mut(true, rel)
|
||||||
.skip(1)
|
.skip(1)
|
||||||
.filter_map(|p| try_focus(p, source))
|
.filter_map(|p| try_focus(p, source))
|
||||||
.next()
|
.next()
|
||||||
},
|
}) {
|
||||||
) {
|
|
||||||
i
|
i
|
||||||
} else {
|
} else {
|
||||||
return EventResult::Ignored;
|
return EventResult::Ignored;
|
||||||
@ -291,9 +280,7 @@ impl LinearLayout {
|
|||||||
let child_size = item.child.size.get(self.orientation);
|
let child_size = item.child.size.get(self.orientation);
|
||||||
|
|
||||||
if (item.offset + child_size > position)
|
if (item.offset + child_size > position)
|
||||||
&& item.child
|
&& item.child.view.take_focus(direction::Direction::none())
|
||||||
.view
|
|
||||||
.take_focus(direction::Direction::none())
|
|
||||||
{
|
{
|
||||||
// eprintln!("It's a match!");
|
// eprintln!("It's a match!");
|
||||||
self.focus = i;
|
self.focus = i;
|
||||||
@ -359,9 +346,7 @@ impl View for LinearLayout {
|
|||||||
// Every item has the same size orthogonal to the layout
|
// Every item has the same size orthogonal to the layout
|
||||||
item.child.size.set_axis_from(o.swap(), &size);
|
item.child.size.set_axis_from(o.swap(), &size);
|
||||||
|
|
||||||
item.child
|
item.child.view.layout(size.with_axis(o, item.length));
|
||||||
.view
|
|
||||||
.layout(size.with_axis(o, item.length));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -438,11 +423,7 @@ impl View for LinearLayout {
|
|||||||
let mut overweight: Vec<(usize, usize)> = ideal_sizes
|
let mut overweight: Vec<(usize, usize)> = ideal_sizes
|
||||||
.iter()
|
.iter()
|
||||||
.map(|v| self.orientation.get(v))
|
.map(|v| self.orientation.get(v))
|
||||||
.zip(
|
.zip(min_sizes.iter().map(|v| self.orientation.get(v)))
|
||||||
min_sizes
|
|
||||||
.iter()
|
|
||||||
.map(|v| self.orientation.get(v)),
|
|
||||||
)
|
|
||||||
.map(|(a, b)| a.saturating_sub(b))
|
.map(|(a, b)| a.saturating_sub(b))
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.collect();
|
.collect();
|
||||||
@ -529,9 +510,7 @@ impl View for LinearLayout {
|
|||||||
);
|
);
|
||||||
let item = iterator.nth(self.focus).unwrap();
|
let item = iterator.nth(self.focus).unwrap();
|
||||||
let offset = self.orientation.make_vec(item.offset, 0);
|
let offset = self.orientation.make_vec(item.offset, 0);
|
||||||
item.child
|
item.child.view.on_event(event.relativized(offset))
|
||||||
.view
|
|
||||||
.on_event(event.relativized(offset))
|
|
||||||
};
|
};
|
||||||
match result {
|
match result {
|
||||||
EventResult::Ignored => match event {
|
EventResult::Ignored => match event {
|
||||||
@ -574,8 +553,7 @@ impl View for LinearLayout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn call_on_any<'a>(
|
fn call_on_any<'a>(
|
||||||
&mut self, selector: &Selector,
|
&mut self, selector: &Selector, mut callback: AnyCb<'a>
|
||||||
mut callback: Box<FnMut(&mut Any) + 'a>,
|
|
||||||
) {
|
) {
|
||||||
for child in &mut self.children {
|
for child in &mut self.children {
|
||||||
child
|
child
|
||||||
|
@ -2,9 +2,8 @@ use Cursive;
|
|||||||
use Printer;
|
use Printer;
|
||||||
use With;
|
use With;
|
||||||
use direction;
|
use direction;
|
||||||
use event::{Callback, Event, EventResult, Key, MouseButton, MouseEvent};
|
use event::{AnyCb, Callback, Event, EventResult, Key, MouseButton, MouseEvent};
|
||||||
use rect::Rect;
|
use rect::Rect;
|
||||||
use std::any::Any;
|
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use unicode_width::UnicodeWidthStr;
|
use unicode_width::UnicodeWidthStr;
|
||||||
use vec::Vec2;
|
use vec::Vec2;
|
||||||
@ -94,10 +93,8 @@ impl ListView {
|
|||||||
/// Adds a view to the end of the list.
|
/// Adds a view to the end of the list.
|
||||||
pub fn add_child<V: View + 'static>(&mut self, label: &str, mut view: V) {
|
pub fn add_child<V: View + 'static>(&mut self, label: &str, mut view: V) {
|
||||||
view.take_focus(direction::Direction::none());
|
view.take_focus(direction::Direction::none());
|
||||||
self.children.push(ListChild::Row(
|
self.children
|
||||||
label.to_string(),
|
.push(ListChild::Row(label.to_string(), Box::new(view)));
|
||||||
Box::new(view),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Removes all children from this view.
|
/// Removes all children from this view.
|
||||||
@ -169,12 +166,7 @@ impl ListView {
|
|||||||
} else {
|
} else {
|
||||||
self.children.len()
|
self.children.len()
|
||||||
};
|
};
|
||||||
Box::new(
|
Box::new(self.children[..end].iter_mut().enumerate().rev())
|
||||||
self.children[..end]
|
|
||||||
.iter_mut()
|
|
||||||
.enumerate()
|
|
||||||
.rev(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -313,8 +305,7 @@ impl View for ListView {
|
|||||||
|
|
||||||
fn layout(&mut self, size: Vec2) {
|
fn layout(&mut self, size: Vec2) {
|
||||||
self.last_size = size;
|
self.last_size = size;
|
||||||
self.scrollbase
|
self.scrollbase.set_heights(size.y, self.children.len());
|
||||||
.set_heights(size.y, self.children.len());
|
|
||||||
|
|
||||||
// We'll show 2 columns: the labels, and the views.
|
// We'll show 2 columns: the labels, and the views.
|
||||||
let label_width = self.children
|
let label_width = self.children
|
||||||
@ -325,21 +316,14 @@ impl View for ListView {
|
|||||||
.unwrap_or(0);
|
.unwrap_or(0);
|
||||||
|
|
||||||
let spacing = 1;
|
let spacing = 1;
|
||||||
let scrollbar_width = if self.children.len() > size.y {
|
let scrollbar_width = if self.children.len() > size.y { 2 } else { 0 };
|
||||||
2
|
|
||||||
} else {
|
|
||||||
0
|
|
||||||
};
|
|
||||||
|
|
||||||
let available = size.x
|
let available = size.x
|
||||||
.saturating_sub(label_width + spacing + scrollbar_width);
|
.saturating_sub(label_width + spacing + scrollbar_width);
|
||||||
|
|
||||||
debug!("Available: {}", available);
|
debug!("Available: {}", available);
|
||||||
|
|
||||||
for child in self.children
|
for child in self.children.iter_mut().filter_map(ListChild::view) {
|
||||||
.iter_mut()
|
|
||||||
.filter_map(ListChild::view)
|
|
||||||
{
|
|
||||||
child.layout(Vec2::new(available, 1));
|
child.layout(Vec2::new(available, 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -358,8 +342,7 @@ impl View for ListView {
|
|||||||
} if position
|
} if position
|
||||||
.checked_sub(offset)
|
.checked_sub(offset)
|
||||||
.map(|position| {
|
.map(|position| {
|
||||||
self.scrollbase
|
self.scrollbase.start_drag(position, self.last_size.x)
|
||||||
.start_drag(position, self.last_size.x)
|
|
||||||
})
|
})
|
||||||
.unwrap_or(false) =>
|
.unwrap_or(false) =>
|
||||||
{
|
{
|
||||||
@ -394,8 +377,7 @@ impl View for ListView {
|
|||||||
if let ListChild::Row(_, ref mut view) = self.children[self.focus] {
|
if let ListChild::Row(_, ref mut view) = self.children[self.focus] {
|
||||||
// If self.focus < self.scrollbase.start_line, it means the focus is not
|
// If self.focus < self.scrollbase.start_line, it means the focus is not
|
||||||
// in view. Something's fishy, so don't send the event.
|
// in view. Something's fishy, so don't send the event.
|
||||||
if let Some(y) = self.focus
|
if let Some(y) = self.focus.checked_sub(self.scrollbase.start_line)
|
||||||
.checked_sub(self.scrollbase.start_line)
|
|
||||||
{
|
{
|
||||||
let offset = (labels_width + 1, y);
|
let offset = (labels_width + 1, y);
|
||||||
let result = view.on_event(event.relativized(offset));
|
let result = view.on_event(event.relativized(offset));
|
||||||
@ -419,10 +401,12 @@ impl View for ListView {
|
|||||||
Event::Key(Key::PageDown) => {
|
Event::Key(Key::PageDown) => {
|
||||||
self.move_focus(10, direction::Direction::up())
|
self.move_focus(10, direction::Direction::up())
|
||||||
}
|
}
|
||||||
Event::Key(Key::Home) | Event::Ctrl(Key::Home) => self.move_focus(
|
Event::Key(Key::Home) | Event::Ctrl(Key::Home) => {
|
||||||
usize::max_value(),
|
self.move_focus(
|
||||||
direction::Direction::back(),
|
usize::max_value(),
|
||||||
),
|
direction::Direction::back(),
|
||||||
|
)
|
||||||
|
}
|
||||||
Event::Key(Key::End) | Event::Ctrl(Key::End) => self.move_focus(
|
Event::Key(Key::End) | Event::Ctrl(Key::End) => self.move_focus(
|
||||||
usize::max_value(),
|
usize::max_value(),
|
||||||
direction::Direction::front(),
|
direction::Direction::front(),
|
||||||
@ -472,13 +456,9 @@ impl View for ListView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn call_on_any<'a>(
|
fn call_on_any<'a>(
|
||||||
&mut self, selector: &Selector,
|
&mut self, selector: &Selector, mut callback: AnyCb<'a>
|
||||||
mut callback: Box<FnMut(&mut Any) + 'a>,
|
|
||||||
) {
|
) {
|
||||||
for view in self.children
|
for view in self.children.iter_mut().filter_map(ListChild::view) {
|
||||||
.iter_mut()
|
|
||||||
.filter_map(ListChild::view)
|
|
||||||
{
|
|
||||||
view.call_on_any(selector, Box::new(|any| callback(any)));
|
view.call_on_any(selector, Box::new(|any| callback(any)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,14 +3,15 @@ use view::View;
|
|||||||
use view::ViewWrapper;
|
use view::ViewWrapper;
|
||||||
|
|
||||||
/// Wrapper around a view that remembers its size.
|
/// Wrapper around a view that remembers its size.
|
||||||
pub struct SizedView<T: View> {
|
pub struct SizedView<T> {
|
||||||
/// Wrapped view.
|
/// Wrapped view.
|
||||||
pub view: T,
|
pub view: T,
|
||||||
/// Cached size from the last layout() call.
|
/// Cached size from the last layout() call.
|
||||||
pub size: Vec2,
|
pub size: Vec2,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: View> SizedView<T> {
|
impl<T> SizedView<T> {
|
||||||
|
|
||||||
/// Wraps the given view.
|
/// Wraps the given view.
|
||||||
pub fn new(view: T) -> Self {
|
pub fn new(view: T) -> Self {
|
||||||
SizedView {
|
SizedView {
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
use Printer;
|
use Printer;
|
||||||
use With;
|
use With;
|
||||||
use direction::Direction;
|
use direction::Direction;
|
||||||
use event::{Event, EventResult};
|
use event::{AnyCb, Event, EventResult};
|
||||||
use std::any::Any;
|
|
||||||
use std::cell;
|
use std::cell;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use theme::ColorStyle;
|
use theme::ColorStyle;
|
||||||
@ -65,13 +64,9 @@ impl<T: View> ChildWrapper<T> {
|
|||||||
fn unwrap(self) -> T {
|
fn unwrap(self) -> T {
|
||||||
match self {
|
match self {
|
||||||
// ShadowView::into_inner and Layer::into_inner can never fail.
|
// ShadowView::into_inner and Layer::into_inner can never fail.
|
||||||
ChildWrapper::Shadow(shadow) => shadow
|
ChildWrapper::Shadow(shadow) => {
|
||||||
.into_inner()
|
shadow.into_inner().ok().unwrap().into_inner().ok().unwrap()
|
||||||
.ok()
|
}
|
||||||
.unwrap()
|
|
||||||
.into_inner()
|
|
||||||
.ok()
|
|
||||||
.unwrap(),
|
|
||||||
ChildWrapper::Plain(layer) => layer.into_inner().ok().unwrap(),
|
ChildWrapper::Plain(layer) => layer.into_inner().ok().unwrap(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -134,9 +129,7 @@ impl<T: View> View for ChildWrapper<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call_on_any<'a>(
|
fn call_on_any<'a>(&mut self, selector: &Selector, callback: AnyCb<'a>) {
|
||||||
&mut self, selector: &Selector, callback: Box<FnMut(&mut Any) + 'a>
|
|
||||||
) {
|
|
||||||
match *self {
|
match *self {
|
||||||
ChildWrapper::Shadow(ref mut v) => {
|
ChildWrapper::Shadow(ref mut v) => {
|
||||||
v.call_on_any(selector, callback)
|
v.call_on_any(selector, callback)
|
||||||
@ -216,9 +209,7 @@ impl StackView {
|
|||||||
/// Returns a reference to the layer at the given position.
|
/// Returns a reference to the layer at the given position.
|
||||||
pub fn get(&self, pos: LayerPosition) -> Option<&View> {
|
pub fn get(&self, pos: LayerPosition) -> Option<&View> {
|
||||||
let i = self.get_index(pos);
|
let i = self.get_index(pos);
|
||||||
self.layers
|
self.layers.get(i).map(|child| child.view.get_inner())
|
||||||
.get(i)
|
|
||||||
.map(|child| child.view.get_inner())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a mutable reference to the layer at the given position.
|
/// Returns a mutable reference to the layer at the given position.
|
||||||
@ -331,10 +322,7 @@ impl StackView {
|
|||||||
|
|
||||||
/// Returns the size for each layer in this view.
|
/// Returns the size for each layer in this view.
|
||||||
pub fn layer_sizes(&self) -> Vec<Vec2> {
|
pub fn layer_sizes(&self) -> Vec<Vec2> {
|
||||||
self.layers
|
self.layers.iter().map(|layer| layer.size).collect()
|
||||||
.iter()
|
|
||||||
.map(|layer| layer.size)
|
|
||||||
.collect()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_index(&self, pos: LayerPosition) -> usize {
|
fn get_index(&self, pos: LayerPosition) -> usize {
|
||||||
@ -535,8 +523,7 @@ impl View for StackView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn call_on_any<'a>(
|
fn call_on_any<'a>(
|
||||||
&mut self, selector: &Selector,
|
&mut self, selector: &Selector, mut callback: AnyCb<'a>
|
||||||
mut callback: Box<FnMut(&mut Any) + 'a>,
|
|
||||||
) {
|
) {
|
||||||
for layer in &mut self.layers {
|
for layer in &mut self.layers {
|
||||||
layer
|
layer
|
||||||
|
Loading…
Reference in New Issue
Block a user