Ribbon: Font Size value is centered in its box (fixes #3155)

The size box draws its value with a frameless TextEdit. The theme floors
a text edit at interact_size.y (22 pt), and egui's text edit style aligns
its text to the top of that, which wins over the child layout's
Align::Center. The digits sat 3.5 pt above the middle of the 24 pt box,
4 pt above the Font name's baseline. The text edit now aligns its text
LEFT_CENTER.

The new test checks that the value is centered in its box and on the
Font name label's baseline. It fails without the change.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Ken Kölzer
2026-11-02 14:41:27 +01:00
co-authored by Claude Sonnet 5.5
parent 488f9982eb
commit de254a0a6e
2 changed files with 34 additions and 2 deletions
+3
View File
@@ -622,10 +622,13 @@ fn size_combo(app: &mut SheetApp, ui: &mut Ui, st: &Style) {
let arrow_rect = Rect::from_min_max(egui::pos2(frame.right() - 16.0, frame.top() + 1.0), egui::pos2(frame.right() - 1.0, frame.bottom() - 1.0));
let mut field_ui =
ui.new_child(egui::UiBuilder::new().max_rect(text_rect.shrink2(vec2(6.0, 0.0))).layout(egui::Layout::left_to_right(egui::Align::Center)));
// The text edit is `interact_size.y` tall and puts its text at the top of that unless told
// otherwise: center it, on the Font name's baseline (#3155).
let out = egui::TextEdit::singleline(&mut text)
.id(field)
.font(theme::ui_font(12.5))
.frame(egui::Frame::NONE)
.align(egui::Align2::LEFT_CENTER)
.desired_width(text_rect.width() - 12.0)
.show(&mut field_ui);
let resp = out.response;
+31 -2
View File
@@ -1,6 +1,7 @@
//! Home ▸ Font Size is a box you type a size into, with the standard sizes behind its arrow (#932).
//! Home ▸ Font Size is a box you type a size into, with the standard sizes behind its arrow (#932),
//! and the size sits in the middle of that box (#3155).
use egui::{Event, Key, Modifiers, accesskit::Role};
use egui::{Event, Key, Modifiers, Rect, Shape, accesskit::Role};
use egui_kittest::kittest::Queryable as _;
use gridcraft_engine::Session;
use gridcraft_engine::core::{CellRef, Value};
@@ -124,3 +125,31 @@ fn the_arrow_opens_the_plain_list_of_sizes() {
h.run_steps(3);
assert_eq!(size(&h, "A1"), 12.0, "Down from 11 then Enter picks 12");
}
/// The on-screen box of the painted text `text` that overlaps `within`. The grid's row headers
/// paint "11" too, so the size has to be looked for inside its own box.
fn painted_text(h: &Harness, text: &str, within: Rect) -> Rect {
h.output()
.shapes
.iter()
.find_map(|s| match &s.shape {
Shape::Text(t) if t.galley.job.text == text => {
let rect = t.galley.rect.translate(t.pos.to_vec2());
within.intersects(rect).then_some(rect)
}
_ => None,
})
.unwrap_or_else(|| panic!("{text:?} is painted inside {within:?}"))
}
#[test]
/// A text edit aligns its text to the top of its rect unless told otherwise, which left the size
/// 4 pt above the Font name's baseline.
fn the_size_is_vertically_centered_in_its_box() {
let h = harness();
let field = h.get_by_role_and_label(Role::TextInput, "Font Size").rect();
let value = painted_text(&h, "11", field);
let name = painted_text(&h, "Calibri", Rect::EVERYTHING);
assert!((value.center().y - field.center().y).abs() <= 1.0, "the size is centered in its box: {value:?} in {field:?}");
assert!((value.center().y - name.center().y).abs() <= 1.0, "the size is on the Font name's baseline: {value:?} against {name:?}");
}