Restore select tool functionality and shallow select mode (#1583)
* Restore select tool functionality * UI tweak * Change all of the things --------- Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
parent
5c9d3c5d75
commit
208e907fa4
|
|
@ -398,12 +398,29 @@ impl MessageHandler<DocumentMessage, DocumentInputs<'_>> for DocumentMessageHand
|
|||
responses.add(FrontendMessage::UpdateDocumentLayerStructure { data_buffer });
|
||||
}
|
||||
DuplicateSelectedLayers => {
|
||||
// TODO: Reimplement selected layer duplication
|
||||
// self.backup(responses);
|
||||
// self.layer_range_selection_reference = None;
|
||||
// for path in self.selected_layers_sorted() {
|
||||
// responses.add(DocumentOperation::DuplicateLayer { path: path.to_vec() });
|
||||
// }
|
||||
self.backup(responses);
|
||||
for layer_ancestors in self.metadata.shallowest_unique_layers(self.selected_nodes.selected_layers(&self.metadata)) {
|
||||
let Some(layer) = layer_ancestors.last().copied() else { continue };
|
||||
let Some(parent) = layer.parent(&self.metadata) else { continue };
|
||||
let Some(node) = self.network().nodes.get(&layer.to_node()).and_then(|node| node.inputs.first()).and_then(|input| input.as_node()) else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let nodes = NodeGraphMessageHandler::copy_nodes(
|
||||
self.network(),
|
||||
&self
|
||||
.network()
|
||||
.upstream_flow_back_from_nodes(vec![node], false)
|
||||
.enumerate()
|
||||
.map(|(index, (_, node_id))| (node_id, NodeId(index as u64)))
|
||||
.collect(),
|
||||
)
|
||||
.collect();
|
||||
|
||||
let id = NodeId(generate_uuid());
|
||||
let insert_index = -1;
|
||||
responses.add(GraphOperationMessage::NewCustomLayer { id, nodes, parent, insert_index });
|
||||
}
|
||||
}
|
||||
FlipSelectedLayers { flip_axis } => {
|
||||
self.backup(responses);
|
||||
|
|
|
|||
|
|
@ -86,33 +86,20 @@ impl SelectedEdges {
|
|||
|
||||
let mut pivot = self.pivot_from_bounds(min, max);
|
||||
if let Some(center_around) = center_around {
|
||||
// The below ratio is: `dragging edge / being centered`.
|
||||
// The `is_finite()` checks are in case the user is dragging the edge where the pivot is located (in which case the centering mode is ignored).
|
||||
let center_around = transform.inverse().transform_point2(center_around);
|
||||
if self.top {
|
||||
let ratio = (center_around.y - min.y) / (center_around.y - self.bounds[0].y);
|
||||
if ratio.is_finite() {
|
||||
max.y = center_around.y + ratio * (self.bounds[1].y - center_around.y);
|
||||
pivot.y = center_around.y;
|
||||
}
|
||||
pivot.y = center_around.y;
|
||||
max.y = center_around.y * 2. - min.y;
|
||||
} else if self.bottom {
|
||||
let ratio = (max.y - center_around.y) / (self.bounds[1].y - center_around.y);
|
||||
if ratio.is_finite() {
|
||||
min.y = center_around.y - ratio * (center_around.y - self.bounds[0].y);
|
||||
pivot.y = center_around.y;
|
||||
}
|
||||
pivot.y = center_around.y;
|
||||
min.y = center_around.y * 2. - max.y;
|
||||
}
|
||||
if self.left {
|
||||
let ratio = (center_around.x - min.x) / (center_around.x - self.bounds[0].x);
|
||||
if ratio.is_finite() {
|
||||
max.x = center_around.x + ratio * (self.bounds[1].x - center_around.x);
|
||||
pivot.x = center_around.x;
|
||||
}
|
||||
pivot.x = center_around.x;
|
||||
max.x = center_around.x * 2. - min.x;
|
||||
} else if self.right {
|
||||
let ratio = (max.x - center_around.x) / (self.bounds[1].x - center_around.x);
|
||||
if ratio.is_finite() {
|
||||
min.x = center_around.x - ratio * (center_around.x - self.bounds[0].x);
|
||||
pivot.x = center_around.x;
|
||||
}
|
||||
pivot.x = center_around.x;
|
||||
min.x = center_around.x * 2. - max.x;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -128,7 +115,9 @@ impl SelectedEdges {
|
|||
let delta_size = new_size - size;
|
||||
min -= delta_size * min_pivot;
|
||||
max = min + new_size;
|
||||
} else if let Some(SizeSnapData { manager, points, snap_data }) = snap {
|
||||
}
|
||||
|
||||
if let Some(SizeSnapData { manager, points, snap_data }) = snap {
|
||||
let view_to_doc = snap_data.document.metadata.document_to_viewport.inverse();
|
||||
let bounds_to_doc = view_to_doc * transform;
|
||||
let mut best_snap = SnappedPoint::infinite_snap(pivot);
|
||||
|
|
@ -140,7 +129,13 @@ impl SelectedEdges {
|
|||
let normalised = (bounds_space - self.bounds[0]) / (self.bounds[1] - self.bounds[0]);
|
||||
let updated = normalised * (max - min) + min;
|
||||
point.document_point = bounds_to_doc.transform_point2(updated);
|
||||
let mut snapped = if !(self.top || self.bottom) || !(self.left || self.right) {
|
||||
let mut snapped = if constrain {
|
||||
let constraint = SnapConstraint::Line {
|
||||
origin: point.document_point,
|
||||
direction: (point.document_point - bounds_to_doc.transform_point2(pivot)).normalize_or_zero(),
|
||||
};
|
||||
manager.constrained_snap(&snap_data, point, constraint, None)
|
||||
} else if !(self.top || self.bottom) || !(self.left || self.right) {
|
||||
let axis = if !(self.top || self.bottom) { DVec2::X } else { DVec2::Y };
|
||||
let constraint = SnapConstraint::Line {
|
||||
origin: point.document_point,
|
||||
|
|
@ -158,10 +153,10 @@ impl SelectedEdges {
|
|||
let snapped_bounds = bounds_to_doc.inverse().transform_point2(snapped.snapped_point_document);
|
||||
|
||||
let mut scale_factor = (snapped_bounds - pivot) / (updated - pivot);
|
||||
if !(self.left || self.right) {
|
||||
if !(self.left || self.right) && !constrain {
|
||||
scale_factor.x = 1.
|
||||
}
|
||||
if !(self.top || self.bottom) {
|
||||
if !(self.top || self.bottom) && !constrain {
|
||||
scale_factor.y = 1.
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ impl ArtboardToolData {
|
|||
|
||||
fn start_resizing(&mut self, _selected_edges: (bool, bool, bool, bool), _document: &DocumentMessageHandler, _input: &InputPreprocessorMessageHandler) {
|
||||
if let Some(bounds) = &mut self.bounding_box_manager {
|
||||
bounds.center_of_transformation = (bounds.bounds[0] + bounds.bounds[1]) / 2.;
|
||||
bounds.center_of_transformation = bounds.transform.transform_point2((bounds.bounds[0] + bounds.bounds[1]) / 2.);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,18 +1,20 @@
|
|||
#![allow(clippy::too_many_arguments)]
|
||||
|
||||
use super::tool_prelude::*;
|
||||
use crate::application::generate_uuid;
|
||||
use crate::consts::{ROTATE_SNAP_ANGLE, SELECTION_TOLERANCE};
|
||||
use crate::messages::input_mapper::utility_types::input_mouse::ViewportPosition;
|
||||
use crate::messages::portfolio::document::overlays::utility_types::OverlayContext;
|
||||
use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
|
||||
use crate::messages::portfolio::document::utility_types::misc::{AlignAggregate, AlignAxis, FlipAxis};
|
||||
use crate::messages::portfolio::document::utility_types::transformation::Selected;
|
||||
use crate::messages::tool;
|
||||
use crate::messages::tool::common_functionality::graph_modification_utils::is_layer_fed_by_node_of_name;
|
||||
use crate::messages::tool::common_functionality::pivot::Pivot;
|
||||
use crate::messages::tool::common_functionality::snapping::{self, SnapCandidatePoint, SnapConstraint, SnapData, SnapManager, SnappedPoint};
|
||||
use crate::messages::tool::common_functionality::transformation_cage::*;
|
||||
|
||||
use graph_craft::document::NodeNetwork;
|
||||
use graph_craft::document::{NodeId, NodeNetwork};
|
||||
use graphene_core::renderer::Quad;
|
||||
|
||||
use std::fmt;
|
||||
|
|
@ -96,21 +98,21 @@ impl ToolMetadata for SelectTool {
|
|||
}
|
||||
|
||||
impl SelectTool {
|
||||
// fn deep_selection_widget(&self) -> WidgetHolder {
|
||||
// let layer_selection_behavior_entries = [NestedSelectionBehavior::Deepest, NestedSelectionBehavior::Shallowest]
|
||||
// .iter()
|
||||
// .map(|mode| {
|
||||
// MenuListEntry::new(mode.to_string())
|
||||
// .value(mode.to_string())
|
||||
// .on_update(move |_| SelectToolMessage::SelectOptions(SelectOptionsUpdate::NestedSelectionBehavior(*mode)).into())
|
||||
// })
|
||||
// .collect();
|
||||
fn deep_selection_widget(&self) -> WidgetHolder {
|
||||
let layer_selection_behavior_entries = [NestedSelectionBehavior::Deepest, NestedSelectionBehavior::Shallowest]
|
||||
.iter()
|
||||
.map(|mode| {
|
||||
MenuListEntry::new(mode.to_string())
|
||||
.value(mode.to_string())
|
||||
.on_update(move |_| SelectToolMessage::SelectOptions(SelectOptionsUpdate::NestedSelectionBehavior(*mode)).into())
|
||||
})
|
||||
.collect();
|
||||
|
||||
// DropdownInput::new(vec![layer_selection_behavior_entries])
|
||||
// .selected_index(Some((self.tool_data.nested_selection_behavior == NestedSelectionBehavior::Shallowest) as u32))
|
||||
// .tooltip("Choose if clicking nested layers directly selects the deepest, or selects the shallowest and deepens by double clicking")
|
||||
// .widget_holder()
|
||||
// }
|
||||
DropdownInput::new(vec![layer_selection_behavior_entries])
|
||||
.selected_index(Some((self.tool_data.nested_selection_behavior == NestedSelectionBehavior::Shallowest) as u32))
|
||||
.tooltip("Choose if clicking nested layers directly selects the deepest, or selects the shallowest and deepens by double clicking")
|
||||
.widget_holder()
|
||||
}
|
||||
|
||||
fn pivot_widget(&self, disabled: bool) -> WidgetHolder {
|
||||
PivotInput::new(self.tool_data.pivot.to_pivot_position())
|
||||
|
|
@ -163,10 +165,12 @@ impl SelectTool {
|
|||
impl LayoutHolder for SelectTool {
|
||||
fn layout(&self) -> Layout {
|
||||
let mut widgets = Vec::new();
|
||||
// widgets.push(self.deep_selection_widget()); // TODO: Reenable once Deep/Shallow Selection is implemented again
|
||||
|
||||
// Select mode (Deep/Shallow)
|
||||
widgets.push(self.deep_selection_widget());
|
||||
|
||||
// Pivot
|
||||
// widgets.push(Separator::new(SeparatorType::Related).widget_holder()); // TODO: Reenable once Deep/Shallow Selection is implemented again
|
||||
widgets.push(Separator::new(SeparatorType::Unrelated).widget_holder());
|
||||
widgets.push(self.pivot_widget(self.tool_data.selected_layers_count == 0));
|
||||
|
||||
// Align
|
||||
|
|
@ -179,13 +183,11 @@ impl LayoutHolder for SelectTool {
|
|||
let disabled = self.tool_data.selected_layers_count == 0;
|
||||
widgets.push(Separator::new(SeparatorType::Unrelated).widget_holder());
|
||||
widgets.extend(self.flip_widgets(disabled));
|
||||
widgets.push(PopoverButton::new("Flip", "Coming soon").disabled(disabled).widget_holder());
|
||||
|
||||
// Boolean
|
||||
if self.tool_data.selected_layers_count >= 2 {
|
||||
widgets.push(Separator::new(SeparatorType::Unrelated).widget_holder());
|
||||
widgets.extend(self.boolean_widgets());
|
||||
widgets.push(PopoverButton::new("Boolean", "Coming soon").widget_holder());
|
||||
}
|
||||
|
||||
Layout::WidgetLayout(WidgetLayout::new(vec![LayoutGroup::Row { widgets }]))
|
||||
|
|
@ -259,7 +261,7 @@ struct SelectToolData {
|
|||
layer_selected_on_start: Option<LayerNodeIdentifier>,
|
||||
select_single_layer: Option<LayerNodeIdentifier>,
|
||||
has_dragged: bool,
|
||||
not_duplicated_layers: Option<Vec<LayerNodeIdentifier>>,
|
||||
non_duplicated_layers: Option<Vec<LayerNodeIdentifier>>,
|
||||
bounding_box_manager: Option<BoundingBoxManager>,
|
||||
snap_manager: SnapManager,
|
||||
cursor: MouseCursorIcon,
|
||||
|
|
@ -300,57 +302,54 @@ impl SelectToolData {
|
|||
|
||||
/// Duplicates the currently dragging layers. Called when Alt is pressed and the layers have not yet been duplicated.
|
||||
fn start_duplicates(&mut self, document: &DocumentMessageHandler, responses: &mut VecDeque<Message>) {
|
||||
responses.add(DocumentMessage::DeselectAllLayers);
|
||||
self.non_duplicated_layers = Some(self.layers_dragging.clone());
|
||||
let mut new_dragging = Vec::new();
|
||||
for layer_ancestors in document.metadata().shallowest_unique_layers(self.layers_dragging.iter().copied().rev()) {
|
||||
let Some(layer) = layer_ancestors.last().copied() else { continue };
|
||||
let Some(parent) = layer.parent(&document.metadata) else { continue };
|
||||
|
||||
// Take the selected layers and store them in a separate list.
|
||||
self.not_duplicated_layers = Some(self.layers_dragging.clone());
|
||||
// Copy the layer
|
||||
let node = layer.to_node();
|
||||
let Some(node) = document.network().nodes.get(&node).and_then(|node| node.inputs.first()).and_then(|input| input.as_node()) else {
|
||||
continue;
|
||||
};
|
||||
|
||||
// Duplicate each previously selected layer and select the new ones.
|
||||
for layer_ancestors in document.metadata().shallowest_unique_layers(self.layers_dragging.iter().copied()) {
|
||||
let layer = *layer_ancestors.last().unwrap();
|
||||
// Moves the original back to its starting position.
|
||||
responses.add_front(GraphOperationMessage::TransformChange {
|
||||
let nodes = NodeGraphMessageHandler::copy_nodes(
|
||||
document.network(),
|
||||
&document
|
||||
.network()
|
||||
.upstream_flow_back_from_nodes(vec![node], false)
|
||||
.enumerate()
|
||||
.map(|(index, (_, node_id))| (node_id, NodeId(index as u64)))
|
||||
.collect(),
|
||||
)
|
||||
.collect();
|
||||
|
||||
// Moves the layer back to its starting position.
|
||||
responses.add(GraphOperationMessage::TransformChange {
|
||||
layer,
|
||||
transform: DAffine2::from_translation(self.drag_start - self.drag_current),
|
||||
transform_in: TransformIn::Viewport,
|
||||
skip_rerender: true,
|
||||
});
|
||||
|
||||
// Copy the layers.
|
||||
// Not using the Copy message allows us to retrieve the ids of the new layers to initialize the drag.
|
||||
todo!();
|
||||
// let layer = match document.document_legacy.layer(layer_path) {
|
||||
// Ok(layer) => layer.clone(),
|
||||
// Err(e) => {
|
||||
// warn!("Could not access selected layer {layer_path:?}: {e:?}");
|
||||
// continue;
|
||||
// }
|
||||
// };
|
||||
|
||||
// let layer_metadata = *document.layer_metadata(layer_path);
|
||||
// *layer_path.last_mut().unwrap() = generate_uuid();
|
||||
|
||||
// responses.add(Operation::InsertLayer {
|
||||
// layer: Box::new(layer),
|
||||
// destination_path: layer_path.clone(),
|
||||
// insert_index: -1,
|
||||
// duplicating: false,
|
||||
// });
|
||||
// responses.add(DocumentMessage::UpdateLayerMetadata {
|
||||
// layer_path: layer_path.clone(),
|
||||
// layer_metadata,
|
||||
// });
|
||||
let id = NodeId(generate_uuid());
|
||||
let insert_index = -1;
|
||||
let layer = LayerNodeIdentifier::new_unchecked(id);
|
||||
responses.add(GraphOperationMessage::NewCustomLayer { id, nodes, parent, insert_index });
|
||||
new_dragging.push(layer);
|
||||
}
|
||||
let nodes = new_dragging.iter().map(|layer| layer.to_node()).collect();
|
||||
responses.add(NodeGraphMessage::SelectedNodesSet { nodes });
|
||||
self.layers_dragging = new_dragging;
|
||||
}
|
||||
|
||||
/// Removes the duplicated layers. Called when Alt is released and the layers have previously been duplicated.
|
||||
fn stop_duplicates(&mut self, document: &DocumentMessageHandler, responses: &mut VecDeque<Message>) {
|
||||
let Some(originals) = self.not_duplicated_layers.take() else {
|
||||
let Some(original) = self.non_duplicated_layers.take() else {
|
||||
return;
|
||||
};
|
||||
|
||||
responses.add(DocumentMessage::DeselectAllLayers);
|
||||
|
||||
// Delete the duplicated layers
|
||||
for layer_ancestors in document.metadata().shallowest_unique_layers(self.layers_dragging.iter().copied()) {
|
||||
responses.add(GraphOperationMessage::DeleteLayer {
|
||||
|
|
@ -358,22 +357,17 @@ impl SelectToolData {
|
|||
});
|
||||
}
|
||||
|
||||
// Move the original to under the mouse
|
||||
for layer_ancestors in document.metadata().shallowest_unique_layers(originals.iter().copied()) {
|
||||
responses.add_front(GraphOperationMessage::TransformChange {
|
||||
layer: *layer_ancestors.last().unwrap(),
|
||||
for &layer in &original {
|
||||
responses.add(GraphOperationMessage::TransformChange {
|
||||
layer,
|
||||
transform: DAffine2::from_translation(self.drag_current - self.drag_start),
|
||||
transform_in: TransformIn::Viewport,
|
||||
skip_rerender: true,
|
||||
});
|
||||
}
|
||||
|
||||
// Select the originals
|
||||
responses.add(NodeGraphMessage::SelectedNodesSet {
|
||||
nodes: originals.iter().map(|layer| layer.to_node()).collect::<Vec<_>>(),
|
||||
});
|
||||
|
||||
self.layers_dragging = originals;
|
||||
let nodes = original.iter().map(|layer| layer.to_node()).collect();
|
||||
responses.add(NodeGraphMessage::SelectedNodesSet { nodes });
|
||||
self.layers_dragging = original;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -455,7 +449,7 @@ impl Fsm for SelectToolFsmState {
|
|||
|
||||
self
|
||||
}
|
||||
(SelectToolFsmState::Ready, SelectToolMessage::DragStart { add_to_selection, select_deepest: _ }) => {
|
||||
(SelectToolFsmState::Ready, SelectToolMessage::DragStart { add_to_selection, select_deepest }) => {
|
||||
tool_data.drag_start = input.mouse.position;
|
||||
tool_data.drag_current = input.mouse.position;
|
||||
|
||||
|
|
@ -538,11 +532,14 @@ impl Fsm for SelectToolFsmState {
|
|||
tool_data.layers_dragging = selected;
|
||||
|
||||
SelectToolFsmState::RotatingBounds
|
||||
} else if intersection.is_some_and(|intersection| selected.iter().any(|selected_layer| intersection.starts_with(*selected_layer, document.metadata())))
|
||||
&& tool_data.nested_selection_behavior == NestedSelectionBehavior::Deepest
|
||||
{
|
||||
} else if intersection.is_some_and(|intersection| selected.iter().any(|selected_layer| intersection.starts_with(*selected_layer, document.metadata()))) {
|
||||
responses.add(DocumentMessage::StartTransaction);
|
||||
tool_data.select_single_layer = intersection;
|
||||
|
||||
if tool_data.nested_selection_behavior == NestedSelectionBehavior::Deepest {
|
||||
tool_data.select_single_layer = intersection;
|
||||
} else {
|
||||
tool_data.select_single_layer = intersection.and_then(|intersection| intersection.ancestors(&document.metadata).find(|ancestor| selected.contains(ancestor)));
|
||||
}
|
||||
|
||||
tool_data.layers_dragging = selected;
|
||||
|
||||
|
|
@ -552,7 +549,7 @@ impl Fsm for SelectToolFsmState {
|
|||
} else {
|
||||
tool_data.layers_dragging = selected;
|
||||
|
||||
if !input.keyboard.key(add_to_selection) && tool_data.nested_selection_behavior == NestedSelectionBehavior::Deepest {
|
||||
if !input.keyboard.key(add_to_selection) {
|
||||
responses.add(DocumentMessage::DeselectAllLayers);
|
||||
tool_data.layers_dragging.clear();
|
||||
}
|
||||
|
|
@ -564,8 +561,8 @@ impl Fsm for SelectToolFsmState {
|
|||
selected = vec![intersection];
|
||||
|
||||
match tool_data.nested_selection_behavior {
|
||||
NestedSelectionBehavior::Shallowest => drag_shallowest_manipulation(responses, selected, tool_data, document),
|
||||
NestedSelectionBehavior::Deepest => drag_deepest_manipulation(responses, selected, tool_data),
|
||||
NestedSelectionBehavior::Shallowest if !input.keyboard.key(select_deepest) => drag_shallowest_manipulation(responses, selected, tool_data, document),
|
||||
_ => drag_deepest_manipulation(responses, selected, tool_data),
|
||||
}
|
||||
tool_data.get_snap_candidates(document, input);
|
||||
SelectToolFsmState::Dragging
|
||||
|
|
@ -579,18 +576,28 @@ impl Fsm for SelectToolFsmState {
|
|||
SelectToolFsmState::DrawingBox
|
||||
}
|
||||
};
|
||||
tool_data.not_duplicated_layers = None;
|
||||
tool_data.non_duplicated_layers = None;
|
||||
|
||||
state
|
||||
}
|
||||
(SelectToolFsmState::Dragging, SelectToolMessage::PointerMove { axis_align, duplicate, .. }) => {
|
||||
tool_data.has_dragged = true;
|
||||
|
||||
if input.keyboard.key(duplicate) && tool_data.non_duplicated_layers.is_none() {
|
||||
tool_data.start_duplicates(document, responses);
|
||||
} else if !input.keyboard.key(duplicate) && tool_data.non_duplicated_layers.is_some() {
|
||||
tool_data.stop_duplicates(document, responses);
|
||||
}
|
||||
|
||||
let axis_align = input.keyboard.key(axis_align);
|
||||
let mouse_position = axis_align_drag(axis_align, input.mouse.position, tool_data.drag_start);
|
||||
let total_mouse_delta_document = document.metadata.document_to_viewport.inverse().transform_vector2(mouse_position - tool_data.drag_start);
|
||||
|
||||
let snap_data = SnapData::ignore(document, input, &tool_data.layers_dragging);
|
||||
// Ignore the non duplicated layers if the current layers have not spawned yet.
|
||||
let layers_exist = tool_data.layers_dragging.iter().all(|&layer| document.metadata().click_target(layer).is_some());
|
||||
let ignore = tool_data.non_duplicated_layers.as_ref().filter(|_| !layers_exist).unwrap_or(&tool_data.layers_dragging);
|
||||
|
||||
let snap_data = SnapData::ignore(document, input, ignore);
|
||||
let mouse_delta_document = document.metadata.document_to_viewport.inverse().transform_vector2(mouse_position - tool_data.drag_current);
|
||||
let mut offset = mouse_delta_document;
|
||||
let mut best_snap = SnappedPoint::infinite_snap(document.metadata.document_to_viewport.inverse().transform_point2(mouse_position));
|
||||
|
|
@ -627,22 +634,12 @@ impl Fsm for SelectToolFsmState {
|
|||
}
|
||||
tool_data.drag_current += mouse_delta;
|
||||
|
||||
// TODO: Reenable this feature after fixing it
|
||||
if false {
|
||||
if input.keyboard.key(duplicate) && tool_data.not_duplicated_layers.is_none() {
|
||||
tool_data.start_duplicates(document, responses);
|
||||
} else if !input.keyboard.key(duplicate) && tool_data.not_duplicated_layers.is_some() {
|
||||
tool_data.stop_duplicates(document, responses);
|
||||
}
|
||||
}
|
||||
|
||||
SelectToolFsmState::Dragging
|
||||
}
|
||||
(SelectToolFsmState::ResizingBounds, SelectToolMessage::PointerMove { axis_align, center, .. }) => {
|
||||
if let Some(bounds) = &mut tool_data.bounding_box_manager {
|
||||
if let Some(movement) = &mut bounds.selected_edges {
|
||||
let (_center, constrain) = (input.keyboard.key(center), input.keyboard.key(axis_align));
|
||||
let center = false; // TODO: Reenable this feature after fixing it
|
||||
let (center, constrain) = (input.keyboard.key(center), input.keyboard.key(axis_align));
|
||||
|
||||
let center = center.then_some(bounds.center_of_transformation);
|
||||
let snap = Some(SizeSnapData {
|
||||
|
|
@ -944,21 +941,32 @@ impl Fsm for SelectToolFsmState {
|
|||
}
|
||||
}
|
||||
|
||||
fn not_artboard<'a>(document: &'a DocumentMessageHandler) -> impl Fn(&LayerNodeIdentifier) -> bool + 'a {
|
||||
|&layer| !document.metadata.is_artboard(layer)
|
||||
}
|
||||
|
||||
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.selected_nodes.selected_layers_contains(ancestor, document.metadata()));
|
||||
for layer in selected {
|
||||
let ancestor = layer
|
||||
.ancestors(document.metadata())
|
||||
.filter(not_artboard(document))
|
||||
.find(|&ancestor| document.selected_nodes.selected_layers_contains(ancestor, document.metadata()));
|
||||
|
||||
let new_selected = ancestor.unwrap_or_else(|| layer.child_of_root(document.metadata()));
|
||||
let new_selected = ancestor.unwrap_or_else(|| {
|
||||
layer
|
||||
.ancestors(document.metadata())
|
||||
.take_while(|&layer| layer != LayerNodeIdentifier::ROOT)
|
||||
.filter(not_artboard(document))
|
||||
.last()
|
||||
.unwrap_or(layer)
|
||||
});
|
||||
tool_data.layers_dragging.retain(|layer| !layer.ancestors(document.metadata()).any(|ancestor| ancestor == new_selected));
|
||||
tool_data.layers_dragging.push(new_selected);
|
||||
}
|
||||
|
||||
tool_data.layers_dragging = vec![new_selected];
|
||||
responses.add(NodeGraphMessage::SelectedNodesSet {
|
||||
nodes: tool_data.layers_dragging.iter().map(|layer| layer.to_node()).collect(),
|
||||
});
|
||||
// tool_data
|
||||
// .snap_manager
|
||||
// .start_snap(document, input, document.bounding_boxes(Some(&tool_data.layers_dragging), None, font_cache), true, true);
|
||||
}
|
||||
|
||||
fn drag_deepest_manipulation(responses: &mut VecDeque<Message>, mut selected: Vec<LayerNodeIdentifier>, tool_data: &mut SelectToolData) {
|
||||
|
|
@ -966,9 +974,6 @@ fn drag_deepest_manipulation(responses: &mut VecDeque<Message>, mut selected: Ve
|
|||
responses.add(NodeGraphMessage::SelectedNodesSet {
|
||||
nodes: tool_data.layers_dragging.iter().map(|layer| layer.to_node()).collect(),
|
||||
});
|
||||
// tool_data
|
||||
// .snap_manager
|
||||
// .start_snap(document, input, document.bounding_boxes(Some(&tool_data.layers_dragging), None, font_cache), true, true);
|
||||
}
|
||||
|
||||
fn edit_layer_shallowest_manipulation(document: &DocumentMessageHandler, layer: LayerNodeIdentifier, responses: &mut VecDeque<Message>) {
|
||||
|
|
@ -977,7 +982,7 @@ fn edit_layer_shallowest_manipulation(document: &DocumentMessageHandler, layer:
|
|||
return;
|
||||
}
|
||||
|
||||
let Some(new_selected) = layer.ancestors(document.metadata()).find(|ancestor| {
|
||||
let Some(new_selected) = layer.ancestors(document.metadata()).filter(not_artboard(document)).find(|ancestor| {
|
||||
ancestor
|
||||
.parent(document.metadata())
|
||||
.is_some_and(|parent| document.selected_nodes.selected_layers_contains(parent, document.metadata()))
|
||||
|
|
|
|||
Loading…
Reference in New Issue