4.3 KiB
Document Expansion Plan for Pasted Panel Larger Than Canvas
Problem
When pasting a panel via Ctrl+V that is larger than the current canvas, the pasted content gets cropped instead of permanently expanding the document and all layers.
Discoveries
Paste Handler Location
hcie-egui-app/crates/hcie-gui-egui/src/app/mod.rs:1827-1898 — AppEvent::ClipboardPaste:
- Gets clipboard image, centers it, creates new layer
- Line 1871:
if dst_x >= 0 && dst_x < canvas_w as i32 && dst_y >= 0 && dst_y < canvas_h as i32— silently clips pixels outside canvas
Engine API — resize_canvas Already Exists
hcie-engine-api/src/lib.rs:504-507:
pub fn resize_canvas(&mut self, w: u32, h: u32) {
self.document.resize_canvas(w, h);
self.pre_tile_all_layers();
}
Document Resize Implementation
hcie-document/src/lib.rs:384-407 — Resizes all layer pixel buffers, copies existing content, zeroes new areas. Already handles all layers.
Dialog System
dialogs.rs — show_new_image_dialog pattern exists. modern_dialogs.rs — ready button/frame helpers.
No locked crate changes needed — resize_canvas is already exposed in hcie-engine-api.
Implementation Tasks
Task 1: Add ExpandCanvas event variant
File: hcie-egui-app/crates/hcie-gui-egui/src/event_bus.rs
Add to AppEvent enum:
ExpandCanvas { w: u32, h: u32 },
Task 2: Add show_expand_dialog state field
File: hcie-egui-app/crates/hcie-gui-egui/src/app/mod.rs
Add field to HcieApp:
pub show_expand_dialog: Option<(u32, u32, u32, u32)>,
// (paste_width, paste_height, canvas_width, canvas_height)
Initialize in HcieApp::new:
show_expand_dialog: None,
Task 3: Modify paste handler to detect oversized paste
File: hcie-egui-app/crates/hcie-gui-egui/src/app/mod.rs — ClipboardPaste handler (lines 1827-1898)
After clipboard data is resolved (after line 1856), before creating the layer:
- If
clip.width > canvas_w || clip.height > canvas_h:- Set
self.show_expand_dialog = Some((clip.width, clip.height, canvas_w, canvas_h)) - Store clipboard data in
self.internal_clipboardfor later use - Skip the paste (don't create layer, don't write pixels)
- Set
- Else: proceed with existing paste flow unchanged
Task 4: Add ExpandCanvas event handler
File: hcie-egui-app/crates/hcie-gui-egui/src/app/mod.rs — event loop
AppEvent::ExpandCanvas { w, h } => {
if let Some(doc) = self.active_doc_mut() {
doc.engine.resize_canvas(w, h);
doc.engine.set_modified(true);
self.event_bus.push(AppEvent::RenderRequested);
}
}
Task 5: Create expand confirmation dialog
File: hcie-egui-app/crates/hcie-gui-egui/src/app/dialogs.rs
New function show_expand_dialog(app: &mut HcieApp, ctx: &egui::Context):
- Follow
show_new_image_dialogpattern (dim background, centered area, modern_dialog_frame) - Show: "Pasted image (WxH) exceeds canvas (WxH). Expand document to fit?"
- Two buttons:
- Expand (accent_button): Push
AppEvent::ExpandCanvas { w: paste_w, h: paste_h }, then pushAppEvent::ClipboardPaste(to retry paste on expanded canvas), close dialog - Cancel (ghost_button): Close dialog, paste proceeds as-is (will be cropped)
- Expand (accent_button): Push
Task 6: Render expand dialog in update loop
File: hcie-egui-app/crates/hcie-gui-egui/src/app/mod.rs — update method
Add alongside existing dialog calls:
if self.show_expand_dialog.is_some() {
dialogs::show_expand_dialog(self, ctx);
}
Validation Plan
- Paste smaller image: 100x100 into 800x600 → no dialog, normal paste
- Paste larger image + Cancel: 1920x1080 into 800x600 → dialog appears, Cancel → image is cropped to canvas
- Paste larger image + Expand: 1920x1080 into 800x600 → dialog appears, Expand → canvas resizes to 1920x1080, all layers expand, pasted image fits perfectly
Risks
- Performance:
resize_canvasreallocates all layer pixel buffers. For very large documents this may cause a frame drop. Acceptable for user-initiated paste. - Retrigger loop: After Expand, pushing
ClipboardPasteagain re-reads clipboard. Ensureinternal_clipboardis still set so it doesn't re-prompt. The second paste will see canvas is now large enough and proceed normally.