Add View::as_any and View::as_any_mut

This commit is contained in:
Alexandre Bury 2018-01-22 09:20:32 -08:00
parent 208b812976
commit 1551fbb543
21 changed files with 62 additions and 0 deletions

View File

@ -1,3 +1,4 @@
#[macro_use]
extern crate cursive;
use cursive::{Cursive, Printer};
@ -30,6 +31,8 @@ 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() {

View File

@ -1,3 +1,4 @@
#[macro_use]
extern crate cursive;
use cursive::{Cursive, Printer};
@ -80,6 +81,8 @@ impl BufferView {
}
impl View for BufferView {
view_any!();
fn layout(&mut self, _: Vec2) {
// Before drawing, we'll want to update the buffer
self.update();

View File

@ -35,6 +35,15 @@
//! 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 +82,12 @@ 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.
///
/// If the view is flexible (it has multiple size options), it can try

View File

@ -119,6 +119,8 @@ 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);
}

View File

@ -126,6 +126,8 @@ impl Button {
}
impl View for Button {
view_any!();
fn draw(&self, printer: &Printer) {
if printer.size.x == 0 {
return;

View File

@ -173,6 +173,8 @@ impl<T> Canvas<T> {
}
impl<T: 'static> View for Canvas<T> {
view_any!();
fn draw(&self, printer: &Printer) {
(self.draw)(&self.state, printer);
}

View File

@ -105,6 +105,8 @@ impl Checkbox {
}
impl View for Checkbox {
view_any!();
fn required_size(&mut self, _: Vec2) -> Vec2 {
Vec2::new(3, 1)
}

View File

@ -423,6 +423,8 @@ 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) {

View File

@ -7,5 +7,7 @@ use view::View;
pub struct DummyView;
impl View for DummyView {
view_any!();
fn draw(&self, _: &Printer) {}
}

View File

@ -434,6 +434,8 @@ fn make_small_stars(length: usize) -> &'static str {
}
impl View for EditView {
view_any!();
fn draw(&self, printer: &Printer) {
assert_eq!(
printer.size.x,

View File

@ -297,6 +297,8 @@ fn try_focus(
}
impl View for LinearLayout {
view_any!();
fn draw(&self, printer: &Printer) {
// Use pre-computed sizes
// eprintln!("Pre loop!");

View File

@ -261,6 +261,9 @@ fn try_focus(
}
impl View for ListView {
view_any!();
fn draw(&self, printer: &Printer) {
if self.children.is_empty() {
return;

View File

@ -199,6 +199,8 @@ impl MenuPopup {
}
impl View for MenuPopup {
view_any!();
fn draw(&self, printer: &Printer) {
if !printer.size.fits((2, 2)) {
return;

View File

@ -259,6 +259,8 @@ 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| {

View File

@ -193,6 +193,8 @@ impl ProgressBar {
}
impl View for ProgressBar {
view_any!();
fn draw(&self, printer: &Printer) {
// Now, the bar itself...
let available = printer.size.x;

View File

@ -154,6 +154,9 @@ impl<T> RadioButton<T> {
}
impl<T: 'static> View for RadioButton<T> {
view_any!();
fn required_size(&mut self, _: Vec2) -> Vec2 {
self.req_size()
}

View File

@ -570,6 +570,9 @@ impl SelectView<String> {
}
impl<T: 'static> View for SelectView<T> {
view_any!();
fn draw(&self, printer: &Printer) {
self.last_offset.set(printer.offset);

View File

@ -112,6 +112,8 @@ impl SliderView {
}
impl View for SliderView {
view_any!();
fn draw(&self, printer: &Printer) {
match self.orientation {
Orientation::Vertical => {

View File

@ -71,6 +71,8 @@ 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),
@ -322,6 +324,8 @@ 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| {

View File

@ -396,6 +396,8 @@ 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);

View File

@ -448,6 +448,8 @@ 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.