mirror of
https://github.com/storytold/pdfcraft.git
synced 2026-11-06 10:47:27 +00:00
fix(ui): the line spacing list keeps its column in every language (#5634)
A longer "Auto" (Czech "Automaticky") pushed the list 46 pt past the Tools pane at its narrowest. It is now cut short, with the whole word in the list's menu and tooltip. A test checks the lists in every interface language the fonts can draw, and the narrow-pane test also runs at the largest interface size.
This commit is contained in:
1 parent
8f1d23d991
commit
d90cf79a2a
2 files changed
+46
-9
No files matched your search
@@ -271,13 +271,20 @@ pub(crate) fn panel(
|
||||
let own = tl!("Auto").to_string();
|
||||
let shown = if e.line_spacing == 0.0 { own.clone() } else { number(e.line_spacing) };
|
||||
outlined(ui, |ui| {
|
||||
let list = craft_ui::ComboBox::from_id_salt("format-line-spacing").selected_text(centred(ui, &shown)).width(half).show_ui(ui, |ui| {
|
||||
ui.selectable_value(&mut e.line_spacing, 0.0, own.as_str());
|
||||
for v in LINE_SPACINGS {
|
||||
ui.selectable_value(&mut e.line_spacing, v, number(v));
|
||||
}
|
||||
});
|
||||
list.response.labelled_by(label.id);
|
||||
// The column is `half` wide in every language: a longer "Auto" is cut short (the
|
||||
// menu and the tooltip have it whole).
|
||||
ui.set_max_width(half);
|
||||
let list = craft_ui::ComboBox::from_id_salt("format-line-spacing")
|
||||
.selected_text(centred(ui, &shown))
|
||||
.width(half)
|
||||
.wrap_mode(egui::TextWrapMode::Truncate)
|
||||
.show_ui(ui, |ui| {
|
||||
ui.selectable_value(&mut e.line_spacing, 0.0, own.as_str());
|
||||
for v in LINE_SPACINGS {
|
||||
ui.selectable_value(&mut e.line_spacing, v, number(v));
|
||||
}
|
||||
});
|
||||
list.response.labelled_by(label.id).on_hover_text(&shown);
|
||||
});
|
||||
ui.add_space(8.0);
|
||||
ui.add_enabled_ui(false, |ui| {
|
||||
@@ -382,11 +389,13 @@ struct Number<'a> {
|
||||
|
||||
/// A combo box's selected text, centred in its button. The button lays out the text and then its
|
||||
/// arrow, and every growing atom takes an equal share of the room left: a pad as wide as the arrow
|
||||
/// before the text balances the arrow after it, and the text centres itself in its own share.
|
||||
/// before the text balances the arrow after it, and the text centres itself in its own share. Text
|
||||
/// longer than the list is wide (a translated "Auto") is cut short rather than widening it.
|
||||
fn centred<'a>(ui: &egui::Ui, text: &str) -> egui::Atoms<'a> {
|
||||
use egui::AtomExt as _;
|
||||
let pad = egui::Atom::custom(egui::IdSalt::new("combo-pad"), vec2(ui.spacing().icon_width, 0.0)).atom_grow(true);
|
||||
egui::Atoms::new((pad, egui::Atom::from(text.to_string()).atom_grow(true).atom_align(egui::Align2::CENTER_CENTER)))
|
||||
let text = egui::Atom::from(text.to_string()).atom_grow(true).atom_shrink(true).atom_align(egui::Align2::CENTER_CENTER);
|
||||
egui::Atoms::new((pad, text))
|
||||
}
|
||||
|
||||
/// The arrow that lists a field's common values, centred on the 26-point field beside it.
|
||||
|
||||
@@ -727,6 +727,8 @@ fn format_text_rows_line_up_and_fit_the_panel() {
|
||||
fn format_text_fits_the_tools_pane_at_its_narrowest() {
|
||||
use egui::accesskit::Role;
|
||||
let mut h = harness();
|
||||
// At the largest interface size too: it scales points to pixels, and the layout is in points.
|
||||
h.state_mut().set_option("ui-scale", "300").unwrap();
|
||||
h.state_mut().side_panels.tools_width = 0.0;
|
||||
assert!(h.state_mut().execute("edit.text"));
|
||||
h.run_steps(3);
|
||||
@@ -752,6 +754,32 @@ fn format_text_fits_the_tools_pane_at_its_narrowest() {
|
||||
}
|
||||
}
|
||||
|
||||
/// The lists in Format text fit the narrowest Tools pane in every interface language: "Auto" in
|
||||
/// the line spacing list is the one word in them that is translated, and in German, Ukrainian or
|
||||
/// Lao it is twice as long. The font list spans the pane, so nothing may end past it.
|
||||
#[test]
|
||||
fn format_text_lists_fit_the_narrowest_tools_pane_in_every_language() {
|
||||
use egui::accesskit::Role;
|
||||
for lang in pdfcraft_ui_egui::i18n::Lang::all() {
|
||||
let mut h = harness();
|
||||
// A script with no face on this machine (Lao without system fonts) can't be drawn at all.
|
||||
if !h.ctx.fonts_mut(|f| f.has_glyphs(&egui::FontId::proportional(13.0), lang.name())) {
|
||||
continue;
|
||||
}
|
||||
h.state_mut().set_option("language", lang.code()).unwrap();
|
||||
h.state_mut().side_panels.tools_width = 0.0;
|
||||
assert!(h.state_mut().execute("edit.text"));
|
||||
h.run_steps(3);
|
||||
let lists: Vec<egui::Rect> = h.query_all_by_role(Role::ComboBox).map(|n| n.rect()).collect();
|
||||
// Found by its value (a font name, never translated), not as the widest list: an overrun
|
||||
// could make another list the widest.
|
||||
let font = h.query_all_by_role(Role::ComboBox).find(|n| n.value().as_deref() == Some("Helvetica")).map(|n| n.rect()).expect("the font list");
|
||||
for r in &lists {
|
||||
assert!(r.right() <= font.right() + 0.5, "{}: {r:?} reaches past the font list ({font:?})", lang.code());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn format_text_panel_sets_alignment_and_lists_planned_controls_disabled() {
|
||||
use egui_kittest::kittest::NodeT;
|
||||
|
||||
Reference in new issue
Block a user