Prevent rendering when transforming frame layer
Reduces confusion from rendering lag and lessens the opportunity to build up leaked memory from the present lack of node graph cache eviction
This commit is contained in:
parent
4bdb026d9a
commit
1b50878f3f
|
|
@ -257,6 +257,7 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
|
||||||
layer: path.to_vec(),
|
layer: path.to_vec(),
|
||||||
transform: DAffine2::from_translation(translation),
|
transform: DAffine2::from_translation(translation),
|
||||||
transform_in: TransformIn::Viewport,
|
transform_in: TransformIn::Viewport,
|
||||||
|
skip_rerender: false,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
responses.push_back(BroadcastEvent::DocumentIsDirty.into());
|
responses.push_back(BroadcastEvent::DocumentIsDirty.into());
|
||||||
|
|
@ -397,6 +398,7 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
|
||||||
layer: path.to_vec(),
|
layer: path.to_vec(),
|
||||||
transform: DAffine2::from_scale(scale),
|
transform: DAffine2::from_scale(scale),
|
||||||
transform_in: TransformIn::Scope { scope: bbox_trans },
|
transform_in: TransformIn::Scope { scope: bbox_trans },
|
||||||
|
skip_rerender: false,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
responses.push_back(BroadcastEvent::DocumentIsDirty.into());
|
responses.push_back(BroadcastEvent::DocumentIsDirty.into());
|
||||||
|
|
@ -577,7 +579,12 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
|
||||||
|
|
||||||
if let Some(transform) = transform {
|
if let Some(transform) = transform {
|
||||||
let transform_in = TransformIn::Viewport;
|
let transform_in = TransformIn::Viewport;
|
||||||
responses.add(GraphOperationMessage::TransformChange { layer: path, transform, transform_in });
|
responses.add(GraphOperationMessage::TransformChange {
|
||||||
|
layer: path,
|
||||||
|
transform,
|
||||||
|
transform_in,
|
||||||
|
skip_rerender: false,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
responses.push_back(BroadcastEvent::DocumentIsDirty.into());
|
responses.push_back(BroadcastEvent::DocumentIsDirty.into());
|
||||||
|
|
@ -665,6 +672,7 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
|
||||||
layer: path.clone(),
|
layer: path.clone(),
|
||||||
transform,
|
transform,
|
||||||
transform_in: TransformIn::Local,
|
transform_in: TransformIn::Local,
|
||||||
|
skip_rerender: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
responses.push_back(DocumentMessage::NodeGraphFrameGenerate { layer_path: path }.into());
|
responses.push_back(DocumentMessage::NodeGraphFrameGenerate { layer_path: path }.into());
|
||||||
|
|
@ -821,7 +829,10 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
|
||||||
resolution,
|
resolution,
|
||||||
document_id,
|
document_id,
|
||||||
} => {
|
} => {
|
||||||
let layer = self.document_legacy.layer(&layer_path).expect("Setting blob URL for invalid layer");
|
let Ok(layer) = self.document_legacy.layer(&layer_path) else {
|
||||||
|
warn!("Setting blob URL for invalid layer");
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
// Revoke the old blob URL
|
// Revoke the old blob URL
|
||||||
match &layer.data {
|
match &layer.data {
|
||||||
|
|
@ -830,10 +841,13 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
|
||||||
responses.push_back(FrontendMessage::TriggerRevokeBlobUrl { url: url.clone() }.into());
|
responses.push_back(FrontendMessage::TriggerRevokeBlobUrl { url: url.clone() }.into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
other => panic!(
|
other => {
|
||||||
"Setting blob URL for invalid layer type, which must be an `Imaginate`, `NodeGraphFrame` or `Image`. Found: `{:?}`",
|
warn!(
|
||||||
other
|
"Setting blob URL for invalid layer type, which must be an `Imaginate`, `NodeGraphFrame` or `Image`. Found: `{:?}`",
|
||||||
),
|
other
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
responses.push_back(
|
responses.push_back(
|
||||||
|
|
|
||||||
|
|
@ -11,15 +11,37 @@ pub type LayerIdentifier = Vec<document_legacy::LayerId>;
|
||||||
#[impl_message(Message, DocumentMessage, GraphOperation)]
|
#[impl_message(Message, DocumentMessage, GraphOperation)]
|
||||||
#[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize)]
|
#[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize)]
|
||||||
pub enum GraphOperationMessage {
|
pub enum GraphOperationMessage {
|
||||||
FillSet { layer: LayerIdentifier, fill: Fill },
|
FillSet {
|
||||||
|
layer: LayerIdentifier,
|
||||||
|
fill: Fill,
|
||||||
|
},
|
||||||
|
|
||||||
StrokeSet { layer: LayerIdentifier, stroke: Stroke },
|
StrokeSet {
|
||||||
|
layer: LayerIdentifier,
|
||||||
|
stroke: Stroke,
|
||||||
|
},
|
||||||
|
|
||||||
TransformChange { layer: LayerIdentifier, transform: DAffine2, transform_in: TransformIn },
|
TransformChange {
|
||||||
TransformSet { layer: LayerIdentifier, transform: DAffine2, transform_in: TransformIn },
|
layer: LayerIdentifier,
|
||||||
TransformSetPivot { layer: LayerIdentifier, pivot: DVec2 },
|
transform: DAffine2,
|
||||||
|
transform_in: TransformIn,
|
||||||
|
skip_rerender: bool,
|
||||||
|
},
|
||||||
|
TransformSet {
|
||||||
|
layer: LayerIdentifier,
|
||||||
|
transform: DAffine2,
|
||||||
|
transform_in: TransformIn,
|
||||||
|
skip_rerender: bool,
|
||||||
|
},
|
||||||
|
TransformSetPivot {
|
||||||
|
layer: LayerIdentifier,
|
||||||
|
pivot: DVec2,
|
||||||
|
},
|
||||||
|
|
||||||
Vector { layer: LayerIdentifier, modification: VectorDataModification },
|
Vector {
|
||||||
|
layer: LayerIdentifier,
|
||||||
|
modification: VectorDataModification,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Copy, Debug, serde::Serialize, serde::Deserialize)]
|
#[derive(PartialEq, Clone, Copy, Debug, serde::Serialize, serde::Deserialize)]
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@ impl<'a> ModifyInputsContext<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Changes the inputs of a specific node
|
/// Changes the inputs of a specific node
|
||||||
fn modify_inputs(&mut self, name: &'static str, update_input: impl FnOnce(&mut Vec<NodeInput>)) {
|
fn modify_inputs(&mut self, name: &'static str, skip_rerender: bool, update_input: impl FnOnce(&mut Vec<NodeInput>)) {
|
||||||
let existing_node_id = self.network.primary_flow().find(|(node, _)| node.name == name).map(|(_, id)| id);
|
let existing_node_id = self.network.primary_flow().find(|(node, _)| node.name == name).map(|(_, id)| id);
|
||||||
if let Some(node_id) = existing_node_id {
|
if let Some(node_id) = existing_node_id {
|
||||||
self.modify_existing_node_inputs(node_id, update_input);
|
self.modify_existing_node_inputs(node_id, update_input);
|
||||||
|
|
@ -74,15 +74,19 @@ impl<'a> ModifyInputsContext<'a> {
|
||||||
self.node_graph.nested_path.clear();
|
self.node_graph.nested_path.clear();
|
||||||
self.responses.add(PropertiesPanelMessage::ResendActiveProperties);
|
self.responses.add(PropertiesPanelMessage::ResendActiveProperties);
|
||||||
let layer_path = self.layer.to_vec();
|
let layer_path = self.layer.to_vec();
|
||||||
self.responses.add(DocumentMessage::NodeGraphFrameGenerate { layer_path });
|
|
||||||
|
|
||||||
|
if !skip_rerender {
|
||||||
|
self.responses.add(DocumentMessage::NodeGraphFrameGenerate { layer_path });
|
||||||
|
} else {
|
||||||
|
self.responses.add(DocumentMessage::FrameClear);
|
||||||
|
}
|
||||||
if existing_node_id.is_none() {
|
if existing_node_id.is_none() {
|
||||||
self.responses.add(NodeGraphMessage::SendGraph { should_rerender: false });
|
self.responses.add(NodeGraphMessage::SendGraph { should_rerender: false });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fill_set(&mut self, fill: Fill) {
|
fn fill_set(&mut self, fill: Fill) {
|
||||||
self.modify_inputs("Fill", |inputs| {
|
self.modify_inputs("Fill", false, |inputs| {
|
||||||
let fill_type = match fill {
|
let fill_type = match fill {
|
||||||
Fill::None => FillType::None,
|
Fill::None => FillType::None,
|
||||||
Fill::Solid(_) => FillType::Solid,
|
Fill::Solid(_) => FillType::Solid,
|
||||||
|
|
@ -104,7 +108,7 @@ impl<'a> ModifyInputsContext<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stroke_set(&mut self, stroke: Stroke) {
|
fn stroke_set(&mut self, stroke: Stroke) {
|
||||||
self.modify_inputs("Stroke", |inputs| {
|
self.modify_inputs("Stroke", false, |inputs| {
|
||||||
inputs[1] = NodeInput::value(TaggedValue::Color(stroke.color.unwrap_or_default()), false);
|
inputs[1] = NodeInput::value(TaggedValue::Color(stroke.color.unwrap_or_default()), false);
|
||||||
inputs[2] = NodeInput::value(TaggedValue::F64(stroke.weight), false);
|
inputs[2] = NodeInput::value(TaggedValue::F64(stroke.weight), false);
|
||||||
inputs[3] = NodeInput::value(TaggedValue::VecF32(stroke.dash_lengths), false);
|
inputs[3] = NodeInput::value(TaggedValue::VecF32(stroke.dash_lengths), false);
|
||||||
|
|
@ -115,8 +119,8 @@ impl<'a> ModifyInputsContext<'a> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transform_change(&mut self, transform: DAffine2, transform_in: TransformIn, parent_transform: DAffine2) {
|
fn transform_change(&mut self, transform: DAffine2, transform_in: TransformIn, parent_transform: DAffine2, skip_rerender: bool) {
|
||||||
self.modify_inputs("Transform", |inputs| {
|
self.modify_inputs("Transform", skip_rerender, |inputs| {
|
||||||
let layer_transform = transform_utils::get_current_transform(inputs);
|
let layer_transform = transform_utils::get_current_transform(inputs);
|
||||||
let to = match transform_in {
|
let to = match transform_in {
|
||||||
TransformIn::Local => DAffine2::IDENTITY,
|
TransformIn::Local => DAffine2::IDENTITY,
|
||||||
|
|
@ -128,8 +132,8 @@ impl<'a> ModifyInputsContext<'a> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transform_set(&mut self, transform: DAffine2, transform_in: TransformIn, parent_transform: DAffine2, bounds: LayerBounds) {
|
fn transform_set(&mut self, transform: DAffine2, transform_in: TransformIn, parent_transform: DAffine2, bounds: LayerBounds, skip_rerender: bool) {
|
||||||
self.modify_inputs("Transform", |inputs| {
|
self.modify_inputs("Transform", skip_rerender, |inputs| {
|
||||||
let to = match transform_in {
|
let to = match transform_in {
|
||||||
TransformIn::Local => DAffine2::IDENTITY,
|
TransformIn::Local => DAffine2::IDENTITY,
|
||||||
TransformIn::Scope { scope } => scope * parent_transform,
|
TransformIn::Scope { scope } => scope * parent_transform,
|
||||||
|
|
@ -142,7 +146,7 @@ impl<'a> ModifyInputsContext<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pivot_set(&mut self, new_pivot: DVec2, bounds: LayerBounds) {
|
fn pivot_set(&mut self, new_pivot: DVec2, bounds: LayerBounds) {
|
||||||
self.modify_inputs("Transform", |inputs| {
|
self.modify_inputs("Transform", false, |inputs| {
|
||||||
let layer_transform = transform_utils::get_current_transform(inputs);
|
let layer_transform = transform_utils::get_current_transform(inputs);
|
||||||
let old_pivot_transform = DAffine2::from_translation(bounds.local_pivot(transform_utils::get_current_normalized_pivot(inputs)));
|
let old_pivot_transform = DAffine2::from_translation(bounds.local_pivot(transform_utils::get_current_normalized_pivot(inputs)));
|
||||||
let new_pivot_transform = DAffine2::from_translation(bounds.local_pivot(new_pivot));
|
let new_pivot_transform = DAffine2::from_translation(bounds.local_pivot(new_pivot));
|
||||||
|
|
@ -156,7 +160,7 @@ impl<'a> ModifyInputsContext<'a> {
|
||||||
let [mut old_bounds_min, mut old_bounds_max] = [DVec2::ZERO, DVec2::ONE];
|
let [mut old_bounds_min, mut old_bounds_max] = [DVec2::ZERO, DVec2::ONE];
|
||||||
let [mut new_bounds_min, mut new_bounds_max] = [DVec2::ZERO, DVec2::ONE];
|
let [mut new_bounds_min, mut new_bounds_max] = [DVec2::ZERO, DVec2::ONE];
|
||||||
|
|
||||||
self.modify_inputs("Path Generator", |inputs| {
|
self.modify_inputs("Path Generator", false, |inputs| {
|
||||||
let [subpaths, mirror_angle_groups] = inputs.as_mut_slice() else {
|
let [subpaths, mirror_angle_groups] = inputs.as_mut_slice() else {
|
||||||
panic!("Path generator does not have subpath and mirror angle inputs");
|
panic!("Path generator does not have subpath and mirror angle inputs");
|
||||||
};
|
};
|
||||||
|
|
@ -180,7 +184,7 @@ impl<'a> ModifyInputsContext<'a> {
|
||||||
|
|
||||||
[new_bounds_min, new_bounds_max] = transform_utils::nonzero_subpath_bounds(subpaths);
|
[new_bounds_min, new_bounds_max] = transform_utils::nonzero_subpath_bounds(subpaths);
|
||||||
});
|
});
|
||||||
self.modify_inputs("Transform", |inputs| {
|
self.modify_inputs("Transform", false, |inputs| {
|
||||||
let layer_transform = transform_utils::get_current_transform(inputs);
|
let layer_transform = transform_utils::get_current_transform(inputs);
|
||||||
let normalized_pivot = transform_utils::get_current_normalized_pivot(inputs);
|
let normalized_pivot = transform_utils::get_current_normalized_pivot(inputs);
|
||||||
|
|
||||||
|
|
@ -214,27 +218,37 @@ impl MessageHandler<GraphOperationMessage, (&mut Document, &mut NodeGraphMessage
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GraphOperationMessage::TransformChange { layer, transform, transform_in } => {
|
GraphOperationMessage::TransformChange {
|
||||||
|
layer,
|
||||||
|
transform,
|
||||||
|
transform_in,
|
||||||
|
skip_rerender,
|
||||||
|
} => {
|
||||||
let parent_transform = document.multiply_transforms(&layer[..layer.len() - 1]).unwrap_or_default();
|
let parent_transform = document.multiply_transforms(&layer[..layer.len() - 1]).unwrap_or_default();
|
||||||
if let Some(mut modify_inputs) = ModifyInputsContext::new(&layer, document, node_graph, responses) {
|
if let Some(mut modify_inputs) = ModifyInputsContext::new(&layer, document, node_graph, responses) {
|
||||||
modify_inputs.transform_change(transform, transform_in, parent_transform);
|
modify_inputs.transform_change(transform, transform_in, parent_transform, skip_rerender);
|
||||||
} else {
|
|
||||||
let transform = transform.to_cols_array();
|
|
||||||
responses.add(match transform_in {
|
|
||||||
TransformIn::Local => Operation::TransformLayer { path: layer, transform },
|
|
||||||
TransformIn::Scope { scope } => {
|
|
||||||
let scope = scope.to_cols_array();
|
|
||||||
Operation::TransformLayerInScope { path: layer, transform, scope }
|
|
||||||
}
|
|
||||||
TransformIn::Viewport => Operation::TransformLayerInViewport { path: layer, transform },
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let transform = transform.to_cols_array();
|
||||||
|
responses.add(match transform_in {
|
||||||
|
TransformIn::Local => Operation::TransformLayer { path: layer, transform },
|
||||||
|
TransformIn::Scope { scope } => {
|
||||||
|
let scope = scope.to_cols_array();
|
||||||
|
Operation::TransformLayerInScope { path: layer, transform, scope }
|
||||||
|
}
|
||||||
|
TransformIn::Viewport => Operation::TransformLayerInViewport { path: layer, transform },
|
||||||
|
});
|
||||||
}
|
}
|
||||||
GraphOperationMessage::TransformSet { layer, transform, transform_in } => {
|
GraphOperationMessage::TransformSet {
|
||||||
|
layer,
|
||||||
|
transform,
|
||||||
|
transform_in,
|
||||||
|
skip_rerender,
|
||||||
|
} => {
|
||||||
let parent_transform = document.multiply_transforms(&layer[..layer.len() - 1]).unwrap_or_default();
|
let parent_transform = document.multiply_transforms(&layer[..layer.len() - 1]).unwrap_or_default();
|
||||||
let bounds = LayerBounds::new(document, &layer);
|
let bounds = LayerBounds::new(document, &layer);
|
||||||
if let Some(mut modify_inputs) = ModifyInputsContext::new(&layer, document, node_graph, responses) {
|
if let Some(mut modify_inputs) = ModifyInputsContext::new(&layer, document, node_graph, responses) {
|
||||||
modify_inputs.transform_set(transform, transform_in, parent_transform, bounds);
|
modify_inputs.transform_set(transform, transform_in, parent_transform, bounds, skip_rerender);
|
||||||
}
|
}
|
||||||
let transform = transform.to_cols_array();
|
let transform = transform.to_cols_array();
|
||||||
responses.add(match transform_in {
|
responses.add(match transform_in {
|
||||||
|
|
|
||||||
|
|
@ -166,7 +166,7 @@ impl TransformOperation {
|
||||||
self.apply_transform_operation(selected, snapping, axis);
|
self.apply_transform_operation(selected, snapping, axis);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_typed(&mut self, typed: Option<f64>, selected: &mut Selected, snapping: bool) {
|
pub fn grs_typed(&mut self, typed: Option<f64>, selected: &mut Selected, snapping: bool) {
|
||||||
match self {
|
match self {
|
||||||
TransformOperation::None => (),
|
TransformOperation::None => (),
|
||||||
TransformOperation::Grabbing(translation) => translation.typed_distance = typed,
|
TransformOperation::Grabbing(translation) => translation.typed_distance = typed,
|
||||||
|
|
@ -287,6 +287,7 @@ impl<'a> Selected<'a> {
|
||||||
layer: layer_path.to_vec(),
|
layer: layer_path.to_vec(),
|
||||||
transform: new,
|
transform: new,
|
||||||
transform_in: TransformIn::Local,
|
transform_in: TransformIn::Local,
|
||||||
|
skip_rerender: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -302,6 +303,7 @@ impl<'a> Selected<'a> {
|
||||||
layer: layer.to_vec(),
|
layer: layer.to_vec(),
|
||||||
transform,
|
transform,
|
||||||
transform_in: TransformIn::Local,
|
transform_in: TransformIn::Local,
|
||||||
|
skip_rerender: false,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,35 +34,36 @@ impl Resize {
|
||||||
&mut self,
|
&mut self,
|
||||||
responses: &mut VecDeque<Message>,
|
responses: &mut VecDeque<Message>,
|
||||||
document: &DocumentMessageHandler,
|
document: &DocumentMessageHandler,
|
||||||
|
ipp: &InputPreprocessorMessageHandler,
|
||||||
center: Key,
|
center: Key,
|
||||||
lock_ratio: Key,
|
lock_ratio: Key,
|
||||||
ipp: &InputPreprocessorMessageHandler,
|
skip_rerender: bool,
|
||||||
) -> Option<Message> {
|
) -> Option<Message> {
|
||||||
if let Some(path) = &self.path {
|
let Some(path) = &self.path else {
|
||||||
let mut start = self.viewport_drag_start(document);
|
return None;
|
||||||
|
};
|
||||||
|
|
||||||
let stop = self.snap_manager.snap_position(responses, document, ipp.mouse.position);
|
let mut start = self.viewport_drag_start(document);
|
||||||
|
let stop = self.snap_manager.snap_position(responses, document, ipp.mouse.position);
|
||||||
|
|
||||||
let mut size = stop - start;
|
let mut size = stop - start;
|
||||||
if ipp.keyboard.get(lock_ratio as usize) {
|
if ipp.keyboard.get(lock_ratio as usize) {
|
||||||
size = size.abs().max(size.abs().yx()) * size.signum();
|
size = size.abs().max(size.abs().yx()) * size.signum();
|
||||||
}
|
|
||||||
if ipp.keyboard.get(center as usize) {
|
|
||||||
start -= size;
|
|
||||||
size *= 2.;
|
|
||||||
}
|
|
||||||
|
|
||||||
Some(
|
|
||||||
GraphOperationMessage::TransformSet {
|
|
||||||
layer: path.to_vec(),
|
|
||||||
transform: DAffine2::from_scale_angle_translation(size, 0., start),
|
|
||||||
transform_in: TransformIn::Viewport,
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
}
|
||||||
|
if ipp.keyboard.get(center as usize) {
|
||||||
|
start -= size;
|
||||||
|
size *= 2.;
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(
|
||||||
|
GraphOperationMessage::TransformSet {
|
||||||
|
layer: path.to_vec(),
|
||||||
|
transform: DAffine2::from_scale_angle_translation(size, 0., start),
|
||||||
|
transform_in: TransformIn::Viewport,
|
||||||
|
skip_rerender,
|
||||||
|
}
|
||||||
|
.into(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cleanup(&mut self, responses: &mut VecDeque<Message>) {
|
pub fn cleanup(&mut self, responses: &mut VecDeque<Message>) {
|
||||||
|
|
|
||||||
|
|
@ -151,7 +151,7 @@ impl Fsm for EllipseToolFsmState {
|
||||||
Drawing
|
Drawing
|
||||||
}
|
}
|
||||||
(state, Resize { center, lock_ratio }) => {
|
(state, Resize { center, lock_ratio }) => {
|
||||||
if let Some(message) = shape_data.calculate_transform(responses, document, center, lock_ratio, input) {
|
if let Some(message) = shape_data.calculate_transform(responses, document, input, center, lock_ratio, false) {
|
||||||
responses.push_back(message);
|
responses.push_back(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -113,39 +113,39 @@ impl Fsm for NodeGraphToolFsmState {
|
||||||
match (self, event) {
|
match (self, event) {
|
||||||
(Ready, DragStart) => {
|
(Ready, DragStart) => {
|
||||||
shape_data.start(responses, document, input, render_data);
|
shape_data.start(responses, document, input, render_data);
|
||||||
responses.push_back(DocumentMessage::StartTransaction.into());
|
responses.add(DocumentMessage::StartTransaction);
|
||||||
shape_data.path = Some(document.get_path_for_new_layer());
|
shape_data.path = Some(document.get_path_for_new_layer());
|
||||||
responses.push_back(DocumentMessage::DeselectAllLayers.into());
|
responses.add(DocumentMessage::DeselectAllLayers);
|
||||||
|
|
||||||
let network = node_graph::new_image_network(8, 0);
|
let network = node_graph::new_image_network(8, 0);
|
||||||
|
|
||||||
responses.push_back(
|
responses.add(Operation::AddNodeGraphFrame {
|
||||||
Operation::AddNodeGraphFrame {
|
path: shape_data.path.clone().unwrap(),
|
||||||
path: shape_data.path.clone().unwrap(),
|
insert_index: -1,
|
||||||
insert_index: -1,
|
transform: DAffine2::ZERO.to_cols_array(),
|
||||||
transform: DAffine2::ZERO.to_cols_array(),
|
network,
|
||||||
network,
|
});
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
|
|
||||||
Drawing
|
Drawing
|
||||||
}
|
}
|
||||||
(state, Resize { center, lock_ratio }) => {
|
(state, Resize { center, lock_ratio }) => {
|
||||||
if let Some(message) = shape_data.calculate_transform(responses, document, center, lock_ratio, input) {
|
let message = shape_data.calculate_transform(responses, document, input, center, lock_ratio, true);
|
||||||
responses.push_back(message);
|
responses.try_add(message);
|
||||||
}
|
|
||||||
|
|
||||||
state
|
state
|
||||||
}
|
}
|
||||||
(Drawing, DragStop) => {
|
(Drawing, DragStop) => {
|
||||||
|
if let Some(layer_path) = &shape_data.path {
|
||||||
|
responses.add(DocumentMessage::NodeGraphFrameGenerate { layer_path: layer_path.to_vec() });
|
||||||
|
}
|
||||||
|
|
||||||
input.mouse.finish_transaction(shape_data.viewport_drag_start(document), responses);
|
input.mouse.finish_transaction(shape_data.viewport_drag_start(document), responses);
|
||||||
shape_data.cleanup(responses);
|
shape_data.cleanup(responses);
|
||||||
|
|
||||||
Ready
|
Ready
|
||||||
}
|
}
|
||||||
(Drawing, Abort) => {
|
(Drawing, Abort) => {
|
||||||
responses.push_back(DocumentMessage::AbortTransaction.into());
|
responses.add(DocumentMessage::AbortTransaction);
|
||||||
|
|
||||||
shape_data.cleanup(responses);
|
shape_data.cleanup(responses);
|
||||||
|
|
||||||
|
|
@ -168,10 +168,10 @@ impl Fsm for NodeGraphToolFsmState {
|
||||||
NodeGraphToolFsmState::Drawing => HintData(vec![HintGroup(vec![HintInfo::keys([Key::Shift], "Constrain Square"), HintInfo::keys([Key::Alt], "From Center")])]),
|
NodeGraphToolFsmState::Drawing => HintData(vec![HintGroup(vec![HintInfo::keys([Key::Shift], "Constrain Square"), HintInfo::keys([Key::Alt], "From Center")])]),
|
||||||
};
|
};
|
||||||
|
|
||||||
responses.push_back(FrontendMessage::UpdateInputHints { hint_data }.into());
|
responses.add(FrontendMessage::UpdateInputHints { hint_data });
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_cursor(&self, responses: &mut VecDeque<Message>) {
|
fn update_cursor(&self, responses: &mut VecDeque<Message>) {
|
||||||
responses.push_back(FrontendMessage::UpdateMouseCursor { cursor: MouseCursorIcon::Crosshair }.into());
|
responses.add(FrontendMessage::UpdateMouseCursor { cursor: MouseCursorIcon::Crosshair });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -230,5 +230,6 @@ fn add_polyline(data: &FreehandToolData, tool_data: &DocumentToolData, responses
|
||||||
layer: layer_path,
|
layer: layer_path,
|
||||||
transform: DAffine2::from_translation(position),
|
transform: DAffine2::from_translation(position),
|
||||||
transform_in: TransformIn::Local,
|
transform_in: TransformIn::Local,
|
||||||
|
skip_rerender: false,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -113,9 +113,9 @@ impl Fsm for ImaginateToolFsmState {
|
||||||
match (self, event) {
|
match (self, event) {
|
||||||
(Ready, DragStart) => {
|
(Ready, DragStart) => {
|
||||||
shape_data.start(responses, document, input, render_data);
|
shape_data.start(responses, document, input, render_data);
|
||||||
responses.push_back(DocumentMessage::StartTransaction.into());
|
responses.add(DocumentMessage::StartTransaction);
|
||||||
shape_data.path = Some(document.get_path_for_new_layer());
|
shape_data.path = Some(document.get_path_for_new_layer());
|
||||||
responses.push_back(DocumentMessage::DeselectAllLayers.into());
|
responses.add(DocumentMessage::DeselectAllLayers);
|
||||||
|
|
||||||
use graph_craft::document::*;
|
use graph_craft::document::*;
|
||||||
|
|
||||||
|
|
@ -149,34 +149,34 @@ impl Fsm for ImaginateToolFsmState {
|
||||||
);
|
);
|
||||||
|
|
||||||
// Add the node graph frame layer to the document
|
// Add the node graph frame layer to the document
|
||||||
responses.push_back(
|
responses.add(Operation::AddNodeGraphFrame {
|
||||||
Operation::AddNodeGraphFrame {
|
path: shape_data.path.clone().unwrap(),
|
||||||
path: shape_data.path.clone().unwrap(),
|
insert_index: -1,
|
||||||
insert_index: -1,
|
transform: DAffine2::ZERO.to_cols_array(),
|
||||||
transform: DAffine2::ZERO.to_cols_array(),
|
network,
|
||||||
network,
|
});
|
||||||
}
|
responses.add(NodeGraphMessage::ShiftNode { node_id: imaginate_node_id });
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
responses.push_back(NodeGraphMessage::ShiftNode { node_id: imaginate_node_id }.into());
|
|
||||||
|
|
||||||
Drawing
|
Drawing
|
||||||
}
|
}
|
||||||
(state, Resize { center, lock_ratio }) => {
|
(state, Resize { center, lock_ratio }) => {
|
||||||
if let Some(message) = shape_data.calculate_transform(responses, document, center, lock_ratio, input) {
|
let message = shape_data.calculate_transform(responses, document, input, center, lock_ratio, true);
|
||||||
responses.push_back(message);
|
responses.try_add(message);
|
||||||
}
|
|
||||||
|
|
||||||
state
|
state
|
||||||
}
|
}
|
||||||
(Drawing, DragStop) => {
|
(Drawing, DragStop) => {
|
||||||
|
if let Some(layer_path) = &shape_data.path {
|
||||||
|
responses.add(DocumentMessage::NodeGraphFrameGenerate { layer_path: layer_path.to_vec() });
|
||||||
|
}
|
||||||
|
|
||||||
input.mouse.finish_transaction(shape_data.viewport_drag_start(document), responses);
|
input.mouse.finish_transaction(shape_data.viewport_drag_start(document), responses);
|
||||||
shape_data.cleanup(responses);
|
shape_data.cleanup(responses);
|
||||||
|
|
||||||
Ready
|
Ready
|
||||||
}
|
}
|
||||||
(Drawing, Abort) => {
|
(Drawing, Abort) => {
|
||||||
responses.push_back(DocumentMessage::AbortTransaction.into());
|
responses.add(DocumentMessage::AbortTransaction);
|
||||||
|
|
||||||
shape_data.cleanup(responses);
|
shape_data.cleanup(responses);
|
||||||
|
|
||||||
|
|
@ -199,10 +199,10 @@ impl Fsm for ImaginateToolFsmState {
|
||||||
ImaginateToolFsmState::Drawing => HintData(vec![HintGroup(vec![HintInfo::keys([Key::Shift], "Constrain Square"), HintInfo::keys([Key::Alt], "From Center")])]),
|
ImaginateToolFsmState::Drawing => HintData(vec![HintGroup(vec![HintInfo::keys([Key::Shift], "Constrain Square"), HintInfo::keys([Key::Alt], "From Center")])]),
|
||||||
};
|
};
|
||||||
|
|
||||||
responses.push_back(FrontendMessage::UpdateInputHints { hint_data }.into());
|
responses.add(FrontendMessage::UpdateInputHints { hint_data });
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_cursor(&self, responses: &mut VecDeque<Message>) {
|
fn update_cursor(&self, responses: &mut VecDeque<Message>) {
|
||||||
responses.push_back(FrontendMessage::UpdateMouseCursor { cursor: MouseCursorIcon::Crosshair }.into());
|
responses.add(FrontendMessage::UpdateMouseCursor { cursor: MouseCursorIcon::Crosshair });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -256,6 +256,7 @@ fn generate_transform(tool_data: &mut LineToolData, lock_angle: bool, snap_angle
|
||||||
layer: tool_data.path.clone().unwrap(),
|
layer: tool_data.path.clone().unwrap(),
|
||||||
transform: glam::DAffine2::from_scale_angle_translation(DVec2::new(line_length, 1.), angle, start),
|
transform: glam::DAffine2::from_scale_angle_translation(DVec2::new(line_length, 1.), angle, start),
|
||||||
transform_in: TransformIn::Viewport,
|
transform_in: TransformIn::Viewport,
|
||||||
|
skip_rerender: false,
|
||||||
}
|
}
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -133,7 +133,7 @@ impl Fsm for RectangleToolFsmState {
|
||||||
Drawing
|
Drawing
|
||||||
}
|
}
|
||||||
(state, Resize { center, lock_ratio }) => {
|
(state, Resize { center, lock_ratio }) => {
|
||||||
if let Some(message) = shape_data.calculate_transform(responses, document, center, lock_ratio, input) {
|
if let Some(message) = shape_data.calculate_transform(responses, document, input, center, lock_ratio, false) {
|
||||||
responses.push_back(message);
|
responses.push_back(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -338,6 +338,7 @@ impl SelectToolData {
|
||||||
fn start_duplicates(&mut self, document: &DocumentMessageHandler, responses: &mut VecDeque<Message>) {
|
fn start_duplicates(&mut self, document: &DocumentMessageHandler, responses: &mut VecDeque<Message>) {
|
||||||
responses.push_back(DocumentMessage::DeselectAllLayers.into());
|
responses.push_back(DocumentMessage::DeselectAllLayers.into());
|
||||||
|
|
||||||
|
// Take the selected layers and store them in a separate list.
|
||||||
self.not_duplicated_layers = Some(self.layers_dragging.clone());
|
self.not_duplicated_layers = Some(self.layers_dragging.clone());
|
||||||
|
|
||||||
// Duplicate each previously selected layer and select the new ones.
|
// Duplicate each previously selected layer and select the new ones.
|
||||||
|
|
@ -348,6 +349,7 @@ impl SelectToolData {
|
||||||
layer: layer_path.clone(),
|
layer: layer_path.clone(),
|
||||||
transform: DAffine2::from_translation(self.drag_start - self.drag_current),
|
transform: DAffine2::from_translation(self.drag_start - self.drag_current),
|
||||||
transform_in: TransformIn::Viewport,
|
transform_in: TransformIn::Viewport,
|
||||||
|
skip_rerender: true,
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
);
|
);
|
||||||
|
|
@ -365,26 +367,24 @@ impl SelectToolData {
|
||||||
let layer_metadata = *document.layer_metadata(layer_path);
|
let layer_metadata = *document.layer_metadata(layer_path);
|
||||||
*layer_path.last_mut().unwrap() = generate_uuid();
|
*layer_path.last_mut().unwrap() = generate_uuid();
|
||||||
|
|
||||||
responses.push_back(
|
responses.add(Operation::InsertLayer {
|
||||||
Operation::InsertLayer {
|
layer: Box::new(layer),
|
||||||
layer: Box::new(layer),
|
destination_path: layer_path.clone(),
|
||||||
destination_path: layer_path.clone(),
|
insert_index: -1,
|
||||||
insert_index: -1,
|
});
|
||||||
}
|
responses.add(DocumentMessage::UpdateLayerMetadata {
|
||||||
.into(),
|
layer_path: layer_path.clone(),
|
||||||
);
|
layer_metadata,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
responses.push_back(
|
// Since the selected layers have now moved back to their original transforms before the drag began, we rerender them to be displayed as if they weren't touched.
|
||||||
DocumentMessage::UpdateLayerMetadata {
|
for layer_path in self.not_duplicated_layers.iter().flatten() {
|
||||||
layer_path: layer_path.clone(),
|
responses.add(DocumentMessage::NodeGraphFrameGenerate { layer_path: layer_path.clone() });
|
||||||
layer_metadata,
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Removes the duplicated layers. Called when Alt is released and the layers have been duplicated.
|
/// Removes the duplicated layers. Called when Alt is released and the layers have previously been duplicated.
|
||||||
fn stop_duplicates(&mut self, responses: &mut VecDeque<Message>) {
|
fn stop_duplicates(&mut self, responses: &mut VecDeque<Message>) {
|
||||||
let originals = match self.not_duplicated_layers.take() {
|
let originals = match self.not_duplicated_layers.take() {
|
||||||
Some(x) => x,
|
Some(x) => x,
|
||||||
|
|
@ -405,6 +405,7 @@ impl SelectToolData {
|
||||||
layer: layer_path.clone(),
|
layer: layer_path.clone(),
|
||||||
transform: DAffine2::from_translation(self.drag_current - self.drag_start),
|
transform: DAffine2::from_translation(self.drag_current - self.drag_start),
|
||||||
transform_in: TransformIn::Viewport,
|
transform_in: TransformIn::Viewport,
|
||||||
|
skip_rerender: true,
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
);
|
);
|
||||||
|
|
@ -624,6 +625,7 @@ impl Fsm for SelectToolFsmState {
|
||||||
layer: path.to_vec(),
|
layer: path.to_vec(),
|
||||||
transform: DAffine2::from_translation(mouse_delta + closest_move),
|
transform: DAffine2::from_translation(mouse_delta + closest_move),
|
||||||
transform_in: TransformIn::Viewport,
|
transform_in: TransformIn::Viewport,
|
||||||
|
skip_rerender: true,
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
);
|
);
|
||||||
|
|
@ -729,15 +731,20 @@ impl Fsm for SelectToolFsmState {
|
||||||
Ready
|
Ready
|
||||||
}
|
}
|
||||||
(Dragging, Enter) => {
|
(Dragging, Enter) => {
|
||||||
|
rerender_selected_layers(tool_data, responses);
|
||||||
|
|
||||||
let response = match input.mouse.position.distance(tool_data.drag_start) < 10. * f64::EPSILON {
|
let response = match input.mouse.position.distance(tool_data.drag_start) < 10. * f64::EPSILON {
|
||||||
true => DocumentMessage::Undo,
|
true => DocumentMessage::Undo,
|
||||||
false => DocumentMessage::CommitTransaction,
|
false => DocumentMessage::CommitTransaction,
|
||||||
};
|
};
|
||||||
tool_data.snap_manager.cleanup(responses);
|
tool_data.snap_manager.cleanup(responses);
|
||||||
responses.push_front(response.into());
|
responses.push_front(response.into());
|
||||||
|
|
||||||
Ready
|
Ready
|
||||||
}
|
}
|
||||||
(Dragging, DragStop { remove_from_selection }) => {
|
(Dragging, DragStop { remove_from_selection }) => {
|
||||||
|
rerender_selected_layers(tool_data, responses);
|
||||||
|
|
||||||
// Deselect layer if not snap dragging
|
// Deselect layer if not snap dragging
|
||||||
if !tool_data.is_dragging && input.keyboard.get(remove_from_selection as usize) && tool_data.layer_selected_on_start.is_none() {
|
if !tool_data.is_dragging && input.keyboard.get(remove_from_selection as usize) && tool_data.layer_selected_on_start.is_none() {
|
||||||
let quad = tool_data.selection_quad();
|
let quad = tool_data.selection_quad();
|
||||||
|
|
@ -760,9 +767,12 @@ impl Fsm for SelectToolFsmState {
|
||||||
|
|
||||||
responses.push_back(DocumentMessage::CommitTransaction.into());
|
responses.push_back(DocumentMessage::CommitTransaction.into());
|
||||||
tool_data.snap_manager.cleanup(responses);
|
tool_data.snap_manager.cleanup(responses);
|
||||||
|
|
||||||
Ready
|
Ready
|
||||||
}
|
}
|
||||||
(ResizingBounds, DragStop { .. } | Enter) => {
|
(ResizingBounds, DragStop { .. } | Enter) => {
|
||||||
|
rerender_selected_layers(tool_data, responses);
|
||||||
|
|
||||||
let response = match input.mouse.position.distance(tool_data.drag_start) < 10. * f64::EPSILON {
|
let response = match input.mouse.position.distance(tool_data.drag_start) < 10. * f64::EPSILON {
|
||||||
true => DocumentMessage::Undo,
|
true => DocumentMessage::Undo,
|
||||||
false => DocumentMessage::CommitTransaction,
|
false => DocumentMessage::CommitTransaction,
|
||||||
|
|
@ -778,6 +788,8 @@ impl Fsm for SelectToolFsmState {
|
||||||
Ready
|
Ready
|
||||||
}
|
}
|
||||||
(RotatingBounds, DragStop { .. } | Enter) => {
|
(RotatingBounds, DragStop { .. } | Enter) => {
|
||||||
|
rerender_selected_layers(tool_data, responses);
|
||||||
|
|
||||||
let response = match input.mouse.position.distance(tool_data.drag_start) < 10. * f64::EPSILON {
|
let response = match input.mouse.position.distance(tool_data.drag_start) < 10. * f64::EPSILON {
|
||||||
true => DocumentMessage::Undo,
|
true => DocumentMessage::Undo,
|
||||||
false => DocumentMessage::CommitTransaction,
|
false => DocumentMessage::CommitTransaction,
|
||||||
|
|
@ -838,6 +850,8 @@ impl Fsm for SelectToolFsmState {
|
||||||
Ready
|
Ready
|
||||||
}
|
}
|
||||||
(Dragging, Abort) => {
|
(Dragging, Abort) => {
|
||||||
|
rerender_selected_layers(tool_data, responses);
|
||||||
|
|
||||||
tool_data.snap_manager.cleanup(responses);
|
tool_data.snap_manager.cleanup(responses);
|
||||||
responses.push_back(DocumentMessage::Undo.into());
|
responses.push_back(DocumentMessage::Undo.into());
|
||||||
|
|
||||||
|
|
@ -951,6 +965,18 @@ impl Fsm for SelectToolFsmState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn rerender_selected_layers(tool_data: &mut SelectToolData, responses: &mut VecDeque<Message>) {
|
||||||
|
for layer_path in &tool_data.layers_dragging {
|
||||||
|
responses.add(DocumentMessage::NodeGraphFrameGenerate { layer_path: layer_path.clone() });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn rerender_duplicated_layers(tool_data: &mut SelectToolData, responses: &mut VecDeque<Message>) {
|
||||||
|
for layer_path in tool_data.not_duplicated_layers.iter().flatten() {
|
||||||
|
responses.add(DocumentMessage::NodeGraphFrameGenerate { layer_path: layer_path.clone() });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Majorly clean up these next five functions
|
// TODO: Majorly clean up these next five functions
|
||||||
|
|
||||||
fn drag_shallowest_manipulation(
|
fn drag_shallowest_manipulation(
|
||||||
|
|
|
||||||
|
|
@ -172,7 +172,7 @@ impl Fsm for ShapeToolFsmState {
|
||||||
Drawing
|
Drawing
|
||||||
}
|
}
|
||||||
(state, Resize { center, lock_ratio }) => {
|
(state, Resize { center, lock_ratio }) => {
|
||||||
if let Some(message) = shape_data.calculate_transform(responses, document, center, lock_ratio, input) {
|
if let Some(message) = shape_data.calculate_transform(responses, document, input, center, lock_ratio, false) {
|
||||||
responses.push_back(message);
|
responses.push_back(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -274,5 +274,6 @@ fn add_spline(tool_data: &SplineToolData, global_tool_data: &DocumentToolData, s
|
||||||
layer: layer_path,
|
layer: layer_path,
|
||||||
transform: glam::DAffine2::from_translation(position),
|
transform: glam::DAffine2::from_translation(position),
|
||||||
transform_in: TransformIn::Local,
|
transform_in: TransformIn::Local,
|
||||||
|
skip_rerender: false,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -330,6 +330,7 @@ impl Fsm for TextToolFsmState {
|
||||||
layer: tool_data.layer_path.clone(),
|
layer: tool_data.layer_path.clone(),
|
||||||
transform,
|
transform,
|
||||||
transform_in: TransformIn::Viewport,
|
transform_in: TransformIn::Viewport,
|
||||||
|
skip_rerender: false,
|
||||||
}
|
}
|
||||||
.into(),
|
.into(),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,9 @@ impl<'a> MessageHandler<TransformLayerMessage, TransformData<'a>> for TransformL
|
||||||
|
|
||||||
responses.add(ToolMessage::UpdateHints);
|
responses.add(ToolMessage::UpdateHints);
|
||||||
responses.add(BroadcastEvent::DocumentIsDirty);
|
responses.add(BroadcastEvent::DocumentIsDirty);
|
||||||
|
for layer_path in document.selected_layers() {
|
||||||
|
responses.add(DocumentMessage::NodeGraphFrameGenerate { layer_path: layer_path.to_vec() });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
BeginGrab => {
|
BeginGrab => {
|
||||||
if let TransformOperation::Grabbing(_) = self.transform_operation {
|
if let TransformOperation::Grabbing(_) = self.transform_operation {
|
||||||
|
|
@ -194,10 +197,10 @@ impl<'a> MessageHandler<TransformLayerMessage, TransformData<'a>> for TransformL
|
||||||
let layer_paths = document.selected_visible_layers().map(|layer_path| layer_path.to_vec()).collect();
|
let layer_paths = document.selected_visible_layers().map(|layer_path| layer_path.to_vec()).collect();
|
||||||
shape_editor.set_selected_layers(layer_paths);
|
shape_editor.set_selected_layers(layer_paths);
|
||||||
}
|
}
|
||||||
TypeBackspace => self.transform_operation.handle_typed(self.typing.type_backspace(), &mut selected, self.snap),
|
TypeBackspace => self.transform_operation.grs_typed(self.typing.type_backspace(), &mut selected, self.snap),
|
||||||
TypeDecimalPoint => self.transform_operation.handle_typed(self.typing.type_decimal_point(), &mut selected, self.snap),
|
TypeDecimalPoint => self.transform_operation.grs_typed(self.typing.type_decimal_point(), &mut selected, self.snap),
|
||||||
TypeDigit { digit } => self.transform_operation.handle_typed(self.typing.type_number(digit), &mut selected, self.snap),
|
TypeDigit { digit } => self.transform_operation.grs_typed(self.typing.type_number(digit), &mut selected, self.snap),
|
||||||
TypeNegate => self.transform_operation.handle_typed(self.typing.type_negate(), &mut selected, self.snap),
|
TypeNegate => self.transform_operation.grs_typed(self.typing.type_negate(), &mut selected, self.snap),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue