mirror of
https://github.com/storytold/pdfcraft.git
synced 2026-11-10 21:11:52 +00:00
fix(ui): apply continuous scrolling and view defaults to active and remembered documents (#6780)
This commit is contained in:
1 parent
debb826f29
commit
4f16190e52
4 files changed
+111
-23
No files matched your search
@@ -710,37 +710,75 @@ fn card_documents_and_view(ui: &mut egui::Ui, app: &mut PdfCraftApp, t: &Tokens,
|
||||
ctx.label_secondary(ui, tl!("Used when opening PDFs. An explicit launch or control mode takes precedence for the session."), t);
|
||||
ui.add_space(6.0);
|
||||
|
||||
let defaults = &mut app.view_defaults;
|
||||
let mut layout_choice = app.view_defaults.layout;
|
||||
let mut continuous = app.view_defaults.continuous;
|
||||
let mut layout_changed = false;
|
||||
let mut continuous_changed = false;
|
||||
ui.horizontal(|ui| {
|
||||
ctx.label_primary(ui, tl!("Default page display"), t);
|
||||
let mut layout_choice = defaults.layout;
|
||||
if ctx.pill_choice(ui, t, &mut layout_choice, &[(PageLayout::Single, tl!("Single page")), (PageLayout::TwoUp, tl!("Two-page view"))]) {
|
||||
defaults.layout = layout_choice;
|
||||
app.view_defaults.layout = layout_choice;
|
||||
layout_changed = true;
|
||||
}
|
||||
let mut continuous = defaults.continuous;
|
||||
if ctx.toggle_pill(ui, t, &mut continuous, tl!("Continuous scrolling")) {
|
||||
defaults.continuous = continuous;
|
||||
app.view_defaults.continuous = continuous;
|
||||
continuous_changed = true;
|
||||
}
|
||||
});
|
||||
ctx.checkbox(ui, &mut defaults.show_page_gaps, tl!("Show gaps between pages"), t);
|
||||
let mut show_page_gaps = app.view_defaults.show_page_gaps;
|
||||
let gaps_changed = ctx.checkbox(ui, &mut show_page_gaps, tl!("Show gaps between pages"), t).changed();
|
||||
if gaps_changed {
|
||||
app.view_defaults.show_page_gaps = show_page_gaps;
|
||||
}
|
||||
ctx.label_secondary(ui, tl!("Hide gaps to join page edges. Margins inside the PDF remain unchanged."), t);
|
||||
ui.add_space(6.0);
|
||||
|
||||
let mut fit_changed = false;
|
||||
let mut zoom_changed = false;
|
||||
ui.horizontal(|ui| {
|
||||
ctx.label_primary(ui, tl!("Default zoom"), t);
|
||||
ctx.pill_choice(
|
||||
ui,
|
||||
t,
|
||||
&mut defaults.fit,
|
||||
&[(Fit::Width, tl!("Fit to width")), (Fit::Page, tl!("Zoom to page level")), (Fit::None, tl!("Custom"))],
|
||||
);
|
||||
let mut percent = defaults.zoom * 100.0;
|
||||
let mut fit = app.view_defaults.fit;
|
||||
if ctx.pill_choice(ui, t, &mut fit, &[(Fit::Width, tl!("Fit to width")), (Fit::Page, tl!("Zoom to page level")), (Fit::None, tl!("Custom"))])
|
||||
{
|
||||
app.view_defaults.fit = fit;
|
||||
fit_changed = true;
|
||||
}
|
||||
let mut percent = app.view_defaults.zoom * 100.0;
|
||||
if ui.add(egui::DragValue::new(&mut percent).range(8.0..=6400.0).max_decimals(0).suffix("%")).changed() {
|
||||
(defaults.fit, defaults.zoom) = (Fit::None, percent / 100.0);
|
||||
(app.view_defaults.fit, app.view_defaults.zoom) = (Fit::None, percent / 100.0);
|
||||
zoom_changed = true;
|
||||
}
|
||||
});
|
||||
ctx.label_secondary(ui, tl!("Used when a PDF doesn't ask for a layout or zoom. Continuous scrolling never snaps between pages."), t);
|
||||
ctx.checkbox(ui, &mut app.always_default_view, tl!("Always use my default zoom and page layout"), t);
|
||||
let always_changed = ctx.checkbox(ui, &mut app.always_default_view, tl!("Always use my default zoom and page layout"), t).changed();
|
||||
|
||||
if app.always_default_view && (always_changed || layout_changed || continuous_changed || gaps_changed || fit_changed || zoom_changed) {
|
||||
let defaults = app.view_defaults;
|
||||
for view in &mut app.views {
|
||||
view.set_display(defaults.layout, defaults.continuous);
|
||||
view.show_page_gaps = defaults.show_page_gaps;
|
||||
match defaults.fit {
|
||||
Fit::None => view.set_zoom(defaults.zoom),
|
||||
fit => view.set_fit(fit),
|
||||
}
|
||||
}
|
||||
} else if let Some(i) = app.active {
|
||||
if layout_changed {
|
||||
app.views[i].set_layout(layout_choice);
|
||||
}
|
||||
if continuous_changed {
|
||||
app.views[i].set_continuous(continuous);
|
||||
}
|
||||
if gaps_changed {
|
||||
app.views[i].show_page_gaps = show_page_gaps;
|
||||
}
|
||||
if fit_changed {
|
||||
app.views[i].set_fit(app.view_defaults.fit);
|
||||
}
|
||||
if zoom_changed {
|
||||
app.views[i].set_zoom(app.view_defaults.zoom);
|
||||
}
|
||||
}
|
||||
ctx.checkbox(ui, &mut app.text_links, tl!("Open web and email addresses written in the page text"), t);
|
||||
ctx.label_secondary(ui, tl!("Only web (http, https) and email addresses open, and PdfCraft asks first, as for other links."), t);
|
||||
ui.add_space(6.0);
|
||||
|
||||
@@ -112,14 +112,16 @@ impl PdfCraftApp {
|
||||
let pages = doc.info.pages.len();
|
||||
let Some(last) = self.last_views.iter().find(|l| l.path == path).cloned() else { return };
|
||||
let Some(view) = self.views.get_mut(index) else { return };
|
||||
if let Some((layout, continuous)) = canvas::parse_display_token(&last.display) {
|
||||
view.set_display(layout, continuous);
|
||||
}
|
||||
view.set_cover(last.cover);
|
||||
if let Some(defaults) = ViewDefaults::default().with_zoom(&last.zoom) {
|
||||
match defaults.fit {
|
||||
canvas::Fit::None => view.set_zoom(defaults.zoom),
|
||||
fit => view.set_fit(fit),
|
||||
if !self.always_default_view {
|
||||
if let Some((layout, continuous)) = canvas::parse_display_token(&last.display) {
|
||||
view.set_display(layout, continuous);
|
||||
}
|
||||
view.set_cover(last.cover);
|
||||
if let Some(defaults) = ViewDefaults::default().with_zoom(&last.zoom) {
|
||||
match defaults.fit {
|
||||
canvas::Fit::None => view.set_zoom(defaults.zoom),
|
||||
fit => view.set_fit(fit),
|
||||
}
|
||||
}
|
||||
}
|
||||
if last.page < pages {
|
||||
|
||||
@@ -1255,6 +1255,39 @@ fn preferences_turn_on_always_use_my_default_zoom_and_page_layout() {
|
||||
assert!(h.state().always_default_view);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn preferences_turn_on_always_use_my_default_zoom_and_page_layout_updates_open_documents() {
|
||||
use egui_kittest::kittest::Queryable;
|
||||
let mut h = harness(&[("continuous", "off"), ("zoom", "50")]);
|
||||
assert!(!h.state().views[0].continuous());
|
||||
assert_ne!(h.state().views[0].fit, pdfcraft_ui_egui::canvas::Fit::Width);
|
||||
assert!(h.state_mut().execute("app.preferences"));
|
||||
h.run_steps(3);
|
||||
h.get_by_label("Always use my default zoom and page layout").scroll_to_me();
|
||||
h.run_steps(4);
|
||||
h.get_by_label("Always use my default zoom and page layout").click();
|
||||
h.run_steps(2);
|
||||
assert!(h.state().always_default_view);
|
||||
assert!(h.state().views[0].continuous(), "continuous scrolling is applied");
|
||||
assert_eq!(h.state().views[0].fit, pdfcraft_ui_egui::canvas::Fit::Width, "default fit width is applied");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn preferences_toggle_continuous_scrolling_updates_active_document() {
|
||||
use egui_kittest::kittest::Queryable;
|
||||
let mut h = harness(&[("default-continuous", "off"), ("continuous", "off")]);
|
||||
assert!(!h.state().view_defaults.continuous);
|
||||
assert!(!h.state().views[0].continuous());
|
||||
assert!(h.state_mut().execute("app.preferences"));
|
||||
h.run_steps(3);
|
||||
h.get_by_label("Continuous scrolling").scroll_to_me();
|
||||
h.run_steps(4);
|
||||
h.get_by_label("Continuous scrolling").click();
|
||||
h.run_steps(2);
|
||||
assert!(h.state().view_defaults.continuous, "defaults are updated");
|
||||
assert!(h.state().views[0].continuous(), "active document view is updated");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn preferences_set_the_default_zoom() {
|
||||
use egui_kittest::kittest::Queryable;
|
||||
|
||||
@@ -231,6 +231,21 @@ fn a_remembered_zoom_wins_over_the_layouts_fit_page() {
|
||||
assert_eq!((v.fit, v.zoom, v.current), (Fit::None, 0.625, 1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn always_default_view_wins_over_a_remembered_view() {
|
||||
let path = std::env::temp_dir().join(format!("pdfcraft-viewer-prefs-always-default-{}.pdf", std::process::id())).to_string_lossy().into_owned();
|
||||
let mut app = PdfCraftApp::new();
|
||||
let json_path = serde_json::to_string(&path).unwrap();
|
||||
app.restore(&format!(
|
||||
r#"{{"last_views": [{{"path": {json_path}, "page": 1, "zoom": "62.5%", "display": "single"}}], "always_default_view": true}}"#
|
||||
));
|
||||
assert!(app.always_default_view);
|
||||
assert!(app.restore_last_view);
|
||||
app.open_bytes("x.pdf", Some(path), fixture("/PageLayout /SinglePage")).unwrap();
|
||||
let v = &app.views[0];
|
||||
assert_eq!((v.fit, v.layout, v.continuous(), v.current), (Fit::Width, pdfcraft_ui_egui::canvas::PageLayout::Single, true, 1));
|
||||
}
|
||||
|
||||
/// The last `InnerSize` and `OuterPosition` asked for over `frames` frames.
|
||||
fn window_commands(h: &mut Harness<'static, PdfCraftApp>, frames: usize) -> (Option<egui::Vec2>, Option<egui::Pos2>) {
|
||||
let (mut size, mut at) = (None, None);
|
||||
|
||||
Reference in new issue
Block a user