From b10d7a93b6edfe06bc3e9144a90528f100e1ab89 Mon Sep 17 00:00:00 2001 From: Kit PANG Date: Sun, 23 Oct 2022 00:14:37 +0800 Subject: [PATCH] Disallow zero-area artboards (#794) * Fix zero-area artboard * Add artboard only when user starts dragging * Rename variables for clarity * Revert regression caused by commit a11c9ef6ef9c4daa35140148cec9ff85b3a3d8c8 * Fix zero-area artboard properly --- .../artboard/artboard_message_handler.rs | 9 ++- .../properties_panel/utility_functions.rs | 4 + .../tool/tool_messages/artboard_tool.rs | 75 ++++++++++--------- 3 files changed, 53 insertions(+), 35 deletions(-) diff --git a/editor/src/messages/portfolio/document/artboard/artboard_message_handler.rs b/editor/src/messages/portfolio/document/artboard/artboard_message_handler.rs index 018af1bf..663fcf5f 100644 --- a/editor/src/messages/portfolio/document/artboard/artboard_message_handler.rs +++ b/editor/src/messages/portfolio/document/artboard/artboard_message_handler.rs @@ -94,7 +94,14 @@ impl MessageHandler for ArtboardMessageHandler { ); } } - ResizeArtboard { artboard, position, size } => { + ResizeArtboard { artboard, position, mut size } => { + if size.0.abs() == 0. { + size.0 = size.0.signum(); + } + if size.1.abs() == 0. { + size.1 = size.1.signum(); + } + responses.push_back( ArtboardMessage::DispatchOperation(Box::new(DocumentOperation::SetLayerTransform { path: vec![artboard], diff --git a/editor/src/messages/portfolio/document/properties_panel/utility_functions.rs b/editor/src/messages/portfolio/document/properties_panel/utility_functions.rs index 608ef211..4758fa59 100644 --- a/editor/src/messages/portfolio/document/properties_panel/utility_functions.rs +++ b/editor/src/messages/portfolio/document/properties_panel/utility_functions.rs @@ -147,6 +147,8 @@ pub fn register_artboard_layer_properties(layer: &Layer, responses: &mut VecDequ value: Some(layer.bounding_transform(&persistent_data.font_cache).scale_x()), label: "W".into(), unit: " px".into(), + is_integer: true, + min: Some(1.), on_update: WidgetCallback::new(|number_input: &NumberInput| { PropertiesPanelMessage::ModifyTransform { value: number_input.value.unwrap(), @@ -164,6 +166,8 @@ pub fn register_artboard_layer_properties(layer: &Layer, responses: &mut VecDequ value: Some(layer.bounding_transform(&persistent_data.font_cache).scale_y()), label: "H".into(), unit: " px".into(), + is_integer: true, + min: Some(1.), on_update: WidgetCallback::new(|number_input: &NumberInput| { PropertiesPanelMessage::ModifyTransform { value: number_input.value.unwrap(), diff --git a/editor/src/messages/tool/tool_messages/artboard_tool.rs b/editor/src/messages/tool/tool_messages/artboard_tool.rs index 3b3b0283..87e3f815 100644 --- a/editor/src/messages/tool/tool_messages/artboard_tool.rs +++ b/editor/src/messages/tool/tool_messages/artboard_tool.rs @@ -117,7 +117,7 @@ impl Default for ArtboardToolFsmState { #[derive(Clone, Debug, Default)] struct ArtboardToolData { bounding_box_overlays: Option, - selected_board: Option, + selected_artboard: Option, snap_manager: SnapManager, cursor: MouseCursorIcon, drag_start: DVec2, @@ -140,7 +140,10 @@ impl Fsm for ArtboardToolFsmState { match (self, event) { (ArtboardToolFsmState::Ready | ArtboardToolFsmState::ResizingBounds | ArtboardToolFsmState::Dragging, ArtboardToolMessage::DocumentIsDirty) => { match ( - tool_data.selected_board.map(|path| document.artboard_bounding_box_and_transform(&[path], font_cache)).unwrap_or(None), + tool_data + .selected_artboard + .map(|path| document.artboard_bounding_box_and_transform(&[path], font_cache)) + .unwrap_or(None), tool_data.bounding_box_overlays.take(), ) { (None, Some(bounding_box_overlays)) => bounding_box_overlays.delete(responses), @@ -157,7 +160,7 @@ impl Fsm for ArtboardToolFsmState { responses.push_back(OverlaysMessage::Rerender.into()); responses.push_back( PropertiesPanelMessage::SetActiveLayers { - paths: vec![vec![tool_data.selected_board.unwrap()]], + paths: vec![vec![tool_data.selected_artboard.unwrap()]], document: TargetDocument::Artboard, } .into(), @@ -190,12 +193,12 @@ impl Fsm for ArtboardToolFsmState { let snap_x = selected_edges.2 || selected_edges.3; let snap_y = selected_edges.0 || selected_edges.1; - let board = tool_data.selected_board.unwrap(); - tool_data.snap_manager.start_snap(document, document.bounding_boxes(None, Some(board), font_cache), snap_x, snap_y); + let artboard = tool_data.selected_artboard.unwrap(); + tool_data.snap_manager.start_snap(document, document.bounding_boxes(None, Some(artboard), font_cache), snap_x, snap_y); tool_data.snap_manager.add_all_document_handles(document, &[], &[], &[]); if let Some(bounds) = &mut tool_data.bounding_box_overlays { - let pivot = document.artboard_message_handler.artboards_graphene_document.pivot(&[board], font_cache).unwrap_or_default(); + let pivot = document.artboard_message_handler.artboards_graphene_document.pivot(&[artboard], font_cache).unwrap_or_default(); let root = document.graphene_document.root.transform; let pivot = root.inverse().transform_point2(pivot); bounds.center_of_transformation = pivot; @@ -209,7 +212,7 @@ impl Fsm for ArtboardToolFsmState { responses.push_back(BroadcastEvent::DocumentIsDirty.into()); if let Some(intersection) = intersection.last() { - tool_data.selected_board = Some(intersection[0]); + tool_data.selected_artboard = Some(intersection[0]); tool_data .snap_manager @@ -226,20 +229,7 @@ impl Fsm for ArtboardToolFsmState { ArtboardToolFsmState::Dragging } else { - let id = generate_uuid(); - tool_data.selected_board = Some(id); - - tool_data.snap_manager.start_snap(document, document.bounding_boxes(None, Some(id), font_cache), true, true); - tool_data.snap_manager.add_all_document_handles(document, &[], &[], &[]); - - responses.push_back( - ArtboardMessage::AddArtboard { - id: Some(id), - position: (0., 0.), - size: (0., 0.), - } - .into(), - ); + tool_data.selected_artboard = None; responses.push_back(PropertiesPanelMessage::ClearSelection.into()); @@ -259,7 +249,7 @@ impl Fsm for ArtboardToolFsmState { let (position, size) = movement.new_size(snapped_mouse_position, bounds.transform, from_center, bounds.center_of_transformation, constrain_square); responses.push_back( ArtboardMessage::ResizeArtboard { - artboard: tool_data.selected_board.unwrap(), + artboard: tool_data.selected_artboard.unwrap(), position: position.round().into(), size: size.round().into(), } @@ -287,7 +277,7 @@ impl Fsm for ArtboardToolFsmState { responses.push_back( ArtboardMessage::ResizeArtboard { - artboard: tool_data.selected_board.unwrap(), + artboard: tool_data.selected_artboard.unwrap(), position: position.round().into(), size: size.round().into(), } @@ -321,20 +311,37 @@ impl Fsm for ArtboardToolFsmState { let start = root_transform.transform_point2(start); let size = root_transform.transform_vector2(size); - responses.push_back( - ArtboardMessage::ResizeArtboard { - artboard: tool_data.selected_board.unwrap(), - position: start.round().into(), - size: size.round().into(), - } - .into(), - ); + if let Some(artboard) = tool_data.selected_artboard { + responses.push_back( + ArtboardMessage::ResizeArtboard { + artboard, + position: start.round().into(), + size: size.round().into(), + } + .into(), + ); + } else { + let id = generate_uuid(); + tool_data.selected_artboard = Some(id); + + tool_data.snap_manager.start_snap(document, document.bounding_boxes(None, Some(id), font_cache), true, true); + tool_data.snap_manager.add_all_document_handles(document, &[], &[], &[]); + + responses.push_back( + ArtboardMessage::AddArtboard { + id: Some(id), + position: start.round().into(), + size: (1., 1.), + } + .into(), + ); + } // Have to put message here instead of when Artboard is created // This might result in a few more calls but it is not reliant on the order of messages responses.push_back( PropertiesPanelMessage::SetActiveLayers { - paths: vec![vec![tool_data.selected_board.unwrap()]], + paths: vec![vec![tool_data.selected_artboard.unwrap()]], document: TargetDocument::Artboard, } .into(), @@ -384,7 +391,7 @@ impl Fsm for ArtboardToolFsmState { ArtboardToolFsmState::Ready } (_, ArtboardToolMessage::DeleteSelected) => { - if let Some(artboard) = tool_data.selected_board.take() { + if let Some(artboard) = tool_data.selected_artboard.take() { responses.push_back(ArtboardMessage::DeleteArtboard { artboard }.into()); responses.push_back(BroadcastEvent::DocumentIsDirty.into()); } @@ -394,7 +401,7 @@ impl Fsm for ArtboardToolFsmState { if let Some(bounds) = &mut tool_data.bounding_box_overlays { responses.push_back( ArtboardMessage::ResizeArtboard { - artboard: tool_data.selected_board.unwrap(), + artboard: tool_data.selected_artboard.unwrap(), position: (bounds.bounds[0].x + delta_x, bounds.bounds[0].y + delta_y), size: (bounds.bounds[1] - bounds.bounds[0]).round().into(), }