WIP flexbox-ish layout

This commit is contained in:
marceline-cramer 2022-07-27 20:39:36 -06:00
parent c22baff89e
commit aa0d49b6c4
3 changed files with 141 additions and 4 deletions

View File

@ -0,0 +1,132 @@
#[derive(Clone, Debug)]
pub enum Unit {
Fixed(f32),
Percentage(f32),
Stretch(f32),
}
impl Unit {
pub fn as_fixed(&self, parent_size: f32) -> Option<f32> {
match self {
Unit::Fixed(u) => Some(*u),
Unit::Percentage(u) => Some(u * parent_size),
Unit::Stretch(_) => None,
}
}
pub fn as_stretch(&self) -> f32 {
if let Unit::Stretch(stretch) = self {
*stretch
} else {
0.0
}
}
pub fn calc_stretched(&self, parent_size: f32, stretch_factor: f32) -> f32 {
match self {
Unit::Fixed(u) => *u,
Unit::Percentage(u) => u * parent_size,
Unit::Stretch(u) => u * stretch_factor,
}
}
}
#[derive(Clone, Debug)]
pub struct Constraint {
pub desired: Unit,
pub min: Option<Unit>,
pub max: Option<Unit>,
}
impl Constraint {
pub fn calc_minimum_size(&self, parent_size: f32) -> f32 {
let desired = self.desired.as_fixed(parent_size).unwrap_or(0.0);
if let Some(min) = self.min.as_ref() {
let min = min.as_fixed(parent_size).unwrap_or(0.0);
min.max(desired)
} else {
desired
}
}
pub fn calc_stretch(&self) -> f32 {
self.desired.as_stretch()
+ self.min.as_ref().map(|u| u.as_stretch()).unwrap_or(0.0)
+ self.max.as_ref().map(|u| u.as_stretch()).unwrap_or(0.0)
}
pub fn calc_stretched(&self, parent_size: f32, stretch_factor: f32) -> f32 {
self.desired
.calc_stretched(parent_size, stretch_factor)
.max(
self.min
.as_ref()
.map(|u| u.calc_stretched(parent_size, stretch_factor))
.unwrap_or(0.0),
)
}
}
#[derive(Clone, Debug)]
pub struct Metrics {
pub margin_before: Constraint,
pub content: Constraint,
pub margin_after: Constraint,
}
impl Metrics {
pub fn calc_minimum_size(&self, parent_size: f32) -> f32 {
self.margin_before.calc_minimum_size(parent_size)
+ self.content.calc_minimum_size(parent_size)
+ self.margin_after.calc_minimum_size(parent_size)
}
pub fn calc_stretch(&self) -> f32 {
self.margin_before.calc_stretch()
+ self.content.calc_stretch()
+ self.margin_after.calc_stretch()
}
}
pub trait Node {
fn get_flex_hori(&self) -> Metrics;
fn get_flex_vert(&self) -> Metrics;
}
#[derive(Clone, Debug)]
pub enum AbsoluteConstraint {}
#[derive(Clone, Debug)]
pub struct AbsoluteMetrics {}
#[derive(Clone, Debug)]
pub struct Position {
pub start: f32,
pub end: f32,
}
pub fn compute_layout(size: f32, nodes: &[Metrics]) -> Vec<Position> {
let mut minimum_size = 0.0;
let mut stretch_total = 0.0;
for node in nodes.iter() {
minimum_size += node.calc_minimum_size(size);
stretch_total += stretch_total;
}
let remaining = (size - minimum_size).max(0.0);
let stretch = remaining / stretch_total;
let mut cursor = 0.0;
let mut positions = Vec::new();
for node in nodes.iter() {
cursor += node.margin_before.calc_stretched(size, stretch);
let start = cursor;
cursor += node.content.calc_stretched(size, stretch);
let end = cursor;
cursor += node.margin_after.calc_stretched(size, stretch);
positions.push(Position { start, end });
}
positions
}

View File

@ -6,6 +6,7 @@ use keyframe::functions::*;
pub mod button;
pub mod dialog;
pub mod flex;
pub mod menu;
pub mod scroll;
pub mod shell;
@ -44,10 +45,6 @@ impl<T: Widget> Widget for Option<T> {
}
}
pub trait FixedWidth {
fn get_width(&self) -> f32;
}
pub struct MainMenu {
pub menu: Offset<SlotMenu<RoundButton>>,
pub inventory: Reveal<Offset<TabMenu>>,

View File

@ -23,6 +23,14 @@ bitflags! {
}
}
#[derive(Copy, Clone, Debug)]
pub enum Side {
Top,
Right,
Bottom,
Left,
}
#[derive(Copy, Clone)]
pub struct ColoredTriangle {
pub v1: Vec2,