Skip to content

Commit 07d104e

Browse files
0SlowPoke0Keavon
authored andcommitted
implement arc gizmo handler
1 parent c797877 commit 07d104e

File tree

13 files changed

+656
-35
lines changed

13 files changed

+656
-35
lines changed

editor/src/consts.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,9 @@ pub const POINT_RADIUS_HANDLE_SNAP_THRESHOLD: f64 = 8.;
124124
pub const POINT_RADIUS_HANDLE_SEGMENT_THRESHOLD: f64 = 7.9;
125125
pub const NUMBER_OF_POINTS_DIAL_SPOKE_EXTENSION: f64 = 1.2;
126126
pub const NUMBER_OF_POINTS_DIAL_SPOKE_LENGTH: f64 = 10.;
127+
pub const ARC_SNAP_THRESHOLD: f64 = 5.;
128+
pub const ARC_SWEEP_GIZMO_RADIUS: f64 = 14.;
129+
pub const ARC_SWEEP_GIZMO_TEXT_HEIGHT: f64 = 12.;
127130
pub const GIZMO_HIDE_THRESHOLD: f64 = 20.;
128131

129132
// SCROLLBARS

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

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use super::utility_functions::overlay_canvas_context;
22
use crate::consts::{
3-
COLOR_OVERLAY_BLUE, COLOR_OVERLAY_GREEN, COLOR_OVERLAY_RED, COLOR_OVERLAY_WHITE, COLOR_OVERLAY_YELLOW, COMPASS_ROSE_ARROW_SIZE, COMPASS_ROSE_HOVER_RING_DIAMETER, COMPASS_ROSE_MAIN_RING_DIAMETER,
4-
COMPASS_ROSE_RING_INNER_DIAMETER, MANIPULATOR_GROUP_MARKER_SIZE, PIVOT_CROSSHAIR_LENGTH, PIVOT_CROSSHAIR_THICKNESS, PIVOT_DIAMETER,
3+
ARC_SWEEP_GIZMO_RADIUS, COLOR_OVERLAY_BLUE, COLOR_OVERLAY_GREEN, COLOR_OVERLAY_RED, COLOR_OVERLAY_WHITE, COLOR_OVERLAY_YELLOW, COMPASS_ROSE_ARROW_SIZE, COMPASS_ROSE_HOVER_RING_DIAMETER,
4+
COMPASS_ROSE_MAIN_RING_DIAMETER, COMPASS_ROSE_RING_INNER_DIAMETER, MANIPULATOR_GROUP_MARKER_SIZE, PIVOT_CROSSHAIR_LENGTH, PIVOT_CROSSHAIR_THICKNESS, PIVOT_DIAMETER,
55
};
66
use crate::messages::prelude::Message;
77
use bezier_rs::{Bezier, Subpath};
@@ -550,6 +550,12 @@ impl OverlayContext {
550550
self.end_dpi_aware_transform();
551551
}
552552

553+
pub fn arc_sweep_angle(&mut self, offset_angle: f64, angle: f64, end_point_position: DVec2, radius: f64, pivot: DVec2, text: &str, transform: DAffine2) {
554+
self.manipulator_handle(end_point_position, true, Some(COLOR_OVERLAY_RED));
555+
self.draw_angle(pivot, radius, ARC_SWEEP_GIZMO_RADIUS, offset_angle, angle.to_radians());
556+
self.text(&text, COLOR_OVERLAY_BLUE, None, transform, 16., [Pivot::Middle, Pivot::Middle]);
557+
}
558+
553559
/// Used by the Pen and Path tools to outline the path of the shape.
554560
pub fn outline_vector(&mut self, vector_data: &VectorData, transform: DAffine2) {
555561
self.start_dpi_aware_transform();

editor/src/messages/tool/common_functionality/gizmos/gizmo_manager.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use crate::messages::portfolio::document::utility_types::document_metadata::Laye
44
use crate::messages::prelude::{DocumentMessageHandler, InputPreprocessorMessageHandler};
55
use crate::messages::tool::common_functionality::graph_modification_utils;
66
use crate::messages::tool::common_functionality::shape_editor::ShapeState;
7+
use crate::messages::tool::common_functionality::shapes::arc_shape::ArcGizmoHandler;
78
use crate::messages::tool::common_functionality::shapes::polygon_shape::PolygonGizmoHandler;
89
use crate::messages::tool::common_functionality::shapes::shape_utility::ShapeGizmoHandler;
910
use crate::messages::tool::common_functionality::shapes::star_shape::StarGizmoHandler;
@@ -23,6 +24,7 @@ pub enum ShapeGizmoHandlers {
2324
None,
2425
Star(StarGizmoHandler),
2526
Polygon(PolygonGizmoHandler),
27+
Arc(ArcGizmoHandler),
2628
}
2729

2830
impl ShapeGizmoHandlers {
@@ -32,6 +34,7 @@ impl ShapeGizmoHandlers {
3234
match self {
3335
Self::Star(_) => "star",
3436
Self::Polygon(_) => "polygon",
37+
Self::Arc(_) => "arc",
3538
Self::None => "none",
3639
}
3740
}
@@ -41,6 +44,7 @@ impl ShapeGizmoHandlers {
4144
match self {
4245
Self::Star(h) => h.handle_state(layer, mouse_position, document, responses),
4346
Self::Polygon(h) => h.handle_state(layer, mouse_position, document, responses),
47+
Self::Arc(h) => h.handle_state(layer, mouse_position, document, responses),
4448
Self::None => {}
4549
}
4650
}
@@ -50,6 +54,7 @@ impl ShapeGizmoHandlers {
5054
match self {
5155
Self::Star(h) => h.is_any_gizmo_hovered(),
5256
Self::Polygon(h) => h.is_any_gizmo_hovered(),
57+
Self::Arc(h) => h.is_any_gizmo_hovered(),
5358
Self::None => false,
5459
}
5560
}
@@ -59,6 +64,7 @@ impl ShapeGizmoHandlers {
5964
match self {
6065
Self::Star(h) => h.handle_click(),
6166
Self::Polygon(h) => h.handle_click(),
67+
Self::Arc(h) => h.handle_click(),
6268
Self::None => {}
6369
}
6470
}
@@ -68,6 +74,7 @@ impl ShapeGizmoHandlers {
6874
match self {
6975
Self::Star(h) => h.handle_update(drag_start, document, input, responses),
7076
Self::Polygon(h) => h.handle_update(drag_start, document, input, responses),
77+
Self::Arc(h) => h.handle_update(drag_start, document, input, responses),
7178
Self::None => {}
7279
}
7380
}
@@ -77,6 +84,7 @@ impl ShapeGizmoHandlers {
7784
match self {
7885
Self::Star(h) => h.cleanup(),
7986
Self::Polygon(h) => h.cleanup(),
87+
Self::Arc(h) => h.cleanup(),
8088
Self::None => {}
8189
}
8290
}
@@ -94,6 +102,7 @@ impl ShapeGizmoHandlers {
94102
match self {
95103
Self::Star(h) => h.overlays(document, layer, input, shape_editor, mouse_position, overlay_context),
96104
Self::Polygon(h) => h.overlays(document, layer, input, shape_editor, mouse_position, overlay_context),
105+
Self::Arc(h) => h.overlays(document, layer, input, shape_editor, mouse_position, overlay_context),
97106
Self::None => {}
98107
}
99108
}
@@ -110,6 +119,7 @@ impl ShapeGizmoHandlers {
110119
match self {
111120
Self::Star(h) => h.dragging_overlays(document, input, shape_editor, mouse_position, overlay_context),
112121
Self::Polygon(h) => h.dragging_overlays(document, input, shape_editor, mouse_position, overlay_context),
122+
Self::Arc(h) => h.dragging_overlays(document, input, shape_editor, mouse_position, overlay_context),
113123
Self::None => {}
114124
}
115125
}
@@ -146,6 +156,9 @@ impl GizmoManager {
146156
if graph_modification_utils::get_polygon_id(layer, &document.network_interface).is_some() {
147157
return Some(ShapeGizmoHandlers::Polygon(PolygonGizmoHandler::default()));
148158
}
159+
if graph_modification_utils::get_arc_id(layer, &document.network_interface).is_some() {
160+
return Some(ShapeGizmoHandlers::Arc(ArcGizmoHandler::new()));
161+
}
149162

150163
None
151164
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
pub mod number_of_points_dial;
22
pub mod point_radius_handle;
3+
pub mod sweep_angle_gizmo;

editor/src/messages/tool/common_functionality/gizmos/shape_gizmos/point_radius_handle.rs

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,6 @@ impl PointRadiusHandle {
262262
};
263263

264264
let viewport = document.metadata().transform_to_viewport(layer);
265-
let center = viewport.transform_point2(DVec2::ZERO);
266265

267266
match snapping_index {
268267
// Make a triangle with previous two points
@@ -274,41 +273,57 @@ impl PointRadiusHandle {
274273
overlay_context.line(before_outer_position, outer_position, Some(COLOR_OVERLAY_RED), Some(3.));
275274
overlay_context.line(outer_position, point_position, Some(COLOR_OVERLAY_RED), Some(3.));
276275

276+
let before_outer_position = viewport.inverse().transform_point2(before_outer_position);
277+
let outer_position = viewport.inverse().transform_point2(outer_position);
278+
let point_position = viewport.inverse().transform_point2(point_position);
279+
277280
let l1 = (before_outer_position - outer_position).length() * 0.2;
278281
let Some(l1_direction) = (before_outer_position - outer_position).try_normalize() else { return };
279282
let Some(l2_direction) = (point_position - outer_position).try_normalize() else { return };
280-
let Some(direction) = (center - outer_position).try_normalize() else { return };
283+
let Some(direction) = (-outer_position).try_normalize() else { return };
281284

282285
let new_point = SQRT_2 * l1 * direction + outer_position;
283286

284287
let before_outer_position = l1 * l1_direction + outer_position;
285288
let point_position = l1 * l2_direction + outer_position;
286289

287-
overlay_context.line(before_outer_position, new_point, Some(COLOR_OVERLAY_RED), Some(3.));
288-
overlay_context.line(new_point, point_position, Some(COLOR_OVERLAY_RED), Some(3.));
290+
overlay_context.line(
291+
viewport.transform_point2(before_outer_position),
292+
viewport.transform_point2(new_point),
293+
Some(COLOR_OVERLAY_RED),
294+
Some(3.),
295+
);
296+
overlay_context.line(viewport.transform_point2(new_point), viewport.transform_point2(point_position), Some(COLOR_OVERLAY_RED), Some(3.));
289297
}
290298
1 => {
291299
let before_outer_position = star_vertex_position(viewport, (self.point as i32) - 1, sides, radius1, radius2);
292-
293300
let after_point_position = star_vertex_position(viewport, (self.point as i32) + 1, sides, radius1, radius2);
294-
295301
let point_position = star_vertex_position(viewport, self.point as i32, sides, radius1, radius2);
296302

297303
overlay_context.line(before_outer_position, point_position, Some(COLOR_OVERLAY_RED), Some(3.));
298304
overlay_context.line(point_position, after_point_position, Some(COLOR_OVERLAY_RED), Some(3.));
299305

306+
let before_outer_position = viewport.inverse().transform_point2(before_outer_position);
307+
let after_point_position = viewport.inverse().transform_point2(after_point_position);
308+
let point_position = viewport.inverse().transform_point2(point_position);
309+
300310
let l1 = (before_outer_position - point_position).length() * 0.2;
301311
let Some(l1_direction) = (before_outer_position - point_position).try_normalize() else { return };
302312
let Some(l2_direction) = (after_point_position - point_position).try_normalize() else { return };
303-
let Some(direction) = (center - point_position).try_normalize() else { return };
313+
let Some(direction) = (-point_position).try_normalize() else { return };
304314

305315
let new_point = SQRT_2 * l1 * direction + point_position;
306316

307317
let before_outer_position = l1 * l1_direction + point_position;
308318
let after_point_position = l1 * l2_direction + point_position;
309319

310-
overlay_context.line(before_outer_position, new_point, Some(COLOR_OVERLAY_RED), Some(3.));
311-
overlay_context.line(new_point, after_point_position, Some(COLOR_OVERLAY_RED), Some(3.));
320+
overlay_context.line(
321+
viewport.transform_point2(before_outer_position),
322+
viewport.transform_point2(new_point),
323+
Some(COLOR_OVERLAY_RED),
324+
Some(3.),
325+
);
326+
overlay_context.line(viewport.transform_point2(new_point), viewport.transform_point2(after_point_position), Some(COLOR_OVERLAY_RED), Some(3.));
312327
}
313328
i => {
314329
// Use `self.point` as absolute reference as it matches the index of vertices of the star starting from 0

0 commit comments

Comments
 (0)