mirror of
https://github.com/FliegendeWurst/cursive.git
synced 2024-11-23 17:35:00 +00:00
Move View::as_any
to separate trait AnyView
This commit is contained in:
parent
1551fbb543
commit
98aff39904
@ -31,8 +31,6 @@ impl KeyCodeView {
|
||||
}
|
||||
|
||||
impl View for KeyCodeView {
|
||||
view_any!();
|
||||
|
||||
fn draw(&self, printer: &Printer) {
|
||||
// We simply draw every event from the history.
|
||||
for (y, line) in self.history.iter().enumerate() {
|
||||
|
@ -81,8 +81,6 @@ impl BufferView {
|
||||
}
|
||||
|
||||
impl View for BufferView {
|
||||
view_any!();
|
||||
|
||||
fn layout(&mut self, _: Vec2) {
|
||||
// Before drawing, we'll want to update the buffer
|
||||
self.update();
|
||||
|
@ -9,7 +9,7 @@ use std::path::Path;
|
||||
use std::sync::mpsc;
|
||||
use theme;
|
||||
use vec::Vec2;
|
||||
use view::{self, Finder, View};
|
||||
use view::{self, AnyView, Finder, View};
|
||||
use views;
|
||||
|
||||
/// Identifies a screen in the cursive root.
|
||||
@ -418,7 +418,7 @@ impl Cursive {
|
||||
}
|
||||
|
||||
/// Convenient method to remove a layer from the current screen.
|
||||
pub fn pop_layer(&mut self) -> Option<Box<View>> {
|
||||
pub fn pop_layer(&mut self) -> Option<Box<AnyView>> {
|
||||
let result = self.screen_mut().pop_layer();
|
||||
self.clear();
|
||||
result
|
||||
|
@ -35,15 +35,6 @@
|
||||
//! no matter what the request is. This means calling `View::layout()` with
|
||||
//! a size returned by `required_size` is **never** an error.
|
||||
|
||||
/// Helper macro to implement `View::as_any` and `View::as_any_mut`
|
||||
#[macro_export]
|
||||
macro_rules! view_any {
|
||||
() => {
|
||||
fn as_any(&self) -> &::std::any::Any { self }
|
||||
fn as_any_mut(&mut self) -> &mut ::std::any::Any { self }
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_use]
|
||||
mod view_wrapper;
|
||||
|
||||
@ -73,6 +64,23 @@ use std::any::Any;
|
||||
use vec::Vec2;
|
||||
use views::IdView;
|
||||
|
||||
/// A view that can be downcasted to its concrete type.
|
||||
pub trait AnyView: View {
|
||||
/// Downcast self to a `Any`.
|
||||
fn as_any(&self) -> &Any;
|
||||
|
||||
/// Downcast self to a mutable `Any`.
|
||||
fn as_any_mut(&mut self) -> &mut Any;
|
||||
}
|
||||
|
||||
impl <T: View> AnyView for T {
|
||||
/// Downcast self to a `Any`.
|
||||
fn as_any(&self) -> &Any { self }
|
||||
|
||||
/// Downcast self to a mutable `Any`.
|
||||
fn as_any_mut(&mut self) -> &mut Any { self }
|
||||
}
|
||||
|
||||
/// Main trait defining a view behaviour.
|
||||
pub trait View: Any {
|
||||
/// Called when a key was pressed.
|
||||
@ -82,11 +90,6 @@ pub trait View: Any {
|
||||
EventResult::Ignored
|
||||
}
|
||||
|
||||
/// Downcast self to a `Any`.
|
||||
fn as_any(&self) -> &Any;
|
||||
|
||||
/// Downcast self to a mutable `Any`.
|
||||
fn as_any_mut(&mut self) -> &mut Any;
|
||||
|
||||
/// Returns the minimum size the view requires with the given restrictions.
|
||||
///
|
||||
|
@ -78,7 +78,9 @@ pub trait ViewWrapper: 'static {
|
||||
|
||||
/// Wraps the `find` method.
|
||||
fn wrap_call_on_any<'a>(
|
||||
&mut self, selector: &Selector, callback: Box<FnMut(&mut Any) + 'a>
|
||||
&mut self,
|
||||
selector: &Selector,
|
||||
callback: Box<FnMut(&mut Any) + 'a>,
|
||||
) {
|
||||
self.with_view_mut(|v| v.call_on_any(selector, callback));
|
||||
}
|
||||
@ -98,8 +100,12 @@ pub trait ViewWrapper: 'static {
|
||||
// Some types easily implement ViewWrapper.
|
||||
// This includes Box<T: View>
|
||||
use std::ops::{Deref, DerefMut};
|
||||
impl<U: View + ?Sized, T: Deref<Target = U> + DerefMut + 'static> ViewWrapper
|
||||
for T {
|
||||
|
||||
impl<U, T> ViewWrapper for T
|
||||
where
|
||||
U: View + ?Sized,
|
||||
T: Deref<Target = U> + DerefMut + 'static,
|
||||
{
|
||||
type V = U;
|
||||
|
||||
fn with_view<F, R>(&self, f: F) -> Option<R>
|
||||
@ -119,8 +125,6 @@ impl<U: View + ?Sized, T: Deref<Target = U> + DerefMut + 'static> ViewWrapper
|
||||
|
||||
// The main point of implementing ViewWrapper is to have View for free.
|
||||
impl<T: ViewWrapper> View for T {
|
||||
view_any!();
|
||||
|
||||
fn draw(&self, printer: &Printer) {
|
||||
self.wrap_draw(printer);
|
||||
}
|
||||
@ -142,7 +146,9 @@ impl<T: ViewWrapper> View for T {
|
||||
}
|
||||
|
||||
fn call_on_any<'a>(
|
||||
&mut self, selector: &Selector, callback: Box<FnMut(&mut Any) + 'a>
|
||||
&mut self,
|
||||
selector: &Selector,
|
||||
callback: Box<FnMut(&mut Any) + 'a>,
|
||||
) {
|
||||
self.wrap_call_on_any(selector, callback)
|
||||
}
|
||||
|
@ -126,8 +126,6 @@ impl Button {
|
||||
}
|
||||
|
||||
impl View for Button {
|
||||
view_any!();
|
||||
|
||||
fn draw(&self, printer: &Printer) {
|
||||
if printer.size.x == 0 {
|
||||
return;
|
||||
|
@ -173,8 +173,6 @@ impl<T> Canvas<T> {
|
||||
}
|
||||
|
||||
impl<T: 'static> View for Canvas<T> {
|
||||
view_any!();
|
||||
|
||||
fn draw(&self, printer: &Printer) {
|
||||
(self.draw)(&self.state, printer);
|
||||
}
|
||||
|
@ -105,8 +105,6 @@ impl Checkbox {
|
||||
}
|
||||
|
||||
impl View for Checkbox {
|
||||
view_any!();
|
||||
|
||||
fn required_size(&mut self, _: Vec2) -> Vec2 {
|
||||
Vec2::new(3, 1)
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ use std::cmp::max;
|
||||
use theme::ColorStyle;
|
||||
use unicode_width::UnicodeWidthStr;
|
||||
use vec::{Vec2, Vec4};
|
||||
use view::{Selector, View};
|
||||
use view::{AnyView, Selector, View};
|
||||
use views::{Button, DummyView, SizedView, TextView};
|
||||
|
||||
#[derive(PartialEq)]
|
||||
@ -53,7 +53,7 @@ pub struct Dialog {
|
||||
title_position: HAlign,
|
||||
|
||||
// The actual inner view.
|
||||
content: SizedView<Box<View>>,
|
||||
content: SizedView<Box<AnyView>>,
|
||||
|
||||
// Optional list of buttons under the main view.
|
||||
// Include the top-left corner.
|
||||
@ -423,8 +423,6 @@ impl Dialog {
|
||||
}
|
||||
|
||||
impl View for Dialog {
|
||||
view_any!();
|
||||
|
||||
fn draw(&self, printer: &Printer) {
|
||||
// This will be the buttons_height used by the buttons.
|
||||
let buttons_height = match self.draw_buttons(printer) {
|
||||
|
@ -7,7 +7,5 @@ use view::View;
|
||||
pub struct DummyView;
|
||||
|
||||
impl View for DummyView {
|
||||
view_any!();
|
||||
|
||||
fn draw(&self, _: &Printer) {}
|
||||
}
|
||||
|
@ -434,8 +434,6 @@ fn make_small_stars(length: usize) -> &'static str {
|
||||
}
|
||||
|
||||
impl View for EditView {
|
||||
view_any!();
|
||||
|
||||
fn draw(&self, printer: &Printer) {
|
||||
assert_eq!(
|
||||
printer.size.x,
|
||||
|
@ -7,8 +7,7 @@ use std::any::Any;
|
||||
use std::cmp::min;
|
||||
use std::ops::Deref;
|
||||
use vec::Vec2;
|
||||
use view::{Selector, SizeCache};
|
||||
use view::View;
|
||||
use view::{AnyView, View, Selector, SizeCache};
|
||||
|
||||
/// Arranges its children linearly according to its orientation.
|
||||
pub struct LinearLayout {
|
||||
@ -20,7 +19,7 @@ pub struct LinearLayout {
|
||||
}
|
||||
|
||||
struct Child {
|
||||
view: Box<View>,
|
||||
view: Box<AnyView>,
|
||||
// The last result from the child's required_size
|
||||
// Doesn't have to be what the child actually gets.
|
||||
size: Vec2,
|
||||
@ -34,7 +33,7 @@ impl Child {
|
||||
self.size
|
||||
}
|
||||
|
||||
fn as_view(&self) -> &View {
|
||||
fn as_view(&self) -> &AnyView {
|
||||
&*self.view
|
||||
}
|
||||
}
|
||||
@ -161,12 +160,12 @@ impl LinearLayout {
|
||||
}
|
||||
|
||||
/// Returns a reference to a child.
|
||||
pub fn get_child(&self, i: usize) -> Option<&View> {
|
||||
pub fn get_child(&self, i: usize) -> Option<&AnyView> {
|
||||
self.children.get(i).map(|child| &*child.view)
|
||||
}
|
||||
|
||||
/// 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 AnyView> {
|
||||
self.children.get_mut(i).map(|child| &mut *child.view)
|
||||
}
|
||||
|
||||
@ -297,8 +296,6 @@ fn try_focus(
|
||||
}
|
||||
|
||||
impl View for LinearLayout {
|
||||
view_any!();
|
||||
|
||||
fn draw(&self, printer: &Printer) {
|
||||
// Use pre-computed sizes
|
||||
// eprintln!("Pre loop!");
|
||||
|
@ -7,16 +7,14 @@ use std::any::Any;
|
||||
use std::rc::Rc;
|
||||
use unicode_width::UnicodeWidthStr;
|
||||
use vec::Vec2;
|
||||
use view::ScrollBase;
|
||||
use view::Selector;
|
||||
use view::View;
|
||||
use view::{AnyView, ScrollBase, Selector, View};
|
||||
|
||||
/// Represents a child from a [`ListView`].
|
||||
///
|
||||
/// [`ListView`]: struct.ListView.html
|
||||
pub enum ListChild {
|
||||
/// A single row, with a label and a view.
|
||||
Row(String, Box<View>),
|
||||
Row(String, Box<AnyView>),
|
||||
/// A delimiter between groups.
|
||||
Delimiter,
|
||||
}
|
||||
@ -29,7 +27,7 @@ impl ListChild {
|
||||
}
|
||||
}
|
||||
|
||||
fn view(&mut self) -> Option<&mut View> {
|
||||
fn view(&mut self) -> Option<&mut AnyView> {
|
||||
match *self {
|
||||
ListChild::Row(_, ref mut view) => Some(view.as_mut()),
|
||||
_ => None,
|
||||
@ -150,7 +148,9 @@ impl ListView {
|
||||
}
|
||||
|
||||
fn iter_mut<'a>(
|
||||
&'a mut self, from_focus: bool, source: direction::Relative
|
||||
&'a mut self,
|
||||
from_focus: bool,
|
||||
source: direction::Relative,
|
||||
) -> Box<Iterator<Item = (usize, &mut ListChild)> + 'a> {
|
||||
match source {
|
||||
direction::Relative::Front => {
|
||||
@ -174,7 +174,9 @@ impl ListView {
|
||||
}
|
||||
|
||||
fn move_focus(
|
||||
&mut self, n: usize, source: direction::Direction
|
||||
&mut self,
|
||||
n: usize,
|
||||
source: direction::Direction,
|
||||
) -> EventResult {
|
||||
let i = if let Some(i) = source
|
||||
.relative(direction::Orientation::Vertical)
|
||||
@ -248,7 +250,8 @@ impl ListView {
|
||||
}
|
||||
|
||||
fn try_focus(
|
||||
(i, child): (usize, &mut ListChild), source: direction::Direction
|
||||
(i, child): (usize, &mut ListChild),
|
||||
source: direction::Direction,
|
||||
) -> Option<usize> {
|
||||
match *child {
|
||||
ListChild::Delimiter => None,
|
||||
@ -261,9 +264,6 @@ fn try_focus(
|
||||
}
|
||||
|
||||
impl View for ListView {
|
||||
view_any!();
|
||||
|
||||
|
||||
fn draw(&self, printer: &Printer) {
|
||||
if self.children.is_empty() {
|
||||
return;
|
||||
@ -454,7 +454,8 @@ impl View for ListView {
|
||||
}
|
||||
|
||||
fn call_on_any<'a>(
|
||||
&mut self, selector: &Selector,
|
||||
&mut self,
|
||||
selector: &Selector,
|
||||
mut callback: Box<FnMut(&mut Any) + 'a>,
|
||||
) {
|
||||
for view in self.children.iter_mut().filter_map(ListChild::view) {
|
||||
|
@ -199,8 +199,6 @@ impl MenuPopup {
|
||||
}
|
||||
|
||||
impl View for MenuPopup {
|
||||
view_any!();
|
||||
|
||||
fn draw(&self, printer: &Printer) {
|
||||
if !printer.size.fits((2, 2)) {
|
||||
return;
|
||||
|
@ -259,8 +259,6 @@ fn show_child(s: &mut Cursive, offset: Vec2, menu: Rc<MenuTree>) {
|
||||
}
|
||||
|
||||
impl View for Menubar {
|
||||
view_any!();
|
||||
|
||||
fn draw(&self, printer: &Printer) {
|
||||
// Draw the bar at the top
|
||||
printer.with_color(ColorStyle::primary(), |printer| {
|
||||
|
@ -193,8 +193,6 @@ impl ProgressBar {
|
||||
}
|
||||
|
||||
impl View for ProgressBar {
|
||||
view_any!();
|
||||
|
||||
fn draw(&self, printer: &Printer) {
|
||||
// Now, the bar itself...
|
||||
let available = printer.size.x;
|
||||
|
@ -154,9 +154,6 @@ impl<T> RadioButton<T> {
|
||||
}
|
||||
|
||||
impl<T: 'static> View for RadioButton<T> {
|
||||
view_any!();
|
||||
|
||||
|
||||
fn required_size(&mut self, _: Vec2) -> Vec2 {
|
||||
self.req_size()
|
||||
}
|
||||
|
@ -570,8 +570,6 @@ impl SelectView<String> {
|
||||
}
|
||||
|
||||
impl<T: 'static> View for SelectView<T> {
|
||||
view_any!();
|
||||
|
||||
|
||||
fn draw(&self, printer: &Printer) {
|
||||
self.last_offset.set(printer.offset);
|
||||
|
@ -112,8 +112,6 @@ impl SliderView {
|
||||
}
|
||||
|
||||
impl View for SliderView {
|
||||
view_any!();
|
||||
|
||||
fn draw(&self, printer: &Printer) {
|
||||
match self.orientation {
|
||||
Orientation::Vertical => {
|
||||
|
@ -6,7 +6,7 @@ use std::any::Any;
|
||||
use std::ops::Deref;
|
||||
use theme::ColorStyle;
|
||||
use vec::Vec2;
|
||||
use view::{Offset, Position, Selector, View, ViewWrapper};
|
||||
use view::{AnyView, Offset, Position, Selector, View, ViewWrapper};
|
||||
use views::{Layer, ShadowView};
|
||||
|
||||
/// Simple stack of views.
|
||||
@ -71,8 +71,6 @@ impl<T: View> ChildWrapper<T> {
|
||||
|
||||
// TODO: use macros to make this less ugly?
|
||||
impl<T: View> View for ChildWrapper<T> {
|
||||
view_any!();
|
||||
|
||||
fn draw(&self, printer: &Printer) {
|
||||
match *self {
|
||||
ChildWrapper::Shadow(ref v) => v.draw(printer),
|
||||
@ -130,7 +128,7 @@ impl<T: View> View for ChildWrapper<T> {
|
||||
}
|
||||
|
||||
struct Child {
|
||||
view: ChildWrapper<Box<View>>,
|
||||
view: ChildWrapper<Box<AnyView>>,
|
||||
size: Vec2,
|
||||
placement: Placement,
|
||||
|
||||
@ -159,7 +157,7 @@ impl StackView {
|
||||
where
|
||||
T: 'static + View,
|
||||
{
|
||||
let boxed: Box<View> = Box::new(view);
|
||||
let boxed: Box<AnyView> = Box::new(view);
|
||||
self.layers.push(Child {
|
||||
view: ChildWrapper::Plain(Layer::new(boxed)),
|
||||
size: Vec2::zero(),
|
||||
@ -201,7 +199,7 @@ impl StackView {
|
||||
where
|
||||
T: 'static + View,
|
||||
{
|
||||
let boxed: Box<View> = Box::new(view);
|
||||
let boxed: Box<AnyView> = Box::new(view);
|
||||
self.layers.push(Child {
|
||||
// Skip padding for absolute/parent-placed views
|
||||
view: ChildWrapper::Shadow(
|
||||
@ -226,7 +224,7 @@ impl StackView {
|
||||
}
|
||||
|
||||
/// Remove the top-most layer.
|
||||
pub fn pop_layer(&mut self) -> Option<Box<View>> {
|
||||
pub fn pop_layer(&mut self) -> Option<Box<AnyView>> {
|
||||
self.layers.pop().map(|child| child.view.unwrap())
|
||||
}
|
||||
|
||||
@ -324,8 +322,6 @@ impl<R: Deref<Target = Child>, I: Iterator<Item = R>> Iterator
|
||||
}
|
||||
|
||||
impl View for StackView {
|
||||
view_any!();
|
||||
|
||||
fn draw(&self, printer: &Printer) {
|
||||
let last = self.layers.len();
|
||||
printer.with_color(ColorStyle::primary(), |printer| {
|
||||
|
@ -396,8 +396,6 @@ impl TextArea {
|
||||
}
|
||||
|
||||
impl View for TextArea {
|
||||
view_any!();
|
||||
|
||||
fn required_size(&mut self, constraint: Vec2) -> Vec2 {
|
||||
// Make sure our structure is up to date
|
||||
self.soft_compute_rows(constraint);
|
||||
|
@ -448,8 +448,6 @@ impl TextView {
|
||||
}
|
||||
|
||||
impl View for TextView {
|
||||
view_any!();
|
||||
|
||||
fn draw(&self, printer: &Printer) {
|
||||
let h = self.rows.len();
|
||||
// If the content is smaller than the view, align it somewhere.
|
||||
|
Loading…
Reference in New Issue
Block a user