mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-13 13:09:16 +00:00
Merge pull request #7062 from dotCooCoo/fix/para-style-options-height
Text styles: Paragraph Style Options keeps OK and Cancel on a small screen after a section switch
This commit is contained in:
@@ -979,7 +979,7 @@ fn body(app: &mut VectorcraftApp, ui: &mut egui::Ui, d: &mut Dialog) -> bool {
|
||||
ui.separator();
|
||||
let section = d.str("section");
|
||||
let content_w = ui.available_width();
|
||||
egui::ScrollArea::both()
|
||||
let shown = egui::ScrollArea::both()
|
||||
.id_salt(("para-style-sections", section))
|
||||
.max_height(room)
|
||||
.min_scrolled_height(room)
|
||||
@@ -987,15 +987,17 @@ fn body(app: &mut VectorcraftApp, ui: &mut egui::Ui, d: &mut Dialog) -> bool {
|
||||
.auto_shrink([false, true])
|
||||
.show(ui, |ui| {
|
||||
ui.vertical(|ui| section_body(ui, d));
|
||||
})
|
||||
.inner_rect
|
||||
.height()
|
||||
});
|
||||
// `inner_rect` is the height offered before a short section shrinks the area to its content.
|
||||
shown.inner_rect.height().min(shown.content_size.y)
|
||||
});
|
||||
let content_h = drawn.inner;
|
||||
let was = ui.ctx().data(|m| m.get_temp::<f32>(content_id(ui)));
|
||||
ui.ctx().data_mut(|m| m.insert_temp(content_id(ui), content_h));
|
||||
// A new height lays the frame out again before it is shown, so the window is placed at its new
|
||||
// size and OK and Cancel stay on the screen in the frame of a section switch.
|
||||
if was.is_none_or(|was| (was - content_h).abs() > 0.5) {
|
||||
ui.ctx().request_repaint();
|
||||
ui.ctx().request_discard("paragraph style content height changed");
|
||||
}
|
||||
reset_button(ui, d);
|
||||
match edited_attrs(d) {
|
||||
|
||||
@@ -578,3 +578,62 @@ fn every_section_draws_its_fields() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The texts of one headless frame at a screen `w` by `h`, with their screen rects.
|
||||
fn texts_at(ctx: &egui::Context, app: &mut VectorcraftApp, w: f32, h: f32) -> Vec<(String, egui::Rect)> {
|
||||
fn collect(s: &egui::Shape, out: &mut Vec<(String, egui::Rect)>) {
|
||||
match s {
|
||||
egui::Shape::Text(t) => out.push((t.galley.text().to_string(), t.visual_bounding_rect())),
|
||||
egui::Shape::Vec(v) => v.iter().for_each(|s| collect(s, out)),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
let screen = egui::Rect::from_min_size(egui::Pos2::ZERO, egui::vec2(w, h));
|
||||
let mut out = ctx.run_ui(egui::RawInput { screen_rect: Some(screen), ..Default::default() }, |ui| super::super::show(app, ui.ctx()));
|
||||
out.textures_delta.clear();
|
||||
let mut texts = vec![];
|
||||
for c in &out.shapes {
|
||||
collect(&c.shape, &mut texts);
|
||||
}
|
||||
texts
|
||||
}
|
||||
|
||||
/// Going from a shorter section to a longer one keeps OK and Cancel on a small screen in the first
|
||||
/// frame after the switch, not only once the window has measured itself again.
|
||||
#[test]
|
||||
fn switching_to_a_long_section_keeps_the_buttons_on_a_small_screen() {
|
||||
let mut app = app();
|
||||
let mut attrs: Value = serde_json::from_str(KEPT).unwrap();
|
||||
for (key, value) in [
|
||||
("right_indent", json!(4.0)),
|
||||
("first_line_indent", json!(12.0)),
|
||||
("space_after", json!(6.0)),
|
||||
("composer", json!("singleLine")),
|
||||
("roman_hanging", json!(true)),
|
||||
("hyphenate", json!(true)),
|
||||
("justification", json!({"auto_leading": 150.0})),
|
||||
("korean_line_break_anywhere", json!(true)),
|
||||
] {
|
||||
attrs[key] = value;
|
||||
}
|
||||
app.run("paraStyle.new", json!({"name": "Body", "attrs": attrs})).unwrap();
|
||||
app.run("ui.paraStyleOptions", json!({"name": "Body"})).unwrap();
|
||||
for h in [500.0, 560.0, 640.0, 720.0] {
|
||||
for to in SECTIONS {
|
||||
for from in SECTIONS.into_iter().filter(|s| *s != to) {
|
||||
let ctx = egui::Context::default();
|
||||
crate::theme::install_fonts(&ctx);
|
||||
set(&mut app, "section", json!(from));
|
||||
for _ in 0..5 {
|
||||
let _ = texts_at(&ctx, &mut app, 900.0, h);
|
||||
}
|
||||
set(&mut app, "section", json!(to));
|
||||
let texts = texts_at(&ctx, &mut app, 900.0, h);
|
||||
for label in ["OK", "Cancel"] {
|
||||
let r = texts.iter().find(|(text, _)| text == label).unwrap_or_else(|| panic!("{label} is drawn")).1;
|
||||
assert!(r.bottom() <= h + 1.0, "{label} stays on a {h}-point screen going from {from} to {to}: {r:?}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user