Complete UI layer refactoring to achieve Clean Architecture + TEA principles. Major Changes: - Eliminated sync.rs (76 LOC of manual synchronization) - Restructured AppModel: pure UI state only - Introduced AppMode enum (View, Crop, Transform, Fullscreen) - Added Viewport struct (scale, pan, canvas, cached_image_handle) - Added PanelState struct (left, right panels) - Removed all cached document data from UI layer - Views now access DocumentManager directly (no caching) - Update functions work on both model and manager directly Architecture: - TEA-compliant: Single source of truth, unidirectional flow - Clean separation: UI state vs Document state - No manual synchronization required Benefits: - Simplified codebase: -1,986 LOC net (-75.6%) - Better maintainability: Clear responsibilities - Type-safe state: Enums instead of flags - Performance: Cached rendering where needed Refactored Files: - src/ui/model.rs: Complete rewrite - src/ui/update.rs: Complete rewrite - src/ui/views/*: Updated to use new architecture - src/ui/views/meta_panel.rs: Extracted from panels.rs Testing: - All 24 unit tests passing - Compiles successfully (cargo check, cargo build) - 32 warnings (non-critical, future features) BREAKING CHANGES: None (internal refactoring only) Co-authored-by: Clean Architecture principles Co-authored-by: TEA (The Elm Architecture) pattern
74 lines
1.8 KiB
Rust
74 lines
1.8 KiB
Rust
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
// src/domain/document/core/page.rs
|
|
//
|
|
// Page abstraction for multi-page documents.
|
|
|
|
use cosmic::widget::image::Handle as ImageHandle;
|
|
|
|
/// Represents a single page in a multi-page document.
|
|
#[derive(Debug, Clone)]
|
|
#[allow(dead_code)]
|
|
pub struct Page {
|
|
/// Page index (0-based).
|
|
pub index: usize,
|
|
/// Page width in pixels.
|
|
pub width: u32,
|
|
/// Page height in pixels.
|
|
pub height: u32,
|
|
/// Optional thumbnail handle.
|
|
pub thumbnail: Option<ImageHandle>,
|
|
}
|
|
|
|
impl Page {
|
|
/// Create a new page.
|
|
#[must_use]
|
|
pub fn new(index: usize, width: u32, height: u32) -> Self {
|
|
Self {
|
|
index,
|
|
width,
|
|
height,
|
|
thumbnail: None,
|
|
}
|
|
}
|
|
|
|
/// Create a page with a thumbnail.
|
|
#[must_use]
|
|
pub fn with_thumbnail(index: usize, width: u32, height: u32, thumbnail: ImageHandle) -> Self {
|
|
Self {
|
|
index,
|
|
width,
|
|
height,
|
|
thumbnail: Some(thumbnail),
|
|
}
|
|
}
|
|
|
|
/// Set the thumbnail for this page.
|
|
pub fn set_thumbnail(&mut self, thumbnail: ImageHandle) {
|
|
self.thumbnail = Some(thumbnail);
|
|
}
|
|
|
|
/// Check if this page has a thumbnail.
|
|
#[must_use]
|
|
pub fn has_thumbnail(&self) -> bool {
|
|
self.thumbnail.is_some()
|
|
}
|
|
|
|
/// Get the aspect ratio of the page.
|
|
#[must_use]
|
|
pub fn aspect_ratio(&self) -> f32 {
|
|
if self.height == 0 {
|
|
1.0
|
|
} else {
|
|
#[allow(clippy::cast_precision_loss)]
|
|
{
|
|
self.width as f32 / self.height as f32
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Get page dimensions as a tuple.
|
|
#[must_use]
|
|
pub fn dimensions(&self) -> (u32, u32) {
|
|
(self.width, self.height)
|
|
}
|
|
}
|