diff options
author | rabite <rabite@posteo.de> | 2019-03-09 11:06:13 +0100 |
---|---|---|
committer | rabite <rabite@posteo.de> | 2019-03-09 11:06:13 +0100 |
commit | 5d456539015876c1891bf0ac05b8f7dd3fbe8d57 (patch) | |
tree | 39e2e42cd28773eb9ac785d0430b51f72e6876d6 /src/hbox.rs | |
parent | 6e02ef6486b6660b69136e19c7086e8b2b3eb7ee (diff) |
use enum to allow multiple widget types in hbox
Diffstat (limited to 'src/hbox.rs')
-rw-r--r-- | src/hbox.rs | 91 |
1 files changed, 61 insertions, 30 deletions
diff --git a/src/hbox.rs b/src/hbox.rs index 6a2aa8e..7982333 100644 --- a/src/hbox.rs +++ b/src/hbox.rs @@ -2,12 +2,13 @@ use termion::event::{Event}; use crate::widget::{Widget, WidgetCore}; use crate::coordinates::{Coordinates, Size, Position}; -use crate::fail::{HResult, ErrorLog}; +use crate::fail::{HResult, HError, ErrorLog}; #[derive(PartialEq)] pub struct HBox<T: Widget> { pub core: WidgetCore, pub widgets: Vec<T>, + pub ratios: Option<Vec<usize>>, pub active: Option<usize>, } @@ -16,59 +17,89 @@ impl<T> HBox<T> where T: Widget + PartialEq { pub fn new(core: &WidgetCore) -> HBox<T> { HBox { core: core.clone(), widgets: vec![], + ratios: None, active: None } } - pub fn resize_children(&mut self) { - let coords: Vec<Coordinates> - = self.widgets.iter().map( - |w| - self.calculate_coordinates(w)).collect(); + pub fn resize_children(&mut self) -> HResult<()> { + let len = self.widgets.len(); + if len == 0 { return Ok(()) } + + let coords: Vec<Coordinates> = self.calculate_coordinates()?; + + for (widget, coord) in self.widgets.iter_mut().zip(coords.iter()) { widget.set_coordinates(coord).log(); } + + Ok(()) } - pub fn push_widget(&mut self, widget: T) where T: PartialEq { + pub fn push_widget(&mut self, widget: T) { self.widgets.push(widget); - self.resize_children(); - self.refresh().log(); } pub fn pop_widget(&mut self) -> Option<T> { let widget = self.widgets.pop(); - self.resize_children(); - self.refresh().log(); widget } pub fn prepend_widget(&mut self, widget: T) { self.widgets.insert(0, widget); - self.resize_children(); - self.refresh().log(); } - pub fn calculate_coordinates(&self, widget: &T) - -> Coordinates where T: PartialEq { - let coordinates = self.get_coordinates().unwrap(); - let xsize = coordinates.xsize(); - let ysize = coordinates.ysize(); - let top = coordinates.top().y(); + pub fn set_ratios(&mut self, ratios: Vec<usize>) { + self.ratios = Some(ratios); + } - let pos = self.widgets.iter().position(|w | w == widget).unwrap(); - let num = self.widgets.len(); + pub fn calculate_equal_ratios(&self) -> HResult<Vec<usize>> { + let len = self.widgets.len(); + if len == 0 { return HError::no_widget(); } - let widget_xsize = (xsize / num as u16) + 1; - let widget_xpos = widget_xsize * pos as u16; + let ratios = (0..len).map(|_| 100 / len).collect(); + Ok(ratios) + } - Coordinates { - size: Size((widget_xsize, - ysize)), - position: Position((widget_xpos, - top)) - } + pub fn calculate_coordinates(&self) + -> HResult<Vec<Coordinates>> { + let box_coords = self.get_coordinates()?; + let box_xsize = box_coords.xsize(); + let box_ysize = box_coords.ysize(); + let box_top = box_coords.top().y(); + + let ratios = match &self.ratios { + Some(ratios) => ratios.clone(), + None => self.calculate_equal_ratios()? + }; + + let coords = ratios.iter().fold(Vec::<Coordinates>::new(), |mut coords, ratio| { + let ratio = *ratio as u16; + let len = coords.len(); + let gap = if len == 0 { 0 } else { 1 }; + + let widget_xsize = box_xsize * ratio / 100; + let widget_xpos = if len == 0 { + box_coords.top().x() + } else { + let prev_coords = coords.last().unwrap(); + let prev_xsize = prev_coords.xsize(); + let prev_xpos = prev_coords.position().x(); + + prev_xsize + prev_xpos + gap + }; + + coords.push(Coordinates { + size: Size((widget_xsize, + box_ysize)), + position: Position((widget_xpos, + box_top)) + }); + coords + }); + + Ok(coords) } pub fn active_widget(&self) -> &T { @@ -92,7 +123,7 @@ impl<T> Widget for HBox<T> where T: Widget + PartialEq { } fn refresh(&mut self) -> HResult<()> { - self.resize_children(); + self.resize_children().log(); for child in &mut self.widgets { child.refresh()? } |