Fix artboard tool and remove old artboard code

This commit is contained in:
0hypercube
2023-10-17 11:02:06 -07:00
committed by Keavon Chambers
parent 9a39c4a0cc
commit b52f831b21
27 changed files with 196 additions and 553 deletions
@@ -91,6 +91,11 @@ pub fn get_gradient(layer: LayerNodeIdentifier, document: &Document) -> Option<G
})
}
/// Is a specified layer an artboard?
pub fn is_artboard(layer: LayerNodeIdentifier, document: &Document) -> bool {
NodeGraphLayer::new(layer, document).is_some_and(|layer| layer.uses_node("Artboard"))
}
/// Convert subpaths to an iterator of manipulator groups
pub fn get_manipulator_groups(subpaths: &[Subpath<ManipulatorGroupId>]) -> impl Iterator<Item = &bezier_rs::ManipulatorGroup<ManipulatorGroupId>> + DoubleEndedIterator {
subpaths.iter().flat_map(|subpath| subpath.manipulator_groups())
@@ -145,14 +150,14 @@ impl<'a> NodeGraphLayer<'a> {
self.node_graph.primary_flow_from_opt(Some(self.layer_node))
}
/// Does a node exist in the layer's primary flow
pub fn uses_node(&self, node_name: &str) -> bool {
self.primary_layer_flow().any(|(node, _id)| node.name == node_name)
}
/// Find all of the inputs of a specific node within the layer's primary flow
pub fn find_node_inputs(&self, node_name: &str) -> Option<&'a Vec<NodeInput>> {
for (node, _id) in self.primary_layer_flow() {
if node.name == node_name {
return Some(&node.inputs);
}
}
None
self.primary_layer_flow().find(|(node, _id)| node.name == node_name).map(|(node, _id)| &node.inputs)
}
/// Find a specific input of a node within the layer's primary flow
@@ -1,12 +1,10 @@
use super::tool_prelude::*;
use crate::application::generate_uuid;
use crate::consts::SELECTION_TOLERANCE;
use crate::messages::portfolio::document::utility_types::misc::TargetDocument;
use crate::messages::tool::common_functionality::graph_modification_utils::is_artboard;
use crate::messages::tool::common_functionality::snapping::SnapManager;
use crate::messages::tool::common_functionality::transformation_cage::*;
use document_legacy::intersection::Quad;
use document_legacy::LayerId;
use document_legacy::document_metadata::LayerNodeIdentifier;
use document_legacy::layers::RenderData;
use glam::{IVec2, Vec2Swizzles};
@@ -96,7 +94,7 @@ enum ArtboardToolFsmState {
#[derive(Clone, Debug, Default)]
struct ArtboardToolData {
bounding_box_overlays: Option<BoundingBoxOverlays>,
selected_artboard: Option<LayerId>,
selected_artboard: Option<LayerNodeIdentifier>,
snap_manager: SnapManager,
cursor: MouseCursorIcon,
drag_start: DVec2,
@@ -104,15 +102,15 @@ struct ArtboardToolData {
}
impl ArtboardToolData {
fn refresh_overlays(&mut self, document: &DocumentMessageHandler, render_data: &RenderData, responses: &mut VecDeque<Message>) {
let current_artboard = self.selected_artboard.and_then(|path| document.artboard_bounding_box_and_transform(&[path], render_data));
fn refresh_overlays(&mut self, document: &DocumentMessageHandler, responses: &mut VecDeque<Message>) {
let current_artboard = self.selected_artboard.and_then(|layer| document.document_legacy.metadata.bounding_box_document(layer));
match (current_artboard, self.bounding_box_overlays.take()) {
(None, Some(bounding_box_overlays)) => bounding_box_overlays.delete(responses),
(Some((bounds, transform)), paths) => {
(Some(bounds), paths) => {
let mut bounding_box_overlays = paths.unwrap_or_else(|| BoundingBoxOverlays::new(responses));
bounding_box_overlays.bounds = bounds;
bounding_box_overlays.transform = transform;
bounding_box_overlays.transform = document.document_legacy.metadata.document_to_viewport;
bounding_box_overlays.transform(responses);
@@ -130,6 +128,7 @@ impl ArtboardToolData {
let (top, bottom, left, right) = edges;
let selected_edges = SelectedEdges::new(top, bottom, left, right, bounding_box.bounds);
bounding_box.opposite_pivot = selected_edges.calculate_pivot();
bounding_box.selected_edges = Some(selected_edges);
Some(edges)
}
@@ -140,29 +139,29 @@ impl ArtboardToolData {
let artboard = self.selected_artboard.unwrap();
self.snap_manager
.start_snap(document, input, document.bounding_boxes(None, Some(artboard), render_data), snap_x, snap_y);
.start_snap(document, input, document.bounding_boxes(None, Some(artboard.to_node()), render_data), snap_x, snap_y);
self.snap_manager.add_all_document_handles(document, input, &[], &[], &[]);
if let Some(bounds) = &mut self.bounding_box_overlays {
let pivot = document.artboard_message_handler.artboards_document.pivot(&[artboard], render_data).unwrap_or_default();
let root = document.document_legacy.metadata.document_to_viewport;
let pivot = root.inverse().transform_point2(pivot);
bounds.center_of_transformation = pivot;
bounds.center_of_transformation = (bounds.bounds[0] + bounds.bounds[1]) / 2.;
}
}
fn select_artboard(&mut self, document: &DocumentMessageHandler, render_data: &RenderData, input: &InputPreprocessorMessageHandler, responses: &mut VecDeque<Message>) -> bool {
responses.add(DocumentMessage::StartTransaction);
let tolerance = DVec2::splat(SELECTION_TOLERANCE);
let quad = Quad::from_box([input.mouse.position - tolerance, input.mouse.position + tolerance]);
let intersection = document.artboard_message_handler.artboards_document.intersects_quad_root(quad, render_data);
let mut intersections = document
.document_legacy
.metadata
.click_xray(input.mouse.position)
.filter(|&layer| is_artboard(layer, &document.document_legacy));
responses.add(BroadcastEvent::DocumentIsDirty);
if let Some(intersection) = intersection.last() {
self.selected_artboard = Some(intersection[0]);
if let Some(intersection) = intersections.next() {
self.selected_artboard = Some(intersection);
self.snap_manager
.start_snap(document, input, document.bounding_boxes(None, Some(intersection[0]), render_data), true, true);
.start_snap(document, input, document.bounding_boxes(None, Some(intersection.to_node()), render_data), true, true);
self.snap_manager.add_all_document_handles(document, input, &[], &[], &[]);
true
@@ -186,13 +185,8 @@ impl ArtboardToolData {
let snapped_mouse_position: DVec2 = self.snap_manager.snap_position(responses, document, mouse_position);
let (position, size) = movement.new_size(snapped_mouse_position, bounds.transform, from_center, bounds.center_of_transformation, constrain_square);
responses.add(ArtboardMessage::ResizeArtboard {
artboard: self.selected_artboard.unwrap(),
position: position.round().into(),
size: size.round().into(),
});
responses.add(GraphOperationMessage::ResizeArtboard {
id: self.selected_artboard.unwrap(),
id: self.selected_artboard.unwrap().to_node(),
location: position.round().as_ivec2(),
dimensions: size.round().as_ivec2(),
});
@@ -214,7 +208,7 @@ impl Fsm for ArtboardToolFsmState {
match (self, event) {
(state, ArtboardToolMessage::DocumentIsDirty) if state != ArtboardToolFsmState::Drawing => {
tool_data.refresh_overlays(document, render_data, responses);
tool_data.refresh_overlays(document, responses);
self
}
@@ -255,13 +249,8 @@ impl Fsm for ArtboardToolFsmState {
let position = bounds.bounds[0] + bounds.transform.inverse().transform_vector2(mouse_position - tool_data.drag_current + closest_move);
responses.add(ArtboardMessage::ResizeArtboard {
artboard: tool_data.selected_artboard.unwrap(),
position: position.round().into(),
size: size.round().into(),
});
responses.add(GraphOperationMessage::ResizeArtboard {
id: tool_data.selected_artboard.unwrap(),
id: tool_data.selected_artboard.unwrap().to_node(),
location: position.round().as_ivec2(),
dimensions: size.round().as_ivec2(),
});
@@ -294,28 +283,18 @@ impl Fsm for ArtboardToolFsmState {
let size = root_transform.transform_vector2(size);
if let Some(artboard) = tool_data.selected_artboard {
responses.add(ArtboardMessage::ResizeArtboard {
artboard,
position: start.round().into(),
size: size.round().into(),
});
responses.add(GraphOperationMessage::ResizeArtboard {
id: tool_data.selected_artboard.unwrap(),
id: artboard.to_node(),
location: start.round().as_ivec2(),
dimensions: size.round().as_ivec2(),
});
} else {
let id = generate_uuid();
tool_data.selected_artboard = Some(id);
tool_data.selected_artboard = Some(LayerNodeIdentifier::new_unchecked(id));
tool_data.snap_manager.start_snap(document, input, document.bounding_boxes(None, Some(id), render_data), true, true);
tool_data.snap_manager.add_all_document_handles(document, input, &[], &[], &[]);
responses.add(ArtboardMessage::AddArtboard {
id: Some(id),
position: start.round().into(),
size: (1., 1.),
});
responses.add(GraphOperationMessage::NewArtboard {
id,
artboard: graphene_core::Artboard {
@@ -376,8 +355,8 @@ impl Fsm for ArtboardToolFsmState {
}
(_, ArtboardToolMessage::DeleteSelected) => {
if let Some(artboard) = tool_data.selected_artboard.take() {
responses.add(ArtboardMessage::DeleteArtboard { artboard });
responses.add(GraphOperationMessage::DeleteLayer { id: artboard });
let id = artboard.to_node();
responses.add(GraphOperationMessage::DeleteLayer { id });
responses.add(BroadcastEvent::DocumentIsDirty);
}
@@ -385,13 +364,8 @@ impl Fsm for ArtboardToolFsmState {
}
(_, ArtboardToolMessage::NudgeSelected { delta_x, delta_y }) => {
if let Some(bounds) = &mut tool_data.bounding_box_overlays {
responses.add(ArtboardMessage::ResizeArtboard {
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(),
});
responses.add(GraphOperationMessage::ResizeArtboard {
id: tool_data.selected_artboard.unwrap(),
id: tool_data.selected_artboard.unwrap().to_node(),
location: DVec2::new(bounds.bounds[0].x + delta_x, bounds.bounds[0].y + delta_y).round().as_ivec2(),
dimensions: (bounds.bounds[1] - bounds.bounds[0]).round().as_ivec2(),
});
@@ -407,7 +381,6 @@ impl Fsm for ArtboardToolFsmState {
// Register properties when switching back to other tools
responses.add(PropertiesPanelMessage::SetActiveLayers {
paths: document.selected_layers().map(|path| path.to_vec()).collect(),
document: TargetDocument::Artwork,
});
tool_data.snap_manager.cleanup(responses);
@@ -68,7 +68,7 @@ impl Fsm for FillToolFsmState {
let ToolMessage::Fill(event) = event else {
return self;
};
let Some((layer_identifier, _)) = document.document_legacy.metadata.click(input.mouse.position) else {
let Some(layer_identifier) = document.document_legacy.metadata.click(input.mouse.position) else {
return self;
};
let layer = layer_identifier.to_path();
@@ -116,7 +116,7 @@ enum GradientToolFsmState {
/// Computes the transform from gradient space to viewport space (where gradient space is 0..1)
fn gradient_space_transform(layer: LayerNodeIdentifier, document: &DocumentMessageHandler) -> DAffine2 {
let bounds = document.document_legacy.metadata.bounding_box(layer, DAffine2::IDENTITY).unwrap();
let bounds = document.document_legacy.metadata.bounding_box_with_transform(layer, DAffine2::IDENTITY).unwrap();
let bound_transform = DAffine2::from_scale_angle_translation(bounds[1] - bounds[0], 0., bounds[0]);
let multiplied = document.document_legacy.metadata.transform_from_viewport(layer);
@@ -529,7 +529,7 @@ impl Fsm for GradientToolFsmState {
let selected_layer = document.document_legacy.metadata.click(input.mouse.position);
// Apply the gradient to the selected layer
if let Some((layer, _)) = selected_layer {
if let Some(layer) = selected_layer {
// let is_bitmap = document
// .document_legacy
// .layer(&layer)
@@ -242,7 +242,7 @@ impl PathToolData {
PathToolFsmState::Dragging
}
// We didn't find a point nearby, so consider selecting the nearest shape instead
else if let Some((layer, _)) = document.document_legacy.metadata.click(input.mouse.position) {
else if let Some(layer) = document.document_legacy.metadata.click(input.mouse.position) {
// TODO: Actual selection
let layer_list = vec![layer.to_path()];
if shift {