diff --git a/src/config.rs b/src/config.rs index b0a6011..9066650 100644 --- a/src/config.rs +++ b/src/config.rs @@ -9,8 +9,8 @@ use crate::{ fonts::{find_font, FontMap}, widgets::{ Backlight, Battery, Calendar, Clock, Date, HorizontalLayout, IndexedLayout, Interface, - InvertedHorizontalLayout, Layout, Line, Margin, PulseAudio, VerticalLayout, - Widget as RealWidget, + InvertedHorizontalLayout, InvertedVerticalLayout, Layout, Line, Margin, PulseAudio, + VerticalLayout, Widget as RealWidget, }, }; @@ -31,6 +31,7 @@ pub enum Widget { HorizontalLayout(Vec), InvertedHorizontalLayout(Vec), VerticalLayout(Vec), + InvertedVerticalLayout(Vec), HorizontalLine(u32), VerticalLine(u32), Clock { @@ -272,6 +273,9 @@ impl Widget { Widget::VerticalLayout(widgets) => widgets .into_iter() .for_each(|w| w.construct_widgets(v, fm, events)), + Widget::InvertedVerticalLayout(widgets) => widgets + .into_iter() + .for_each(|w| w.construct_widgets(v, fm, events)), Widget::HorizontalLine(width) => v.push(Box::new(Line::new(width, false))), Widget::VerticalLine(width) => v.push(Box::new(Line::new(width, true))), Widget::Clock { font, font_size } => v.push(Box::new(Clock::new( @@ -343,6 +347,9 @@ impl Widget { Widget::VerticalLayout(widgets) => { VerticalLayout::new(widgets.iter().map(|w| w.construct_layout(idx)).collect()) } + Widget::InvertedVerticalLayout(widgets) => InvertedVerticalLayout::new( + widgets.iter().map(|w| w.construct_layout(idx)).collect(), + ), _ => IndexedLayout::new({ let i = *idx; *idx += 1; diff --git a/src/widgets/layout.rs b/src/widgets/layout.rs index fb958ed..1009fad 100644 --- a/src/widgets/layout.rs +++ b/src/widgets/layout.rs @@ -142,50 +142,6 @@ impl Layout for IndexedLayout { } } -pub struct Margin { - pub widget: Box, - pub margin: (u32, u32, u32, u32), -} - -impl Margin { - pub fn new(widget: Box, margin: (u32, u32, u32, u32)) -> Box { - Box::new(Margin { widget, margin }) - } -} - -impl Layout for Margin { - fn geometry_update( - &self, - fonts: &mut FontMap, - geometry: &Geometry, - state: &mut State, - ) -> Geometry { - let geo = Geometry { - x: geometry.x + self.margin.0, - y: geometry.y + self.margin.1, - width: geometry.width - self.margin.0 - self.margin.2, - height: geometry.height - self.margin.1 - self.margin.3, - }; - let out = self.widget.geometry_update(fonts, &geo, state); - Geometry { - x: out.x - self.margin.0, - y: out.y - self.margin.1, - width: out.width + self.margin.0 + self.margin.2, - height: out.height + self.margin.1 + self.margin.3, - } - } - - fn minimum_size(&self, fonts: &mut FontMap, state: &mut State) -> Geometry { - let size = self.widget.minimum_size(fonts, state); - Geometry { - width: size.x + size.width + self.margin.0 + self.margin.2, - height: size.y + size.height + self.margin.1 + self.margin.3, - x: 0, - y: 0, - } - } -} - pub struct InvertedHorizontalLayout { pub widgets: Vec>, } @@ -233,3 +189,96 @@ impl Layout for InvertedHorizontalLayout { } } } + +pub struct InvertedVerticalLayout { + pub widgets: Vec>, +} + +impl InvertedVerticalLayout { + pub fn new(widgets: Vec>) -> Box { + Box::new(InvertedVerticalLayout { widgets }) + } +} + +impl Layout for InvertedVerticalLayout { + fn geometry_update( + &self, + fonts: &mut FontMap, + geometry: &Geometry, + state: &mut State, + ) -> Geometry { + let mut geo = geometry.clone(); + let mut max_width = 0; + for w in self.widgets.iter() { + let mut temp_geo = geo.clone(); + let temp_result = w.geometry_update(fonts, &temp_geo, state); + temp_geo.y = geo.y + (geo.height - temp_result.height); + let result = w.geometry_update(fonts, &temp_geo, state); + geo.height -= result.height; + max_width = max(result.width, max_width); + } + geo.width = max_width; + geo + } + + fn minimum_size(&self, fonts: &mut FontMap, state: &mut State) -> Geometry { + let mut max_width = 0; + let mut max_height = 0; + for w in self.widgets.iter() { + let result = w.minimum_size(fonts, state); + max_width = max(result.x + result.width, max_width); + max_height += result.y + result.height; + } + Geometry { + width: max_width, + height: max_height, + x: 0, + y: 0, + } + } +} + +pub struct Margin { + pub widget: Box, + pub margin: (u32, u32, u32, u32), +} + +impl Margin { + pub fn new(widget: Box, margin: (u32, u32, u32, u32)) -> Box { + Box::new(Margin { widget, margin }) + } +} + +impl Layout for Margin { + fn geometry_update( + &self, + fonts: &mut FontMap, + geometry: &Geometry, + state: &mut State, + ) -> Geometry { + let geo = Geometry { + x: geometry.x + self.margin.0, + y: geometry.y + self.margin.1, + width: geometry.width - self.margin.0 - self.margin.2, + height: geometry.height - self.margin.1 - self.margin.3, + }; + let out = self.widget.geometry_update(fonts, &geo, state); + Geometry { + x: out.x - self.margin.0, + y: out.y - self.margin.1, + width: out.width + self.margin.0 + self.margin.2, + height: out.height + self.margin.1 + self.margin.3, + } + } + + fn minimum_size(&self, fonts: &mut FontMap, state: &mut State) -> Geometry { + let size = self.widget.minimum_size(fonts, state); + Geometry { + width: size.x + size.width + self.margin.0 + self.margin.2, + height: size.y + size.height + self.margin.1 + self.margin.3, + x: 0, + y: 0, + } + } +} + diff --git a/src/widgets/mod.rs b/src/widgets/mod.rs index 4b7dd68..cbcf071 100644 --- a/src/widgets/mod.rs +++ b/src/widgets/mod.rs @@ -19,8 +19,8 @@ pub use clock::Clock; pub use date::Date; pub use launcher::Interface; pub use layout::{ - HorizontalLayout, IndexedLayout, InvertedHorizontalLayout, Layout, Margin, VerticalLayout, - WidgetUpdater, + HorizontalLayout, IndexedLayout, InvertedHorizontalLayout, InvertedVerticalLayout, Layout, + Margin, VerticalLayout, WidgetUpdater, }; pub use line::Line; pub use pulseaudio::PulseAudio;