[grid] Ensure the contents of each grid cell is aligned left+center
This commit is contained in:
parent
db591bc56c
commit
03c9cda89b
5 changed files with 87 additions and 23 deletions
|
@ -100,6 +100,15 @@ impl GridLayout {
|
|||
Rect::from_min_size(cursor, size)
|
||||
}
|
||||
|
||||
pub(crate) fn align_size_within_rect(&self, size: Vec2, frame: Rect) -> Rect {
|
||||
// TODO: allow this alignment to be customized
|
||||
Align2::LEFT_CENTER.align_size_within_rect(size, frame)
|
||||
}
|
||||
|
||||
pub(crate) fn justify_or_align(&self, frame: Rect, size: Vec2) -> Rect {
|
||||
self.align_size_within_rect(size, frame)
|
||||
}
|
||||
|
||||
pub(crate) fn advance(&mut self, cursor: &mut Pos2, frame_rect: Rect, widget_rect: Rect) {
|
||||
self.curr_state
|
||||
.set_min_col_width(self.col, widget_rect.width());
|
||||
|
@ -145,6 +154,10 @@ impl GridLayout {
|
|||
|
||||
/// A simple `Grid` layout.
|
||||
///
|
||||
/// The contents of each cell be aligned to the left and center.
|
||||
/// If you want to add multiple widgets to a cell you need to group them with
|
||||
/// [`Ui::horizontal`], [`Ui::vertical`] etc.
|
||||
///
|
||||
/// ```
|
||||
/// # let ui = &mut egui::Ui::__test();
|
||||
/// egui::Grid::new("some_unique_id").show(ui, |ui| {
|
||||
|
@ -196,7 +209,11 @@ impl Grid {
|
|||
min_row_height,
|
||||
} = self;
|
||||
|
||||
ui.wrap(|ui| {
|
||||
// Each grid cell is aligned LEFT_CENTER.
|
||||
// If somebody wants to wrap more things inside a cell,
|
||||
// then we should pick a default layout that matches that alignment,
|
||||
// which we do here:
|
||||
ui.horizontal(|ui| {
|
||||
let id = ui.make_persistent_id(id_source);
|
||||
let grid = GridLayout {
|
||||
striped,
|
||||
|
|
|
@ -432,16 +432,27 @@ impl Layout {
|
|||
|
||||
/// Apply justify or alignment after calling `next_space`.
|
||||
pub(crate) fn justify_or_align(&self, rect: Rect, mut child_size: Vec2) -> Rect {
|
||||
if self.main_dir.is_horizontal() {
|
||||
if self.cross_justify {
|
||||
if self.cross_justify {
|
||||
if self.main_dir.is_horizontal() {
|
||||
child_size.y = rect.height(); // fill full height
|
||||
}
|
||||
Align2([Align::Center, self.cross_align]).align_size_within_rect(child_size, rect)
|
||||
} else {
|
||||
if self.cross_justify {
|
||||
} else {
|
||||
child_size.x = rect.width(); // fill full width
|
||||
}
|
||||
Align2([self.cross_align, Align::Center]).align_size_within_rect(child_size, rect)
|
||||
}
|
||||
|
||||
match self.main_dir {
|
||||
Direction::LeftToRight => {
|
||||
Align2([Align::Min, self.cross_align]).align_size_within_rect(child_size, rect)
|
||||
}
|
||||
Direction::RightToLeft => {
|
||||
Align2([Align::Max, self.cross_align]).align_size_within_rect(child_size, rect)
|
||||
}
|
||||
Direction::TopDown => {
|
||||
Align2([self.cross_align, Align::Min]).align_size_within_rect(child_size, rect)
|
||||
}
|
||||
Direction::BottomUp => {
|
||||
Align2([self.cross_align, Align::Max]).align_size_within_rect(child_size, rect)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -58,7 +58,11 @@ impl Placer {
|
|||
|
||||
impl Placer {
|
||||
pub(crate) fn align_size_within_rect(&self, size: Vec2, outer: Rect) -> Rect {
|
||||
self.layout.align_size_within_rect(size, outer)
|
||||
if let Some(grid) = &self.grid {
|
||||
grid.align_size_within_rect(size, outer)
|
||||
} else {
|
||||
self.layout.align_size_within_rect(size, outer)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn available_rect_before_wrap(&self) -> Rect {
|
||||
|
@ -102,7 +106,11 @@ impl Placer {
|
|||
|
||||
/// Apply justify or alignment after calling `next_space`.
|
||||
pub(crate) fn justify_or_align(&self, rect: Rect, child_size: Vec2) -> Rect {
|
||||
self.layout.justify_or_align(rect, child_size)
|
||||
if let Some(grid) = &self.grid {
|
||||
grid.justify_or_align(rect, child_size)
|
||||
} else {
|
||||
self.layout.justify_or_align(rect, child_size)
|
||||
}
|
||||
}
|
||||
|
||||
/// Advance the cursor by this many points.
|
||||
|
@ -115,7 +123,7 @@ impl Placer {
|
|||
}
|
||||
|
||||
/// Advance cursor after a widget was added to a specific rectangle
|
||||
/// and expand the region min_rect.
|
||||
/// and expand the region `min_rect`.
|
||||
///
|
||||
/// * `frame_rect`: the frame inside which a widget was e.g. centered
|
||||
/// * `widget_rect`: the actual rect used by the widget
|
||||
|
|
|
@ -4,11 +4,15 @@ use crate::*;
|
|||
#[must_use = "You should put this widget in an ui with `ui.add(widget);`"]
|
||||
pub struct Separator {
|
||||
spacing: f32,
|
||||
is_horizontal_line: Option<bool>,
|
||||
}
|
||||
|
||||
impl Separator {
|
||||
pub fn new() -> Self {
|
||||
Self { spacing: 6.0 }
|
||||
Self {
|
||||
spacing: 6.0,
|
||||
is_horizontal_line: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// How much space we take up. The line is painted in the middle of this.
|
||||
|
@ -16,31 +20,53 @@ impl Separator {
|
|||
self.spacing = spacing;
|
||||
self
|
||||
}
|
||||
|
||||
/// Explicitly ask for a horizontal line.
|
||||
/// By default you will get a horizontal line in vertical layouts,
|
||||
/// and a vertical line in horizontal layouts.
|
||||
pub fn horizontal(mut self) -> Self {
|
||||
self.is_horizontal_line = Some(true);
|
||||
self
|
||||
}
|
||||
|
||||
/// Explicitly ask for a vertical line.
|
||||
/// By default you will get a horizontal line in vertical layouts,
|
||||
/// and a vertical line in horizontal layouts.
|
||||
pub fn vertical(mut self) -> Self {
|
||||
self.is_horizontal_line = Some(false);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Widget for Separator {
|
||||
fn ui(self, ui: &mut Ui) -> Response {
|
||||
let Separator { spacing } = self;
|
||||
let Separator {
|
||||
spacing,
|
||||
is_horizontal_line,
|
||||
} = self;
|
||||
|
||||
let is_horizontal_line =
|
||||
is_horizontal_line.unwrap_or_else(|| !ui.layout().main_dir().is_horizontal());
|
||||
|
||||
let available_space = ui.available_size_before_wrap_finite();
|
||||
|
||||
let size = if ui.layout().main_dir().is_horizontal() {
|
||||
vec2(spacing, available_space.y)
|
||||
} else {
|
||||
let size = if is_horizontal_line {
|
||||
vec2(available_space.x, spacing)
|
||||
} else {
|
||||
vec2(spacing, available_space.y)
|
||||
};
|
||||
|
||||
let (rect, response) = ui.allocate_at_least(size, Sense::hover());
|
||||
let points = if ui.layout().main_dir().is_horizontal() {
|
||||
[
|
||||
pos2(rect.center().x, rect.top()),
|
||||
pos2(rect.center().x, rect.bottom()),
|
||||
]
|
||||
} else {
|
||||
let points = if is_horizontal_line {
|
||||
[
|
||||
pos2(rect.left(), rect.center().y),
|
||||
pos2(rect.right(), rect.center().y),
|
||||
]
|
||||
} else {
|
||||
[
|
||||
pos2(rect.center().x, rect.top()),
|
||||
pos2(rect.center().x, rect.bottom()),
|
||||
]
|
||||
};
|
||||
let stroke = ui.style().visuals.widgets.noninteractive.bg_stroke;
|
||||
ui.painter().line_segment(points, stroke);
|
||||
|
|
|
@ -131,7 +131,9 @@ impl super::View for WidgetGallery {
|
|||
ui.end_row();
|
||||
|
||||
ui.label("Separator:");
|
||||
ui.separator();
|
||||
// Putting a separator in a grid is kind of meaningless since there is no well-defined direction.
|
||||
// Normally you'd just do ui.separator(), but here we need to explicitly pick a dimension:
|
||||
ui.add(egui::Separator::new().horizontal());
|
||||
ui.end_row();
|
||||
|
||||
ui.label("CollapsingHeader:");
|
||||
|
|
Loading…
Reference in a new issue