Skip to content

Commit 8227d42

Browse files
committed
make hints update when changing shape,add default behaviour when dragging to make circle earlier fixed to from center
1 parent 5696f47 commit 8227d42

4 files changed

Lines changed: 180 additions & 126 deletions

File tree

editor/src/messages/tool/common_functionality/resize.rs

Lines changed: 69 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -48,71 +48,101 @@ impl Resize {
4848
/// Compute the drag start and end based on the current mouse position. Ignores the state of the layer.
4949
/// If you want to only draw whilst a layer exists, use [`Resize::calculate_points`].
5050
pub fn calculate_points_ignore_layer(&mut self, document: &DocumentMessageHandler, input: &InputPreprocessorMessageHandler, center: Key, lock_ratio: Key, in_document: bool) -> [DVec2; 2] {
51+
let ratio = input.keyboard.get(lock_ratio as usize);
52+
let center = input.keyboard.get(center as usize);
53+
54+
// Use shared snapping logic with optional center and ratio constraints, considering if coordinates are in document space.
55+
self.compute_snapped_resize_points(document, input, center, ratio, in_document)
56+
}
57+
58+
pub fn calculate_transform(&mut self, document: &DocumentMessageHandler, input: &InputPreprocessorMessageHandler, center: Key, lock_ratio: Key, skip_rerender: bool) -> Option<Message> {
59+
let points_viewport = self.calculate_points(document, input, center, lock_ratio)?;
60+
Some(
61+
GraphOperationMessage::TransformSet {
62+
layer: self.layer?,
63+
transform: DAffine2::from_scale_angle_translation(points_viewport[1] - points_viewport[0], 0., points_viewport[0]),
64+
transform_in: TransformIn::Viewport,
65+
skip_rerender,
66+
}
67+
.into(),
68+
)
69+
}
70+
71+
pub fn calculate_circle_points(&mut self, document: &DocumentMessageHandler, input: &InputPreprocessorMessageHandler, center: Key) -> [DVec2; 2] {
72+
let center = input.keyboard.get(center as usize);
73+
74+
// Use shared snapping logic with enforced aspect ratio and optional center snapping.
75+
self.compute_snapped_resize_points(document, input, center, true, false)
76+
}
77+
78+
/// Calculates two points in viewport space from a drag, applying snapping, optional center mode, and aspect ratio locking.
79+
fn compute_snapped_resize_points(&mut self, document: &DocumentMessageHandler, input: &InputPreprocessorMessageHandler, center: bool, lock_ratio: bool, in_document: bool) -> [DVec2; 2] {
5180
let start = self.viewport_drag_start(document);
5281
let mouse = input.mouse.position;
5382
let document_to_viewport = document.navigation_handler.calculate_offset_transform(input.viewport_bounds.center(), &document.document_ptz);
54-
let document_mouse = document_to_viewport.inverse().transform_point2(mouse);
83+
let drag_start = self.drag_start;
5584
let mut points_viewport = [start, mouse];
85+
5686
let ignore = if let Some(layer) = self.layer { vec![layer] } else { vec![] };
57-
let ratio = input.keyboard.get(lock_ratio as usize);
58-
let center = input.keyboard.get(center as usize);
59-
let snap_data = SnapData::ignore(document, input, &ignore);
60-
let config = SnapTypeConfiguration::default();
61-
if ratio {
87+
let snap_data = &SnapData::ignore(document, input, &ignore);
88+
89+
if lock_ratio {
6290
let viewport_size = points_viewport[1] - points_viewport[0];
63-
let raw_size = if in_document { document_to_viewport.inverse() } else { DAffine2::IDENTITY }.transform_vector2(viewport_size);
91+
let raw_size = if in_document {
92+
document_to_viewport.inverse().transform_vector2(viewport_size)
93+
} else {
94+
viewport_size
95+
};
96+
6497
let adjusted_size = raw_size.abs().max(raw_size.abs().yx()) * raw_size.signum();
6598
let size = if in_document { document_to_viewport.transform_vector2(adjusted_size) } else { adjusted_size };
66-
points_viewport[1] = points_viewport[0] + size;
6799

100+
points_viewport[1] = points_viewport[0] + size;
68101
let end_document = document_to_viewport.inverse().transform_point2(points_viewport[1]);
69102
let constraint = SnapConstraint::Line {
70-
origin: self.drag_start,
71-
direction: end_document - self.drag_start,
103+
origin: drag_start,
104+
direction: end_document - drag_start,
72105
};
106+
73107
if center {
74-
let snapped = self.snap_manager.constrained_snap(&snap_data, &SnapCandidatePoint::handle(end_document), constraint, config);
75-
let far = SnapCandidatePoint::handle(2. * self.drag_start - end_document);
76-
let snapped_far = self.snap_manager.constrained_snap(&snap_data, &far, constraint, config);
108+
let snapped = self
109+
.snap_manager
110+
.constrained_snap(snap_data, &SnapCandidatePoint::handle(end_document), constraint, SnapTypeConfiguration::default());
111+
let far = SnapCandidatePoint::handle(2. * drag_start - end_document);
112+
let snapped_far = self.snap_manager.constrained_snap(snap_data, &far, constraint, SnapTypeConfiguration::default());
77113
let best = if snapped_far.other_snap_better(&snapped) { snapped } else { snapped_far };
114+
78115
points_viewport[0] = document_to_viewport.transform_point2(best.snapped_point_document);
79-
points_viewport[1] = document_to_viewport.transform_point2(self.drag_start * 2. - best.snapped_point_document);
116+
points_viewport[1] = document_to_viewport.transform_point2(drag_start * 2. - best.snapped_point_document);
80117
self.snap_manager.update_indicator(best);
81118
} else {
82-
let snapped = self.snap_manager.constrained_snap(&snap_data, &SnapCandidatePoint::handle(end_document), constraint, config);
119+
let snapped = self
120+
.snap_manager
121+
.constrained_snap(snap_data, &SnapCandidatePoint::handle(end_document), constraint, SnapTypeConfiguration::default());
83122
points_viewport[1] = document_to_viewport.transform_point2(snapped.snapped_point_document);
84123
self.snap_manager.update_indicator(snapped);
85124
}
86-
} else if center {
87-
let snapped = self.snap_manager.free_snap(&snap_data, &SnapCandidatePoint::handle(document_mouse), config);
88-
let opposite = 2. * self.drag_start - document_mouse;
89-
let snapped_far = self.snap_manager.free_snap(&snap_data, &SnapCandidatePoint::handle(opposite), config);
90-
let best = if snapped_far.other_snap_better(&snapped) { snapped } else { snapped_far };
91-
points_viewport[0] = document_to_viewport.transform_point2(best.snapped_point_document);
92-
points_viewport[1] = document_to_viewport.transform_point2(self.drag_start * 2. - best.snapped_point_document);
93-
self.snap_manager.update_indicator(best);
94125
} else {
95-
let snapped = self.snap_manager.free_snap(&snap_data, &SnapCandidatePoint::handle(document_mouse), config);
96-
points_viewport[1] = document_to_viewport.transform_point2(snapped.snapped_point_document);
97-
self.snap_manager.update_indicator(snapped);
126+
let document_mouse = document_to_viewport.inverse().transform_point2(mouse);
127+
if center {
128+
let snapped = self.snap_manager.free_snap(snap_data, &SnapCandidatePoint::handle(document_mouse), SnapTypeConfiguration::default());
129+
let opposite = 2. * drag_start - document_mouse;
130+
let snapped_far = self.snap_manager.free_snap(snap_data, &SnapCandidatePoint::handle(opposite), SnapTypeConfiguration::default());
131+
let best = if snapped_far.other_snap_better(&snapped) { snapped } else { snapped_far };
132+
133+
points_viewport[0] = document_to_viewport.transform_point2(best.snapped_point_document);
134+
points_viewport[1] = document_to_viewport.transform_point2(drag_start * 2. - best.snapped_point_document);
135+
self.snap_manager.update_indicator(best);
136+
} else {
137+
let snapped = self.snap_manager.free_snap(snap_data, &SnapCandidatePoint::handle(document_mouse), SnapTypeConfiguration::default());
138+
points_viewport[1] = document_to_viewport.transform_point2(snapped.snapped_point_document);
139+
self.snap_manager.update_indicator(snapped);
140+
}
98141
}
99142

100143
points_viewport
101144
}
102145

103-
pub fn calculate_transform(&mut self, document: &DocumentMessageHandler, input: &InputPreprocessorMessageHandler, center: Key, lock_ratio: Key, skip_rerender: bool) -> Option<Message> {
104-
let points_viewport = self.calculate_points(document, input, center, lock_ratio)?;
105-
Some(
106-
GraphOperationMessage::TransformSet {
107-
layer: self.layer?,
108-
transform: DAffine2::from_scale_angle_translation(points_viewport[1] - points_viewport[0], 0., points_viewport[0]),
109-
transform_in: TransformIn::Viewport,
110-
skip_rerender,
111-
}
112-
.into(),
113-
)
114-
}
115-
116146
pub fn cleanup(&mut self, responses: &mut VecDeque<Message>) {
117147
self.snap_manager.cleanup(responses);
118148
self.layer = None;

editor/src/messages/tool/common_functionality/shapes/arc_shape.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,11 +149,9 @@ impl Arc {
149149
// We keep the smaller dimension's scale at 1 and scale the other dimension accordingly
150150
if dimensions.x > dimensions.y {
151151
scale.x = dimensions.x / dimensions.y;
152-
scale.y = 1.;
153152
radius = dimensions.y / 2.;
154153
} else {
155154
scale.y = dimensions.y / dimensions.x;
156-
scale.x = 1.;
157155
radius = dimensions.x / 2.;
158156
}
159157

editor/src/messages/tool/common_functionality/shapes/circle_shape.rs

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ use crate::messages::portfolio::document::utility_types::network_interface::{Inp
66
use crate::messages::tool::common_functionality::gizmos::shape_gizmos::circle_arc_radius_handle::{RadiusHandle, RadiusHandleState};
77
use crate::messages::tool::common_functionality::graph_modification_utils;
88
use crate::messages::tool::common_functionality::shape_editor::ShapeState;
9-
use crate::messages::tool::common_functionality::shapes::shape_utility::ShapeGizmoHandler;
9+
use crate::messages::tool::common_functionality::shapes::shape_utility::{ShapeGizmoHandler, ShapeToolModifierKey};
10+
use crate::messages::tool::tool_messages::shape_tool::ShapeToolData;
1011
use crate::messages::tool::tool_messages::tool_prelude::*;
1112
use glam::DAffine2;
1213
use graph_craft::document::NodeInput;
@@ -85,15 +86,29 @@ impl Circle {
8586
node_type.node_template_input_override([None, Some(NodeInput::value(TaggedValue::F64(0.), false))])
8687
}
8788

88-
pub fn update_shape(document: &DocumentMessageHandler, ipp: &InputPreprocessorMessageHandler, layer: LayerNodeIdentifier, responses: &mut VecDeque<Message>) {
89+
pub fn update_shape(
90+
document: &DocumentMessageHandler,
91+
ipp: &InputPreprocessorMessageHandler,
92+
layer: LayerNodeIdentifier,
93+
shape_tool_data: &mut ShapeToolData,
94+
modifier: ShapeToolModifierKey,
95+
responses: &mut VecDeque<Message>,
96+
) {
97+
let center = modifier[0];
98+
let [start, end] = shape_tool_data.data.calculate_circle_points(document, ipp, center);
8999
let Some(node_id) = graph_modification_utils::get_circle_id(layer, &document.network_interface) else {
90100
return;
91101
};
92102

93-
let viewport = document.metadata().transform_to_viewport(layer);
94-
let center = viewport.transform_point2(DVec2::ZERO);
103+
let dimensions = (start - end).abs();
104+
let radius: f64;
95105

96-
let radius = ipp.mouse.position.distance(center);
106+
// We keep the smaller dimension's scale at 1 and scale the other dimension accordingly
107+
if dimensions.x > dimensions.y {
108+
radius = dimensions.y / 2.;
109+
} else {
110+
radius = dimensions.x / 2.;
111+
}
97112

98113
responses.add(NodeGraphMessage::SetInput {
99114
input_connector: InputConnector::node(node_id, 1),
@@ -102,7 +117,7 @@ impl Circle {
102117

103118
responses.add(GraphOperationMessage::TransformSet {
104119
layer,
105-
transform: DAffine2::from_translation(center),
120+
transform: DAffine2::from_scale_angle_translation(DVec2::ONE, 0., start.midpoint(end)),
106121
transform_in: TransformIn::Viewport,
107122
skip_rerender: false,
108123
});

0 commit comments

Comments
 (0)