Update `Button` to correctly align contained image (#4891)

Similar to #4889

Updated the `ui` method of the `Button` widget so that the alignment
given by the layout is applied to the image contained in the button (if
one exists).

Currently, only the text inside the button has alignment applied to it,
and only when it is not accompanied by an image or shortcut text. Images
within buttons are always aligned to the centre left, no matter the
alignment of the containing `Ui`. This update now also applies this
alignment to an image when it has no accompanying text, which makes
buttons with an image and no text more consistent with the appearance of
ones with text and no image.

I've also made an additional change so that the vertical alignment is
now also respected when displaying some combination of image and text,
but the original horizontal alignment remains the same, so that the
image always appears left of the text. Any shortcut text now also
follows vertical alignment, but is always horizontally aligned to the
right.

Here are some comparisons of the difference between how buttons look
with different alignments, before and after this change:

### Before

![Before](https://github.com/user-attachments/assets/b5086ccb-765d-42e6-88a5-8fa427544568)

### After

![After](https://github.com/user-attachments/assets/ecf6c6aa-b1b9-4b45-be44-8c71665df5c3)

* [x] I have followed the instructions in the PR template
This commit is contained in:
PrimmR 2024-08-05 10:19:20 +01:00 committed by GitHub
parent 76fe6c855b
commit ed0254288a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 24 additions and 16 deletions

View File

@ -306,10 +306,14 @@ impl Widget for Button<'_> {
let mut cursor_x = rect.min.x + button_padding.x;
if let Some(image) = &image {
let image_rect = Rect::from_min_size(
pos2(cursor_x, rect.center().y - 0.5 - (image_size.y / 2.0)),
image_size,
);
let mut image_pos = ui
.layout()
.align_size_within_rect(image_size, rect.shrink2(button_padding))
.min;
if galley.is_some() || shortcut_galley.is_some() {
image_pos.x = cursor_x;
}
let image_rect = Rect::from_min_size(image_pos, image_size);
cursor_x += image_size.x;
let tlr = image.load_for_size(ui.ctx(), image_size);
widgets::image::paint_texture_load_result(
@ -331,22 +335,26 @@ impl Widget for Button<'_> {
}
if let Some(galley) = galley {
let text_pos = if image.is_some() || shortcut_galley.is_some() {
pos2(cursor_x, rect.center().y - 0.5 * galley.size().y)
} else {
// Make sure button text is centered if within a centered layout
ui.layout()
.align_size_within_rect(galley.size(), rect.shrink2(button_padding))
.min
};
let mut text_pos = ui
.layout()
.align_size_within_rect(galley.size(), rect.shrink2(button_padding))
.min;
if image.is_some() || shortcut_galley.is_some() {
text_pos.x = cursor_x;
}
ui.painter().galley(text_pos, galley, visuals.text_color());
}
if let Some(shortcut_galley) = shortcut_galley {
let shortcut_text_pos = pos2(
rect.max.x - button_padding.x - shortcut_galley.size().x,
rect.center().y - 0.5 * shortcut_galley.size().y,
);
// Always align to the right
let layout = if ui.layout().is_horizontal() {
ui.layout().with_main_align(Align::Max)
} else {
ui.layout().with_cross_align(Align::Max)
};
let shortcut_text_pos = layout
.align_size_within_rect(shortcut_galley.size(), rect.shrink2(button_padding))
.min;
ui.painter().galley(
shortcut_text_pos,
shortcut_galley,