Add helper struct Align2
This commit is contained in:
parent
1b3a5e5b50
commit
72ed94fcb3
5 changed files with 68 additions and 51 deletions
|
@ -50,50 +50,66 @@ impl Default for Align {
|
|||
}
|
||||
}
|
||||
|
||||
pub type Align2 = (Align, Align);
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
pub const LEFT_BOTTOM: Align2 = (Align::Min, Align::Max);
|
||||
pub const LEFT_CENTER: Align2 = (Align::Min, Align::Center);
|
||||
pub const LEFT_TOP: Align2 = (Align::Min, Align::Min);
|
||||
pub const CENTER_BOTTOM: Align2 = (Align::Center, Align::Max);
|
||||
pub const CENTER_CENTER: Align2 = (Align::Center, Align::Center);
|
||||
pub const CENTER_TOP: Align2 = (Align::Center, Align::Min);
|
||||
pub const RIGHT_BOTTOM: Align2 = (Align::Max, Align::Max);
|
||||
pub const RIGHT_CENTER: Align2 = (Align::Max, Align::Center);
|
||||
pub const RIGHT_TOP: Align2 = (Align::Max, Align::Min);
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
|
||||
#[cfg_attr(feature = "serde", serde(rename_all = "snake_case"))]
|
||||
pub struct Align2(pub [Align; 2]);
|
||||
|
||||
/// Used e.g. to anchor a piece of text to a part of the rectangle.
|
||||
/// Give a position within the rect, specified by the aligns
|
||||
pub(crate) fn anchor_rect(rect: Rect, anchor: (Align, Align)) -> Rect {
|
||||
let x = match anchor.0 {
|
||||
Align::Min => rect.left(),
|
||||
Align::Center => rect.left() - 0.5 * rect.width(),
|
||||
Align::Max => rect.left() - rect.width(),
|
||||
};
|
||||
let y = match anchor.1 {
|
||||
Align::Min => rect.top(),
|
||||
Align::Center => rect.top() - 0.5 * rect.height(),
|
||||
Align::Max => rect.top() - rect.height(),
|
||||
};
|
||||
Rect::from_min_size(pos2(x, y), rect.size())
|
||||
impl Align2 {
|
||||
pub const LEFT_BOTTOM: Align2 = Align2([Align::Min, Align::Max]);
|
||||
pub const LEFT_CENTER: Align2 = Align2([Align::Min, Align::Center]);
|
||||
pub const LEFT_TOP: Align2 = Align2([Align::Min, Align::Min]);
|
||||
pub const CENTER_BOTTOM: Align2 = Align2([Align::Center, Align::Max]);
|
||||
pub const CENTER_CENTER: Align2 = Align2([Align::Center, Align::Center]);
|
||||
pub const CENTER_TOP: Align2 = Align2([Align::Center, Align::Min]);
|
||||
pub const RIGHT_BOTTOM: Align2 = Align2([Align::Max, Align::Max]);
|
||||
pub const RIGHT_CENTER: Align2 = Align2([Align::Max, Align::Center]);
|
||||
pub const RIGHT_TOP: Align2 = Align2([Align::Max, Align::Min]);
|
||||
}
|
||||
|
||||
/// e.g. center a size within a given frame
|
||||
pub fn align_size_within_rect(align: (Align, Align), size: Vec2, frame: Rect) -> Rect {
|
||||
let x = match align.0 {
|
||||
Align::Min => frame.left(),
|
||||
Align::Center => frame.center().x - size.x / 2.0,
|
||||
Align::Max => frame.right() - size.x,
|
||||
};
|
||||
let y = match align.1 {
|
||||
Align::Min => frame.top(),
|
||||
Align::Center => frame.center().y - size.y / 2.0,
|
||||
Align::Max => frame.bottom() - size.y,
|
||||
};
|
||||
impl Align2 {
|
||||
pub fn x(self) -> Align {
|
||||
self.0[0]
|
||||
}
|
||||
pub fn y(self) -> Align {
|
||||
self.0[1]
|
||||
}
|
||||
|
||||
Rect::from_min_size(Pos2::new(x, y), size)
|
||||
/// Used e.g. to anchor a piece of text to a part of the rectangle.
|
||||
/// Give a position within the rect, specified by the aligns
|
||||
pub(crate) fn anchor_rect(self, rect: Rect) -> Rect {
|
||||
let x = match self.x() {
|
||||
Align::Min => rect.left(),
|
||||
Align::Center => rect.left() - 0.5 * rect.width(),
|
||||
Align::Max => rect.left() - rect.width(),
|
||||
};
|
||||
let y = match self.y() {
|
||||
Align::Min => rect.top(),
|
||||
Align::Center => rect.top() - 0.5 * rect.height(),
|
||||
Align::Max => rect.top() - rect.height(),
|
||||
};
|
||||
Rect::from_min_size(pos2(x, y), rect.size())
|
||||
}
|
||||
|
||||
/// e.g. center a size within a given frame
|
||||
pub fn align_size_within_rect(self, size: Vec2, frame: Rect) -> Rect {
|
||||
let x = match self.x() {
|
||||
Align::Min => frame.left(),
|
||||
Align::Center => frame.center().x - size.x / 2.0,
|
||||
Align::Max => frame.right() - size.x,
|
||||
};
|
||||
let y = match self.y() {
|
||||
Align::Min => frame.top(),
|
||||
Align::Center => frame.center().y - size.y / 2.0,
|
||||
Align::Max => frame.bottom() - size.y,
|
||||
};
|
||||
|
||||
Rect::from_min_size(Pos2::new(x, y), size)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn center_size_in_rect(size: Vec2, frame: Rect) -> Rect {
|
||||
align_size_within_rect(CENTER_CENTER, size, frame)
|
||||
Align2::CENTER_CENTER.align_size_within_rect(size, frame)
|
||||
}
|
||||
|
|
|
@ -496,6 +496,7 @@ impl Layout {
|
|||
impl Layout {
|
||||
/// Shows where the next widget is going to be placed
|
||||
pub(crate) fn debug_paint_cursor(&self, region: &Region, painter: &crate::Painter) {
|
||||
use crate::align::Align2;
|
||||
use crate::paint::*;
|
||||
|
||||
let cursor = region.cursor;
|
||||
|
@ -510,19 +511,19 @@ impl Layout {
|
|||
match self.main_dir {
|
||||
Direction::LeftToRight => {
|
||||
painter.arrow(cursor, vec2(l, 0.0), stroke);
|
||||
align = (Align::Min, Align::Min);
|
||||
align = Align2::LEFT_TOP;
|
||||
}
|
||||
Direction::RightToLeft => {
|
||||
painter.arrow(cursor, vec2(-l, 0.0), stroke);
|
||||
align = (Align::Max, Align::Min);
|
||||
align = Align2::RIGHT_TOP;
|
||||
}
|
||||
Direction::TopDown => {
|
||||
painter.arrow(cursor, vec2(0.0, l), stroke);
|
||||
align = (Align::Min, Align::Min);
|
||||
align = Align2::LEFT_TOP;
|
||||
}
|
||||
Direction::BottomUp => {
|
||||
painter.arrow(cursor, vec2(0.0, -l), stroke);
|
||||
align = (Align::Min, Align::Max);
|
||||
align = Align2::LEFT_BOTTOM;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use {
|
||||
super::{fonts::TextStyle, Color32, Fonts, Galley, Triangles},
|
||||
crate::{
|
||||
align::{anchor_rect, Align},
|
||||
align::Align2,
|
||||
math::{Pos2, Rect},
|
||||
*,
|
||||
},
|
||||
|
@ -127,14 +127,14 @@ impl PaintCmd {
|
|||
pub fn text(
|
||||
fonts: &Fonts,
|
||||
pos: Pos2,
|
||||
anchor: (Align, Align),
|
||||
anchor: Align2,
|
||||
text: impl Into<String>,
|
||||
text_style: TextStyle,
|
||||
color: Color32,
|
||||
) -> Self {
|
||||
let font = &fonts[text_style];
|
||||
let galley = font.layout_multiline(text.into(), f32::INFINITY);
|
||||
let rect = anchor_rect(Rect::from_min_size(pos, galley.size), anchor);
|
||||
let rect = anchor.anchor_rect(Rect::from_min_size(pos, galley.size));
|
||||
Self::Text {
|
||||
pos: rect.min,
|
||||
galley,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::{
|
||||
align::{anchor_rect, Align, LEFT_TOP},
|
||||
align::Align2,
|
||||
layers::PaintCmdIdx,
|
||||
math::{Pos2, Rect, Vec2},
|
||||
paint::{Fonts, Galley, PaintCmd, Stroke, TextStyle},
|
||||
|
@ -135,14 +135,14 @@ impl Painter {
|
|||
pub fn debug_rect(&mut self, rect: Rect, color: Color32, text: impl Into<String>) {
|
||||
self.rect_stroke(rect, 0.0, (1.0, color));
|
||||
let text_style = TextStyle::Monospace;
|
||||
self.text(rect.min, LEFT_TOP, text.into(), text_style, color);
|
||||
self.text(rect.min, Align2::LEFT_TOP, text.into(), text_style, color);
|
||||
}
|
||||
|
||||
pub fn error(&self, pos: Pos2, text: impl std::fmt::Display) -> Rect {
|
||||
let text_style = TextStyle::Monospace;
|
||||
let font = &self.fonts()[text_style];
|
||||
let galley = font.layout_multiline(format!("🔥 {}", text), f32::INFINITY);
|
||||
let rect = anchor_rect(Rect::from_min_size(pos, galley.size), LEFT_TOP);
|
||||
let rect = Align2::LEFT_TOP.anchor_rect(Rect::from_min_size(pos, galley.size));
|
||||
let frame_rect = rect.expand(2.0);
|
||||
self.add(PaintCmd::Rect {
|
||||
rect: frame_rect,
|
||||
|
@ -253,14 +253,14 @@ impl Painter {
|
|||
pub fn text(
|
||||
&self,
|
||||
pos: Pos2,
|
||||
anchor: (Align, Align),
|
||||
anchor: Align2,
|
||||
text: impl Into<String>,
|
||||
text_style: TextStyle,
|
||||
text_color: Color32,
|
||||
) -> Rect {
|
||||
let font = &self.fonts()[text_style];
|
||||
let galley = font.layout_multiline(text.into(), f32::INFINITY);
|
||||
let rect = anchor_rect(Rect::from_min_size(pos, galley.size), anchor);
|
||||
let rect = anchor.anchor_rect(Rect::from_min_size(pos, galley.size));
|
||||
self.galley(rect.min, galley, text_style, text_color);
|
||||
rect
|
||||
}
|
||||
|
|
|
@ -91,7 +91,7 @@ impl FrameHistory {
|
|||
cmds.push(PaintCmd::text(
|
||||
ui.fonts(),
|
||||
pos2(rect.left(), y),
|
||||
align::LEFT_BOTTOM,
|
||||
egui::align::Align2::LEFT_BOTTOM,
|
||||
text,
|
||||
TextStyle::Monospace,
|
||||
Color32::WHITE,
|
||||
|
|
Loading…
Reference in a new issue