Refactor ui canvas for strict Clippy checks

This commit is contained in:
Dylan M. Taylor
2026-10-27 23:12:52 +00:00
parent 074d4f3111
commit e7a60f2fd4
10 changed files with 2202 additions and 1499 deletions
+2089 -1426
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -1,4 +1,4 @@
use super::*;
use super::{LayerOp, PdfCraftApp, Pos2, Rect};
/// A validation badge drawn over a signature widget: the widget rectangle (user space), the verdict it shows, and its hover text.
pub(crate) struct SignatureBadge {
+4 -1
View File
@@ -1,4 +1,7 @@
use super::*;
use super::{
Color32, CornerRadius, DocInfo, DocView, Edit, PdfCraftApp, Pos2, QuickTool, Rect, Sense, SnapshotKind, Stroke, Tokens, comments, icons, theme,
vec2,
};
/// Whether `p` lies in the bottom-left quadrant of `area`, where the page size shows (#1855).
pub(super) fn in_size_hint_zone(area: Rect, p: Pos2) -> bool {
+4 -1
View File
@@ -1,5 +1,8 @@
use super::find::Follow;
use super::*;
use super::{
Arc, Color32, DocInfo, DocView, HashSet, PRINT_TAG, PT, PageText, Range, RenderPool, RenderRequest, RequestKind, TextureHandle, TextureOptions,
device_pixels,
};
pub(super) const THUMB_TAG: u64 = 1 << 63;
+1 -1
View File
@@ -1,4 +1,4 @@
use super::*;
use super::{Align2, Color32, CornerRadius, DocView, Range, Rect, Stroke, Tokens, icons, theme, vec2, widgets};
/// The find bar (⌘F): query, matches across the document, current match.
#[derive(Default)]
+39 -32
View File
@@ -1,5 +1,5 @@
use super::zoom::GRID_ZOOM_STEP;
use super::*;
use super::{DestView, DocInfo, DocView, Fit, PT, PageLayout, SIDE, ViewAction, pos2, vec2};
impl DocView {
/// Where a bookmark made now should go: the page and the `/XYZ` position `[left, top]` in user
@@ -299,6 +299,43 @@ impl DocView {
}
}
/// ⌘+ / ⌘− / ⌘0 / ⌘1 / ⌘2: zoom the page, or size the pages in the page grid.
fn zoom_shortcuts(view: &mut DocView, pressed: &impl Fn(egui::KeyboardShortcut) -> bool) {
use egui::{Key, KeyboardShortcut, Modifiers};
let cmd = |k| KeyboardShortcut::new(Modifiers::COMMAND, k);
// In the page grid ⌘+ / ⌘− / ⌘0 size its pages instead (looking is always allowed).
let (zoom_in, zoom_out, zoom_reset) = (pressed(cmd(Key::Plus)) || pressed(cmd(Key::Equals)), pressed(cmd(Key::Minus)), pressed(cmd(Key::Num0)));
if view.organize {
if zoom_in {
view.grid_zoom_request = Some(view.grid_zoom * GRID_ZOOM_STEP);
}
if zoom_out {
view.grid_zoom_request = Some(view.grid_zoom / GRID_ZOOM_STEP);
}
if zoom_reset {
view.grid_zoom_request = Some(1.0);
}
} else {
if zoom_in {
view.zoom_step(true);
}
if zoom_out {
view.zoom_step(false);
}
if zoom_reset {
view.fit = Fit::Page;
view.goto = Some((view.current, 0.0));
}
}
if pressed(cmd(Key::Num1)) {
view.set_zoom(1.0);
}
if pressed(cmd(Key::Num2)) {
view.fit = Fit::Width;
view.goto = Some((view.current, 0.0));
}
}
pub fn shortcuts(view: &mut DocView, ctx: &egui::Context, speed: crate::scroll_speed::ScrollSpeed) {
use egui::{Key, KeyboardShortcut, Modifiers};
if ctx.input_mut(|i| i.consume_shortcut(&KeyboardShortcut::new(Modifiers::COMMAND, Key::F))) {
@@ -331,37 +368,7 @@ pub fn shortcuts(view: &mut DocView, ctx: &egui::Context, speed: crate::scroll_s
if pressed(KeyboardShortcut::new(Modifiers::COMMAND | Modifiers::SHIFT, Key::Minus)) {
view.rotate_view(false);
}
// In the page grid ⌘+ / ⌘− / ⌘0 size its pages instead (looking is always allowed).
let (zoom_in, zoom_out, zoom_reset) = (pressed(cmd(Key::Plus)) || pressed(cmd(Key::Equals)), pressed(cmd(Key::Minus)), pressed(cmd(Key::Num0)));
if view.organize {
if zoom_in {
view.grid_zoom_request = Some(view.grid_zoom * GRID_ZOOM_STEP);
}
if zoom_out {
view.grid_zoom_request = Some(view.grid_zoom / GRID_ZOOM_STEP);
}
if zoom_reset {
view.grid_zoom_request = Some(1.0);
}
} else {
if zoom_in {
view.zoom_step(true);
}
if zoom_out {
view.zoom_step(false);
}
if zoom_reset {
view.fit = Fit::Page;
view.goto = Some((view.current, 0.0));
}
}
if pressed(cmd(Key::Num1)) {
view.set_zoom(1.0);
}
if pressed(cmd(Key::Num2)) {
view.fit = Fit::Width;
view.goto = Some((view.current, 0.0));
}
zoom_shortcuts(view, &pressed);
if pressed(cmd(Key::OpenBracket)) {
view.view_history(false);
}
+61 -34
View File
@@ -1,6 +1,9 @@
use super::cache::{GRID_TAG, thumbnail_density, thumbnail_rows, thumbnail_scale};
use super::zoom::{GRID_ZOOM_RANGE, GRID_ZOOM_STEP};
use super::*;
use super::{
Align2, Color32, CornerRadius, DocInfo, DocView, Edit, Pos2, Rect, RenderRequest, RequestKind, Sense, Stroke, Tokens, Vec2, ViewAction,
device_pixels, icons, pos2, theme, vec2, widgets,
};
/// How far a sharp grid render may be from the size drawn before it is redone: a pinch changes
/// the size on every frame, and a slightly soft or slightly large image is fine meanwhile.
@@ -210,6 +213,60 @@ fn gap_button(ui: &mut egui::Ui, gap: usize, at: Pos2, height: f32, label: Strin
resp.on_hover_text(label).clicked()
}
/// Middle-button auto-scroll: its delta scrolls the grid, and the page controls under it are
/// disabled (but not dimmed) while the gesture lasts.
fn apply_auto_scroll(ui: &mut egui::Ui, middle_gesture: bool, auto_delta: Vec2) {
if middle_gesture {
let opacity = ui.opacity();
ui.disable();
ui.set_opacity(opacity);
}
if auto_delta != Vec2::ZERO {
ui.scroll_with_delta_animation(auto_delta, egui::style::ScrollAnimation::none());
}
}
/// Drag pages to move them (the selection, or the page grabbed); `drop` is set when the drag ends.
fn drag_pages(view: &mut DocView, resp: &egui::Response, page: usize, drop: &mut bool) {
if resp.drag_started() {
if !view.selected.contains(&page) {
view.selected = [page].into();
view.select_anchor = Some(page);
}
let mut pages: Vec<usize> = view.selected.iter().copied().collect();
pages.sort_unstable();
view.org_drag = Some(pages);
}
if resp.drag_stopped() {
*drop = true;
}
}
/// A page drawn larger than its thumbnail gets a render at the size drawn, while it is in view;
/// until that arrives the thumbnail stands in.
fn request_sharper(
view: &DocView,
page: usize,
want: f32,
page_width: f32,
drawn_width: Option<u32>,
in_view: &mut Vec<(usize, f32)>,
sharper: &mut Vec<RenderRequest>,
) {
in_view.push((page, want));
if !drawn_width.is_some_and(|w| sharp_enough(w, want)) && !view.errors.contains_key(&page) {
sharper.push(RenderRequest {
page,
kind: RequestKind::Pixels,
tile: None,
scale: want / page_width.max(1.0),
tag: GRID_TAG,
// Grid cells are previews: tiny images are skipped for them.
preview: true,
});
}
}
pub(super) fn organize_grid(view: &mut DocView, info: &DocInfo, editable: bool, dirty: bool, unobstructed: bool, ui: &mut egui::Ui, t: &Tokens) {
let ppp = ui.ctx().pixels_per_point();
// The page image scales with the zoom; the padding and the page number don't.
@@ -234,14 +291,7 @@ pub(super) fn organize_grid(view: &mut DocView, info: &DocInfo, editable: bool,
// The source cell can scroll out of the virtualized rows during a drag.
let mut drop = view.org_drag.is_some() && ui.input(|i| i.pointer.primary_released());
egui::ScrollArea::vertical().auto_shrink([false, false]).show_viewport(ui, |ui, clip| {
if middle_gesture {
let opacity = ui.opacity();
ui.disable();
ui.set_opacity(opacity);
}
if auto_delta != Vec2::ZERO {
ui.scroll_with_delta_animation(auto_delta, egui::style::ScrollAnimation::none());
}
apply_auto_scroll(ui, middle_gesture, auto_delta);
ui.add_space(20.0);
let cols = ((ui.available_width() - 40.0) / cell.x).floor().max(1.0) as usize;
let rows = info.pages.len().div_ceil(cols);
@@ -267,19 +317,7 @@ pub(super) fn organize_grid(view: &mut DocView, info: &DocInfo, editable: bool,
if let Some((_, above)) = anchor.filter(|(page, _)| *page == i) {
ui.scroll_to_rect_animation(c.translate(vec2(0.0, -above)), Some(egui::Align::Min), egui::style::ScrollAnimation::none());
}
// Drag pages to move them (the selection, or the page grabbed).
if resp.drag_started() {
if !view.selected.contains(&i) {
view.selected = [i].into();
view.select_anchor = Some(i);
}
let mut pages: Vec<usize> = view.selected.iter().copied().collect();
pages.sort_unstable();
view.org_drag = Some(pages);
}
if resp.drag_stopped() {
drop = true;
}
drag_pages(view, &resp, i, &mut drop);
let page_label = crate::i18n::fmt(tl!("Page {label}"), &[("label", &p.label)]);
resp.widget_info(|| egui::WidgetInfo::selected(egui::Role::CheckBox, true, view.selected.contains(&i), page_label.clone()));
let pr = grid_page_rect(c, vec2(p.width, p.height));
@@ -300,18 +338,7 @@ pub(super) fn organize_grid(view: &mut DocView, info: &DocInfo, editable: bool,
let thumb_ok = thumb.is_some_and(|t| t.size()[0] as f32 >= want * GRID_SHARP.start());
let sharp = view.grid_pages.get(&i).filter(|_| !thumb_ok);
if !thumb_ok && ui.is_rect_visible(c) {
in_view.push((i, want));
if !sharp.is_some_and(|(w, _)| sharp_enough(*w, want)) && !view.errors.contains_key(&i) {
sharper.push(RenderRequest {
page: i,
kind: RequestKind::Pixels,
tile: None,
scale: want / p.width.max(1.0),
tag: GRID_TAG,
// Grid cells are previews: tiny images are skipped for them.
preview: true,
});
}
request_sharper(view, i, want, p.width, sharp.map(|(w, _)| *w), &mut in_view, &mut sharper);
}
if let Some(tex) = sharp.map(|(_, t)| t).or(thumb) {
ui.painter().image(tex.id(), pr, Rect::from_min_max(pos2(0.0, 0.0), pos2(1.0, 1.0)), Color32::WHITE);
+1 -1
View File
@@ -1,4 +1,4 @@
use super::*;
use super::{Arc, DocInfo, DocView, Edit, HashMap, PageText, Pos2, Range, Rect, comments, pos2};
/// A text selection on one page.
#[derive(Clone, Copy, Debug, PartialEq)]
+1 -1
View File
@@ -1,4 +1,4 @@
use super::*;
use super::{Color32, DocInfo, DocView, Pos2, Rect, pos2, vec2};
impl DocView {
/// Where `page` is drawn on screen this frame (`None` when it is not on screen).
+1 -1
View File
@@ -1,4 +1,4 @@
use super::*;
use super::{DocInfo, DocView, Fit, GAP, MARGIN, PT, PageLayout, Pos2, Rect, SIDE, SavedDisplay, Vec2, device_pixels, pos2, vec2};
/// The page grid's zoom range and the step of its buttons and keys.
pub const GRID_ZOOM_RANGE: std::ops::RangeInclusive<f32> = 0.5..=3.0;