diff --git a/src/views/mod.rs b/src/views/mod.rs index ae7eb49..3248072 100644 --- a/src/views/mod.rs +++ b/src/views/mod.rs @@ -51,6 +51,7 @@ mod list_view; mod menu_popup; mod menubar; mod on_event_view; +mod padded_view; mod panel; mod progress_bar; mod radio; @@ -81,6 +82,7 @@ pub use self::list_view::{ListChild, ListView}; pub use self::menu_popup::MenuPopup; pub use self::menubar::Menubar; pub use self::on_event_view::OnEventView; +pub use self::padded_view::PaddedView; pub use self::panel::Panel; pub use self::progress_bar::ProgressBar; pub use self::radio::{RadioButton, RadioGroup}; diff --git a/src/views/padded_view.rs b/src/views/padded_view.rs new file mode 100644 index 0000000..6df1717 --- /dev/null +++ b/src/views/padded_view.rs @@ -0,0 +1,65 @@ +use event::{Event, EventResult}; +use vec::Vec2; +use view::{Margins, View, ViewWrapper}; +use Printer; + +/// Adds padding to another view. +/// +/// This view wraps another view and adds some padding. +/// +/// The wrapped view will see a reduced space available. +/// +/// # Examples +/// +/// ```rust +/// # use cursive::views::{TextView, PaddedView}; +/// // Adds 2 columns of padding to the left and to the right. +/// let view = PaddedView::new( +/// ((2,2), (0,0)), // ((left, right), (top, bottom)) +/// TextView::new("Padded text") +/// ); +/// ``` +pub struct PaddedView { + view: V, + margins: Margins, +} + +impl PaddedView { + /// Wraps `view` in a new `PaddedView` with the given margins. + pub fn new>(margins: M, view: V) -> Self { + let margins = margins.into(); + PaddedView { view, margins } + } + + /// Sets the margins for this view. + pub fn set_margins>(&mut self, margins: M) { + // TODO: invalidate? + self.margins = margins.into(); + } +} + +impl ViewWrapper for PaddedView { + wrap_impl!(self.view: V); + + fn wrap_required_size(&mut self, req: Vec2) -> Vec2 { + let margins = self.margins.combined(); + self.view.required_size(req.saturating_sub(margins)) + margins + } + + fn wrap_layout(&mut self, size: Vec2) { + let margins = self.margins.combined(); + self.view.layout(size.saturating_sub(margins)); + } + + fn wrap_on_event(&mut self, event: Event) -> EventResult { + let padding = self.margins.top_left(); + self.view.on_event(event.relativized(padding)) + } + + fn wrap_draw(&self, printer: &Printer) { + let top_left = self.margins.top_left(); + let bot_right = self.margins.bot_right(); + let printer = &printer.offset(top_left).shrinked(bot_right); + self.view.draw(printer); + } +} diff --git a/src/views/shadow_view.rs b/src/views/shadow_view.rs index 3d6a0a3..3097356 100644 --- a/src/views/shadow_view.rs +++ b/src/views/shadow_view.rs @@ -11,6 +11,7 @@ pub struct ShadowView { view: T, top_padding: bool, left_padding: bool, + // TODO: invalidate if we change the padding? } impl ShadowView {