Skip to content

Add Arc Shape and Arc Gizmos #2757

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions editor/src/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,9 @@ pub const POINT_RADIUS_HANDLE_SNAP_THRESHOLD: f64 = 8.;
pub const POINT_RADIUS_HANDLE_SEGMENT_THRESHOLD: f64 = 7.9;
pub const NUMBER_OF_POINTS_DIAL_SPOKE_EXTENSION: f64 = 1.2;
pub const NUMBER_OF_POINTS_DIAL_SPOKE_LENGTH: f64 = 10.;
pub const ARC_SNAP_THRESHOLD: f64 = 5.;
pub const ARC_SWEEP_GIZMO_RADIUS: f64 = 14.;
pub const ARC_SWEEP_GIZMO_TEXT_HEIGHT: f64 = 12.;
pub const GIZMO_HIDE_THRESHOLD: f64 = 20.;

// SCROLLBARS
Expand Down
20 changes: 17 additions & 3 deletions editor/src/messages/portfolio/document/overlays/utility_types.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use super::utility_functions::overlay_canvas_context;
use crate::consts::{
COLOR_OVERLAY_BLUE, COLOR_OVERLAY_BLUE_50, COLOR_OVERLAY_GREEN, COLOR_OVERLAY_RED, COLOR_OVERLAY_WHITE, COLOR_OVERLAY_YELLOW, COLOR_OVERLAY_YELLOW_DULL, COMPASS_ROSE_ARROW_SIZE,
COMPASS_ROSE_HOVER_RING_DIAMETER, COMPASS_ROSE_MAIN_RING_DIAMETER, COMPASS_ROSE_RING_INNER_DIAMETER, DOWEL_PIN_RADIUS, MANIPULATOR_GROUP_MARKER_SIZE, PIVOT_CROSSHAIR_LENGTH,
PIVOT_CROSSHAIR_THICKNESS, PIVOT_DIAMETER,
ARC_SWEEP_GIZMO_RADIUS, COLOR_OVERLAY_BLUE, COLOR_OVERLAY_BLUE_50, COLOR_OVERLAY_GREEN, COLOR_OVERLAY_RED, COLOR_OVERLAY_WHITE, COLOR_OVERLAY_YELLOW, COLOR_OVERLAY_YELLOW_DULL,
COMPASS_ROSE_ARROW_SIZE, COMPASS_ROSE_HOVER_RING_DIAMETER, COMPASS_ROSE_MAIN_RING_DIAMETER, COMPASS_ROSE_RING_INNER_DIAMETER, DOWEL_PIN_RADIUS, MANIPULATOR_GROUP_MARKER_SIZE,
PIVOT_CROSSHAIR_LENGTH, PIVOT_CROSSHAIR_THICKNESS, PIVOT_DIAMETER,
};
use crate::messages::prelude::Message;
use bezier_rs::{Bezier, Subpath};
Expand Down Expand Up @@ -423,6 +423,14 @@ impl OverlayContext {
self.render_context.stroke();
}

pub fn draw_arc_gizmo_angle(&mut self, pivot: DVec2, bold_radius: f64, dash_radius: f64, arc_radius: f64, offset_angle: f64, angle: f64) {
let end_point1 = pivot + bold_radius * DVec2::from_angle(angle + offset_angle);
let end_point2 = pivot + dash_radius * DVec2::from_angle(offset_angle);
self.line(pivot, end_point1, None, None);
self.dashed_line(pivot, end_point2, None, None, Some(2.), Some(2.), Some(0.5));
self.draw_arc(pivot, arc_radius, offset_angle, (angle) % TAU + offset_angle);
}

pub fn draw_angle(&mut self, pivot: DVec2, radius: f64, arc_radius: f64, offset_angle: f64, angle: f64) {
let end_point1 = pivot + radius * DVec2::from_angle(angle + offset_angle);
let end_point2 = pivot + radius * DVec2::from_angle(offset_angle);
Expand Down Expand Up @@ -584,6 +592,12 @@ impl OverlayContext {
self.end_dpi_aware_transform();
}

pub fn arc_sweep_angle(&mut self, offset_angle: f64, angle: f64, end_point_position: DVec2, bold_radius: f64, dash_radius: f64, pivot: DVec2, text: &str, transform: DAffine2) {
self.manipulator_handle(end_point_position, true, Some(COLOR_OVERLAY_RED));
self.draw_arc_gizmo_angle(pivot, bold_radius, dash_radius, ARC_SWEEP_GIZMO_RADIUS, offset_angle, angle.to_radians());
self.text(&text, COLOR_OVERLAY_BLUE, None, transform, 16., [Pivot::Middle, Pivot::Middle]);
}

/// Used by the Pen and Path tools to outline the path of the shape.
pub fn outline_vector(&mut self, vector_data: &VectorData, transform: DAffine2) {
self.start_dpi_aware_transform();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -517,8 +517,8 @@ impl<'a> Selected<'a> {
tool_type: &'a ToolType,
pen_handle: Option<&'a mut DVec2>,
) -> Self {
// If user is using the Select tool then use the original layer transforms
if (*tool_type == ToolType::Select) && (*original_transforms == OriginalTransforms::Path(HashMap::new())) {
// If user is using the Select tool or Shape tool then use the original layer transforms
if (*tool_type == ToolType::Select || *tool_type == ToolType::Shape) && (*original_transforms == OriginalTransforms::Path(HashMap::new())) {
*original_transforms = OriginalTransforms::Layer(HashMap::new());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::messages::portfolio::document::utility_types::document_metadata::Laye
use crate::messages::prelude::{DocumentMessageHandler, InputPreprocessorMessageHandler};
use crate::messages::tool::common_functionality::graph_modification_utils;
use crate::messages::tool::common_functionality::shape_editor::ShapeState;
use crate::messages::tool::common_functionality::shapes::arc_shape::ArcGizmoHandler;
use crate::messages::tool::common_functionality::shapes::polygon_shape::PolygonGizmoHandler;
use crate::messages::tool::common_functionality::shapes::shape_utility::ShapeGizmoHandler;
use crate::messages::tool::common_functionality::shapes::star_shape::StarGizmoHandler;
Expand All @@ -23,6 +24,7 @@ pub enum ShapeGizmoHandlers {
None,
Star(StarGizmoHandler),
Polygon(PolygonGizmoHandler),
Arc(ArcGizmoHandler),
}

impl ShapeGizmoHandlers {
Expand All @@ -32,6 +34,7 @@ impl ShapeGizmoHandlers {
match self {
Self::Star(_) => "star",
Self::Polygon(_) => "polygon",
Self::Arc(_) => "arc",
Self::None => "none",
}
}
Expand All @@ -41,6 +44,7 @@ impl ShapeGizmoHandlers {
match self {
Self::Star(h) => h.handle_state(layer, mouse_position, document, responses),
Self::Polygon(h) => h.handle_state(layer, mouse_position, document, responses),
Self::Arc(h) => h.handle_state(layer, mouse_position, document, responses),
Self::None => {}
}
}
Expand All @@ -50,6 +54,7 @@ impl ShapeGizmoHandlers {
match self {
Self::Star(h) => h.is_any_gizmo_hovered(),
Self::Polygon(h) => h.is_any_gizmo_hovered(),
Self::Arc(h) => h.is_any_gizmo_hovered(),
Self::None => false,
}
}
Expand All @@ -59,6 +64,7 @@ impl ShapeGizmoHandlers {
match self {
Self::Star(h) => h.handle_click(),
Self::Polygon(h) => h.handle_click(),
Self::Arc(h) => h.handle_click(),
Self::None => {}
}
}
Expand All @@ -68,6 +74,7 @@ impl ShapeGizmoHandlers {
match self {
Self::Star(h) => h.handle_update(drag_start, document, input, responses),
Self::Polygon(h) => h.handle_update(drag_start, document, input, responses),
Self::Arc(h) => h.handle_update(drag_start, document, input, responses),
Self::None => {}
}
}
Expand All @@ -77,6 +84,7 @@ impl ShapeGizmoHandlers {
match self {
Self::Star(h) => h.cleanup(),
Self::Polygon(h) => h.cleanup(),
Self::Arc(h) => h.cleanup(),
Self::None => {}
}
}
Expand All @@ -94,6 +102,7 @@ impl ShapeGizmoHandlers {
match self {
Self::Star(h) => h.overlays(document, layer, input, shape_editor, mouse_position, overlay_context),
Self::Polygon(h) => h.overlays(document, layer, input, shape_editor, mouse_position, overlay_context),
Self::Arc(h) => h.overlays(document, layer, input, shape_editor, mouse_position, overlay_context),
Self::None => {}
}
}
Expand All @@ -110,6 +119,7 @@ impl ShapeGizmoHandlers {
match self {
Self::Star(h) => h.dragging_overlays(document, input, shape_editor, mouse_position, overlay_context),
Self::Polygon(h) => h.dragging_overlays(document, input, shape_editor, mouse_position, overlay_context),
Self::Arc(h) => h.dragging_overlays(document, input, shape_editor, mouse_position, overlay_context),
Self::None => {}
}
}
Expand Down Expand Up @@ -146,6 +156,9 @@ impl GizmoManager {
if graph_modification_utils::get_polygon_id(layer, &document.network_interface).is_some() {
return Some(ShapeGizmoHandlers::Polygon(PolygonGizmoHandler::default()));
}
if graph_modification_utils::get_arc_id(layer, &document.network_interface).is_some() {
return Some(ShapeGizmoHandlers::Arc(ArcGizmoHandler::new()));
}

None
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
pub mod number_of_points_dial;
pub mod point_radius_handle;
pub mod sweep_angle_gizmo;
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,6 @@ impl PointRadiusHandle {
};

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

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

let before_outer_position = viewport.inverse().transform_point2(before_outer_position);
let outer_position = viewport.inverse().transform_point2(outer_position);
let point_position = viewport.inverse().transform_point2(point_position);

let l1 = (before_outer_position - outer_position).length() * 0.2;
let Some(l1_direction) = (before_outer_position - outer_position).try_normalize() else { return };
let Some(l2_direction) = (point_position - outer_position).try_normalize() else { return };
let Some(direction) = (center - outer_position).try_normalize() else { return };
let Some(direction) = (-outer_position).try_normalize() else { return };

let new_point = SQRT_2 * l1 * direction + outer_position;

let before_outer_position = l1 * l1_direction + outer_position;
let point_position = l1 * l2_direction + outer_position;

overlay_context.line(before_outer_position, new_point, Some(COLOR_OVERLAY_RED), Some(3.));
overlay_context.line(new_point, point_position, Some(COLOR_OVERLAY_RED), Some(3.));
overlay_context.line(
viewport.transform_point2(before_outer_position),
viewport.transform_point2(new_point),
Some(COLOR_OVERLAY_RED),
Some(3.),
);
overlay_context.line(viewport.transform_point2(new_point), viewport.transform_point2(point_position), Some(COLOR_OVERLAY_RED), Some(3.));
}
1 => {
let before_outer_position = star_vertex_position(viewport, (self.point as i32) - 1, sides, radius1, radius2);

let after_point_position = star_vertex_position(viewport, (self.point as i32) + 1, sides, radius1, radius2);

let point_position = star_vertex_position(viewport, self.point as i32, sides, radius1, radius2);

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

let before_outer_position = viewport.inverse().transform_point2(before_outer_position);
let after_point_position = viewport.inverse().transform_point2(after_point_position);
let point_position = viewport.inverse().transform_point2(point_position);

let l1 = (before_outer_position - point_position).length() * 0.2;
let Some(l1_direction) = (before_outer_position - point_position).try_normalize() else { return };
let Some(l2_direction) = (after_point_position - point_position).try_normalize() else { return };
let Some(direction) = (center - point_position).try_normalize() else { return };
let Some(direction) = (-point_position).try_normalize() else { return };

let new_point = SQRT_2 * l1 * direction + point_position;

let before_outer_position = l1 * l1_direction + point_position;
let after_point_position = l1 * l2_direction + point_position;

overlay_context.line(before_outer_position, new_point, Some(COLOR_OVERLAY_RED), Some(3.));
overlay_context.line(new_point, after_point_position, Some(COLOR_OVERLAY_RED), Some(3.));
overlay_context.line(
viewport.transform_point2(before_outer_position),
viewport.transform_point2(new_point),
Some(COLOR_OVERLAY_RED),
Some(3.),
);
overlay_context.line(viewport.transform_point2(new_point), viewport.transform_point2(after_point_position), Some(COLOR_OVERLAY_RED), Some(3.));
}
i => {
// Use `self.point` as absolute reference as it matches the index of vertices of the star starting from 0
Expand Down
Loading
Loading