mirror of
https://github.com/emilk/egui.git
synced 2026-09-03 15:20:05 -04:00
Add Align2 helpers (#8485)
Add utilities to make it easier to construct and use `Align2` --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -345,9 +345,7 @@ impl<'a> AtomLayout<'a> {
|
||||
|
||||
let mut shrink_item = None;
|
||||
|
||||
let align2 = align2.unwrap_or_else(|| {
|
||||
Align2([ui.layout().horizontal_align(), ui.layout().vertical_align()])
|
||||
});
|
||||
let align2 = align2.unwrap_or_else(|| ui.layout().align2());
|
||||
|
||||
if atoms.len() > 1 {
|
||||
let gap_space = gap * (atoms.len() as f32 - 1.0);
|
||||
|
||||
@@ -348,8 +348,8 @@ impl Layout {
|
||||
}
|
||||
|
||||
/// e.g. for when aligning text within a button.
|
||||
fn align2(&self) -> Align2 {
|
||||
Align2([self.horizontal_align(), self.vertical_align()])
|
||||
pub fn align2(&self) -> Align2 {
|
||||
Align2::new(self.horizontal_align(), self.vertical_align())
|
||||
}
|
||||
|
||||
pub fn horizontal_justify(&self) -> bool {
|
||||
@@ -614,10 +614,10 @@ impl Layout {
|
||||
}
|
||||
|
||||
let align2 = match self.main_dir {
|
||||
Direction::LeftToRight => Align2([Align::LEFT, self.vertical_align()]),
|
||||
Direction::RightToLeft => Align2([Align::RIGHT, self.vertical_align()]),
|
||||
Direction::TopDown => Align2([self.horizontal_align(), Align::TOP]),
|
||||
Direction::BottomUp => Align2([self.horizontal_align(), Align::BOTTOM]),
|
||||
Direction::LeftToRight => self.align2().with_x(Align::LEFT),
|
||||
Direction::RightToLeft => self.align2().with_x(Align::RIGHT),
|
||||
Direction::TopDown => self.align2().with_y(Align::TOP),
|
||||
Direction::BottomUp => self.align2().with_y(Align::BOTTOM),
|
||||
};
|
||||
|
||||
let mut frame_rect = align2.align_size_within_rect(frame_size, available_rect);
|
||||
@@ -818,22 +818,22 @@ impl Layout {
|
||||
Direction::LeftToRight => {
|
||||
painter.line_segment([cursor.left_top(), cursor.left_bottom()], stroke);
|
||||
painter.arrow(next_pos, vec2(l, 0.0), stroke);
|
||||
Align2([Align::LEFT, self.vertical_align()])
|
||||
self.align2().with_x(Align::LEFT)
|
||||
}
|
||||
Direction::RightToLeft => {
|
||||
painter.line_segment([cursor.right_top(), cursor.right_bottom()], stroke);
|
||||
painter.arrow(next_pos, vec2(-l, 0.0), stroke);
|
||||
Align2([Align::RIGHT, self.vertical_align()])
|
||||
self.align2().with_x(Align::RIGHT)
|
||||
}
|
||||
Direction::TopDown => {
|
||||
painter.line_segment([cursor.left_top(), cursor.right_top()], stroke);
|
||||
painter.arrow(next_pos, vec2(0.0, l), stroke);
|
||||
Align2([self.horizontal_align(), Align::TOP])
|
||||
self.align2().with_y(Align::TOP)
|
||||
}
|
||||
Direction::BottomUp => {
|
||||
painter.line_segment([cursor.left_bottom(), cursor.right_bottom()], stroke);
|
||||
painter.arrow(next_pos, vec2(0.0, -l), stroke);
|
||||
Align2([self.horizontal_align(), Align::BOTTOM])
|
||||
self.align2().with_y(Align::BOTTOM)
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -860,7 +860,7 @@ impl Slider<'_> {
|
||||
SliderOrientation::Horizontal => rect.x_range().shrink(handle_radius),
|
||||
// The vertical case has to be flipped because the largest slider value maps to the
|
||||
// lowest y value (which is at the top)
|
||||
SliderOrientation::Vertical => rect.y_range().shrink(handle_radius).flip(),
|
||||
SliderOrientation::Vertical => rect.y_range().shrink(handle_radius).flipped(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -75,10 +75,10 @@ impl crate::View for TextEditDemo {
|
||||
let output = egui::TextEdit::multiline(text)
|
||||
.hint_text("Type something!")
|
||||
// Atoms are centered by default, so we need to pass the right align here:
|
||||
.prefix("🔎".atom_align(Align2([Align::LEFT, *valign])))
|
||||
.prefix("🔎".atom_align(Align2::new(Align::LEFT, *valign)))
|
||||
.suffix(
|
||||
egui::Atom::custom(clear_id, clear_size)
|
||||
.atom_align(Align2([Align::RIGHT, *valign])),
|
||||
.atom_align(Align2::new(Align::RIGHT, *valign)),
|
||||
)
|
||||
.horizontal_align(*halign)
|
||||
.vertical_align(*valign)
|
||||
|
||||
@@ -52,7 +52,8 @@ impl Align {
|
||||
|
||||
/// Returns the inverse alignment.
|
||||
/// `Min` becomes `Max`, `Center` stays the same, `Max` becomes `Min`.
|
||||
pub fn flip(self) -> Self {
|
||||
#[must_use]
|
||||
pub fn flipped(self) -> Self {
|
||||
match self {
|
||||
Self::Min => Self::Max,
|
||||
Self::Center => Self::Center,
|
||||
@@ -60,6 +61,14 @@ impl Align {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the inverse alignment.
|
||||
/// `Min` becomes `Max`, `Center` stays the same, `Max` becomes `Min`.
|
||||
#[must_use]
|
||||
#[deprecated = "Renamed to `flipped`"]
|
||||
pub fn flip(self) -> Self {
|
||||
self.flipped()
|
||||
}
|
||||
|
||||
/// Returns a range of given size within a specified range.
|
||||
///
|
||||
/// If the requested `size` is bigger than the size of `range`, then the returned
|
||||
@@ -163,6 +172,37 @@ impl Align2 {
|
||||
}
|
||||
|
||||
impl Align2 {
|
||||
#[inline(always)]
|
||||
pub fn new(x: Align, y: Align) -> Self {
|
||||
Self([x, y])
|
||||
}
|
||||
|
||||
/// Set align on the horizontal axis.
|
||||
#[inline]
|
||||
pub fn with_x(mut self, x: Align) -> Self {
|
||||
self.set_x(x);
|
||||
self
|
||||
}
|
||||
|
||||
/// Set align on the vertical axis.
|
||||
#[inline]
|
||||
pub fn with_y(mut self, y: Align) -> Self {
|
||||
self.set_y(y);
|
||||
self
|
||||
}
|
||||
|
||||
/// Set align on the horizontal axis.
|
||||
#[inline(always)]
|
||||
pub fn set_x(&mut self, x: Align) {
|
||||
self.0[0] = x;
|
||||
}
|
||||
|
||||
/// Set align on the vertical axis.
|
||||
#[inline(always)]
|
||||
pub fn set_y(&mut self, y: Align) {
|
||||
self.0[1] = y;
|
||||
}
|
||||
|
||||
/// Returns an alignment by the X (horizontal) axis
|
||||
#[inline(always)]
|
||||
pub fn x(self) -> Align {
|
||||
@@ -182,20 +222,47 @@ impl Align2 {
|
||||
|
||||
/// Flip on the x-axis
|
||||
/// e.g. `TOP_LEFT` -> `TOP_RIGHT`
|
||||
#[must_use]
|
||||
pub fn flipped_x(self) -> Self {
|
||||
self.with_x(self.x().flipped())
|
||||
}
|
||||
|
||||
/// Flip on the x-axis
|
||||
/// e.g. `TOP_LEFT` -> `TOP_RIGHT`
|
||||
#[must_use]
|
||||
#[deprecated = "Renamed to `flipped_x`"]
|
||||
pub fn flip_x(self) -> Self {
|
||||
Self([self.x().flip(), self.y()])
|
||||
self.flipped_x()
|
||||
}
|
||||
|
||||
/// Flip on the y-axis
|
||||
/// e.g. `TOP_LEFT` -> `BOTTOM_LEFT`
|
||||
#[must_use]
|
||||
pub fn flipped_y(self) -> Self {
|
||||
self.with_y(self.y().flipped())
|
||||
}
|
||||
|
||||
/// Flip on the y-axis
|
||||
/// e.g. `TOP_LEFT` -> `BOTTOM_LEFT`
|
||||
#[must_use]
|
||||
#[deprecated = "Renamed to `flipped_y`"]
|
||||
pub fn flip_y(self) -> Self {
|
||||
Self([self.x(), self.y().flip()])
|
||||
self.flipped_y()
|
||||
}
|
||||
|
||||
/// Flip on both axes
|
||||
/// e.g. `TOP_LEFT` -> `BOTTOM_RIGHT`
|
||||
#[must_use]
|
||||
pub fn flipped(self) -> Self {
|
||||
Self::new(self.x().flipped(), self.y().flipped())
|
||||
}
|
||||
|
||||
/// Flip on both axes
|
||||
/// e.g. `TOP_LEFT` -> `BOTTOM_RIGHT`
|
||||
#[must_use]
|
||||
#[deprecated = "Renamed to `flipped`"]
|
||||
pub fn flip(self) -> Self {
|
||||
Self([self.x().flip(), self.y().flip()])
|
||||
self.flipped()
|
||||
}
|
||||
|
||||
/// Used e.g. to anchor a piece of text to a part of the rectangle.
|
||||
|
||||
@@ -102,13 +102,21 @@ impl Rangef {
|
||||
/// Flip the min and the max
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn flip(self) -> Self {
|
||||
pub fn flipped(self) -> Self {
|
||||
Self {
|
||||
min: self.max,
|
||||
max: self.min,
|
||||
}
|
||||
}
|
||||
|
||||
/// Flip the min and the max
|
||||
#[inline]
|
||||
#[must_use]
|
||||
#[deprecated = "Renamed to `flipped`"]
|
||||
pub fn flip(self) -> Self {
|
||||
self.flipped()
|
||||
}
|
||||
|
||||
/// The overlap of two ranges, i.e. the range that is contained by both.
|
||||
///
|
||||
/// If the ranges do not overlap, returns a range with `span() < 0.0`.
|
||||
|
||||
@@ -161,7 +161,7 @@ impl RectAlign {
|
||||
pub fn outside(align: Align2) -> Self {
|
||||
Self {
|
||||
parent: align,
|
||||
child: align.flip(),
|
||||
child: align.flipped(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -206,33 +206,58 @@ impl RectAlign {
|
||||
}
|
||||
|
||||
/// Flip the alignment on the x-axis.
|
||||
pub fn flip_x(self) -> Self {
|
||||
#[must_use]
|
||||
pub fn flipped_x(self) -> Self {
|
||||
Self {
|
||||
parent: self.parent.flip_x(),
|
||||
child: self.child.flip_x(),
|
||||
parent: self.parent.flipped_x(),
|
||||
child: self.child.flipped_x(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Flip the alignment on the x-axis.
|
||||
#[must_use]
|
||||
#[deprecated = "Renamed to `flipped_x`"]
|
||||
pub fn flip_x(self) -> Self {
|
||||
self.flipped_x()
|
||||
}
|
||||
|
||||
/// Flip the alignment on the y-axis.
|
||||
#[must_use]
|
||||
pub fn flipped_y(self) -> Self {
|
||||
Self {
|
||||
parent: self.parent.flipped_y(),
|
||||
child: self.child.flipped_y(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Flip the alignment on the y-axis.
|
||||
#[must_use]
|
||||
#[deprecated = "Renamed to `flipped_y`"]
|
||||
pub fn flip_y(self) -> Self {
|
||||
self.flipped_y()
|
||||
}
|
||||
|
||||
/// Flip the alignment on both axes.
|
||||
#[must_use]
|
||||
pub fn flipped(self) -> Self {
|
||||
Self {
|
||||
parent: self.parent.flip_y(),
|
||||
child: self.child.flip_y(),
|
||||
parent: self.parent.flipped(),
|
||||
child: self.child.flipped(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Flip the alignment on both axes.
|
||||
#[must_use]
|
||||
#[deprecated = "Renamed to `flipped`"]
|
||||
pub fn flip(self) -> Self {
|
||||
Self {
|
||||
parent: self.parent.flip(),
|
||||
child: self.child.flip(),
|
||||
}
|
||||
self.flipped()
|
||||
}
|
||||
|
||||
/// Returns the 3 alternative [`RectAlign`]s that are flipped in various ways, for use
|
||||
/// with [`RectAlign::find_best_align`].
|
||||
#[must_use]
|
||||
pub fn symmetries(self) -> [Self; 3] {
|
||||
[self.flip_x(), self.flip_y(), self.flip()]
|
||||
[self.flipped_x(), self.flipped_y(), self.flipped()]
|
||||
}
|
||||
|
||||
/// Look for the first alternative [`RectAlign`] that allows the child rect to fit
|
||||
|
||||
Reference in New Issue
Block a user