Moar dockumentashun

daddy
elfein727 2021-12-28 02:03:17 -08:00
parent b24b7f81d1
commit 844d406763
5 changed files with 102 additions and 92 deletions

View File

@ -7,4 +7,3 @@ edition = "2021"
[dependencies] [dependencies]
crossterm = "0.22.1" crossterm = "0.22.1"
futures = "*"

View File

@ -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)] #[derive(Debug, Clone, Copy, PartialEq)]
pub enum Axis { pub enum Axis {
/// The x axis /// The x axis
Horizontal, Horizontal,
/// The y axis /// The y axis
Vertical, Vertical,
} }
impl Axis { impl Axis {
/// Get the axis perpendicular to this one. /// Get the axis perpendicular to this one.
pub fn cross(self) -> Axis { pub fn cross(self) -> Axis {
match self { match self {
Axis::Horizontal => Axis::Vertical, Axis::Horizontal => Axis::Vertical,
Axis::Vertical => Axis::Horizontal, Axis::Vertical => Axis::Horizontal,
} }
} }
/// Extract from the argument the magnitude along this axis /// Extract from the argument the magnitude along this axis
pub fn major(self, coords: Size) -> usize { pub fn major(self, coords: Size) -> usize {
match self { match self {
Axis::Horizontal => coords.width, Axis::Horizontal => coords.width,
Axis::Vertical => coords.height, Axis::Vertical => coords.height,
} }
} }
/// Extract from the argument the magnitude along the perpendicular axis /// Extract from the argument the magnitude along the perpendicular axis
pub fn minor(self, coords: Size) -> usize { pub fn minor(self, coords: Size) -> usize {
self.cross().major(coords) self.cross().major(coords)
} }
/// Extract the extent of the argument in this axis as a pair. /// Extract the extent of the argument in this axis as a pair.
pub fn major_span(self, rect: Rect) -> (usize, usize) { pub fn major_span(self, rect: Rect) -> (usize, usize) {
match self { match self {
Axis::Horizontal => (rect.x0, rect.x1), Axis::Horizontal => (rect.x0, rect.x1),
Axis::Vertical => (rect.y0, rect.y1), Axis::Vertical => (rect.y0, rect.y1),
} }
} }
/// Extract the extent of the argument in the minor axis as a pair. /// Extract the extent of the argument in the minor axis as a pair.
pub fn minor_span(self, rect: Rect) -> (usize, usize) { pub fn minor_span(self, rect: Rect) -> (usize, usize) {
self.cross().major_span(rect) self.cross().major_span(rect)
} }
/// Extract the coordinate locating the argument with respect to this axis. /// Extract the coordinate locating the argument with respect to this axis.
pub fn major_pos(self, pos: Point) -> usize { pub fn major_pos(self, pos: Point) -> usize {
match self { match self {
Axis::Horizontal => pos.x, Axis::Horizontal => pos.x,
Axis::Vertical => pos.y, Axis::Vertical => pos.y,
} }
} }
/// Extract the coordinate locating the argument with respect to this axis. /// Extract the coordinate locating the argument with respect to this axis.
pub fn major_vec(self, vec: Vec2) -> usize { pub fn major_vec(self, vec: Vec2) -> usize {
match self { match self {
Axis::Horizontal => vec.x, Axis::Horizontal => vec.x,
Axis::Vertical => vec.y, Axis::Vertical => vec.y,
} }
} }
/// Extract the coordinate locating the argument with respect to the perpendicular axis. /// Extract the coordinate locating the argument with respect to the perpendicular axis.
pub fn minor_pos(self, pos: Point) -> usize { pub fn minor_pos(self, pos: Point) -> usize {
self.cross().major_pos(pos) self.cross().major_pos(pos)
} }
/// Extract the coordinate locating the argument with respect to the perpendicular axis. /// Extract the coordinate locating the argument with respect to the perpendicular axis.
pub fn minor_vec(self, vec: Vec2) -> usize { pub fn minor_vec(self, vec: Vec2) -> usize {
self.cross().major_vec(vec) self.cross().major_vec(vec)
} }
/// Arrange the major and minor measurements with respect to this axis such that it forms /// Arrange the major and minor measurements with respect to this axis such that it forms
/// an (x, y) pair. /// an (x, y) pair.
pub fn pack(self, major: usize, minor: usize) -> (usize, usize) { pub fn pack(self, major: usize, minor: usize) -> (usize, usize) {
match self { match self {
Axis::Horizontal => (major, minor), Axis::Horizontal => (major, minor),
Axis::Vertical => (minor, major), Axis::Vertical => (minor, major),
} }
} }
/// Generate constraints with new values on the major axis. /// Generate constraints with new values on the major axis.
pub(crate) fn constraints( pub(super) fn constraints(
self, self,
bc: &BoxConstraints, bc: &BoxConstraints,
min_major: usize, min_major: usize,
major: usize, major: usize,
) -> BoxConstraints { ) -> BoxConstraints {
match self { match self {
Axis::Horizontal => BoxConstraints::new( Axis::Horizontal => BoxConstraints::new(
Size::new(min_major, bc.min().height), Size::new(min_major, bc.min().height),
Size::new(major, bc.max().height), Size::new(major, bc.max().height),
), ),
Axis::Vertical => BoxConstraints::new( Axis::Vertical => BoxConstraints::new(
Size::new(bc.min().width, min_major), Size::new(bc.min().width, min_major),
Size::new(bc.max().width, major), Size::new(bc.max().width, major),
), ),
} }
} }
} }
impl Data for Axis {} impl Data for Axis {}

View File

@ -319,9 +319,11 @@ impl<T: Data> Widget<T> for Flex<T> {
widget, widget,
alignment: _, alignment: _,
} => { } => {
// Get size of child (unbounded on major axis)
let child_bc = self.direction.constraints(&loosened_bc, 0, usize::MAX); let child_bc = self.direction.constraints(&loosened_bc, 0, usize::MAX);
let child_size = widget.layout(&child_bc); let child_size = widget.layout(&child_bc);
// Increment measurements
major_non_flex += self.direction.major(child_size); major_non_flex += self.direction.major(child_size);
minor = minor.max(self.direction.minor(child_size)); minor = minor.max(self.direction.minor(child_size));
} }
@ -332,9 +334,10 @@ impl<T: Data> Widget<T> for Flex<T> {
Child::Flex { flex, .. } | Child::FlexedSpacer(flex, _) => flex_sum += *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 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 remainder = 0.0;
let mut major_flex = 0.0; let mut major_flex = 0.0;
@ -343,19 +346,25 @@ impl<T: Data> Widget<T> for Flex<T> {
for child in &mut self.children { for child in &mut self.children {
match child { match child {
Child::Flex { widget, flex, .. } => { 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; let desired_major = (*flex) * chars_per_flex + remainder;
// Convert messy measurement to neat measurement
let actual_major = desired_major.round(); let actual_major = desired_major.round();
// Take difference of messy - neat and save it for next time
remainder = desired_major - actual_major; remainder = desired_major - actual_major;
// Get size of child (unbounded on major axis)
let child_bc = self let child_bc = self
.direction .direction
.constraints(&loosened_bc, 0, actual_major as usize); .constraints(&loosened_bc, 0, actual_major as usize);
// WidgetPods (which this child should be) cache their size.
let child_size = widget.layout(&child_bc); let child_size = widget.layout(&child_bc);
// Increment measurements
major_flex += self.direction.major(child_size) as f64; major_flex += self.direction.major(child_size) as f64;
minor = minor.max(self.direction.minor(child_size)); minor = minor.max(self.direction.minor(child_size));
} }
Child::FlexedSpacer(flex, calculated_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; let desired_major = (*flex) * chars_per_flex + remainder;
*calculated_size = desired_major.round(); *calculated_size = desired_major.round();
remainder = desired_major - *calculated_size; remainder = desired_major - *calculated_size;
@ -367,7 +376,7 @@ impl<T: Data> Widget<T> for Flex<T> {
// figure out if we have extra space on major axis, and if so how to use it // figure out if we have extra space on major axis, and if so how to use it
let extra = if self.fill_major_axis { let extra = if self.fill_major_axis {
(remaining - major_flex as usize).max(0) remaining.saturating_sub(major_flex as usize)
} else { } else {
// if we are *not* expected to fill our available space this usually // if we are *not* expected to fill our available space this usually
// means we don't have any extra, unless dictated by our constraints. // means we don't have any extra, unless dictated by our constraints.
@ -383,8 +392,6 @@ impl<T: Data> Widget<T> for Flex<T> {
// Unlike the 'minor' var, this ignores the incoming constraints. // Unlike the 'minor' var, this ignores the incoming constraints.
let minor_dim = minor; let minor_dim = minor;
let _extra_height = minor - minor_dim.min(minor);
let mut major = spacing.next().unwrap_or(0); let mut major = spacing.next().unwrap_or(0);
let mut child_paint_rect = Rect::ZERO; let mut child_paint_rect = Rect::ZERO;
@ -394,6 +401,7 @@ impl<T: Data> Widget<T> for Flex<T> {
| Child::Flex { | Child::Flex {
widget, alignment, .. widget, alignment, ..
} => { } => {
// Get the child's origin, origin + size rectangle
let child_size = widget.layout_rect().size(); let child_size = widget.layout_rect().size();
let alignment = alignment.unwrap_or(self.cross_alignment); let alignment = alignment.unwrap_or(self.cross_alignment);
let child_minor_offset = match alignment { let child_minor_offset = match alignment {

View File

@ -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<T: Data> { pub struct Text<T: Data> {
text: Box<dyn Fn(&DataWrapper<T>) -> String>, text: Box<dyn Fn(&DataWrapper<T>) -> String>,
@ -48,6 +48,9 @@ impl<T: Data> Widget<T> for Text<T> {
) { ) {
if ch == '\n' { if ch == '\n' {
break; break;
} else if ch == '\t' {
// TODO: Figure out a way to handle this.
*spot = ch;
} else { } else {
*spot = ch; *spot = ch;
} }

View File

@ -39,8 +39,8 @@ impl<T: Data, W: Widget<T>> Widget<T> for WidgetPod<T, W> {
new_size new_size
} }
fn paint(&mut self, buf: &mut [char], origin: Point, size: &Size) { fn paint(&mut self, buf: &mut [char], origin: Point, _: &Size) {
self.inner.paint(buf, origin + self.origin, size) self.inner.paint(buf, origin + self.origin, &self.size)
} }
fn event(&mut self, data: &mut DataWrapper<T>, event: &Event) { fn event(&mut self, data: &mut DataWrapper<T>, event: &Event) {
self.inner.event(data, event) self.inner.event(data, event)