1
0
mirror of https://github.com/emilk/egui.git synced 2026-09-03 07:10:04 -04:00

Use indexing for main/cross vecs

This commit is contained in:
lucasmerlin
2026-06-03 10:44:30 +02:00
parent 63218a9db6
commit dcede8410a

View File

@@ -9,24 +9,11 @@ use smallvec::SmallVec;
use std::ops::{Deref, DerefMut}; use std::ops::{Deref, DerefMut};
use std::sync::Arc; use std::sync::Arc;
/// The main-axis component of `v` for `direction` (x for horizontal, y for vertical). /// The `(main, cross)` axis indices for `direction`, for indexing a [`Vec2`] (0 = x, 1 = y).
#[inline] #[inline]
fn main_axis(direction: Direction, v: Vec2) -> f32 { fn main_cross_axis(direction: Direction) -> (usize, usize) {
if direction.is_horizontal() { let main = if direction.is_horizontal() { 0 } else { 1 };
v.x (main, 1 - main)
} else {
v.y
}
}
/// The cross-axis component of `v` for `direction` (y for horizontal, x for vertical).
#[inline]
fn cross_axis(direction: Direction, v: Vec2) -> f32 {
if direction.is_horizontal() {
v.y
} else {
v.x
}
} }
/// Build a [`Vec2`] from `main`/`cross` components for `direction`. /// Build a [`Vec2`] from `main`/`cross` components for `direction`.
@@ -39,14 +26,14 @@ fn main_cross_vec(direction: Direction, main: f32, cross: f32) -> Vec2 {
} }
} }
/// Build a cell [`Rect`] spanning `block` fully on the cross axis and `[min_main, max_main]` /// Build a cell [`Rect`] spanning `aligned_rect` fully on the cross axis and `[min_main, max_main]`
/// along the main axis. /// along the main axis.
#[inline] #[inline]
fn main_cross_rect(direction: Direction, block: Rect, min_main: f32, max_main: f32) -> Rect { fn main_cross_rect(direction: Direction, aligned_rect: Rect, min_main: f32, max_main: f32) -> Rect {
if direction.is_horizontal() { if direction.is_horizontal() {
Rect::from_x_y_ranges(min_main..=max_main, block.y_range()) Rect::from_x_y_ranges(min_main..=max_main, aligned_rect.y_range())
} else { } else {
Rect::from_x_y_ranges(block.x_range(), min_main..=max_main) Rect::from_x_y_ranges(aligned_rect.x_range(), min_main..=max_main)
} }
} }
@@ -305,7 +292,9 @@ impl<'a> AtomLayout<'a> {
// We work in main/cross axis terms so the same code handles horizontal and vertical // We work in main/cross axis terms so the same code handles horizontal and vertical
// layouts. For a horizontal `direction`, main = x and cross = y; for vertical it's // layouts. For a horizontal `direction`, main = x and cross = y; for vertical it's
// swapped. `grow`/`shrink`/`gap` apply along the main axis; the cross axis is sized to // swapped. `grow`/`shrink`/`gap` apply along the main axis; the cross axis is sized to
// the largest atom. // the largest atom. `main_axis`/`cross_axis` index into a `Vec2` (0 = x, 1 = y).
let (main_axis, cross_axis) = main_cross_axis(direction);
let mut inner_main = 0.0; let mut inner_main = 0.0;
// intrinsic main / cross is the ideal size of the widget, e.g. the size where the // intrinsic main / cross is the ideal size of the widget, e.g. the size where the
@@ -353,11 +342,11 @@ impl<'a> AtomLayout<'a> {
); );
let size = sized.size; let size = sized.size;
inner_main += main_axis(direction, size); inner_main += size[main_axis];
intrinsic_main += main_axis(direction, sized.intrinsic_size); intrinsic_main += sized.intrinsic_size[main_axis];
cross_size = cross_size.at_least(cross_axis(direction, size)); cross_size = cross_size.at_least(size[cross_axis]);
intrinsic_cross = intrinsic_cross.at_least(cross_axis(direction, sized.intrinsic_size)); intrinsic_cross = intrinsic_cross.at_least(sized.intrinsic_size[cross_axis]);
sized_items.push(sized); sized_items.push(sized);
} }
@@ -366,8 +355,8 @@ impl<'a> AtomLayout<'a> {
// The `shrink` item gets the remaining space along the main axis. // The `shrink` item gets the remaining space along the main axis.
let available_size_for_shrink_item = main_cross_vec( let available_size_for_shrink_item = main_cross_vec(
direction, direction,
main_axis(direction, available_inner_size) - inner_main, available_inner_size[main_axis] - inner_main,
cross_axis(direction, available_inner_size), available_inner_size[cross_axis],
); );
let sized = item.into_sized( let sized = item.into_sized(
@@ -378,11 +367,11 @@ impl<'a> AtomLayout<'a> {
); );
let size = sized.size; let size = sized.size;
inner_main += main_axis(direction, size); inner_main += size[main_axis];
intrinsic_main += main_axis(direction, sized.intrinsic_size); intrinsic_main += sized.intrinsic_size[main_axis];
cross_size = cross_size.at_least(cross_axis(direction, size)); cross_size = cross_size.at_least(size[cross_axis]);
intrinsic_cross = intrinsic_cross.at_least(cross_axis(direction, sized.intrinsic_size)); intrinsic_cross = intrinsic_cross.at_least(sized.intrinsic_size[cross_axis]);
sized_items.insert(index, sized); sized_items.insert(index, sized);
} }
@@ -579,9 +568,11 @@ impl<'atom> SizedAtomLayout<'atom> {
ui.painter().add(frame.paint(inner_rect)); ui.painter().add(frame.paint(inner_rect));
let (main_axis, cross_axis) = main_cross_axis(direction);
// We position atoms along the main axis (the `direction`) and span the cross axis. // We position atoms along the main axis (the `direction`) and span the cross axis.
let main_to_fill = main_axis(direction, inner_rect.size()); let main_to_fill = inner_rect.size()[main_axis];
let inner_main = main_axis(direction, inner_size); let inner_main = inner_size[main_axis];
let extra_space = f32::max(main_to_fill - inner_main, 0.0); let extra_space = f32::max(main_to_fill - inner_main, 0.0);
let grow_main = f32::max(extra_space / grow_count as f32, 0.0).floor_ui(); let grow_main = f32::max(extra_space / grow_count as f32, 0.0).floor_ui();
@@ -592,7 +583,7 @@ impl<'atom> SizedAtomLayout<'atom> {
} else { } else {
inner_main inner_main
}; };
let block_size = main_cross_vec(direction, block_main, cross_axis(direction, inner_size)); let block_size = main_cross_vec(direction, block_main, inner_size[cross_axis]);
let aligned_rect = align2.align_size_within_rect(block_size, inner_rect); let aligned_rect = align2.align_size_within_rect(block_size, inner_rect);
// For reversed directions the first atom sits at the far end, so we lay them out in // For reversed directions the first atom sits at the far end, so we lay them out in
@@ -602,7 +593,7 @@ impl<'atom> SizedAtomLayout<'atom> {
} }
// The cursor walks the main axis from the start (left/top) of the aligned block. // The cursor walks the main axis from the start (left/top) of the aligned block.
let mut cursor = main_axis(direction, aligned_rect.min.to_vec2()); let mut cursor = aligned_rect.min.to_vec2()[main_axis];
let mut response = AtomLayoutResponse::empty(response); let mut response = AtomLayoutResponse::empty(response);
@@ -612,7 +603,7 @@ impl<'atom> SizedAtomLayout<'atom> {
// https://github.com/emilk/egui/pull/5830#discussion_r2079627864 // https://github.com/emilk/egui/pull/5830#discussion_r2079627864
let growth = if sized.is_grow() { grow_main } else { 0.0 }; let growth = if sized.is_grow() { grow_main } else { 0.0 };
let atom_main = main_axis(direction, size) + growth; let atom_main = size[main_axis] + growth;
// The cell spans the cross axis fully and `atom_main` along the main axis. // The cell spans the cross axis fully and `atom_main` along the main axis.
let cell = main_cross_rect(direction, aligned_rect, cursor, cursor + atom_main); let cell = main_cross_rect(direction, aligned_rect, cursor, cursor + atom_main);
@@ -637,12 +628,8 @@ impl<'atom> SizedAtomLayout<'atom> {
} }
SizedAtomKind::Empty { .. } => {} SizedAtomKind::Empty { .. } => {}
SizedAtomKind::Layout(layout) => { SizedAtomKind::Layout(layout) => {
// Hand the nested layout the full (possibly grown) cell extent along the main // TODO(lucasmerlin): Add some kind of justify flag, right now nested atoms are always
// axis so its own `grow` atoms can expand, while keeping its measured cross // shown fully stretched.
// size and honoring this atom's alignment within the cell.
let layout_size =
main_cross_vec(direction, atom_main, cross_axis(direction, size));
let layout_rect = sized.align.align_size_within_rect(layout_size, cell);
let layout_response = ui.interact(cell, layout.id, layout.sense); let layout_response = ui.interact(cell, layout.id, layout.sense);
layout.paint_at(ui, cell, layout_response); layout.paint_at(ui, cell, layout_response);
} }