mirror of
https://github.com/storytold/pdfcraft.git
synced 2026-10-26 19:19:10 -06:00
* Read mode: the rail's Bookmarks and other pane buttons open their panels (#932) Read mode kept the right rail but never drew the right panel, so its buttons did nothing. Read mode now hides the tools, not the navigation panes: the panels open from the rail as in the other workspaces. Entering Read mode closes the open pane and leaving it reopens it, and a document opened into Read mode starts with the panes closed unless its Initial View asks for one (/PageMode /UseOutlines). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * M7: a pane closed in Read mode stays closed when leaving it (#932) Review on #947: opening or closing a pane in Read mode now discards the pane saved on the way in, so leaving Read mode no longer reopens a pane the user closed there (and Comments keeps its close preference). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: DWAA1660 <DWAA1660@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
DWAA1660
parent
5d7700ead6
commit
faea6d69b4
@@ -364,7 +364,7 @@ pub fn mode_bar(app: &mut PdfCraftApp, ui: &mut egui::Ui) {
|
||||
[(Mode::AllTools, "All tools"), (Mode::Read, "Read"), (Mode::Edit, "Edit"), (Mode::Convert, "Convert"), (Mode::Sign, "E-Sign")]
|
||||
{
|
||||
if widgets::mode_tab(ui, tl!(label), app.mode == mode).clicked() {
|
||||
app.select_mode(mode);
|
||||
app.switch_mode(mode, true);
|
||||
}
|
||||
}
|
||||
ui.with_layout(Layout::right_to_left(Align::Center), |ui| {
|
||||
|
||||
@@ -242,7 +242,7 @@ impl PdfCraftApp {
|
||||
None => self.full_screen = on,
|
||||
}
|
||||
}
|
||||
"view.read_mode" => self.mode = if self.mode == Mode::Read { Mode::AllTools } else { Mode::Read },
|
||||
"view.read_mode" => self.switch_mode(if self.mode == Mode::Read { Mode::AllTools } else { Mode::Read }, false),
|
||||
"view.theme" => {
|
||||
let next = if self.theme == ThemeKind::Light { ThemePreference::Dark } else { ThemePreference::Light };
|
||||
self.set_theme_preference(next);
|
||||
|
||||
@@ -408,6 +408,10 @@ pub struct PdfCraftApp {
|
||||
pub left: LeftPanel,
|
||||
pub left_open: bool,
|
||||
pub right: Option<RightPanel>,
|
||||
/// The right panel that was open when the user switched to Read mode, which starts with the
|
||||
/// panes closed; leaving Read mode brings it back unless the user opened or closed a pane in
|
||||
/// Read mode meanwhile.
|
||||
right_before_read: Option<RightPanel>,
|
||||
/// The user closed the Comments panel, so picking a comment tool leaves it closed until they
|
||||
/// open it again (#225). Remembered across restarts.
|
||||
pub comments_panel_closed: bool,
|
||||
@@ -730,6 +734,7 @@ impl PdfCraftApp {
|
||||
pending_panel_reveals: Vec::new(),
|
||||
left_open: true,
|
||||
right: None,
|
||||
right_before_read: None,
|
||||
comments_panel_closed: false,
|
||||
quick_tool: QuickTool::Select,
|
||||
space_hand: None,
|
||||
@@ -957,7 +962,9 @@ impl PdfCraftApp {
|
||||
let doc = self.session.get(id).ok_or("the document could not be opened")?;
|
||||
let pages = doc.info.pages.len();
|
||||
// Acrobat opens straight to the Comments panel when a document has comments.
|
||||
if activate && self.right.is_none() {
|
||||
// Read mode opens with the panes closed; the rail still opens them (#932).
|
||||
let opening_mode = self.mode_override.unwrap_or(self.default_mode);
|
||||
if activate && self.right.is_none() && opening_mode != Mode::Read {
|
||||
self.right = if !doc.info.annotations.is_empty() {
|
||||
Some(RightPanel::Comments)
|
||||
} else if !doc.info.outline.is_empty() {
|
||||
@@ -1421,9 +1428,36 @@ impl PdfCraftApp {
|
||||
};
|
||||
}
|
||||
|
||||
/// Switches workspace because the user chose to (mode bar, Read mode command). Entering Read
|
||||
/// mode closes the right panel, as Acrobat's Read mode hides its panes, and leaving it reopens
|
||||
/// that panel. The rail stays in Read mode, and its buttons open panels there too (#932).
|
||||
pub(crate) fn switch_mode(&mut self, mode: Mode, select_tools: bool) {
|
||||
let was_read = self.mode == Mode::Read;
|
||||
if select_tools {
|
||||
self.select_mode(mode);
|
||||
} else {
|
||||
self.mode = mode;
|
||||
}
|
||||
if mode == Mode::Read && !was_read {
|
||||
self.right_before_read = self.right.take();
|
||||
} else if mode != Mode::Read && was_read {
|
||||
let before = self.right_before_read.take();
|
||||
if self.right.is_none() {
|
||||
self.right = before;
|
||||
}
|
||||
if self.right.is_some() {
|
||||
self.pending_panel_reveals.push(docking::Panel::Inspector);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Opens a right panel, or closes it with `None`, because the user chose to. Closing Comments
|
||||
/// keeps comment tools from reopening it; opening it again lets them (#225).
|
||||
/// keeps comment tools from reopening it; opening it again lets them (#225). A choice made in
|
||||
/// Read mode replaces the pane saved on the way in, so leaving Read mode doesn't undo it.
|
||||
pub fn choose_right_panel(&mut self, panel: Option<RightPanel>) {
|
||||
if self.mode == Mode::Read {
|
||||
self.right_before_read = None;
|
||||
}
|
||||
if panel == Some(RightPanel::Comments) {
|
||||
self.comments_panel_closed = false;
|
||||
} else if panel.is_none() && self.right == Some(RightPanel::Comments) {
|
||||
@@ -2165,6 +2199,17 @@ impl eframe::App for PdfCraftApp {
|
||||
chrome::mode_bar(self, ui);
|
||||
if self.active.is_some() {
|
||||
chrome::right_rail(self, ui);
|
||||
// Read mode hides the tools, not the navigation panes: the rail stays visible
|
||||
// there, so its buttons (Bookmarks, Page thumbnails, ...) must open their panels.
|
||||
// Outside Read mode the docking workspace draws the inspector.
|
||||
if self.mode == Mode::Read && self.right.is_some() {
|
||||
egui::Panel::right("read_right_panel")
|
||||
.resizable(true)
|
||||
.default_size(330.0)
|
||||
.size_range(260.0..=520.0)
|
||||
.frame(egui::Frame::NONE)
|
||||
.show(ui, |ui| panels::right_panel(self, ui));
|
||||
}
|
||||
}
|
||||
let t = theme::Tokens::get(&ctx);
|
||||
egui::CentralPanel::default().frame(egui::Frame::NONE.fill(t.pasteboard)).show(ui, |ui| {
|
||||
|
||||
@@ -114,6 +114,99 @@ fn opening_a_pdf_shows_comments_and_bookmarks() {
|
||||
h.get_by_label("Beta section");
|
||||
}
|
||||
|
||||
/// Read mode hides the tools, not the navigation panes: the rail's Bookmarks button opens the
|
||||
/// bookmarks when Read is the default workspace (#932), and the left tool pane stays hidden.
|
||||
#[test]
|
||||
fn read_mode_rail_buttons_open_their_panels() {
|
||||
use pdfcraft_ui_egui::{Mode, RightPanel};
|
||||
let mut h = harness(|app| {
|
||||
app.default_mode = Mode::Read;
|
||||
app.open_bytes("fixture.pdf", None, FIXTURE.to_vec()).expect("fixture opens");
|
||||
});
|
||||
assert_eq!(h.state().mode, Mode::Read);
|
||||
assert_eq!(h.state().right, None, "Read mode opens with the panes closed");
|
||||
assert!(h.query_by_label("Alpha section").is_none());
|
||||
h.get_by_label("Bookmarks").click();
|
||||
h.run_steps(3);
|
||||
assert_eq!(h.state().right, Some(RightPanel::Bookmarks));
|
||||
h.get_by_label("Alpha section");
|
||||
h.get_by_label("Beta section");
|
||||
// The same button closes them again (the open panel's title is also "Bookmarks").
|
||||
h.get_by_role_and_label(egui::accesskit::Role::Button, "Bookmarks").click();
|
||||
h.run_steps(3);
|
||||
assert_eq!(h.state().right, None);
|
||||
assert!(h.query_by_label("Alpha section").is_none());
|
||||
// A document that asks for its outline (/PageMode /UseOutlines) shows it in Read mode too.
|
||||
let pdf = String::from_utf8(FIXTURE.to_vec()).unwrap().replace("/Outlines 6 0 R", "/Outlines 6 0 R /PageMode /UseOutlines");
|
||||
h.state_mut().open_bytes("outline.pdf", None, pdf.into_bytes()).unwrap();
|
||||
h.run_steps(3);
|
||||
assert_eq!(h.state().mode, Mode::Read);
|
||||
h.get_by_label("Alpha section");
|
||||
}
|
||||
|
||||
/// Switching to Read mode closes the open pane, and switching back reopens it.
|
||||
#[test]
|
||||
fn read_mode_closes_the_panes_and_leaving_it_brings_them_back() {
|
||||
use pdfcraft_ui_egui::{Mode, RightPanel};
|
||||
let mut h = harness(|app| app.open_bytes("fixture.pdf", None, FIXTURE.to_vec()).expect("fixture opens"));
|
||||
assert_eq!(h.state().right, Some(RightPanel::Comments));
|
||||
h.get_by_label("Read").click();
|
||||
h.run_steps(3);
|
||||
assert_eq!(h.state().mode, Mode::Read);
|
||||
assert_eq!(h.state().right, None);
|
||||
assert!(h.query_by_label_contains("Check the numbers").is_none(), "the Comments panel is hidden");
|
||||
h.state_mut().run_command("view.read_mode");
|
||||
h.run_steps(3);
|
||||
assert_eq!(h.state().mode, Mode::AllTools);
|
||||
assert_eq!(h.state().right, Some(RightPanel::Comments));
|
||||
// A pane opened in Read mode stays open on the way out.
|
||||
h.state_mut().run_command("view.read_mode");
|
||||
h.run_steps(2);
|
||||
h.get_by_label("Page thumbnails").click();
|
||||
h.run_steps(2);
|
||||
h.get_by_label("All tools").click();
|
||||
h.run_steps(3);
|
||||
assert_eq!(h.state().right, Some(RightPanel::Pages));
|
||||
}
|
||||
|
||||
/// A pane closed in Read mode stays closed on the way out: leaving Read mode doesn't bring back the
|
||||
/// pane saved on the way in, and closing Comments keeps its close preference.
|
||||
#[test]
|
||||
fn a_pane_closed_in_read_mode_stays_closed_when_leaving_it() {
|
||||
use pdfcraft_ui_egui::{Mode, RightPanel};
|
||||
let mut h = harness(|app| app.open_bytes("fixture.pdf", None, FIXTURE.to_vec()).expect("fixture opens"));
|
||||
assert_eq!(h.state().right, Some(RightPanel::Comments));
|
||||
h.get_by_label("Read").click();
|
||||
h.run_steps(3);
|
||||
assert_eq!(h.state().right, None);
|
||||
// Open Comments from the rail, then close it again.
|
||||
h.get_by_role_and_label(egui::accesskit::Role::Button, "Comments").click();
|
||||
h.run_steps(3);
|
||||
assert_eq!(h.state().right, Some(RightPanel::Comments));
|
||||
h.get_by_role_and_label(egui::accesskit::Role::Button, "Comments").click();
|
||||
h.run_steps(3);
|
||||
assert_eq!(h.state().right, None);
|
||||
assert!(h.state().comments_panel_closed);
|
||||
// Leave Read mode through the toolbar.
|
||||
h.get_by_label("All tools").click();
|
||||
h.run_steps(3);
|
||||
assert_eq!(h.state().mode, Mode::AllTools);
|
||||
assert_eq!(h.state().right, None, "the pane closed in Read mode stays closed");
|
||||
assert!(h.state().comments_panel_closed);
|
||||
// The same through the Read mode command.
|
||||
h.state_mut().choose_right_panel(Some(RightPanel::Comments));
|
||||
h.state_mut().run_command("view.read_mode");
|
||||
h.run_steps(2);
|
||||
assert_eq!(h.state().mode, Mode::Read);
|
||||
h.state_mut().choose_right_panel(Some(RightPanel::Comments));
|
||||
h.state_mut().choose_right_panel(None);
|
||||
h.state_mut().run_command("view.read_mode");
|
||||
h.run_steps(3);
|
||||
assert_ne!(h.state().mode, Mode::Read);
|
||||
assert_eq!(h.state().right, None);
|
||||
assert!(h.state().comments_panel_closed);
|
||||
}
|
||||
|
||||
/// A right-to-left file name opens, lays out and paints; the tab's accessible name keeps the
|
||||
/// logical text (only the painted label is put in visual order).
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user