diff --git a/pulse-ui/src/layout.rs b/pulse-ui/src/layout.rs index ca37247..9209c9d 100644 --- a/pulse-ui/src/layout.rs +++ b/pulse-ui/src/layout.rs @@ -26,23 +26,54 @@ impl LayoutItem { let allocation = if is_row { alloc.height } else { alloc.width }; - let remaining = allocation - - items - .iter() - .map(|item| item.get_size().get_fixed(allocation)) - .sum::(); + let fixed_total: u16 = items + .iter() + .map(|item| item.get_size().get_fixed(allocation)) + .sum(); + + let remaining = allocation.saturating_sub(fixed_total); let total_weight = items .iter() .map(|item| item.get_size().get_flex()) .sum::(); + let base_allocs: Vec = items + .iter() + .map(|item| item.get_size().get(allocation, remaining, total_weight)) + .collect(); + + let flex_alloc_total: u16 = items + .iter() + .zip(base_allocs.iter()) + .filter(|(item, _)| item.get_size().get_flex() > 0) + .map(|(_, a)| a) + .sum(); + + let gap = remaining.saturating_sub(flex_alloc_total); + + let fill_count = items + .iter() + .filter(|item| item.get_size().is_fill()) + .count() as u16; + + let gap_per_fill = if fill_count > 0 { gap / fill_count } else { 0 }; + let gap_remainder = if fill_count > 0 { gap % fill_count } else { 0 }; + let mut curr = if is_row { alloc.y } else { alloc.x }; + let mut fill_idx = 0u16; - for item in items { + for (i, item) in items.iter().enumerate() { let size = item.get_size(); + let mut unit_alloc = base_allocs[i]; - let unit_alloc = size.get(allocation, remaining, total_weight); + if size.is_fill() { + unit_alloc += gap_per_fill; + if fill_idx == 0 { + unit_alloc += gap_remainder; + } + fill_idx += 1; + } let item_alloc = if is_row { Rect { diff --git a/pulse-ui/src/unit.rs b/pulse-ui/src/unit.rs index 83ff31d..c21b503 100644 --- a/pulse-ui/src/unit.rs +++ b/pulse-ui/src/unit.rs @@ -9,6 +9,7 @@ pub enum Size { Fixed(u16), Flex(u16), Percent(u16), + Fill, } #[derive(Debug, Clone, Copy)] @@ -20,17 +21,22 @@ pub struct Rect { } impl Size { + pub fn is_fill(&self) -> bool { + matches!(self, Self::Fill) + } + pub fn get_fixed(&self, alloc: u16) -> u16 { match self { Self::Fixed(v) => *v, Self::Percent(v) => alloc * (*v) / 100, - Self::Flex(_) => 0, + Self::Flex(_) | Self::Fill => 0, } } pub fn get_flex(&self) -> u16 { match self { Self::Flex(f) => *f, + Self::Fill => 1, _ => 0, } } @@ -46,6 +52,13 @@ impl Size { remaining * v / total_weight } } + Self::Fill => { + if total_weight == 0 { + 0 + } else { + remaining / total_weight + } + } } } } diff --git a/src/main.rs b/src/main.rs index 6577301..2b1de93 100644 --- a/src/main.rs +++ b/src/main.rs @@ -111,7 +111,7 @@ impl App for PulseTradeApp { LayoutItem::Widget(Size::Flex(1)), // Event logs LayoutItem::Spacing(Size::Fixed(1)), - LayoutItem::Widget(Size::Flex(1)), + LayoutItem::Widget(Size::Fill), // Input LayoutItem::Spacing(Size::Fixed(1)), LayoutItem::Widget(Size::Fixed(1)),