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:
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user