noctua/src/app/view/canvas.rs
wfx 1182b7b55d feature: PDF and PDF thumbnails and refresh UI
- Implement PDF and PDF thumbnail generation with incremental loading
- Add UI refresh mechanism (tick counter + RefreshView message)
- Improve fl! macro with named parameters
- Clean up code organization (mod.rs: wiring, model.rs: state only)
2026-01-18 20:35:12 +01:00

56 lines
1.9 KiB
Rust

// SPDX-License-Identifier: GPL-3.0-or-later
// src/app/view/canvas.rs
//
// Render the center canvas area with the current document.
use cosmic::iced::{ContentFit, Length};
use cosmic::widget::{container, text};
use cosmic::Element;
use super::image_viewer::Viewer;
use crate::app::model::ViewMode;
use crate::app::{AppMessage, AppModel};
use crate::config::AppConfig;
use crate::fl;
/// Render the center canvas area with the current document.
pub fn view<'a>(model: &'a AppModel, config: &'a AppConfig) -> Element<'a, AppMessage> {
if let Some(doc) = &model.document {
let handle = doc.handle();
// Determine zoom scale and content fit based on view mode
let (scale, content_fit) = match model.view_mode {
ViewMode::Fit => (1.0, ContentFit::Contain),
ViewMode::ActualSize => (1.0, ContentFit::None),
ViewMode::Custom(z) => (z, ContentFit::None),
};
// Use our forked viewer with external state control
// scale_step is (scale_step - 1.0) because viewer uses additive step
let img_viewer = Viewer::new(handle)
.with_state(scale, model.pan_x, model.pan_y)
.on_state_change(|scale, offset_x, offset_y| AppMessage::ViewerStateChanged {
scale,
offset_x,
offset_y,
})
.width(Length::Fill)
.height(Length::Fill)
.content_fit(content_fit)
.min_scale(config.min_scale)
.max_scale(config.max_scale)
.scale_step(config.scale_step - 1.0);
container(img_viewer)
.width(Length::Fill)
.height(Length::Fill)
.into()
} else {
// Placeholder when no document is loaded
container(text(fl!("no-document")))
.width(Length::Fill)
.height(Length::Fill)
.center(Length::Fill)
.into()
}
}