mirror of
https://github.com/storytold/pdfcraft.git
synced 2026-10-24 10:08:00 -06:00
M4: Organize pages remembers its page size, as Acrobat does (#2282)
The grid's size was kept per document view and reset to 100% for every document and every start. Acrobat keeps the size last chosen, observed in its Organize Pages. It is now one value for the app, saved with the other settings like Combine's zoom, and --grid-zoom sets it too. A damaged saved value is ignored or clamped to 50-300%. Co-authored-by: abc2cb <271337822+abc2cb@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: aiongg <67543387+aiongg@users.noreply.github.com>
This commit is contained in:
co-authored by
abc2cb
Claude Opus 5.5
aiongg
parent
d90cee4669
commit
18b61e2401
@@ -2433,9 +2433,13 @@ pub fn document_area(app: &mut PdfCraftApp, index: usize, ui: &mut egui::Ui) {
|
||||
}
|
||||
// No dialog, close prompt or palette over the page: only then does page input count.
|
||||
let unobstructed = !app.modal_open() && !app.palette_open;
|
||||
let organize_zoom = app.organize_zoom;
|
||||
let view = &mut app.views[index];
|
||||
if view.organize {
|
||||
// One remembered grid size for every document, kept in the settings.
|
||||
view.set_grid_zoom(organize_zoom);
|
||||
organize_grid(view, info, doc.allows_assembly(), doc.dirty, unobstructed, ui, &t);
|
||||
app.organize_zoom = view.grid_zoom();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -698,6 +698,9 @@ pub struct PdfCraftApp {
|
||||
/// How large the Combine grid draws its cards (1.0 = the usual; kept in the settings). Set
|
||||
/// with [`PdfCraftApp::set_combine_zoom`].
|
||||
pub combine_zoom: f32,
|
||||
/// How large Organize pages draws its grid, for every document (1.0 = the usual; kept in
|
||||
/// the settings).
|
||||
pub organize_zoom: f32,
|
||||
/// The Combine grid's thumbnails: rendered off the UI thread, a few at a time.
|
||||
pub(crate) combine_thumbs: combine_grid::Thumbs,
|
||||
/// Images waiting for the resolution choice (released on cancel).
|
||||
@@ -1013,6 +1016,7 @@ impl PdfCraftApp {
|
||||
combine_columns: Default::default(),
|
||||
combine_view: Default::default(),
|
||||
combine_zoom: 1.0,
|
||||
organize_zoom: 1.0,
|
||||
combine_thumbs: Default::default(),
|
||||
image_import: None,
|
||||
custom_stamps: Vec::new(),
|
||||
@@ -2309,6 +2313,7 @@ impl PdfCraftApp {
|
||||
v["redact_prefs"] = self.redact_defaults.to_json();
|
||||
// Set outside json! above, which is at serde_json's macro recursion limit.
|
||||
v["hide_empty_highlight_hover"] = serde_json::Value::Bool(self.comment_prefs.hide_empty_highlight_hover);
|
||||
v["organize_zoom"] = serde_json::json!(self.organize_zoom);
|
||||
v.to_string()
|
||||
}
|
||||
|
||||
@@ -2331,6 +2336,10 @@ impl PdfCraftApp {
|
||||
if let Some(zoom) = v["combine_zoom"].as_f64() {
|
||||
self.set_combine_zoom(zoom as f32);
|
||||
}
|
||||
// Clamped like any grid zoom when the grid next shows; nonsense keeps the usual size.
|
||||
if let Some(zoom) = v["organize_zoom"].as_f64().map(|z| z as f32).filter(|z| z.is_finite()) {
|
||||
self.organize_zoom = zoom.clamp(*canvas::GRID_ZOOM_RANGE.start(), *canvas::GRID_ZOOM_RANGE.end());
|
||||
}
|
||||
if let Ok(r) = serde_json::from_value::<Vec<RecentFile>>(v["recent"].clone()) {
|
||||
// Only keep entries whose files still exist.
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
@@ -2641,6 +2650,8 @@ impl PdfCraftApp {
|
||||
return Err("grid-zoom must be between 50 and 300".into());
|
||||
}
|
||||
v.set_grid_zoom(percent / 100.0);
|
||||
// The grid's size is one for every document, as it is remembered.
|
||||
self.organize_zoom = v.grid_zoom();
|
||||
}
|
||||
("rotate", Some(v)) => {
|
||||
let deg: u16 = value.parse().map_err(|_| "rotate: 0, 90, 180 or 270")?;
|
||||
|
||||
@@ -1880,6 +1880,39 @@ fn page_grid_zooms_with_its_buttons_keys_and_pinch() {
|
||||
assert!(!dirty(&h), "zooming is not an edit");
|
||||
}
|
||||
|
||||
/// As in Acrobat, Organize pages keeps the size last chosen: every document's grid opens at it,
|
||||
/// and so does the next start of the app.
|
||||
#[test]
|
||||
fn page_grid_size_is_remembered_for_every_document_and_restart() {
|
||||
let mut h = organize(3);
|
||||
h.get_by_label("Larger pages").click();
|
||||
h.run_steps(3);
|
||||
assert_eq!(grid_zoom(&h), 1.25);
|
||||
h.state_mut().open_bytes("other.pdf", None, fixture(2)).expect("second fixture opens");
|
||||
h.state_mut().set_option("organize", "on").unwrap();
|
||||
h.run_steps(4);
|
||||
let other = h.state().active.expect("the new document is active");
|
||||
assert_ne!(other, 0);
|
||||
assert_eq!(h.state().views[other].grid_zoom(), 1.25, "the other document");
|
||||
let settings = h.state().persist();
|
||||
let h = harness(3, move |app| {
|
||||
app.restore(&settings);
|
||||
app.set_option("organize", "on").unwrap();
|
||||
});
|
||||
assert_eq!(grid_zoom(&h), 1.25, "after a restart");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_damaged_remembered_page_grid_size_is_ignored_or_clamped() {
|
||||
let mut app = PdfCraftApp::new();
|
||||
app.restore(r#"{"organize_zoom": "huge"}"#);
|
||||
assert_eq!(app.organize_zoom, 1.0);
|
||||
app.restore(r#"{"organize_zoom": 40.0}"#);
|
||||
assert_eq!(app.organize_zoom, 3.0);
|
||||
app.restore(r#"{"organize_zoom": -2}"#);
|
||||
assert_eq!(app.organize_zoom, 0.5);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn zoomed_pages_in_view_are_rendered_at_the_size_drawn() {
|
||||
// A long document: sharpness must not depend on how many pages there are.
|
||||
|
||||
@@ -2884,8 +2884,8 @@ milestone = "M4"
|
||||
status = "shipped"
|
||||
commands = ["page.organize"]
|
||||
tools = []
|
||||
evidence = ["crates/ui-egui/tests/editing.rs::page_grid_zooms_with_its_buttons_keys_and_pinch", "crates/ui-egui/tests/editing.rs::a_zoomed_page_grid_still_inserts_and_moves_at_the_right_gap", "crates/ui-egui/tests/editing.rs::zoomed_pages_in_view_are_rendered_at_the_size_drawn"]
|
||||
notes = "Organize page grid: 50–300% with toolbar buttons (and a percentage that resets to 100%), trackpad pinch or Ctrl/⌘ + wheel about the page under the pointer, and ⌘+ / ⌘− / ⌘0; pages drawn larger than their thumbnails are rendered at the size drawn while they are in view (the thumbnail stands in until then, and after an edit), so text stays sharp however long the document is. Missing: a slider as in Acrobat; the size is per document view and not remembered between sessions; the Pages side panel has no size control."
|
||||
evidence = ["crates/ui-egui/tests/editing.rs::page_grid_zooms_with_its_buttons_keys_and_pinch", "crates/ui-egui/tests/editing.rs::a_zoomed_page_grid_still_inserts_and_moves_at_the_right_gap", "crates/ui-egui/tests/editing.rs::zoomed_pages_in_view_are_rendered_at_the_size_drawn", "crates/ui-egui/tests/editing.rs::page_grid_size_is_remembered_for_every_document_and_restart"]
|
||||
notes = "Organize page grid: 50–300% with toolbar buttons (and a percentage that resets to 100%), trackpad pinch or Ctrl/⌘ + wheel about the page under the pointer, and ⌘+ / ⌘− / ⌘0; pages drawn larger than their thumbnails are rendered at the size drawn while they are in view (the thumbnail stands in until then, and after an edit), so text stays sharp however long the document is. As in Acrobat, the size last chosen is one for every document and kept in the settings across restarts (also set by --grid-zoom). Missing: a slider as in Acrobat; the Pages side panel has no size control."
|
||||
|
||||
[[feature]]
|
||||
id = "organize.split-every-n"
|
||||
|
||||
Reference in New Issue
Block a user