diff --git a/src/vec.rs b/src/vec.rs index 632471c..5f8716e 100644 --- a/src/vec.rs +++ b/src/vec.rs @@ -242,7 +242,7 @@ impl Mul for XY { /// Four values representing each direction. #[derive(Clone, Copy)] -pub struct Vec4 { +pub struct Margins { /// Left margin pub left: usize, /// Right margin @@ -253,10 +253,10 @@ pub struct Vec4 { pub bottom: usize, } -impl Vec4 { - /// Creates a new Vec4. +impl Margins { + /// Creates a new Margins. pub fn new(left: usize, right: usize, top: usize, bottom: usize) -> Self { - Vec4 { + Margins { left: left, right: right, top: top, @@ -290,38 +290,38 @@ impl Vec4 { } } -impl From<(usize, usize, usize, usize)> for Vec4 { - fn from((left, right, top, bottom): (usize, usize, usize, usize)) -> Vec4 { - Vec4::new(left, right, top, bottom) +impl From<(usize, usize, usize, usize)> for Margins { + fn from((left, right, top, bottom): (usize, usize, usize, usize)) -> Margins { + Margins::new(left, right, top, bottom) } } -impl From<(i32, i32, i32, i32)> for Vec4 { - fn from((left, right, top, bottom): (i32, i32, i32, i32)) -> Vec4 { +impl From<(i32, i32, i32, i32)> for Margins { + fn from((left, right, top, bottom): (i32, i32, i32, i32)) -> Margins { (left as usize, right as usize, top as usize, bottom as usize).into() } } -impl From<((i32, i32), (i32, i32))> for Vec4 { - fn from(((left, right), (top, bottom)): ((i32, i32), (i32, i32))) -> Vec4 { +impl From<((i32, i32), (i32, i32))> for Margins { + fn from(((left, right), (top, bottom)): ((i32, i32), (i32, i32))) -> Margins { (left, right, top, bottom).into() } } -impl From<((usize, usize), (usize, usize))> for Vec4 { +impl From<((usize, usize), (usize, usize))> for Margins { fn from( ((left, right), (top, bottom)): ((usize, usize), (usize, usize)) - ) -> Vec4 { + ) -> Margins { (left, right, top, bottom).into() } } -impl> Add for Vec4 { - type Output = Vec4; +impl> Add for Margins { + type Output = Margins; - fn add(self, other: T) -> Vec4 { + fn add(self, other: T) -> Margins { let ov = other.into(); - Vec4 { + Margins { left: self.left + ov.left, right: self.right + ov.right, top: self.top + ov.top, @@ -330,13 +330,13 @@ impl> Add for Vec4 { } } -impl> Sub for Vec4 { - type Output = Vec4; +impl> Sub for Margins { + type Output = Margins; - fn sub(self, other: T) -> Vec4 { + fn sub(self, other: T) -> Margins { let ov = other.into(); - Vec4 { + Margins { left: self.left - ov.left, right: self.right - ov.right, top: self.top - ov.top, @@ -345,11 +345,11 @@ impl> Sub for Vec4 { } } -impl Div for Vec4 { - type Output = Vec4; +impl Div for Margins { + type Output = Margins; - fn div(self, other: usize) -> Vec4 { - Vec4 { + fn div(self, other: usize) -> Margins { + Margins { left: self.left / other, right: self.right / other, top: self.top / other, @@ -358,11 +358,11 @@ impl Div for Vec4 { } } -impl Mul for Vec4 { - type Output = Vec4; +impl Mul for Margins { + type Output = Margins; - fn mul(self, other: usize) -> Vec4 { - Vec4 { + fn mul(self, other: usize) -> Margins { + Margins { left: self.left * other, right: self.right * other, top: self.top * other, diff --git a/src/view/view.rs b/src/view/view.rs index 8d03c06..b6221db 100644 --- a/src/view/view.rs +++ b/src/view/view.rs @@ -9,24 +9,21 @@ use view::{AnyView, Selector}; /// /// This is what you should implement to define a custom View. pub trait View: Any + AnyView { - /// Called when a key was pressed. - /// - /// Default implementation just ignores it. - fn on_event(&mut self, Event) -> EventResult { - EventResult::Ignored - } - /// Returns the minimum size the view requires with the given restrictions. + /// Draws the view with the given printer (includes bounds) and focus. /// - /// If the view is flexible (it has multiple size options), it can try - /// to return one that fits the given `constraint`. - /// It's also fine to ignore it and return a fixed value. + /// This is the only *required* method to implement. + fn draw(&self, printer: &Printer); + + /// Called once the size for this view has been decided. /// - /// Default implementation always return `(1,1)`. - fn required_size(&mut self, constraint: Vec2) -> Vec2 { - let _ = constraint; - Vec2::new(1, 1) - } + /// It can be used to pre-compute the configuration of child views. + /// + /// View groups should propagate the information to their children. + /// + /// At this point, the given size is final and cannot be negociated. + /// It is guaranteed to be the size available for the call to `draw()`. + fn layout(&mut self, Vec2) {} /// Returns `true` if the view content changed since last layout phase. /// @@ -43,13 +40,29 @@ pub trait View: Any + AnyView { true } - /// Called once the size for this view has been decided, + /// Returns the minimum size the view requires with the given restrictions. /// - /// View groups should propagate the information to their children. - fn layout(&mut self, Vec2) {} + /// This is the main way a view communicate its size to its parent. + /// + /// If the view is flexible (it has multiple size options), it can try + /// to return one that fits the given `constraint`. + /// It's also fine to ignore it and return a fixed value. + /// + /// Default implementation always return `(1,1)`. + fn required_size(&mut self, constraint: Vec2) -> Vec2 { + let _ = constraint; + Vec2::new(1, 1) + } + + /// Called when an event is received (key press, mouse event, ...). + /// + /// You can return an `EventResult`, with an optional callback to be run. + /// + /// Default implementation just ignores it. + fn on_event(&mut self, Event) -> EventResult { + EventResult::Ignored + } - /// Draws the view with the given printer (includes bounds) and focus. - fn draw(&self, printer: &Printer); /// Runs a closure on the view identified by the given selector. /// diff --git a/src/views/dialog.rs b/src/views/dialog.rs index 076b3c6..063982b 100644 --- a/src/views/dialog.rs +++ b/src/views/dialog.rs @@ -9,7 +9,7 @@ use std::cell::Cell; use std::cmp::max; use theme::ColorStyle; use unicode_width::UnicodeWidthStr; -use vec::{Vec2, Vec4}; +use vec::{Vec2, Margins}; use view::{Selector, View}; use views::{Button, DummyView, SizedView, TextView, ViewBox}; @@ -65,10 +65,10 @@ pub struct Dialog { buttons: Vec, // Padding around the inner view. - padding: Vec4, + padding: Margins, // Borders around everything. - borders: Vec4, + borders: Margins, // The current element in focus focus: DialogFocus, @@ -95,8 +95,8 @@ impl Dialog { title: String::new(), title_position: HAlign::Center, focus: DialogFocus::Content, - padding: Vec4::new(1, 1, 0, 0), - borders: Vec4::new(1, 1, 1, 1), + padding: Margins::new(1, 1, 0, 0), + borders: Margins::new(1, 1, 1, 1), align: Align::top_right(), } } @@ -214,7 +214,7 @@ impl Dialog { } /// Sets the padding in the dialog (around content and buttons). - pub fn padding>(mut self, padding: T) -> Self { + pub fn padding>(mut self, padding: T) -> Self { self.padding = padding.into(); self