Skip to content

Commit

Permalink
refactor(layout): simplify split() function (#396)
Browse files Browse the repository at this point in the history
Removes some unnecessary code and makes the function more readable.
Instead of creating a temporary result and mutating it, we just create
the result directly from the list of changes.
  • Loading branch information
hasezoey committed Aug 14, 2023
1 parent 8c55158 commit 5195099
Showing 1 changed file with 14 additions and 39 deletions.
53 changes: 14 additions & 39 deletions src/layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,27 +273,13 @@ impl Layout {

fn split(area: Rect, layout: &Layout) -> Rc<[Rect]> {
let mut solver = Solver::new();
let mut vars: HashMap<Variable, (usize, usize)> = HashMap::new();
let elements = layout
.constraints
.iter()
.map(|_| Element::new())
.collect::<Vec<Element>>();
let mut res = layout
.constraints
.iter()
.map(|_| Rect::default())
.collect::<Rc<[Rect]>>();

let results = Rc::get_mut(&mut res).expect("newly created Rc should have no shared refs");

let dest_area = area.inner(&layout.margin);
for (i, e) in elements.iter().enumerate() {
vars.insert(e.x, (i, 0));
vars.insert(e.y, (i, 1));
vars.insert(e.width, (i, 2));
vars.insert(e.height, (i, 3));
}
let mut ccs: Vec<CassowaryConstraint> =
Vec::with_capacity(elements.len() * 4 + layout.constraints.len() * 6);
for elt in &elements {
Expand Down Expand Up @@ -379,33 +365,21 @@ fn split(area: Rect, layout: &Layout) -> Rc<[Rect]> {
}
}
solver.add_constraints(&ccs).unwrap();
for &(var, value) in solver.fetch_changes() {
let (index, attr) = vars[&var];
let value = if value.is_sign_negative() {
0
} else {
value as u16
};
match attr {
0 => {
results[index].x = value;
}
1 => {
results[index].y = value;
}
2 => {
results[index].width = value;
}
3 => {
results[index].height = value;
}
_ => {}
}
}
let changes: HashMap<Variable, f64> = solver.fetch_changes().iter().copied().collect();
let mut results = elements
.iter()
.map(|element| Rect {
x: changes.get(&element.x).map(|&v| v as u16).unwrap_or(0),
y: changes.get(&element.y).map(|&v| v as u16).unwrap_or(0),
width: changes.get(&element.width).map(|&v| v as u16).unwrap_or(0),
height: changes.get(&element.height).map(|&v| v as u16).unwrap_or(0),
})
.collect::<Rc<[Rect]>>();

if layout.expand_to_fill {
// Fix imprecision by extending the last item a bit if necessary
if let Some(last) = results.last_mut() {
// "unwrap" is safe, because the Rc at this point has no shared references
if let Some(last) = Rc::get_mut(&mut results).unwrap().last_mut() {
match layout.direction {
Direction::Vertical => {
last.height = dest_area.bottom() - last.y;
Expand All @@ -416,7 +390,8 @@ fn split(area: Rect, layout: &Layout) -> Rc<[Rect]> {
}
}
}
res

results
}

/// A container used by the solver inside split
Expand Down

0 comments on commit 5195099

Please sign in to comment.