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
This commit is contained in:
Kit PANG 2022-10-23 00:14:37 +08:00 committed by Keavon Chambers
parent 7b4c43ff8d
commit b10d7a93b6
3 changed files with 53 additions and 35 deletions

View File

@ -94,7 +94,14 @@ impl MessageHandler<ArtboardMessage, &FontCache> 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( responses.push_back(
ArtboardMessage::DispatchOperation(Box::new(DocumentOperation::SetLayerTransform { ArtboardMessage::DispatchOperation(Box::new(DocumentOperation::SetLayerTransform {
path: vec![artboard], path: vec![artboard],

View File

@ -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()), value: Some(layer.bounding_transform(&persistent_data.font_cache).scale_x()),
label: "W".into(), label: "W".into(),
unit: " px".into(), unit: " px".into(),
is_integer: true,
min: Some(1.),
on_update: WidgetCallback::new(|number_input: &NumberInput| { on_update: WidgetCallback::new(|number_input: &NumberInput| {
PropertiesPanelMessage::ModifyTransform { PropertiesPanelMessage::ModifyTransform {
value: number_input.value.unwrap(), 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()), value: Some(layer.bounding_transform(&persistent_data.font_cache).scale_y()),
label: "H".into(), label: "H".into(),
unit: " px".into(), unit: " px".into(),
is_integer: true,
min: Some(1.),
on_update: WidgetCallback::new(|number_input: &NumberInput| { on_update: WidgetCallback::new(|number_input: &NumberInput| {
PropertiesPanelMessage::ModifyTransform { PropertiesPanelMessage::ModifyTransform {
value: number_input.value.unwrap(), value: number_input.value.unwrap(),

View File

@ -117,7 +117,7 @@ impl Default for ArtboardToolFsmState {
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
struct ArtboardToolData { struct ArtboardToolData {
bounding_box_overlays: Option<BoundingBoxOverlays>, bounding_box_overlays: Option<BoundingBoxOverlays>,
selected_board: Option<LayerId>, selected_artboard: Option<LayerId>,
snap_manager: SnapManager, snap_manager: SnapManager,
cursor: MouseCursorIcon, cursor: MouseCursorIcon,
drag_start: DVec2, drag_start: DVec2,
@ -140,7 +140,10 @@ impl Fsm for ArtboardToolFsmState {
match (self, event) { match (self, event) {
(ArtboardToolFsmState::Ready | ArtboardToolFsmState::ResizingBounds | ArtboardToolFsmState::Dragging, ArtboardToolMessage::DocumentIsDirty) => { (ArtboardToolFsmState::Ready | ArtboardToolFsmState::ResizingBounds | ArtboardToolFsmState::Dragging, ArtboardToolMessage::DocumentIsDirty) => {
match ( 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(), tool_data.bounding_box_overlays.take(),
) { ) {
(None, Some(bounding_box_overlays)) => bounding_box_overlays.delete(responses), (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(OverlaysMessage::Rerender.into());
responses.push_back( responses.push_back(
PropertiesPanelMessage::SetActiveLayers { PropertiesPanelMessage::SetActiveLayers {
paths: vec![vec![tool_data.selected_board.unwrap()]], paths: vec![vec![tool_data.selected_artboard.unwrap()]],
document: TargetDocument::Artboard, document: TargetDocument::Artboard,
} }
.into(), .into(),
@ -190,12 +193,12 @@ impl Fsm for ArtboardToolFsmState {
let snap_x = selected_edges.2 || selected_edges.3; let snap_x = selected_edges.2 || selected_edges.3;
let snap_y = selected_edges.0 || selected_edges.1; let snap_y = selected_edges.0 || selected_edges.1;
let board = tool_data.selected_board.unwrap(); let artboard = tool_data.selected_artboard.unwrap();
tool_data.snap_manager.start_snap(document, document.bounding_boxes(None, Some(board), font_cache), snap_x, snap_y); 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, &[], &[], &[]); tool_data.snap_manager.add_all_document_handles(document, &[], &[], &[]);
if let Some(bounds) = &mut tool_data.bounding_box_overlays { 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 root = document.graphene_document.root.transform;
let pivot = root.inverse().transform_point2(pivot); let pivot = root.inverse().transform_point2(pivot);
bounds.center_of_transformation = pivot; bounds.center_of_transformation = pivot;
@ -209,7 +212,7 @@ impl Fsm for ArtboardToolFsmState {
responses.push_back(BroadcastEvent::DocumentIsDirty.into()); responses.push_back(BroadcastEvent::DocumentIsDirty.into());
if let Some(intersection) = intersection.last() { if let Some(intersection) = intersection.last() {
tool_data.selected_board = Some(intersection[0]); tool_data.selected_artboard = Some(intersection[0]);
tool_data tool_data
.snap_manager .snap_manager
@ -226,20 +229,7 @@ impl Fsm for ArtboardToolFsmState {
ArtboardToolFsmState::Dragging ArtboardToolFsmState::Dragging
} else { } else {
let id = generate_uuid(); tool_data.selected_artboard = None;
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(),
);
responses.push_back(PropertiesPanelMessage::ClearSelection.into()); 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); let (position, size) = movement.new_size(snapped_mouse_position, bounds.transform, from_center, bounds.center_of_transformation, constrain_square);
responses.push_back( responses.push_back(
ArtboardMessage::ResizeArtboard { ArtboardMessage::ResizeArtboard {
artboard: tool_data.selected_board.unwrap(), artboard: tool_data.selected_artboard.unwrap(),
position: position.round().into(), position: position.round().into(),
size: size.round().into(), size: size.round().into(),
} }
@ -287,7 +277,7 @@ impl Fsm for ArtboardToolFsmState {
responses.push_back( responses.push_back(
ArtboardMessage::ResizeArtboard { ArtboardMessage::ResizeArtboard {
artboard: tool_data.selected_board.unwrap(), artboard: tool_data.selected_artboard.unwrap(),
position: position.round().into(), position: position.round().into(),
size: size.round().into(), size: size.round().into(),
} }
@ -321,20 +311,37 @@ impl Fsm for ArtboardToolFsmState {
let start = root_transform.transform_point2(start); let start = root_transform.transform_point2(start);
let size = root_transform.transform_vector2(size); let size = root_transform.transform_vector2(size);
responses.push_back( if let Some(artboard) = tool_data.selected_artboard {
ArtboardMessage::ResizeArtboard { responses.push_back(
artboard: tool_data.selected_board.unwrap(), ArtboardMessage::ResizeArtboard {
position: start.round().into(), artboard,
size: size.round().into(), position: start.round().into(),
} size: size.round().into(),
.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 // 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 // This might result in a few more calls but it is not reliant on the order of messages
responses.push_back( responses.push_back(
PropertiesPanelMessage::SetActiveLayers { PropertiesPanelMessage::SetActiveLayers {
paths: vec![vec![tool_data.selected_board.unwrap()]], paths: vec![vec![tool_data.selected_artboard.unwrap()]],
document: TargetDocument::Artboard, document: TargetDocument::Artboard,
} }
.into(), .into(),
@ -384,7 +391,7 @@ impl Fsm for ArtboardToolFsmState {
ArtboardToolFsmState::Ready ArtboardToolFsmState::Ready
} }
(_, ArtboardToolMessage::DeleteSelected) => { (_, 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(ArtboardMessage::DeleteArtboard { artboard }.into());
responses.push_back(BroadcastEvent::DocumentIsDirty.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 { if let Some(bounds) = &mut tool_data.bounding_box_overlays {
responses.push_back( responses.push_back(
ArtboardMessage::ResizeArtboard { 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), position: (bounds.bounds[0].x + delta_x, bounds.bounds[0].y + delta_y),
size: (bounds.bounds[1] - bounds.bounds[0]).round().into(), size: (bounds.bounds[1] - bounds.bounds[0]).round().into(),
} }