Move selected node list from DocumentMetadata to the document (#1565)

This commit is contained in:
Keavon Chambers
2024-01-13 04:52:47 -08:00
parent aab0fcf84c
commit 78a1bb17cd
27 changed files with 511 additions and 465 deletions
@@ -45,7 +45,7 @@ impl Pivot {
/// Recomputes the pivot position and transform.
fn recalculate_pivot(&mut self, document: &DocumentMessageHandler) {
let mut layers = document.selected_visible_layers();
let mut layers = document.selected_nodes.selected_visible_layers(document.network(), document.metadata());
let Some(first) = layers.next() else {
// If no layers are selected then we revert things back to default
self.normalized_pivot = DVec2::splat(0.5);
@@ -65,8 +65,9 @@ impl Pivot {
} else {
// If more than one layer is selected we use the AABB with the mean of the pivots
let xy_summation = document
.selected_visible_layers()
.map(|layer| graph_modification_utils::get_viewport_pivot(layer, &document.network, &document.document_metadata))
.selected_nodes
.selected_visible_layers(document.network(), document.metadata())
.map(|layer| graph_modification_utils::get_viewport_pivot(layer, &document.network, &document.metadata))
.reduce(|a, b| a + b)
.unwrap_or_default();
@@ -100,7 +101,7 @@ impl Pivot {
/// Sets the viewport position of the pivot for all selected layers.
pub fn set_viewport_position(&self, position: DVec2, document: &DocumentMessageHandler, responses: &mut VecDeque<Message>) {
for layer in document.selected_visible_layers() {
for layer in document.selected_nodes.selected_visible_layers(document.network(), document.metadata()) {
let transform = Self::get_layer_pivot_transform(layer, document);
let pivot = transform.inverse().transform_point2(position);
// Only update the pivot when computed position is finite. Infinite can happen when scale is 0.
@@ -266,10 +266,10 @@ impl BrushToolData {
fn load_existing_strokes(&mut self, document: &DocumentMessageHandler) -> Option<LayerNodeIdentifier> {
self.transform = DAffine2::IDENTITY;
if document.metadata().selected_layers().count() != 1 {
if document.selected_nodes.selected_layers(document.metadata()).count() != 1 {
return None;
}
let Some(layer) = document.metadata().selected_layers().next() else {
let Some(layer) = document.selected_nodes.selected_layers(document.metadata()).next() else {
return None;
};
@@ -295,7 +295,7 @@ impl Fsm for GradientToolFsmState {
(_, GradientToolMessage::Overlays(mut overlay_context)) => {
let selected = tool_data.selected_gradient.as_ref();
for layer in document.selected_visible_layers() {
for layer in document.selected_nodes.selected_visible_layers(document.network(), document.metadata()) {
let Some(gradient) = get_gradient(layer, &document.network) else { continue };
let transform = gradient_space_transform(layer, document);
let dragging = selected.filter(|selected| selected.layer == layer).map(|selected| selected.dragging);
@@ -366,7 +366,7 @@ impl Fsm for GradientToolFsmState {
self
}
(_, GradientToolMessage::InsertStop) => {
for layer in document.selected_visible_layers() {
for layer in document.selected_nodes.selected_visible_layers(document.network(), document.metadata()) {
let Some(mut gradient) = get_gradient(layer, &document.network) else { continue };
let transform = gradient_space_transform(layer, document);
@@ -407,7 +407,7 @@ impl Fsm for GradientToolFsmState {
let tolerance = (MANIPULATOR_GROUP_MARKER_SIZE * 2.).powi(2);
let mut dragging = false;
for layer in document.selected_visible_layers() {
for layer in document.selected_nodes.selected_visible_layers(document.network(), document.metadata()) {
let Some(gradient) = get_gradient(layer, &document.network) else { continue };
let transform = gradient_space_transform(layer, document);
@@ -448,7 +448,7 @@ impl Fsm for GradientToolFsmState {
// Apply the gradient to the selected layer
if let Some(layer) = selected_layer {
if !document.metadata().selected_layers_contains(layer) {
if !document.selected_nodes.selected_layers_contains(layer, document.metadata()) {
let nodes = vec![layer.to_node()];
responses.add(NodeGraphMessage::SelectedNodesSet { nodes });
@@ -223,7 +223,7 @@ impl PathToolData {
let _selected_layers = shape_editor.selected_layers().cloned().collect::<Vec<_>>();
// Select the first point within the threshold (in pixels)
if let Some(selected_points) = shape_editor.select_point(&document.network, &document.document_metadata, input.mouse.position, SELECTION_THRESHOLD, shift) {
if let Some(selected_points) = shape_editor.select_point(&document.network, &document.metadata, input.mouse.position, SELECTION_THRESHOLD, shift) {
self.start_dragging_point(selected_points, input, document, responses);
responses.add(OverlaysMessage::Draw);
@@ -298,7 +298,7 @@ impl PathToolData {
// Move the selected points with the mouse
let snapped_position = self.snap_manager.snap_position(responses, document, input.mouse.position);
shape_editor.move_selected_points(&document.network, &document.document_metadata, snapped_position - self.previous_mouse_position, shift, responses);
shape_editor.move_selected_points(&document.network, &document.metadata, snapped_position - self.previous_mouse_position, shift, responses);
self.previous_mouse_position = snapped_position;
}
}
@@ -316,7 +316,7 @@ impl Fsm for PathToolFsmState {
match (self, event) {
(_, PathToolMessage::SelectionChanged) => {
// Set the newly targeted layers to visible
let target_layers = document.metadata().selected_layers().collect();
let target_layers = document.selected_nodes.selected_layers(document.metadata()).collect();
shape_editor.set_selected_layers(target_layers);
responses.add(OverlaysMessage::Draw);
@@ -362,12 +362,7 @@ impl Fsm for PathToolFsmState {
if tool_data.drag_start_pos == tool_data.previous_mouse_position {
responses.add(NodeGraphMessage::SelectedNodesSet { nodes: vec![] });
} else {
shape_editor.select_all_in_quad(
&document.network,
&document.document_metadata,
[tool_data.drag_start_pos, tool_data.previous_mouse_position],
!shift_pressed,
);
shape_editor.select_all_in_quad(&document.network, &document.metadata, [tool_data.drag_start_pos, tool_data.previous_mouse_position], !shift_pressed);
}
responses.add(OverlaysMessage::Draw);
@@ -381,12 +376,7 @@ impl Fsm for PathToolFsmState {
if tool_data.drag_start_pos == tool_data.previous_mouse_position {
responses.add(NodeGraphMessage::SelectedNodesSet { nodes: vec![] });
} else {
shape_editor.select_all_in_quad(
&document.network,
&document.document_metadata,
[tool_data.drag_start_pos, tool_data.previous_mouse_position],
!shift_pressed,
);
shape_editor.select_all_in_quad(&document.network, &document.metadata, [tool_data.drag_start_pos, tool_data.previous_mouse_position], !shift_pressed);
}
responses.add(OverlaysMessage::Draw);
responses.add(PathToolMessage::SelectedPointUpdated);
@@ -398,16 +388,16 @@ impl Fsm for PathToolFsmState {
let shift_pressed = input.keyboard.get(shift_mirror_distance as usize);
let nearest_point = shape_editor
.find_nearest_point_indices(&document.network, &document.document_metadata, input.mouse.position, SELECTION_THRESHOLD)
.find_nearest_point_indices(&document.network, &document.metadata, input.mouse.position, SELECTION_THRESHOLD)
.map(|(_, nearest_point)| nearest_point);
shape_editor.delete_selected_handles_with_zero_length(&document.network, &document.document_metadata, &tool_data.opposing_handle_lengths, responses);
shape_editor.delete_selected_handles_with_zero_length(&document.network, &document.metadata, &tool_data.opposing_handle_lengths, responses);
if tool_data.drag_start_pos.distance(input.mouse.position) <= DRAG_THRESHOLD && !shift_pressed {
let clicked_selected = shape_editor.selected_points().any(|&point| nearest_point == Some(point));
if clicked_selected {
shape_editor.deselect_all();
shape_editor.select_point(&document.network, &document.document_metadata, input.mouse.position, SELECTION_THRESHOLD, false);
shape_editor.select_point(&document.network, &document.metadata, input.mouse.position, SELECTION_THRESHOLD, false);
responses.add(OverlaysMessage::Draw);
}
}
@@ -428,9 +418,9 @@ impl Fsm for PathToolFsmState {
}
(_, PathToolMessage::InsertPoint) => {
// First we try and flip the sharpness (if they have clicked on an anchor)
if !shape_editor.flip_sharp(&document.network, &document.document_metadata, input.mouse.position, SELECTION_TOLERANCE, responses) {
if !shape_editor.flip_sharp(&document.network, &document.metadata, input.mouse.position, SELECTION_TOLERANCE, responses) {
// If not, then we try and split the path that may have been clicked upon
shape_editor.split(&document.network, &document.document_metadata, input.mouse.position, SELECTION_TOLERANCE, responses);
shape_editor.split(&document.network, &document.metadata, input.mouse.position, SELECTION_TOLERANCE, responses);
}
responses.add(PathToolMessage::SelectedPointUpdated);
@@ -443,7 +433,7 @@ impl Fsm for PathToolFsmState {
}
(_, PathToolMessage::PointerMove { .. }) => self,
(_, PathToolMessage::NudgeSelectedPoints { delta_x, delta_y }) => {
shape_editor.move_selected_points(&document.network, &document.document_metadata, (delta_x, delta_y).into(), true, responses);
shape_editor.move_selected_points(&document.network, &document.metadata, (delta_x, delta_y).into(), true, responses);
PathToolFsmState::Ready
}
@@ -454,18 +444,18 @@ impl Fsm for PathToolFsmState {
}
(_, PathToolMessage::SelectedPointXChanged { new_x }) => {
if let Some(&SingleSelectedPoint { coordinates, id, layer, .. }) = tool_data.selection_status.as_one() {
shape_editor.reposition_control_point(&id, responses, &document.network, &document.document_metadata, DVec2::new(new_x, coordinates.y), layer);
shape_editor.reposition_control_point(&id, responses, &document.network, &document.metadata, DVec2::new(new_x, coordinates.y), layer);
}
PathToolFsmState::Ready
}
(_, PathToolMessage::SelectedPointYChanged { new_y }) => {
if let Some(&SingleSelectedPoint { coordinates, id, layer, .. }) = tool_data.selection_status.as_one() {
shape_editor.reposition_control_point(&id, responses, &document.network, &document.document_metadata, DVec2::new(coordinates.x, new_y), layer);
shape_editor.reposition_control_point(&id, responses, &document.network, &document.metadata, DVec2::new(coordinates.x, new_y), layer);
}
PathToolFsmState::Ready
}
(_, PathToolMessage::SelectedPointUpdated) => {
tool_data.selection_status = get_selection_status(&document.network, &document.document_metadata, shape_editor);
tool_data.selection_status = get_selection_status(&document.network, &document.metadata, shape_editor);
self
}
(_, PathToolMessage::ManipulatorAngleMakeSmooth) => {
@@ -720,7 +720,7 @@ fn should_extend(document: &DocumentMessageHandler, pos: DVec2, tolerance: f64)
let mut best = None;
let mut best_distance_squared = tolerance * tolerance;
for layer in document.metadata().selected_layers() {
for layer in document.selected_nodes.selected_layers(document.metadata()) {
let viewspace = document.metadata().transform_to_viewport(layer);
let subpaths = get_subpaths(layer, &document.network)?;
@@ -381,27 +381,32 @@ impl Fsm for SelectToolFsmState {
};
match (self, event) {
(_, SelectToolMessage::Overlays(mut overlay_context)) => {
let selected_layers_count = document.metadata().selected_layers().count();
let selected_layers_count = document.selected_nodes.selected_layers(document.metadata()).count();
tool_data.selected_layers_changed = selected_layers_count != tool_data.selected_layers_count;
tool_data.selected_layers_count = selected_layers_count;
// Outline selected layers
for layer in document.selected_visible_layers() {
for layer in document.selected_nodes.selected_visible_layers(document.network(), document.metadata()) {
overlay_context.outline(document.metadata().layer_outline(layer), document.metadata().transform_to_viewport(layer));
}
// Get the layer the user is hovering over
let click = document.click(input.mouse.position, &document.network);
let not_selected_click = click.filter(|&hovered_layer| !document.metadata().selected_layers_contains(hovered_layer));
let not_selected_click = click.filter(|&hovered_layer| !document.selected_nodes.selected_layers_contains(hovered_layer, document.metadata()));
if let Some(layer) = not_selected_click {
overlay_context.outline(document.metadata().layer_outline(layer), document.metadata().transform_to_viewport(layer));
}
// Update bounds
let transform = document.selected_visible_layers().next().map(|layer| document.metadata().transform_to_viewport(layer));
let transform = document
.selected_nodes
.selected_visible_layers(document.network(), document.metadata())
.next()
.map(|layer| document.metadata().transform_to_viewport(layer));
let transform = transform.unwrap_or(DAffine2::IDENTITY);
let bounds = document
.selected_visible_layers()
.selected_nodes
.selected_visible_layers(document.network(), document.metadata())
.filter_map(|layer| {
document
.metadata()
@@ -462,7 +467,7 @@ impl Fsm for SelectToolFsmState {
.map(|bounding_box| bounding_box.check_rotate(input.mouse.position))
.unwrap_or_default();
let mut selected: Vec<_> = document.selected_visible_layers().collect();
let mut selected: Vec<_> = document.selected_nodes.selected_visible_layers(document.network(), document.metadata()).collect();
let intersection = document.click(input.mouse.position, &document.network);
// If the user is dragging the bounding box bounds, go into ResizingBounds mode.
@@ -491,7 +496,7 @@ impl Fsm for SelectToolFsmState {
&tool_data.layers_dragging,
responses,
&document.network,
&document.document_metadata,
&document.metadata,
None,
&ToolType::Select,
);
@@ -510,7 +515,7 @@ impl Fsm for SelectToolFsmState {
&selected,
responses,
&document.network,
&document.document_metadata,
&document.metadata,
None,
&ToolType::Select,
);
@@ -630,7 +635,7 @@ impl Fsm for SelectToolFsmState {
selected,
responses,
&document.network,
&document.document_metadata,
&document.metadata,
None,
&ToolType::Select,
);
@@ -665,7 +670,7 @@ impl Fsm for SelectToolFsmState {
&tool_data.layers_dragging,
responses,
&document.network,
&document.document_metadata,
&document.metadata,
None,
&ToolType::Select,
);
@@ -723,7 +728,11 @@ impl Fsm for SelectToolFsmState {
let intersection = document.intersect_quad(quad, &document.network);
if let Some(path) = intersection.last() {
let replacement_selected_layers: Vec<_> = document.metadata().selected_layers().filter(|&layer| !path.starts_with(layer, document.metadata())).collect();
let replacement_selected_layers: Vec<_> = document
.selected_nodes
.selected_layers(document.metadata())
.filter(|&layer| !path.starts_with(layer, document.metadata()))
.collect();
tool_data.layers_dragging.clear();
tool_data.layers_dragging.extend(replacement_selected_layers.iter());
@@ -791,7 +800,7 @@ impl Fsm for SelectToolFsmState {
(SelectToolFsmState::DrawingBox, SelectToolMessage::DragStop { .. } | SelectToolMessage::Enter) => {
let quad = tool_data.selection_quad();
let new_selected: HashSet<_> = document.intersect_quad(quad, &document.network).collect();
let current_selected: HashSet<_> = document.metadata().selected_layers().collect();
let current_selected: HashSet<_> = document.selected_nodes.selected_layers(document.metadata()).collect();
if new_selected != current_selected {
tool_data.layers_dragging = new_selected.into_iter().collect();
responses.add(DocumentMessage::StartTransaction);
@@ -804,7 +813,7 @@ impl Fsm for SelectToolFsmState {
SelectToolFsmState::Ready
}
(SelectToolFsmState::Ready, SelectToolMessage::Enter) => {
let mut selected_layers = document.metadata().selected_layers();
let mut selected_layers = document.selected_nodes.selected_layers(document.metadata());
if let Some(layer) = selected_layers.next() {
// Check that only one layer is selected
@@ -832,7 +841,7 @@ impl Fsm for SelectToolFsmState {
&tool_data.layers_dragging,
responses,
&document.network,
&document.document_metadata,
&document.metadata,
None,
&ToolType::Select,
);
@@ -908,7 +917,9 @@ impl Fsm for SelectToolFsmState {
fn drag_shallowest_manipulation(responses: &mut VecDeque<Message>, selected: Vec<LayerNodeIdentifier>, tool_data: &mut SelectToolData, document: &DocumentMessageHandler) {
let layer = selected[0];
let ancestor = layer.ancestors(document.metadata()).find(|&ancestor| document.metadata().selected_layers_contains(ancestor));
let ancestor = layer
.ancestors(document.metadata())
.find(|&ancestor| document.selected_nodes.selected_layers_contains(ancestor, document.metadata()));
let new_selected = ancestor.unwrap_or_else(|| layer.child_of_root(document.metadata()));
@@ -932,15 +943,16 @@ fn drag_deepest_manipulation(responses: &mut VecDeque<Message>, mut selected: Ve
}
fn edit_layer_shallowest_manipulation(document: &DocumentMessageHandler, layer: LayerNodeIdentifier, responses: &mut VecDeque<Message>) {
if document.metadata().selected_layers_contains(layer) {
if document.selected_nodes.selected_layers_contains(layer, document.metadata()) {
responses.add_front(ToolMessage::ActivateTool { tool_type: ToolType::Path });
return;
}
let Some(new_selected) = layer
.ancestors(document.metadata())
.find(|ancestor| ancestor.parent(document.metadata()).is_some_and(|parent| document.metadata().selected_layers_contains(parent)))
else {
let Some(new_selected) = layer.ancestors(document.metadata()).find(|ancestor| {
ancestor
.parent(document.metadata())
.is_some_and(|parent| document.selected_nodes.selected_layers_contains(parent, document.metadata()))
}) else {
return;
};
@@ -344,9 +344,9 @@ impl TextToolData {
}
fn can_edit_selected(document: &DocumentMessageHandler) -> Option<LayerNodeIdentifier> {
let mut selected_layers = document.metadata().selected_layers();
let mut selected_layers = document.selected_nodes.selected_layers(document.metadata());
let layer = selected_layers.next()?;
// Check that only one layer is selected
if selected_layers.next().is_some() {
return None;
@@ -392,7 +392,7 @@ impl Fsm for TextToolFsmState {
TextToolFsmState::Editing
}
(_, TextToolMessage::Overlays(mut overlay_context)) => {
for layer in document.metadata().selected_layers() {
for layer in document.selected_nodes.selected_layers(document.metadata()) {
let Some((text, font, font_size)) = graph_modification_utils::get_text(layer, &document.network) else {
continue;
};
@@ -48,7 +48,7 @@ impl<'a> MessageHandler<TransformLayerMessage, TransformData<'a>> for TransformL
let using_path_tool = tool_data.active_tool_type == ToolType::Path;
let selected_layers = document.metadata().selected_layers().collect::<Vec<_>>();
let selected_layers = document.selected_nodes.selected_layers(document.metadata()).collect::<Vec<_>>();
let mut selected = Selected::new(
&mut self.original_transforms,
@@ -56,7 +56,7 @@ impl<'a> MessageHandler<TransformLayerMessage, TransformData<'a>> for TransformL
&selected_layers,
responses,
&document.network,
&document.document_metadata,
&document.metadata,
Some(shape_editor),
&tool_data.active_tool_type,
);
@@ -222,7 +222,7 @@ impl<'a> MessageHandler<TransformLayerMessage, TransformData<'a>> for TransformL
self.mouse_position = input.mouse.position;
}
SelectionChanged => {
let target_layers = document.metadata().selected_layers().collect();
let target_layers = document.selected_nodes.selected_layers(document.metadata()).collect();
shape_editor.set_selected_layers(target_layers);
}
TypeBackspace => self.transform_operation.grs_typed(self.typing.type_backspace(), &mut selected, self.snap),