Skip to content

Commit

Permalink
Run formatter
Browse files Browse the repository at this point in the history
  • Loading branch information
Raunak Bhagat committed Sep 22, 2023
1 parent 8483707 commit 565bdb3
Show file tree
Hide file tree
Showing 3 changed files with 163 additions and 51 deletions.
42 changes: 36 additions & 6 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -292,11 +292,26 @@ pub struct Padding {

impl Padding {
fn to_relative_padding(self, direction: Direction) -> RelativePadding {
let Self { left, right, top, bottom } = self;
let Self {
left,
right,
top,
bottom,
} = self;

match direction {
Direction::Horizontal => RelativePadding { main_start: left, main_end: right, cross_start: top, cross_end: bottom },
Direction::Vertical => RelativePadding { main_start: top, main_end: bottom, cross_start: left, cross_end: right },
Direction::Horizontal => RelativePadding {
main_start: left,
main_end: right,
cross_start: top,
cross_end: bottom,
},
Direction::Vertical => RelativePadding {
main_start: top,
main_end: bottom,
cross_start: left,
cross_end: right,
},
}
}
}
Expand Down Expand Up @@ -346,11 +361,26 @@ struct RelativeFrame {

impl RelativeFrame {
fn to_frame(self, direction: Direction) -> Frame {
let Self { offset_main, length_main, offset_cross, length_cross } = self;
let Self {
offset_main,
length_main,
offset_cross,
length_cross,
} = self;

match direction {
Direction::Horizontal => Frame { offset_x: offset_main, length_x: length_main, offset_y: offset_cross, length_y: length_cross },
Direction::Vertical => Frame { offset_x: offset_cross, length_x: length_cross, offset_y: offset_main, length_y: length_main },
Direction::Horizontal => Frame {
offset_x: offset_main,
length_x: length_main,
offset_y: offset_cross,
length_y: length_cross,
},
Direction::Vertical => Frame {
offset_x: offset_cross,
length_x: length_cross,
offset_y: offset_main,
length_y: length_main,
},
}
}
}
167 changes: 124 additions & 43 deletions src/solver/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
use std::collections::BTreeMap;

use cherrytree::{Tree, Node};
use cherrytree::{Node, Tree};
use indexmap::IndexSet;

use crate::{ConstraintKey, Constraint, FrameKey, Frame, Content, RelativePadding, RelativeFrame, FillType, Align, Direction};
use crate::{
Align, Constraint, ConstraintKey, Content, Direction, FillType, Frame, FrameKey, RelativeFrame,
RelativePadding,
};

pub(super) fn solve(
constraint_tree: &Tree<ConstraintKey, Constraint>,
Expand All @@ -14,7 +17,10 @@ pub(super) fn solve(
) {
let (root_constraint_key, root_constraint_node) = constraint_tree.root_key_value().unwrap();

let relative_fill = root_constraint_node.value.fill.to_relative_fill(Direction::Vertical);
let relative_fill = root_constraint_node
.value
.fill
.to_relative_fill(Direction::Vertical);

let length_x = match relative_fill.cross {
FillType::Scale(0) => 0.,
Expand All @@ -39,10 +45,23 @@ pub(super) fn solve(
let root_frame_key = frame_tree.insert_root_with_capacity(root_frame, number_of_child_keys);
key_map.insert(root_constraint_key, root_frame_key);

let relative_padding = root_constraint_node.value.content.padding.to_relative_padding(Direction::Vertical);
let root_relative_content_frame = generate_content_frame_relative(relative_padding, length_y, length_x);

solve_child_keys_relative(constraint_tree, frame_tree, key_map, root_constraint_node.child_keys, root_frame_key, root_relative_content_frame, root_constraint_node.value.content);
let relative_padding = root_constraint_node
.value
.content
.padding
.to_relative_padding(Direction::Vertical);
let root_relative_content_frame =
generate_content_frame_relative(relative_padding, length_y, length_x);

solve_child_keys_relative(
constraint_tree,
frame_tree,
key_map,
root_constraint_node.child_keys,
root_frame_key,
root_relative_content_frame,
root_constraint_node.value.content,
);
}

fn solve_child_keys_relative(
Expand All @@ -59,7 +78,10 @@ fn solve_child_keys_relative(

let mut relative_lengths = iter(constraint_tree, constraint_keys)
.map(|(_, constraint_node)| {
let relatve_fill = constraint_node.value.fill.to_relative_fill(parent_content.direction);
let relatve_fill = constraint_node
.value
.fill
.to_relative_fill(parent_content.direction);

let mut cache = None;

Expand All @@ -68,45 +90,64 @@ fn solve_child_keys_relative(
let exact_main = exact_main.min(remaining_length_main);
remaining_length_main -= exact_main;
Some(exact_main)
},
}
FillType::Scale(scale_main) => {
total_scale_main = total_scale_main.checked_add(scale_main).unwrap();
None
},
}
FillType::Minimize => {
let (minimizing_length_main, minimizing_length_cross) = find_minimizing_length_relative(constraint_tree, constraint_node.child_keys, constraint_node.value.content.direction, remaining_length_main, relative_content_frame.length_cross);
let (minimizing_length_main, minimizing_length_cross) =
find_minimizing_length_relative(
constraint_tree,
constraint_node.child_keys,
constraint_node.value.content.direction,
remaining_length_main,
relative_content_frame.length_cross,
);
cache = Some(minimizing_length_cross);
Some(minimizing_length_main)
},
}
};

let length_cross = match relatve_fill.cross {
FillType::Exact(exact_cross) => exact_cross.min(relative_content_frame.length_cross),
FillType::Exact(exact_cross) => {
exact_cross.min(relative_content_frame.length_cross)
}
FillType::Scale(0) => 0.,
FillType::Scale(_) => relative_content_frame.length_cross,
FillType::Minimize => cache.unwrap_or_else(|| {
let (_, minimizing_length_cross) = find_minimizing_length_relative(constraint_tree, constraint_node.child_keys, constraint_node.value.content.direction, remaining_length_main, relative_content_frame.length_cross);
let (_, minimizing_length_cross) = find_minimizing_length_relative(
constraint_tree,
constraint_node.child_keys,
constraint_node.value.content.direction,
remaining_length_main,
relative_content_frame.length_cross,
);
minimizing_length_cross
}),
};

let remaining_length_cross = relative_content_frame.length_cross - length_cross;
let offset_cross = relative_content_frame.offset_cross + match parent_content.align_cross {
Align::Start => 0.,
Align::Middle => remaining_length_cross / 2.,
Align::End => remaining_length_cross,
};
let offset_cross = relative_content_frame.offset_cross
+ match parent_content.align_cross {
Align::Start => 0.,
Align::Middle => remaining_length_cross / 2.,
Align::End => remaining_length_cross,
};

(relatve_fill, length_main, length_cross, offset_cross)
})
.collect::<Vec<_>>();

let mut offset_main = match total_scale_main {
0 => relative_content_frame.offset_main + match parent_content.align_main {
Align::Start => 0.,
Align::Middle => remaining_length_main / 2.,
Align::End => remaining_length_main,
},
0 => {
relative_content_frame.offset_main
+ match parent_content.align_main {
Align::Start => 0.,
Align::Middle => remaining_length_main / 2.,
Align::End => remaining_length_main,
}
}
_ => {
for (relative_fill, length_main, _, _) in &mut relative_lengths {
if let FillType::Scale(scale_main) = relative_fill.main {
Expand All @@ -116,10 +157,12 @@ fn solve_child_keys_relative(
}

0.
},
}
};

for ((constraint_key, constraint_node), (_, length_main, length_cross, offset_cross)) in iter(constraint_tree, constraint_keys).zip(relative_lengths) {
for ((constraint_key, constraint_node), (_, length_main, length_cross, offset_cross)) in
iter(constraint_tree, constraint_keys).zip(relative_lengths)
{
let length_main = length_main.unwrap_or_default();

let relative_frame = RelativeFrame {
Expand All @@ -133,17 +176,36 @@ fn solve_child_keys_relative(

let number_of_child_keys = constraint_node.child_keys.len();
let frame = relative_frame.to_frame(parent_content.direction);
let frame_key = frame_tree.insert_with_capacity(frame, parent_frame_key, number_of_child_keys).unwrap();
let frame_key = frame_tree
.insert_with_capacity(frame, parent_frame_key, number_of_child_keys)
.unwrap();
key_map.insert(constraint_key, frame_key);

let relative_padding = constraint_node.value.content.padding.to_relative_padding(parent_content.direction);
let relative_content_frame = generate_content_frame_relative(relative_padding, length_main, length_cross);

solve_child_keys_relative(constraint_tree, frame_tree, key_map, constraint_node.child_keys, frame_key, relative_content_frame, constraint_node.value.content);
let relative_padding = constraint_node
.value
.content
.padding
.to_relative_padding(parent_content.direction);
let relative_content_frame =
generate_content_frame_relative(relative_padding, length_main, length_cross);

solve_child_keys_relative(
constraint_tree,
frame_tree,
key_map,
constraint_node.child_keys,
frame_key,
relative_content_frame,
constraint_node.value.content,
);
}
}

fn generate_content_frame_relative(relative_padding: RelativePadding, length_main: f64, length_cross: f64) -> RelativeFrame {
fn generate_content_frame_relative(
relative_padding: RelativePadding,
length_main: f64,
length_cross: f64,
) -> RelativeFrame {
let content_start_main = relative_padding.main_start.min(length_main);
let content_end_main = (length_main - relative_padding.main_end).max(0.);
let content_length_main = (content_end_main - content_start_main).max(0.);
Expand Down Expand Up @@ -174,23 +236,45 @@ fn find_minimizing_length_relative(

for (_, constraint_node) in iter(constraint_tree, constraint_keys) {
let relative_fill = constraint_node.value.fill.to_relative_fill(direction);
let relative_padding = constraint_node.value.content.padding.to_relative_padding(direction);
let relative_padding = constraint_node
.value
.content
.padding
.to_relative_padding(direction);

let length_main = match relative_fill.main {
FillType::Exact(exact_main) => exact_main + relative_padding.main_start + relative_padding.main_end,
FillType::Exact(exact_main) => {
exact_main + relative_padding.main_start + relative_padding.main_end
}
FillType::Scale(..) => relative_padding.main_start + relative_padding.main_end,
FillType::Minimize => {
let (sub_minimizing_length_main, sub_minimizing_length_cross) = find_minimizing_length_relative(constraint_tree, constraint_node.child_keys, constraint_node.value.content.direction, remaining_length_main, max_length_cross);
let (sub_minimizing_length_main, sub_minimizing_length_cross) =
find_minimizing_length_relative(
constraint_tree,
constraint_node.child_keys,
constraint_node.value.content.direction,
remaining_length_main,
max_length_cross,
);
cache = Some(sub_minimizing_length_cross);
sub_minimizing_length_main
},
}.min(remaining_length_main);
}
}
.min(remaining_length_main);

let length_cross = match relative_fill.cross {
FillType::Exact(exact_cross) => exact_cross + relative_padding.cross_start + relative_padding.cross_end,
FillType::Exact(exact_cross) => {
exact_cross + relative_padding.cross_start + relative_padding.cross_end
}
FillType::Scale(..) => relative_padding.cross_start + relative_padding.cross_end,
FillType::Minimize => cache.unwrap_or_else(|| {
let (_, sub_minimizing_length_cross) = find_minimizing_length_relative(constraint_tree, constraint_node.child_keys, constraint_node.value.content.direction, remaining_length_main, max_length_cross);
let (_, sub_minimizing_length_cross) = find_minimizing_length_relative(
constraint_tree,
constraint_node.child_keys,
constraint_node.value.content.direction,
remaining_length_main,
max_length_cross,
);
sub_minimizing_length_cross
}),
};
Expand All @@ -202,10 +286,7 @@ fn find_minimizing_length_relative(
let minimizing_length_main = max_length_main - remaining_length_main;
let minimizing_length_cross = max_seen_length_cross.min(max_length_cross);

(
minimizing_length_main,
minimizing_length_cross,
)
(minimizing_length_main, minimizing_length_cross)
}

fn iter<'a>(
Expand Down
5 changes: 3 additions & 2 deletions tests/test_solver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
mod common;

use common::{make_frame_tree, make_solver};
use stretchbox::{Constraint, Frame, Fill, FillType};
use stretchbox::{Constraint, Fill, FillType, Frame};

#[test]
fn test_solver_with_empty_tree() {
Expand Down Expand Up @@ -31,6 +31,7 @@ fn test_solver_with_single_element_tree() {
solver.solve(10., 10.);

let actual_frame_tree = make_frame_tree(&solver);
let expected_frame_tree = Some(node! { Frame { offset_x: 0., length_x: 10., offset_y: 0., length_y: 10. }});
let expected_frame_tree =
Some(node! { Frame { offset_x: 0., length_x: 10., offset_y: 0., length_y: 10. }});
assert_eq!(actual_frame_tree, expected_frame_tree);
}

0 comments on commit 565bdb3

Please sign in to comment.