diff --git a/Cargo.toml b/Cargo.toml index 3161fb4..8473b89 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,4 +7,3 @@ edition = "2021" [dependencies] crossterm = "0.22.1" -futures = "*" diff --git a/src/widget/flex/axis.rs b/src/widget/flex/axis.rs index e2ed120..c6d36ca 100644 --- a/src/widget/flex/axis.rs +++ b/src/widget/flex/axis.rs @@ -1,101 +1,101 @@ -use crate::{rect::Rect, size::Size, vec2::Vec2, Data, Point, box_constraints::BoxConstraints}; +use crate::{box_constraints::BoxConstraints, rect::Rect, size::Size, vec2::Vec2, Data, Point}; #[derive(Debug, Clone, Copy, PartialEq)] pub enum Axis { - /// The x axis - Horizontal, - /// The y axis - Vertical, + /// The x axis + Horizontal, + /// The y axis + Vertical, } impl Axis { - /// Get the axis perpendicular to this one. - pub fn cross(self) -> Axis { - match self { - Axis::Horizontal => Axis::Vertical, - Axis::Vertical => Axis::Horizontal, - } - } + /// Get the axis perpendicular to this one. + pub fn cross(self) -> Axis { + match self { + Axis::Horizontal => Axis::Vertical, + Axis::Vertical => Axis::Horizontal, + } + } - /// Extract from the argument the magnitude along this axis - pub fn major(self, coords: Size) -> usize { - match self { - Axis::Horizontal => coords.width, - Axis::Vertical => coords.height, - } - } + /// Extract from the argument the magnitude along this axis + pub fn major(self, coords: Size) -> usize { + match self { + Axis::Horizontal => coords.width, + Axis::Vertical => coords.height, + } + } - /// Extract from the argument the magnitude along the perpendicular axis - pub fn minor(self, coords: Size) -> usize { - self.cross().major(coords) - } + /// Extract from the argument the magnitude along the perpendicular axis + pub fn minor(self, coords: Size) -> usize { + self.cross().major(coords) + } - /// Extract the extent of the argument in this axis as a pair. - pub fn major_span(self, rect: Rect) -> (usize, usize) { - match self { - Axis::Horizontal => (rect.x0, rect.x1), - Axis::Vertical => (rect.y0, rect.y1), - } - } + /// Extract the extent of the argument in this axis as a pair. + pub fn major_span(self, rect: Rect) -> (usize, usize) { + match self { + Axis::Horizontal => (rect.x0, rect.x1), + Axis::Vertical => (rect.y0, rect.y1), + } + } - /// Extract the extent of the argument in the minor axis as a pair. - pub fn minor_span(self, rect: Rect) -> (usize, usize) { - self.cross().major_span(rect) - } + /// Extract the extent of the argument in the minor axis as a pair. + pub fn minor_span(self, rect: Rect) -> (usize, usize) { + self.cross().major_span(rect) + } - /// Extract the coordinate locating the argument with respect to this axis. - pub fn major_pos(self, pos: Point) -> usize { - match self { - Axis::Horizontal => pos.x, - Axis::Vertical => pos.y, - } - } + /// Extract the coordinate locating the argument with respect to this axis. + pub fn major_pos(self, pos: Point) -> usize { + match self { + Axis::Horizontal => pos.x, + Axis::Vertical => pos.y, + } + } - /// Extract the coordinate locating the argument with respect to this axis. - pub fn major_vec(self, vec: Vec2) -> usize { - match self { - Axis::Horizontal => vec.x, - Axis::Vertical => vec.y, - } - } + /// Extract the coordinate locating the argument with respect to this axis. + pub fn major_vec(self, vec: Vec2) -> usize { + match self { + Axis::Horizontal => vec.x, + Axis::Vertical => vec.y, + } + } - /// Extract the coordinate locating the argument with respect to the perpendicular axis. - pub fn minor_pos(self, pos: Point) -> usize { - self.cross().major_pos(pos) - } + /// Extract the coordinate locating the argument with respect to the perpendicular axis. + pub fn minor_pos(self, pos: Point) -> usize { + self.cross().major_pos(pos) + } - /// Extract the coordinate locating the argument with respect to the perpendicular axis. - pub fn minor_vec(self, vec: Vec2) -> usize { - self.cross().major_vec(vec) - } + /// Extract the coordinate locating the argument with respect to the perpendicular axis. + pub fn minor_vec(self, vec: Vec2) -> usize { + self.cross().major_vec(vec) + } - /// Arrange the major and minor measurements with respect to this axis such that it forms - /// an (x, y) pair. - pub fn pack(self, major: usize, minor: usize) -> (usize, usize) { - match self { - Axis::Horizontal => (major, minor), - Axis::Vertical => (minor, major), - } - } + /// Arrange the major and minor measurements with respect to this axis such that it forms + /// an (x, y) pair. + pub fn pack(self, major: usize, minor: usize) -> (usize, usize) { + match self { + Axis::Horizontal => (major, minor), + Axis::Vertical => (minor, major), + } + } - /// Generate constraints with new values on the major axis. - pub(crate) fn constraints( - self, - bc: &BoxConstraints, - min_major: usize, - major: usize, - ) -> BoxConstraints { - match self { - Axis::Horizontal => BoxConstraints::new( - Size::new(min_major, bc.min().height), - Size::new(major, bc.max().height), - ), - Axis::Vertical => BoxConstraints::new( - Size::new(bc.min().width, min_major), - Size::new(bc.max().width, major), - ), - } - } + /// Generate constraints with new values on the major axis. + pub(super) fn constraints( + self, + bc: &BoxConstraints, + min_major: usize, + major: usize, + ) -> BoxConstraints { + match self { + Axis::Horizontal => BoxConstraints::new( + Size::new(min_major, bc.min().height), + Size::new(major, bc.max().height), + ), + Axis::Vertical => BoxConstraints::new( + Size::new(bc.min().width, min_major), + Size::new(bc.max().width, major), + ), + } + } } impl Data for Axis {} diff --git a/src/widget/flex/mod.rs b/src/widget/flex/mod.rs index 24c9e94..c501b6a 100644 --- a/src/widget/flex/mod.rs +++ b/src/widget/flex/mod.rs @@ -319,9 +319,11 @@ impl Widget for Flex { widget, alignment: _, } => { + // Get size of child (unbounded on major axis) let child_bc = self.direction.constraints(&loosened_bc, 0, usize::MAX); let child_size = widget.layout(&child_bc); + // Increment measurements major_non_flex += self.direction.major(child_size); minor = minor.max(self.direction.minor(child_size)); } @@ -332,9 +334,10 @@ impl Widget for Flex { Child::Flex { flex, .. } | Child::FlexedSpacer(flex, _) => flex_sum += *flex, } } - + // Get the amount of space on the major axis let total_major = self.direction.major(bc.max()); - let remaining = (total_major - major_non_flex).max(0); + // Calculate the amount of space left on major axis (total - total-non-flex) + let remaining = total_major.saturating_sub(major_non_flex); let mut remainder = 0.0; let mut major_flex = 0.0; @@ -343,19 +346,25 @@ impl Widget for Flex { for child in &mut self.children { match child { Child::Flex { widget, flex, .. } => { + // This thing's flex represents a multiple of the number of chars per flex let desired_major = (*flex) * chars_per_flex + remainder; + // Convert messy measurement to neat measurement let actual_major = desired_major.round(); + // Take difference of messy - neat and save it for next time remainder = desired_major - actual_major; - + // Get size of child (unbounded on major axis) let child_bc = self .direction .constraints(&loosened_bc, 0, actual_major as usize); + // WidgetPods (which this child should be) cache their size. let child_size = widget.layout(&child_bc); + // Increment measurements major_flex += self.direction.major(child_size) as f64; minor = minor.max(self.direction.minor(child_size)); } Child::FlexedSpacer(flex, calculated_size) => { + // Do the same calculation as above (ie, decrement the amount of space left and increment the measurement) let desired_major = (*flex) * chars_per_flex + remainder; *calculated_size = desired_major.round(); remainder = desired_major - *calculated_size; @@ -367,7 +376,7 @@ impl Widget for Flex { // figure out if we have extra space on major axis, and if so how to use it let extra = if self.fill_major_axis { - (remaining - major_flex as usize).max(0) + remaining.saturating_sub(major_flex as usize) } else { // if we are *not* expected to fill our available space this usually // means we don't have any extra, unless dictated by our constraints. @@ -383,8 +392,6 @@ impl Widget for Flex { // Unlike the 'minor' var, this ignores the incoming constraints. let minor_dim = minor; - let _extra_height = minor - minor_dim.min(minor); - let mut major = spacing.next().unwrap_or(0); let mut child_paint_rect = Rect::ZERO; @@ -394,6 +401,7 @@ impl Widget for Flex { | Child::Flex { widget, alignment, .. } => { + // Get the child's origin, origin + size rectangle let child_size = widget.layout_rect().size(); let alignment = alignment.unwrap_or(self.cross_alignment); let child_minor_offset = match alignment { diff --git a/src/widget/text.rs b/src/widget/text.rs index ea781da..38e673b 100644 --- a/src/widget/text.rs +++ b/src/widget/text.rs @@ -1,4 +1,4 @@ -use crate::{box_constraints::BoxConstraints, Data, DataWrapper, Point, Size, Widget, Event}; +use crate::{box_constraints::BoxConstraints, Data, DataWrapper, Event, Point, Size, Widget}; pub struct Text { text: Box) -> String>, @@ -48,6 +48,9 @@ impl Widget for Text { ) { if ch == '\n' { break; + } else if ch == '\t' { + // TODO: Figure out a way to handle this. + *spot = ch; } else { *spot = ch; } diff --git a/src/widget/widget_pod.rs b/src/widget/widget_pod.rs index f536442..1ff488b 100644 --- a/src/widget/widget_pod.rs +++ b/src/widget/widget_pod.rs @@ -39,8 +39,8 @@ impl> Widget for WidgetPod { new_size } - fn paint(&mut self, buf: &mut [char], origin: Point, size: &Size) { - self.inner.paint(buf, origin + self.origin, size) + fn paint(&mut self, buf: &mut [char], origin: Point, _: &Size) { + self.inner.paint(buf, origin + self.origin, &self.size) } fn event(&mut self, data: &mut DataWrapper, event: &Event) { self.inner.event(data, event)