feat(iced): add missing dialogs (Image Size, Canvas Size, About)

This commit is contained in:
2026-07-15 17:54:36 +03:00
parent 45f222b4a0
commit 13f6a62085
5 changed files with 321 additions and 2 deletions
+108 -2
View File
@@ -70,6 +70,9 @@ pub enum ActiveDialog {
CloseConfirm,
SelectionOp(&'static str),
LayerStyleDialog,
ImageSize,
CanvasSize,
About,
}
/// Top-level application state.
@@ -111,6 +114,15 @@ pub struct HcieIcedApp {
pub dialog_lightness: f32,
/// Selection operation dialog state.
pub dialog_selection_value: f32,
/// Image Size dialog state.
pub dialog_image_size_width: u32,
pub dialog_image_size_height: u32,
pub dialog_image_size_constrain: bool,
pub dialog_image_size_original_ratio: f32,
/// Canvas Size dialog state.
pub dialog_canvas_size_width: u32,
pub dialog_canvas_size_height: u32,
pub dialog_canvas_size_anchor: (usize, usize),
/// Selected filter.
pub selected_filter: Option<FilterType>,
/// Filter parameters (JSON) for the currently selected filter.
@@ -429,6 +441,18 @@ pub enum Message {
SelectionOpValue(f32),
SelectionOpApply,
// ── Image Size Dialog ──────────────────────────────
DialogImageSizeWidth(u32),
DialogImageSizeHeight(u32),
DialogImageSizeConstrain(bool),
DialogImageSizeApply,
// ── Canvas Size Dialog ─────────────────────────────
DialogCanvasSizeWidth(u32),
DialogCanvasSizeHeight(u32),
DialogCanvasSizeAnchor(usize, usize),
DialogCanvasSizeApply,
// ── Selection tools ─────────────────────────────────
SelectionDragStart(f32, f32),
SelectionDragMove(f32, f32),
@@ -706,6 +730,13 @@ impl HcieIcedApp {
dialog_saturation: 0.0,
dialog_lightness: 0.0,
dialog_selection_value: 5.0,
dialog_image_size_width: 800,
dialog_image_size_height: 600,
dialog_image_size_constrain: true,
dialog_image_size_original_ratio: 800.0 / 600.0,
dialog_canvas_size_width: 800,
dialog_canvas_size_height: 600,
dialog_canvas_size_anchor: (1, 1),
selected_filter: None,
filter_params: serde_json::json!({}),
filter_preview_active: false,
@@ -2187,6 +2218,54 @@ impl HcieIcedApp {
return Task::perform(async {}, |_| Message::CompositeRefresh);
}
// ── Image Size Dialog ────────────────────────
Message::DialogImageSizeWidth(w) => {
self.dialog_image_size_width = w;
if self.dialog_image_size_constrain && self.dialog_image_size_original_ratio > 0.0 {
self.dialog_image_size_height = (w as f32 / self.dialog_image_size_original_ratio) as u32;
}
}
Message::DialogImageSizeHeight(h) => {
self.dialog_image_size_height = h;
if self.dialog_image_size_constrain && self.dialog_image_size_original_ratio > 0.0 {
self.dialog_image_size_width = (h as f32 * self.dialog_image_size_original_ratio) as u32;
}
}
Message::DialogImageSizeConstrain(c) => {
self.dialog_image_size_constrain = c;
}
Message::DialogImageSizeApply => {
let w = self.dialog_image_size_width.max(1);
let h = self.dialog_image_size_height.max(1);
self.documents[self.active_doc].engine.resize_canvas(w, h);
self.documents[self.active_doc].engine.pre_tile_all_layers();
self.refresh_composite_if_needed();
self.documents[self.active_doc].full_upload.replace(true);
self.active_dialog = ActiveDialog::None;
return Task::perform(async {}, |_| Message::CompositeRefresh);
}
// ── Canvas Size Dialog ───────────────────────
Message::DialogCanvasSizeWidth(w) => {
self.dialog_canvas_size_width = w;
}
Message::DialogCanvasSizeHeight(h) => {
self.dialog_canvas_size_height = h;
}
Message::DialogCanvasSizeAnchor(r, c) => {
self.dialog_canvas_size_anchor = (r, c);
}
Message::DialogCanvasSizeApply => {
let new_w = self.dialog_canvas_size_width.max(1);
let new_h = self.dialog_canvas_size_height.max(1);
self.documents[self.active_doc].engine.resize_canvas(new_w, new_h);
self.documents[self.active_doc].engine.pre_tile_all_layers();
self.refresh_composite_if_needed();
self.documents[self.active_doc].full_upload.replace(true);
self.active_dialog = ActiveDialog::None;
return Task::perform(async {}, |_| Message::CompositeRefresh);
}
// ── Selection tools ───────────────────────────
Message::SelectionDragStart(x, y) => {
self.documents[self.active_doc].selection_rect = Some((x, y, x, y));
@@ -3288,8 +3367,23 @@ impl HcieIcedApp {
// (2, 7) = Vectorize Bitmap...
// (2, 8) = Wavelet Decompose...
// (2, 9) = separator
// (2, 10) = Canvas Size...
// (2, 11) = Image Size...
(2, 10) => {
// Canvas Size...
let (w, h) = self.documents[self.active_doc].engine.get_canvas_size();
self.dialog_canvas_size_width = w;
self.dialog_canvas_size_height = h;
self.dialog_canvas_size_anchor = (1, 1);
self.active_dialog = ActiveDialog::CanvasSize;
}
(2, 11) => {
// Image Size...
let (w, h) = self.documents[self.active_doc].engine.get_canvas_size();
self.dialog_image_size_width = w;
self.dialog_image_size_height = h;
self.dialog_image_size_original_ratio = w as f32 / h as f32;
self.dialog_image_size_constrain = true;
self.active_dialog = ActiveDialog::ImageSize;
}
// (2, 12) = Transform (submenu)
// (2, 13) = Crop
// (2, 14) = Trim...
@@ -3731,6 +3825,18 @@ impl HcieIcedApp {
self.layer_style_offset,
)
}
ActiveDialog::ImageSize => dialogs::image_size::view(
self.dialog_image_size_width,
self.dialog_image_size_height,
self.dialog_image_size_constrain,
),
ActiveDialog::CanvasSize => dialogs::canvas_size::view(
self.dialog_canvas_size_width,
self.dialog_canvas_size_height,
self.dialog_canvas_size_anchor.0,
self.dialog_canvas_size_anchor.1,
),
ActiveDialog::About => dialogs::about::view(),
};
// Stack main content with overlays (dialog + menu dropdown + dock profile dialog).