mirror of
https://github.com/storytold/pdfcraft.git
synced 2026-11-09 12:32:52 +00:00
This commit is contained in:
1 parent
ab7af72347
commit
06911895c6
3 files changed
+78
-1
No files matched your search
@@ -127,7 +127,18 @@ fn dialogs(app: &mut PdfCraftApp, ctx: &egui::Context) {
|
||||
app.custom_draft = Some((id, crate::CustomDraft { props: doc.custom_info(), ..Default::default() }));
|
||||
}
|
||||
let mut req = Pending::default();
|
||||
let modal = widgets::show_modal(ctx, "dialog", |ui| {
|
||||
// Every dialog shares this modal. A different dialog than the one shown before starts from
|
||||
// its own size, not from the last one's: rows that fill the height they are offered would
|
||||
// otherwise keep, say, Print as tall as Preferences (#5118). Tabs of one dialog keep its size;
|
||||
// the kinds of Marks and Export are different dialogs.
|
||||
let shown = egui::Id::unique("dialog").with("shown");
|
||||
let kind = match dialog {
|
||||
Dialog::Properties(_) => Dialog::Properties(PropsTab::Description),
|
||||
_ => dialog,
|
||||
};
|
||||
let remeasure = ctx.data(|d| d.get_temp::<Dialog>(shown)) != Some(kind);
|
||||
ctx.data_mut(|d| d.insert_temp(shown, kind));
|
||||
let modal = widgets::show_modal_sized(ctx, "dialog", remeasure, |ui| {
|
||||
ui.set_width(match dialog {
|
||||
Dialog::Properties(_) => 640.0,
|
||||
Dialog::Print => 820.0,
|
||||
|
||||
@@ -35,7 +35,22 @@ pub fn modal(ctx: &egui::Context, id: impl std::hash::Hash + std::fmt::Debug) ->
|
||||
|
||||
/// Show [`modal`], outline its controls, and remember the card rect for layout checks.
|
||||
pub fn show_modal<R>(ctx: &egui::Context, id: &str, content: impl FnOnce(&mut egui::Ui) -> R) -> egui::ModalResponse<R> {
|
||||
show_modal_sized(ctx, id, false, content)
|
||||
}
|
||||
|
||||
/// [`show_modal`], growing from its contents' own height when `remeasure` is set rather than
|
||||
/// from the height it had last frame: one modal id that shows different contents would
|
||||
/// otherwise keep the height of the previous ones, since rows that fill the height offered to
|
||||
/// them take all of it (#5118). The width stays, and the contents stay visible (no hidden
|
||||
/// sizing frame), so the control channel can inspect a dialog the frame it opens.
|
||||
pub fn show_modal_sized<R>(ctx: &egui::Context, id: &str, remeasure: bool, content: impl FnOnce(&mut egui::Ui) -> R) -> egui::ModalResponse<R> {
|
||||
let stored = egui::Id::unique(id);
|
||||
if remeasure && let Some(mut state) = egui::AreaState::load(ctx, stored) {
|
||||
state.size = state.size.map(|s| egui::vec2(s.x, 0.0));
|
||||
ctx.memory_mut(|m| m.areas_mut().set_state(egui::Modal::default_area(stored).layer(), state));
|
||||
// The card is centred on the height it ends with: draw once more at that height.
|
||||
ctx.request_repaint();
|
||||
}
|
||||
modal(ctx, id).show(ctx, |ui| {
|
||||
begin_dialog(ui);
|
||||
let inner = content(ui);
|
||||
|
||||
@@ -258,3 +258,54 @@ fn page_hover_cursors_stay_off_while_a_dialog_is_open() {
|
||||
h.run_steps(2);
|
||||
assert_eq!(h.output().platform_output.cursor_icon, egui::CursorIcon::Default, "nothing under the dialog's backdrop can be clicked");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_dialog_keeps_its_own_height_after_a_taller_one() {
|
||||
// #5118: Print opened after Preferences was as tall as Preferences, with blank space below
|
||||
// its buttons. Every dialog shares one modal, which kept the last dialog's size.
|
||||
use pdfcraft_ui_egui::Dialog;
|
||||
for dialog in [Dialog::Print, Dialog::RotatePages] {
|
||||
let mut h = Harness::builder().with_size(egui::vec2(1400.0, 900.0)).build_eframe(|_cc| {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
app.open_bytes("doc.pdf", None, fixture()).unwrap();
|
||||
app
|
||||
});
|
||||
let show = |h: &mut Harness<'_, PdfCraftApp>, d: Dialog| {
|
||||
h.state_mut().dialog = None;
|
||||
h.run_steps(2);
|
||||
h.state_mut().dialog = Some(d);
|
||||
h.run_steps(6);
|
||||
card(h, "dialog")
|
||||
};
|
||||
let fresh = show(&mut h, dialog);
|
||||
let prefs = show(&mut h, Dialog::Preferences);
|
||||
assert!(prefs.height() > fresh.height() + 20.0, "{dialog:?} {fresh:?} isn't shorter than Preferences {prefs:?}");
|
||||
let after = show(&mut h, dialog);
|
||||
assert!((after.height() - fresh.height()).abs() < 1.0, "{dialog:?} {fresh:?}, after Preferences {after:?}");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn each_kind_of_marks_dialog_keeps_its_own_height() {
|
||||
// #5118: Header & Footer, Watermark and Background are one `Dialog::Marks` with different
|
||||
// contents. Background opened after Header & Footer kept the taller dialog's height.
|
||||
let mut h = Harness::builder().with_size(egui::vec2(1400.0, 900.0)).build_eframe(|_cc| {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.set_option("language", "en").unwrap();
|
||||
app.open_bytes("doc.pdf", None, fixture()).unwrap();
|
||||
app
|
||||
});
|
||||
let show = |h: &mut Harness<'_, PdfCraftApp>, d: &str| {
|
||||
h.state_mut().dialog = None;
|
||||
h.run_steps(2);
|
||||
h.state_mut().set_option("dialog", d).unwrap();
|
||||
h.run_steps(6);
|
||||
card(h, "dialog")
|
||||
};
|
||||
let fresh = show(&mut h, "background");
|
||||
let header = show(&mut h, "header-footer");
|
||||
assert!(header.height() > fresh.height() + 20.0, "Background {fresh:?} isn't shorter than Header & Footer {header:?}");
|
||||
let after = show(&mut h, "background");
|
||||
assert!((after.height() - fresh.height()).abs() < 1.0, "Background {fresh:?}, after Header & Footer {after:?}");
|
||||
}
|
||||
Reference in new issue
Block a user