Correctly align buttons and labels in justified layouts
This commit is contained in:
parent
c520f2e9cc
commit
a97141fe06
3 changed files with 44 additions and 12 deletions
|
@ -335,14 +335,13 @@ impl LayoutDemo {
|
||||||
|
|
||||||
pub fn content_ui(&mut self, ui: &mut Ui) {
|
pub fn content_ui(&mut self, ui: &mut Ui) {
|
||||||
// ui.label(format!("Available space: {:?}", ui.available().size()));
|
// ui.label(format!("Available space: {:?}", ui.available().size()));
|
||||||
if ui.button("Reset").clicked {
|
if ui.button("Default").clicked {
|
||||||
*self = Default::default();
|
*self = Default::default();
|
||||||
}
|
}
|
||||||
|
|
||||||
ui.separator();
|
ui.separator();
|
||||||
ui.label("Direction:");
|
|
||||||
|
|
||||||
// TODO: enum iter
|
|
||||||
|
|
||||||
|
ui.label("Main Direction:");
|
||||||
for &dir in &[
|
for &dir in &[
|
||||||
Direction::LeftToRight,
|
Direction::LeftToRight,
|
||||||
Direction::RightToLeft,
|
Direction::RightToLeft,
|
||||||
|
@ -354,12 +353,14 @@ impl LayoutDemo {
|
||||||
|
|
||||||
ui.separator();
|
ui.separator();
|
||||||
|
|
||||||
ui.label("Align:");
|
ui.label("Cross Align:");
|
||||||
for &align in &[Align::Min, Align::Center, Align::Max] {
|
for &align in &[Align::Min, Align::Center, Align::Max] {
|
||||||
ui.radio_value(&mut self.cross_align, align, format!("{:?}", align));
|
ui.radio_value(&mut self.cross_align, align, format!("{:?}", align));
|
||||||
}
|
}
|
||||||
|
|
||||||
ui.checkbox(&mut self.cross_justify, "Justified")
|
ui.separator();
|
||||||
|
|
||||||
|
ui.checkbox(&mut self.cross_justify, "Cross Justified")
|
||||||
.on_hover_text("Try to fill full width/height (e.g. buttons)");
|
.on_hover_text("Try to fill full width/height (e.g. buttons)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -216,6 +216,37 @@ impl Layout {
|
||||||
|| self.main_dir.is_vertical() && self.cross_align == Align::Max
|
|| self.main_dir.is_vertical() && self.cross_align == Align::Max
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn horizontal_align(self) -> Align {
|
||||||
|
match self.main_dir {
|
||||||
|
Direction::LeftToRight => Align::left(),
|
||||||
|
Direction::RightToLeft => Align::right(),
|
||||||
|
Direction::TopDown | Direction::BottomUp => self.cross_align,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn vertical_align(self) -> Align {
|
||||||
|
match self.main_dir {
|
||||||
|
Direction::TopDown => Align::top(),
|
||||||
|
Direction::BottomUp => Align::bottom(),
|
||||||
|
Direction::LeftToRight | Direction::RightToLeft => self.cross_align,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn align_size_within_rect(&self, size: Vec2, outer: Rect) -> Rect {
|
||||||
|
let x = match self.horizontal_align() {
|
||||||
|
Align::Min => outer.left(),
|
||||||
|
Align::Center => outer.center().x - size.x / 2.0,
|
||||||
|
Align::Max => outer.right() - size.x,
|
||||||
|
};
|
||||||
|
let y = match self.vertical_align() {
|
||||||
|
Align::Min => outer.top(),
|
||||||
|
Align::Center => outer.center().y - size.y / 2.0,
|
||||||
|
Align::Max => outer.bottom() - size.y,
|
||||||
|
};
|
||||||
|
|
||||||
|
Rect::from_min_size(Pos2::new(x, y), size)
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
fn initial_cursor(self, max_rect: Rect) -> Pos2 {
|
fn initial_cursor(self, max_rect: Rect) -> Pos2 {
|
||||||
|
@ -303,6 +334,7 @@ impl Layout {
|
||||||
/// for justified layouts, like in menus.
|
/// for justified layouts, like in menus.
|
||||||
///
|
///
|
||||||
/// You may get LESS space than you asked for if the current layout won't fit what you asked for.
|
/// You may get LESS space than you asked for if the current layout won't fit what you asked for.
|
||||||
|
#[allow(clippy::collapsible_if)]
|
||||||
pub fn next_space(self, region: &Region, minimum_child_size: Vec2) -> Rect {
|
pub fn next_space(self, region: &Region, minimum_child_size: Vec2) -> Rect {
|
||||||
let available_size = self.available_finite(region).size();
|
let available_size = self.available_finite(region).size();
|
||||||
let available_size = available_size.at_least(minimum_child_size);
|
let available_size = available_size.at_least(minimum_child_size);
|
||||||
|
|
|
@ -127,6 +127,7 @@ impl Widget for Label {
|
||||||
fn ui(self, ui: &mut Ui) -> Response {
|
fn ui(self, ui: &mut Ui) -> Response {
|
||||||
let galley = self.layout(ui);
|
let galley = self.layout(ui);
|
||||||
let rect = ui.allocate_space(galley.size);
|
let rect = ui.allocate_space(galley.size);
|
||||||
|
let rect = ui.layout().align_size_within_rect(galley.size, rect);
|
||||||
self.paint_galley(ui, rect.min, galley);
|
self.paint_galley(ui, rect.min, galley);
|
||||||
ui.interact_hover(rect)
|
ui.interact_hover(rect)
|
||||||
}
|
}
|
||||||
|
@ -314,11 +315,10 @@ impl Widget for Button {
|
||||||
let id = ui.make_position_id();
|
let id = ui.make_position_id();
|
||||||
let response = ui.interact(rect, id, sense);
|
let response = ui.interact(rect, id, sense);
|
||||||
let visuals = ui.style().interact(&response);
|
let visuals = ui.style().interact(&response);
|
||||||
// let text_cursor = response.rect.center() - 0.5 * galley.size; // centered-centered (looks bad for justified drop-down menus
|
let text_cursor = ui
|
||||||
let text_cursor = pos2(
|
.layout()
|
||||||
response.rect.left() + button_padding.x,
|
.align_size_within_rect(galley.size, response.rect.shrink2(button_padding))
|
||||||
response.rect.center().y - 0.5 * galley.size.y,
|
.min;
|
||||||
); // left-centered
|
|
||||||
let fill = fill.unwrap_or(visuals.bg_fill);
|
let fill = fill.unwrap_or(visuals.bg_fill);
|
||||||
ui.painter().rect(
|
ui.painter().rect(
|
||||||
response.rect,
|
response.rect,
|
||||||
|
@ -473,7 +473,6 @@ impl Widget for RadioButton {
|
||||||
desired_size = desired_size.at_least(ui.style().spacing.interact_size);
|
desired_size = desired_size.at_least(ui.style().spacing.interact_size);
|
||||||
desired_size.y = desired_size.y.max(icon_width);
|
desired_size.y = desired_size.y.max(icon_width);
|
||||||
let rect = ui.allocate_space(desired_size);
|
let rect = ui.allocate_space(desired_size);
|
||||||
|
|
||||||
let id = ui.make_position_id();
|
let id = ui.make_position_id();
|
||||||
let response = ui.interact(rect, id, Sense::click());
|
let response = ui.interact(rect, id, Sense::click());
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue