Skip to content

Commit 1510ad8

Browse files
mTvare6Keavon
andauthored
Add draggable skew triangles to the transform cage (#2300)
* Add triangle handles to transform cage for skew transform Fixes #2299 * Add skew triangles * Fix conflicts which github didn't show * cargo fmt * Fix needed * remove unreachable * use the trap and rect logic * fix quad checks * cursor fix; no triangles if already dragging and not skewing * cargo fmt * Resolve Clippy lints * Add min length for triangle visibility * Code review --------- Co-authored-by: Keavon Chambers <[email protected]>
1 parent bc6e762 commit 1510ad8

File tree

10 files changed

+304
-51
lines changed

10 files changed

+304
-51
lines changed

editor/src/consts.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,11 @@ pub const MIN_LENGTH_FOR_RESIZE_TO_INCLUDE_INTERIOR: f64 = 40.;
8888
/// The motion of the user's cursor by an `x` pixel offset results in `x * scale_factor` pixels of offset on the other side.
8989
pub const MAXIMUM_ALT_SCALE_FACTOR: f64 = 25.;
9090

91+
// SKEW TRIANGLES
92+
pub const SKEW_TRIANGLE_SIZE: f64 = 7.;
93+
pub const SKEW_TRIANGLE_OFFSET: f64 = 4.;
94+
pub const MIN_LENGTH_FOR_SKEW_TRIANGLE_VISIBILITY: f64 = 48.;
95+
9196
// PATH TOOL
9297
pub const MANIPULATOR_GROUP_MARKER_SIZE: f64 = 6.;
9398
pub const SELECTION_THRESHOLD: f64 = 10.;

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

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,30 @@ impl OverlayContext {
4242
self.dashed_polygon(&quad.0, color_fill, None, None, None);
4343
}
4444

45+
pub fn draw_triangle(&mut self, base: DVec2, direction: DVec2, size: f64, color_fill: Option<&str>, color_stroke: Option<&str>) {
46+
let color_fill = color_fill.unwrap_or(COLOR_OVERLAY_WHITE);
47+
let color_stroke = color_stroke.unwrap_or(COLOR_OVERLAY_BLUE);
48+
let normal = direction.perp();
49+
let top = base + direction * size;
50+
let edge1 = base + normal * size / 2.;
51+
let edge2 = base - normal * size / 2.;
52+
53+
self.start_dpi_aware_transform();
54+
55+
self.render_context.begin_path();
56+
self.render_context.move_to(top.x, top.y);
57+
self.render_context.line_to(edge1.x, edge1.y);
58+
self.render_context.line_to(edge2.x, edge2.y);
59+
self.render_context.close_path();
60+
61+
self.render_context.set_fill_style_str(color_fill);
62+
self.render_context.set_stroke_style_str(color_stroke);
63+
self.render_context.fill();
64+
self.render_context.stroke();
65+
66+
self.end_dpi_aware_transform();
67+
}
68+
4569
pub fn dashed_quad(&mut self, quad: Quad, color_fill: Option<&str>, dash_width: Option<f64>, dash_gap_width: Option<f64>, dash_offset: Option<f64>) {
4670
self.dashed_polygon(&quad.0, color_fill, dash_width, dash_gap_width, dash_offset);
4771
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5334,7 +5334,7 @@ impl NodeNetworkInterface {
53345334
// If a non artboard layer is attempted to be connected to the exports, and there is already an artboard connected, then connect the layer to the artboard.
53355335
if let Some(first_layer) = LayerNodeIdentifier::ROOT_PARENT.children(&self.document_metadata).next() {
53365336
if parent == LayerNodeIdentifier::ROOT_PARENT
5337-
&& !self.reference(&layer.to_node(), network_path).is_some_and(|reference| *reference == Some("Artboard".to_string()))
5337+
&& self.reference(&layer.to_node(), network_path).is_none_or(|reference| *reference != Some("Artboard".to_string()))
53385338
&& self.is_artboard(&first_layer.to_node(), network_path)
53395339
{
53405340
parent = first_layer;

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,7 @@ pub enum TransformOperation {
306306
}
307307

308308
impl TransformOperation {
309+
#[allow(clippy::too_many_arguments)]
309310
pub fn apply_transform_operation(&self, selected: &mut Selected, increment_mode: bool, local: bool, quad: Quad, transform: DAffine2, pivot: DVec2, local_transform: DAffine2) {
310311
let local_axis_transform_angle = (quad.top_left() - quad.top_right()).to_angle();
311312
if self != &TransformOperation::None {
@@ -351,6 +352,7 @@ impl TransformOperation {
351352
self.is_constraint_to_axis() || !matches!(self, TransformOperation::Grabbing(_))
352353
}
353354

355+
#[allow(clippy::too_many_arguments)]
354356
pub fn constrain_axis(&mut self, axis: Axis, selected: &mut Selected, increment_mode: bool, mut local: bool, quad: Quad, transform: DAffine2, pivot: DVec2, local_transform: DAffine2) -> bool {
355357
(*self, local) = match self {
356358
TransformOperation::Grabbing(translation) => {
@@ -367,6 +369,7 @@ impl TransformOperation {
367369
local
368370
}
369371

372+
#[allow(clippy::too_many_arguments)]
370373
pub fn grs_typed(&mut self, typed: Option<f64>, selected: &mut Selected, increment_mode: bool, local: bool, quad: Quad, transform: DAffine2, pivot: DVec2, local_transform: DAffine2) {
371374
match self {
372375
TransformOperation::None => (),
@@ -457,6 +460,7 @@ impl TransformOperation {
457460
}
458461
}
459462

463+
#[allow(clippy::too_many_arguments)]
460464
pub fn negate(&mut self, selected: &mut Selected, increment_mode: bool, local: bool, quad: Quad, transform: DAffine2, pivot: DVec2, local_transform: DAffine2) {
461465
if *self != TransformOperation::None {
462466
*self = match self {

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

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -48,15 +48,12 @@ pub fn merge_layers(document: &DocumentMessageHandler, first_layer: LayerNodeIde
4848

4949
let mut current_and_other_layer_is_spline = false;
5050

51-
match (find_spline(document, first_layer), find_spline(document, second_layer)) {
52-
(Some(current_layer_spline), Some(other_layer_spline)) => {
53-
responses.add(NodeGraphMessage::DeleteNodes {
54-
node_ids: [current_layer_spline, other_layer_spline].to_vec(),
55-
delete_children: false,
56-
});
57-
current_and_other_layer_is_spline = true;
58-
}
59-
_ => {}
51+
if let (Some(current_layer_spline), Some(other_layer_spline)) = (find_spline(document, first_layer), find_spline(document, second_layer)) {
52+
responses.add(NodeGraphMessage::DeleteNodes {
53+
node_ids: [current_layer_spline, other_layer_spline].to_vec(),
54+
delete_children: false,
55+
});
56+
current_and_other_layer_is_spline = true;
6057
}
6158

6259
// Move the `second_layer` below the `first_layer` for positioning purposes

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -324,10 +324,10 @@ impl SnapManager {
324324
let layer_bounds = document.metadata().transform_to_document(layer) * Quad::from_box(bounds);
325325
let screen_bounds = document.metadata().document_to_viewport.inverse() * Quad::from_box([DVec2::ZERO, snap_data.input.viewport_bounds.size()]);
326326
if screen_bounds.intersects(layer_bounds) {
327-
if !self.alignment_candidates.as_ref().is_some_and(|candidates| candidates.len() > 100) {
327+
if self.alignment_candidates.as_ref().is_none_or(|candidates| candidates.len() <= 100) {
328328
self.alignment_candidates.get_or_insert_with(Vec::new).push(layer);
329329
}
330-
if quad.intersects(layer_bounds) && !self.candidates.as_ref().is_some_and(|candidates| candidates.len() > 10) {
330+
if quad.intersects(layer_bounds) && self.candidates.as_ref().is_none_or(|candidates| candidates.len() <= 10) {
331331
self.candidates.get_or_insert_with(Vec::new).push(layer);
332332
}
333333
}

0 commit comments

Comments
 (0)