Skip to content

Commit 7e7e88f

Browse files
mTvare6Keavon
andauthored
Refactor GRS messages and fix regression in chained GRS operations (#2450)
* Refactor GRS messages and have a switch handler * some cleanup * rename variables * Code review --------- Co-authored-by: Keavon Chambers <keavon@keavon.com>
1 parent b400647 commit 7e7e88f

File tree

4 files changed

+66
-114
lines changed

4 files changed

+66
-114
lines changed

editor/src/messages/input_mapper/input_mappings.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use crate::messages::input_mapper::utility_types::misc::{KeyMappingEntries, Mapp
88
use crate::messages::portfolio::document::node_graph::utility_types::Direction;
99
use crate::messages::portfolio::document::utility_types::clipboards::Clipboard;
1010
use crate::messages::portfolio::document::utility_types::misc::GroupFolderType;
11+
use crate::messages::portfolio::document::utility_types::transformation::TransformType;
1112
use crate::messages::prelude::*;
1213
use crate::messages::tool::tool_messages::brush_tool::BrushToolMessageOptionsUpdate;
1314
use crate::messages::tool::tool_messages::select_tool::SelectToolPointerKeys;
@@ -82,8 +83,8 @@ pub fn input_mappings() -> Mapping {
8283
entry!(KeyDown(ArrowLeft); action_dispatch=NodeGraphMessage::ShiftSelectedNodes { direction: Direction::Left, rubber_band: false }),
8384
//
8485
// TransformLayerMessage
85-
entry!(KeyDown(Enter); action_dispatch=TransformLayerMessage::ApplyTransformOperation),
86-
entry!(KeyDown(MouseLeft); action_dispatch=TransformLayerMessage::ApplyTransformOperation),
86+
entry!(KeyDown(Enter); action_dispatch=TransformLayerMessage::ApplyTransformOperation { final_transform: true }),
87+
entry!(KeyDown(MouseLeft); action_dispatch=TransformLayerMessage::ApplyTransformOperation { final_transform: true }),
8788
entry!(KeyDown(MouseRight); action_dispatch=TransformLayerMessage::CancelTransformOperation),
8889
entry!(KeyDown(Escape); action_dispatch=TransformLayerMessage::CancelTransformOperation),
8990
entry!(KeyDown(KeyX); action_dispatch=TransformLayerMessage::ConstrainX),
@@ -373,9 +374,9 @@ pub fn input_mappings() -> Mapping {
373374
entry!(KeyDown(ArrowRight); action_dispatch=DocumentMessage::NudgeSelectedLayers { delta_x: NUDGE_AMOUNT, delta_y: 0., resize: Alt, resize_opposite_corner: Control }),
374375
//
375376
// TransformLayerMessage
376-
entry!(KeyDown(KeyG); action_dispatch=TransformLayerMessage::BeginGrab),
377-
entry!(KeyDown(KeyR); action_dispatch=TransformLayerMessage::BeginRotate),
378-
entry!(KeyDown(KeyS); action_dispatch=TransformLayerMessage::BeginScale),
377+
entry!(KeyDown(KeyG); action_dispatch=TransformLayerMessage::BeginGRS { transform_type: TransformType::Grab }),
378+
entry!(KeyDown(KeyR); action_dispatch=TransformLayerMessage::BeginGRS { transform_type: TransformType::Rotate }),
379+
entry!(KeyDown(KeyS); action_dispatch=TransformLayerMessage::BeginGRS { transform_type: TransformType::Scale }),
379380
entry!(KeyDown(Digit0); action_dispatch=TransformLayerMessage::TypeDigit { digit: 0 }),
380381
entry!(KeyDown(Digit1); action_dispatch=TransformLayerMessage::TypeDigit { digit: 1 }),
381382
entry!(KeyDown(Digit2); action_dispatch=TransformLayerMessage::TypeDigit { digit: 2 }),

editor/src/messages/portfolio/document/utility_types/transformation.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,22 @@ pub enum TransformOperation {
299299
Scaling(Scale),
300300
}
301301

302+
#[derive(Debug, Clone, PartialEq, Copy, serde::Serialize, serde::Deserialize)]
303+
pub enum TransformType {
304+
Grab,
305+
Rotate,
306+
Scale,
307+
}
308+
309+
impl TransformType {
310+
pub fn equivalent_to(&self, operation: TransformOperation) -> bool {
311+
matches!(
312+
(operation, self),
313+
(TransformOperation::Scaling(_), TransformType::Scale) | (TransformOperation::Grabbing(_), TransformType::Grab) | (TransformOperation::Rotating(_), TransformType::Rotate)
314+
)
315+
}
316+
}
317+
302318
impl TransformOperation {
303319
#[allow(clippy::too_many_arguments)]
304320
pub fn apply_transform_operation(&self, selected: &mut Selected, increment_mode: bool, local: bool, quad: Quad, transform: DAffine2, pivot: DVec2, local_transform: DAffine2) {

editor/src/messages/tool/transform_layer/transform_layer_message.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::messages::input_mapper::utility_types::input_keyboard::Key;
22
use crate::messages::portfolio::document::overlays::utility_types::OverlayContext;
3+
use crate::messages::portfolio::document::utility_types::transformation::TransformType;
34
use crate::messages::prelude::*;
45
use glam::DVec2;
56

@@ -10,10 +11,11 @@ pub enum TransformLayerMessage {
1011
Overlays(OverlayContext),
1112

1213
// Messages
13-
ApplyTransformOperation,
14+
ApplyTransformOperation { final_transform: bool },
1415
BeginGrab,
1516
BeginRotate,
1617
BeginScale,
18+
BeginGRS { transform_type: TransformType },
1719
BeginGrabPen { last_point: DVec2, handle: DVec2 },
1820
BeginRotatePen { last_point: DVec2, handle: DVec2 },
1921
BeginScalePen { last_point: DVec2, handle: DVec2 },

editor/src/messages/tool/transform_layer/transform_layer_message_handler.rs

Lines changed: 41 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use crate::messages::input_mapper::utility_types::input_mouse::{DocumentPosition
33
use crate::messages::portfolio::document::overlays::utility_types::{OverlayProvider, Pivot};
44
use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
55
use crate::messages::portfolio::document::utility_types::misc::PTZ;
6-
use crate::messages::portfolio::document::utility_types::transformation::{Axis, OriginalTransforms, Selected, TransformOperation, Typing};
6+
use crate::messages::portfolio::document::utility_types::transformation::{Axis, OriginalTransforms, Selected, TransformOperation, TransformType, Typing};
77
use crate::messages::prelude::*;
88
use crate::messages::tool::common_functionality::shape_editor::ShapeState;
99
use crate::messages::tool::tool_messages::tool_prelude::Key;
@@ -12,7 +12,7 @@ use glam::{DAffine2, DVec2};
1212
use graphene_core::renderer::Quad;
1313
use graphene_core::vector::ManipulatorPointId;
1414
use graphene_std::vector::{VectorData, VectorModificationType};
15-
use std::f64::consts::TAU;
15+
use std::f64::consts::{PI, TAU};
1616

1717
const TRANSFORM_GRS_OVERLAY_PROVIDER: OverlayProvider = |context| TransformLayerMessage::Overlays(context).into();
1818

@@ -107,8 +107,6 @@ fn project_edge_to_quad(edge: DVec2, quad: &Quad, local: bool, axis_constraint:
107107
}
108108

109109
fn update_colinear_handles(selected_layers: &[LayerNodeIdentifier], document: &DocumentMessageHandler, responses: &mut VecDeque<Message>) {
110-
use std::f64::consts::PI;
111-
112110
for &layer in selected_layers {
113111
let Some(vector_data) = document.network_interface.compute_modified_vector(layer) else { continue };
114112

@@ -243,23 +241,15 @@ impl MessageHandler<TransformLayerMessage, TransformData<'_>> for TransformLayer
243241
let e1 = (self.layer_bounding_box.0[1] - self.layer_bounding_box.0[0]).normalize_or(DVec2::X);
244242

245243
if matches!(axis_constraint, Axis::Both | Axis::X) && translation.x != 0. {
246-
let end = if self.local {
247-
(quad[1] - quad[0]).length() * e1 * e1.dot(quad[1] - quad[0]).signum() + quad[0]
248-
} else {
249-
quad[1]
250-
};
244+
let end = if self.local { (quad[1] - quad[0]).rotate(e1) + quad[0] } else { quad[1] };
251245
overlay_context.line(quad[0], end, None);
252246

253247
let x_transform = DAffine2::from_translation((quad[0] + end) / 2.);
254248
overlay_context.text(&format_rounded(translation.x, 3), COLOR_OVERLAY_BLUE, None, x_transform, 4., [Pivot::Middle, Pivot::End]);
255249
}
256250

257251
if matches!(axis_constraint, Axis::Both | Axis::Y) && translation.y != 0. {
258-
let end = if self.local {
259-
(quad[3] - quad[0]).length() * e1.perp() * e1.perp().dot(quad[3] - quad[0]).signum() + quad[0]
260-
} else {
261-
quad[3]
262-
};
252+
let end = if self.local { (quad[3] - quad[0]).rotate(e1) + quad[0] } else { quad[3] };
263253
overlay_context.line(quad[0], end, None);
264254
let x_parameter = viewport_translate.x.clamp(-1., 1.);
265255
let y_transform = DAffine2::from_translation((quad[0] + end) / 2. + x_parameter * DVec2::X * 0.);
@@ -325,27 +315,30 @@ impl MessageHandler<TransformLayerMessage, TransformData<'_>> for TransformLayer
325315
}
326316

327317
// Messages
328-
TransformLayerMessage::ApplyTransformOperation => {
318+
TransformLayerMessage::ApplyTransformOperation { final_transform } => {
329319
selected.original_transforms.clear();
330320
self.typing.clear();
331-
self.transform_operation = TransformOperation::None;
321+
if final_transform {
322+
self.transform_operation = TransformOperation::None;
323+
self.operation_count = 0;
324+
}
332325

333326
if using_pen_tool {
334327
self.last_point = DVec2::ZERO;
335328
self.grs_pen_handle = false;
336329

337330
selected.pen_handle = None;
338-
339331
selected.responses.add(PenToolMessage::Confirm);
340332
} else {
341333
update_colinear_handles(&selected_layers, document, responses);
342-
self.operation_count = 0;
343334
responses.add(DocumentMessage::EndTransaction);
344335
responses.add(ToolMessage::UpdateHints);
345336
responses.add(NodeGraphMessage::RunDocumentGraph);
346337
}
347338

348-
responses.add(OverlaysMessage::RemoveProvider(TRANSFORM_GRS_OVERLAY_PROVIDER));
339+
if final_transform {
340+
responses.add(OverlaysMessage::RemoveProvider(TRANSFORM_GRS_OVERLAY_PROVIDER));
341+
}
349342
}
350343
TransformLayerMessage::BeginGrabPen { last_point, handle } | TransformLayerMessage::BeginRotatePen { last_point, handle } | TransformLayerMessage::BeginScalePen { last_point, handle } => {
351344
self.typing.clear();
@@ -381,37 +374,12 @@ impl MessageHandler<TransformLayerMessage, TransformData<'_>> for TransformLayer
381374
increments_key: INCREMENTS_KEY,
382375
});
383376
}
384-
TransformLayerMessage::BeginGrab => {
385-
if (!using_path_tool && !using_select_tool && !using_pen_tool)
386-
|| (using_path_tool && shape_editor.selected_points().next().is_none())
387-
|| selected_layers.is_empty()
388-
|| matches!(self.transform_operation, TransformOperation::Grabbing(_))
389-
{
390-
return;
391-
}
392-
393-
begin_operation(self.transform_operation, &mut self.typing, &mut self.mouse_position, &mut self.start_mouse, &mut self.initial_transform);
394-
395-
self.transform_operation = TransformOperation::Grabbing(Default::default());
396-
self.local = false;
397-
self.layer_bounding_box = selected.bounding_box();
398-
self.operation_count += 1;
399-
400-
selected.original_transforms.clear();
401-
402-
responses.add(OverlaysMessage::AddProvider(TRANSFORM_GRS_OVERLAY_PROVIDER));
403-
responses.add(TransformLayerMessage::PointerMove {
404-
slow_key: SLOW_KEY,
405-
increments_key: INCREMENTS_KEY,
406-
});
407-
}
408-
TransformLayerMessage::BeginRotate => {
377+
TransformLayerMessage::BeginGRS { transform_type } => {
409378
let selected_points: Vec<&ManipulatorPointId> = shape_editor.selected_points().collect();
410-
411-
if (!using_path_tool && !using_select_tool && !using_pen_tool)
412-
|| (using_path_tool && selected_points.is_empty())
379+
if (using_path_tool && selected_points.is_empty())
380+
|| (!using_path_tool && !using_select_tool && !using_pen_tool)
413381
|| selected_layers.is_empty()
414-
|| matches!(self.transform_operation, TransformOperation::Rotating(_))
382+
|| transform_type.equivalent_to(self.transform_operation)
415383
{
416384
return;
417385
}
@@ -428,12 +396,12 @@ impl MessageHandler<TransformLayerMessage, TransformData<'_>> for TransformLayer
428396
let handle2_length = handle2.length(&vector_data);
429397

430398
if (handle1_length == 0. && handle2_length == 0.) || (handle1_length == f64::MAX && handle2_length == f64::MAX) {
399+
selected.original_transforms.clear();
431400
return;
432401
}
433402
}
434403
} else {
435-
// TODO: Fix handle snap to anchor issue, see <https://discord.com/channels/731730685944922173/1217752903209713715>
436-
404+
// TODO: Fix handle snap to anchor issue, see <https://github.com/GraphiteEditor/Graphite/issues/2451>
437405
let handle_length = point.as_handle().map(|handle| handle.length(&vector_data));
438406

439407
if handle_length == Some(0.) {
@@ -443,74 +411,41 @@ impl MessageHandler<TransformLayerMessage, TransformData<'_>> for TransformLayer
443411
}
444412
}
445413

446-
begin_operation(self.transform_operation, &mut self.typing, &mut self.mouse_position, &mut self.start_mouse, &mut self.initial_transform);
414+
let chain_operation = self.transform_operation != TransformOperation::None;
415+
if chain_operation {
416+
responses.add(TransformLayerMessage::ApplyTransformOperation { final_transform: false });
417+
} else {
418+
responses.add(OverlaysMessage::AddProvider(TRANSFORM_GRS_OVERLAY_PROVIDER));
419+
}
447420

448-
self.transform_operation = TransformOperation::Rotating(Default::default());
421+
let response = match transform_type {
422+
TransformType::Grab => TransformLayerMessage::BeginGrab,
423+
TransformType::Rotate => TransformLayerMessage::BeginRotate,
424+
TransformType::Scale => TransformLayerMessage::BeginScale,
425+
};
449426

450427
self.local = false;
451-
self.layer_bounding_box = selected.bounding_box();
452428
self.operation_count += 1;
453-
454-
selected.original_transforms.clear();
455-
456-
responses.add(OverlaysMessage::AddProvider(TRANSFORM_GRS_OVERLAY_PROVIDER));
429+
responses.add(response);
457430
responses.add(TransformLayerMessage::PointerMove {
458431
slow_key: SLOW_KEY,
459432
increments_key: INCREMENTS_KEY,
460433
});
461434
}
435+
TransformLayerMessage::BeginGrab => {
436+
begin_operation(self.transform_operation, &mut self.typing, &mut self.mouse_position, &mut self.start_mouse, &mut self.initial_transform);
437+
self.transform_operation = TransformOperation::Grabbing(Default::default());
438+
self.layer_bounding_box = selected.bounding_box();
439+
}
440+
TransformLayerMessage::BeginRotate => {
441+
begin_operation(self.transform_operation, &mut self.typing, &mut self.mouse_position, &mut self.start_mouse, &mut self.initial_transform);
442+
self.transform_operation = TransformOperation::Rotating(Default::default());
443+
self.layer_bounding_box = selected.bounding_box();
444+
}
462445
TransformLayerMessage::BeginScale => {
463-
let selected_points: Vec<&ManipulatorPointId> = shape_editor.selected_points().collect();
464-
465-
if (using_path_tool && selected_points.is_empty())
466-
|| (!using_path_tool && !using_select_tool && !using_pen_tool)
467-
|| selected_layers.is_empty()
468-
|| matches!(self.transform_operation, TransformOperation::Scaling(_))
469-
{
470-
return;
471-
}
472-
473-
let Some(vector_data) = selected_layers.first().and_then(|&layer| document.network_interface.compute_modified_vector(layer)) else {
474-
selected.original_transforms.clear();
475-
return;
476-
};
477-
478-
if let [point] = selected_points.as_slice() {
479-
if matches!(point, ManipulatorPointId::Anchor(_)) {
480-
if let Some([handle1, handle2]) = point.get_handle_pair(&vector_data) {
481-
let handle1_length = handle1.length(&vector_data);
482-
let handle2_length = handle2.length(&vector_data);
483-
484-
if (handle1_length == 0. && handle2_length == 0.) || (handle1_length == f64::MAX && handle2_length == f64::MAX) {
485-
selected.original_transforms.clear();
486-
return;
487-
}
488-
}
489-
} else {
490-
let handle_length = point.as_handle().map(|handle| handle.length(&vector_data));
491-
492-
if handle_length == Some(0.) {
493-
selected.original_transforms.clear();
494-
return;
495-
}
496-
}
497-
}
498-
499446
begin_operation(self.transform_operation, &mut self.typing, &mut self.mouse_position, &mut self.start_mouse, &mut self.initial_transform);
500-
501447
self.transform_operation = TransformOperation::Scaling(Default::default());
502-
503-
self.local = false;
504448
self.layer_bounding_box = selected.bounding_box();
505-
self.operation_count += 1;
506-
507-
selected.original_transforms.clear();
508-
509-
responses.add(OverlaysMessage::AddProvider(TRANSFORM_GRS_OVERLAY_PROVIDER));
510-
responses.add(TransformLayerMessage::PointerMove {
511-
slow_key: SLOW_KEY,
512-
increments_key: INCREMENTS_KEY,
513-
});
514449
}
515450
TransformLayerMessage::CancelTransformOperation => {
516451
if using_pen_tool {
@@ -744,9 +679,7 @@ impl MessageHandler<TransformLayerMessage, TransformData<'_>> for TransformLayer
744679

745680
fn actions(&self) -> ActionList {
746681
let mut common = actions!(TransformLayerMessageDiscriminant;
747-
BeginGrab,
748-
BeginScale,
749-
BeginRotate,
682+
BeginGRS,
750683
);
751684

752685
if self.transform_operation != TransformOperation::None {

0 commit comments

Comments
 (0)