From 3b45fee4a234542bf8fc05d4244213170ec6802d Mon Sep 17 00:00:00 2001 From: hypercube <0hypercube@gmail.com> Date: Fri, 12 Dec 2025 21:58:19 +0000 Subject: [PATCH 1/4] Add blue layer origin cross overlay --- editor/src/consts.rs | 2 ++ .../document/document_message_handler.rs | 19 ++++++++++ .../document/overlays/utility_types_native.rs | 15 ++++++++ .../document/overlays/utility_types_web.rs | 7 ++++ .../blue_layer_origin_cross.rs | 36 +++++++++++++++++++ .../messages/tool/common_functionality/mod.rs | 1 + .../tool/tool_messages/select_tool.rs | 3 ++ frontend/index.html | 6 ++++ 8 files changed, 89 insertions(+) create mode 100644 editor/src/messages/tool/common_functionality/blue_layer_origin_cross.rs diff --git a/editor/src/consts.rs b/editor/src/consts.rs index f515ee07b3..f250d84ed3 100644 --- a/editor/src/consts.rs +++ b/editor/src/consts.rs @@ -56,6 +56,8 @@ pub const DEFAULT_STROKE_WIDTH: f64 = 2.; pub const SELECTION_TOLERANCE: f64 = 5.; pub const DRAG_DIRECTION_MODE_DETERMINATION_THRESHOLD: f64 = 15.; pub const SELECTION_DRAG_ANGLE: f64 = 90.; +pub const BLUE_LAYER_ORIGIN_CROSS_DIAMETER: f64 = 20.; +pub const BLUE_LAYER_ORIGIN_CROSS_THICKNESS: f64 = 4.; // PIVOT pub const PIVOT_CROSSHAIR_THICKNESS: f64 = 1.; diff --git a/editor/src/messages/portfolio/document/document_message_handler.rs b/editor/src/messages/portfolio/document/document_message_handler.rs index 0289db4b17..191823213b 100644 --- a/editor/src/messages/portfolio/document/document_message_handler.rs +++ b/editor/src/messages/portfolio/document/document_message_handler.rs @@ -1262,6 +1262,7 @@ impl MessageHandler> for DocumentMes OverlaysType::TransformCage => visibility_settings.transform_cage = visible, OverlaysType::HoverOutline => visibility_settings.hover_outline = visible, OverlaysType::SelectionOutline => visibility_settings.selection_outline = visible, + OverlaysType::BlueLayerOriginCross => visibility_settings.blue_layer_origin_cross = visible, OverlaysType::Pivot => visibility_settings.pivot = visible, OverlaysType::Origin => visibility_settings.origin = visible, OverlaysType::Path => visibility_settings.path = visible, @@ -2394,6 +2395,24 @@ impl DocumentMessageHandler { ] }, }, + LayoutGroup::Row { + widgets: { + let checkbox_id = CheckboxId::new(); + vec![ + CheckboxInput::new(self.overlays_visibility_settings.blue_layer_origin_cross) + .on_update(|optional_input: &CheckboxInput| { + DocumentMessage::SetOverlaysVisibility { + visible: optional_input.checked, + overlays_type: Some(OverlaysType::BlueLayerOriginCross), + } + .into() + }) + .for_label(checkbox_id) + .widget_instance(), + TextLabel::new("Blue Layer Origin Cross".to_string()).for_checkbox(checkbox_id).widget_instance(), + ] + }, + }, LayoutGroup::Row { widgets: vec![TextLabel::new("Pen & Path Tools").widget_instance()], }, diff --git a/editor/src/messages/portfolio/document/overlays/utility_types_native.rs b/editor/src/messages/portfolio/document/overlays/utility_types_native.rs index 1e86778fb9..5a3296fdf9 100644 --- a/editor/src/messages/portfolio/document/overlays/utility_types_native.rs +++ b/editor/src/messages/portfolio/document/overlays/utility_types_native.rs @@ -25,12 +25,15 @@ use std::sync::{Arc, Mutex, MutexGuard}; use vello::Scene; use vello::peniko; +// TODO Remove duplicated definition of this in `utility_types_web.rs` pub type OverlayProvider = fn(OverlayContext) -> Message; +// TODO Remove duplicated definition of this in `utility_types_web.rs` pub fn empty_provider() -> OverlayProvider { |_| Message::NoOp } +// TODO Remove duplicated definition of this in `utility_types_web.rs` /// Types of overlays used by DocumentMessage to enable/disable the selected set of viewport overlays. #[derive(PartialEq, Clone, Debug, serde::Serialize, serde::Deserialize, specta::Type)] pub enum OverlaysType { @@ -41,6 +44,7 @@ pub enum OverlaysType { TransformCage, HoverOutline, SelectionOutline, + BlueLayerOriginCross, Pivot, Origin, Path, @@ -48,6 +52,7 @@ pub enum OverlaysType { Handles, } +// TODO Remove duplicated definition of this in `utility_types_web.rs` #[derive(PartialEq, Copy, Clone, Debug, serde::Serialize, serde::Deserialize, specta::Type)] #[serde(default)] pub struct OverlaysVisibilitySettings { @@ -59,6 +64,7 @@ pub struct OverlaysVisibilitySettings { pub transform_cage: bool, pub hover_outline: bool, pub selection_outline: bool, + pub blue_layer_origin_cross: bool, pub pivot: bool, pub origin: bool, pub path: bool, @@ -66,6 +72,7 @@ pub struct OverlaysVisibilitySettings { pub handles: bool, } +// TODO Remove duplicated definition of this in `utility_types_web.rs` impl Default for OverlaysVisibilitySettings { fn default() -> Self { Self { @@ -77,6 +84,7 @@ impl Default for OverlaysVisibilitySettings { transform_cage: true, hover_outline: true, selection_outline: true, + blue_layer_origin_cross: true, pivot: true, origin: true, path: true, @@ -86,6 +94,7 @@ impl Default for OverlaysVisibilitySettings { } } +// TODO Remove duplicated definition of this in `utility_types_web.rs` impl OverlaysVisibilitySettings { pub fn all(&self) -> bool { self.all @@ -119,6 +128,10 @@ impl OverlaysVisibilitySettings { self.all && self.selection_outline } + pub fn blue_layer_origin_cross(&self) -> bool { + self.all && self.blue_layer_origin_cross + } + pub fn pivot(&self) -> bool { self.all && self.pivot } @@ -391,12 +404,14 @@ impl OverlayContext { } } +// TODO Remove duplicated definition of this in `utility_types_web.rs` pub enum Pivot { Start, Middle, End, } +// TODO Remove duplicated definition of this in `utility_types_web.rs` pub enum DrawHandles { All, SelectedAnchors(HashMap>), diff --git a/editor/src/messages/portfolio/document/overlays/utility_types_web.rs b/editor/src/messages/portfolio/document/overlays/utility_types_web.rs index 0800c65cfe..80f10349af 100644 --- a/editor/src/messages/portfolio/document/overlays/utility_types_web.rs +++ b/editor/src/messages/portfolio/document/overlays/utility_types_web.rs @@ -37,6 +37,7 @@ pub enum OverlaysType { TransformCage, HoverOutline, SelectionOutline, + BlueLayerOriginCross, Pivot, Origin, Path, @@ -55,6 +56,7 @@ pub struct OverlaysVisibilitySettings { pub transform_cage: bool, pub hover_outline: bool, pub selection_outline: bool, + pub blue_layer_origin_cross: bool, pub pivot: bool, pub origin: bool, pub path: bool, @@ -73,6 +75,7 @@ impl Default for OverlaysVisibilitySettings { transform_cage: true, hover_outline: true, selection_outline: true, + blue_layer_origin_cross: true, pivot: true, origin: true, path: true, @@ -115,6 +118,10 @@ impl OverlaysVisibilitySettings { self.all && self.selection_outline } + pub fn blue_layer_origin_cross(&self) -> bool { + self.all && self.blue_layer_origin_cross + } + pub fn pivot(&self) -> bool { self.all && self.pivot } diff --git a/editor/src/messages/tool/common_functionality/blue_layer_origin_cross.rs b/editor/src/messages/tool/common_functionality/blue_layer_origin_cross.rs new file mode 100644 index 0000000000..8273c6bdb0 --- /dev/null +++ b/editor/src/messages/tool/common_functionality/blue_layer_origin_cross.rs @@ -0,0 +1,36 @@ +//! Draws a blue cross overlay at the origin point of the layers in layer space. +//! +//! This cross is orientated based on the +X vector of the layer. + +use crate::consts::{BLUE_LAYER_ORIGIN_CROSS_DIAMETER, BLUE_LAYER_ORIGIN_CROSS_THICKNESS, COLOR_OVERLAY_BLUE}; +use crate::messages::portfolio::document::overlays::utility_types::OverlayContext; +use crate::messages::tool::tool_messages::tool_prelude::DocumentMessageHandler; +use glam::DVec2; + +pub fn draw_for_selected_layers(overlay_context: &mut OverlayContext, document: &DocumentMessageHandler) { + // Can be disabled + if !overlay_context.visibility_settings.blue_layer_origin_cross() { + return; + } + // Only show visible and unlocked and selected and layers + for layer in document.network_interface.selected_nodes().selected_visible_and_unlocked_layers(&document.network_interface) { + // Don't show artboards + if document.network_interface.is_artboard(&layer.to_node(), &[]) { + continue; + } + + // A transformation from the layer's local space to the viewport space (where overlays are drawn) + let transform_to_viewport = document.metadata().transform_to_viewport(layer); + + // The origin of the layer in viewport space which is the centre of the blue cross/ + let origin_viewport = transform_to_viewport.transform_point2(DVec2::ZERO); + // The forward +X direction vector from layer space (used to orientate the blue orogin cross) + let forward = transform_to_viewport.transform_vector2(DVec2::X).normalize_or_zero(); + + // Draw the cross + let offsets = [forward + forward.perp(), forward - forward.perp()].map(|offset| offset * core::f64::consts::FRAC_1_SQRT_2 * BLUE_LAYER_ORIGIN_CROSS_DIAMETER / 2.); + for offset in offsets { + overlay_context.line(origin_viewport - offset, origin_viewport + offset, Some(COLOR_OVERLAY_BLUE), Some(BLUE_LAYER_ORIGIN_CROSS_THICKNESS)); + } + } +} diff --git a/editor/src/messages/tool/common_functionality/mod.rs b/editor/src/messages/tool/common_functionality/mod.rs index ca3e629e19..4da1fe19be 100644 --- a/editor/src/messages/tool/common_functionality/mod.rs +++ b/editor/src/messages/tool/common_functionality/mod.rs @@ -1,4 +1,5 @@ pub mod auto_panning; +pub mod blue_layer_origin_cross; pub mod color_selector; pub mod compass_rose; pub mod gizmos; diff --git a/editor/src/messages/tool/tool_messages/select_tool.rs b/editor/src/messages/tool/tool_messages/select_tool.rs index 0b2a5c93b1..7046090577 100644 --- a/editor/src/messages/tool/tool_messages/select_tool.rs +++ b/editor/src/messages/tool/tool_messages/select_tool.rs @@ -610,6 +610,8 @@ impl Fsm for SelectToolFsmState { (_, SelectToolMessage::Overlays { context: mut overlay_context }) => { tool_data.snap_manager.draw_overlays(SnapData::new(document, input, viewport), &mut overlay_context); + crate::messages::tool::common_functionality::blue_layer_origin_cross::draw_for_selected_layers(&mut overlay_context, &document); + let selected_layers_count = document.network_interface.selected_nodes().selected_unlocked_layers(&document.network_interface).count(); tool_data.selected_layers_changed = selected_layers_count != tool_data.selected_layers_count; tool_data.selected_layers_count = selected_layers_count; @@ -731,6 +733,7 @@ impl Fsm for SelectToolFsmState { if let Some(bounds) = bounds { let bounding_box_manager = tool_data.bounding_box_manager.get_or_insert(BoundingBoxManager::default()); + // TODO: It is very bad to bounding box calculations only here as the user can disable overlays which breaks the bounding box based resizing. bounding_box_manager.bounds = bounds; bounding_box_manager.transform = transform; bounding_box_manager.transform_tampered = transform_tampered; diff --git a/frontend/index.html b/frontend/index.html index ccaf55e420..852f040ab2 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -44,6 +44,12 @@ border: 4px solid #eee; border-color: #eee transparent #eee transparent; animation: spinning-loading-indicator 1s linear infinite; + + @media (prefers-reduced-motion) { + animation: none; + content: "Loading…"; + border: none; + } } @keyframes spinning-loading-indicator { From 65a41858cf1503e840204ae4e31aa4f2811fa5ac Mon Sep 17 00:00:00 2001 From: Keavon Chambers Date: Sat, 13 Dec 2025 02:44:14 -0800 Subject: [PATCH 2/4] Apply suggestion from @Keavon --- editor/src/consts.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/editor/src/consts.rs b/editor/src/consts.rs index f250d84ed3..a1dc5e5ad4 100644 --- a/editor/src/consts.rs +++ b/editor/src/consts.rs @@ -56,8 +56,8 @@ pub const DEFAULT_STROKE_WIDTH: f64 = 2.; pub const SELECTION_TOLERANCE: f64 = 5.; pub const DRAG_DIRECTION_MODE_DETERMINATION_THRESHOLD: f64 = 15.; pub const SELECTION_DRAG_ANGLE: f64 = 90.; -pub const BLUE_LAYER_ORIGIN_CROSS_DIAMETER: f64 = 20.; -pub const BLUE_LAYER_ORIGIN_CROSS_THICKNESS: f64 = 4.; +pub const BLUE_LAYER_ORIGIN_CROSS_DIAMETER: f64 = 10.; +pub const BLUE_LAYER_ORIGIN_CROSS_THICKNESS: f64 = 1.; // PIVOT pub const PIVOT_CROSSHAIR_THICKNESS: f64 = 1.; From 4820c826baf6b206271c1e7b464f2814fcd9869b Mon Sep 17 00:00:00 2001 From: hypercube <0hypercube@gmail.com> Date: Sat, 13 Dec 2025 11:24:21 +0000 Subject: [PATCH 3/4] Skip layers without local transforms --- .../common_functionality/blue_layer_origin_cross.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/editor/src/messages/tool/common_functionality/blue_layer_origin_cross.rs b/editor/src/messages/tool/common_functionality/blue_layer_origin_cross.rs index 8273c6bdb0..7f015156b1 100644 --- a/editor/src/messages/tool/common_functionality/blue_layer_origin_cross.rs +++ b/editor/src/messages/tool/common_functionality/blue_layer_origin_cross.rs @@ -4,6 +4,7 @@ use crate::consts::{BLUE_LAYER_ORIGIN_CROSS_DIAMETER, BLUE_LAYER_ORIGIN_CROSS_THICKNESS, COLOR_OVERLAY_BLUE}; use crate::messages::portfolio::document::overlays::utility_types::OverlayContext; +use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier; use crate::messages::tool::tool_messages::tool_prelude::DocumentMessageHandler; use glam::DVec2; @@ -19,6 +20,16 @@ pub fn draw_for_selected_layers(overlay_context: &mut OverlayContext, document: continue; } + // Don't crash if we accidentally have the root. + if layer == LayerNodeIdentifier::ROOT_PARENT { + continue; + } + + // Some layers such as groups don't have a local transform. + if !document.metadata().local_transforms.contains_key(&layer.to_node()) { + continue; + } + // A transformation from the layer's local space to the viewport space (where overlays are drawn) let transform_to_viewport = document.metadata().transform_to_viewport(layer); From c53907a6a8769a7e5918301f13e7f0f1162cab9b Mon Sep 17 00:00:00 2001 From: Keavon Chambers Date: Wed, 14 Jan 2026 01:27:30 -0800 Subject: [PATCH 4/4] Disable the Custom Pivot by default --- editor/src/consts.rs | 4 +-- .../document/document_message_handler.rs | 8 ++--- .../document/overlays/utility_types_native.rs | 10 +++--- .../document/overlays/utility_types_web.rs | 10 +++--- ..._origin_cross.rs => layer_origin_cross.rs} | 31 +++++++++---------- .../messages/tool/common_functionality/mod.rs | 2 +- .../tool/common_functionality/pivot.rs | 16 +++++----- .../messages/tool/tool_messages/path_tool.rs | 10 +++--- .../tool/tool_messages/select_tool.rs | 20 ++++++------ .../transform_layer_message_handler.rs | 2 +- frontend/index.html | 6 ---- .../vector-types/src/subpath/lookup.rs | 4 +-- 12 files changed, 58 insertions(+), 65 deletions(-) rename editor/src/messages/tool/common_functionality/{blue_layer_origin_cross.rs => layer_origin_cross.rs} (62%) diff --git a/editor/src/consts.rs b/editor/src/consts.rs index a1dc5e5ad4..bfe61f48f3 100644 --- a/editor/src/consts.rs +++ b/editor/src/consts.rs @@ -56,8 +56,8 @@ pub const DEFAULT_STROKE_WIDTH: f64 = 2.; pub const SELECTION_TOLERANCE: f64 = 5.; pub const DRAG_DIRECTION_MODE_DETERMINATION_THRESHOLD: f64 = 15.; pub const SELECTION_DRAG_ANGLE: f64 = 90.; -pub const BLUE_LAYER_ORIGIN_CROSS_DIAMETER: f64 = 10.; -pub const BLUE_LAYER_ORIGIN_CROSS_THICKNESS: f64 = 1.; +pub const LAYER_ORIGIN_CROSS_DIAMETER: f64 = 10.; +pub const LAYER_ORIGIN_CROSS_THICKNESS: f64 = 1.; // PIVOT pub const PIVOT_CROSSHAIR_THICKNESS: f64 = 1.; diff --git a/editor/src/messages/portfolio/document/document_message_handler.rs b/editor/src/messages/portfolio/document/document_message_handler.rs index 191823213b..180910bac5 100644 --- a/editor/src/messages/portfolio/document/document_message_handler.rs +++ b/editor/src/messages/portfolio/document/document_message_handler.rs @@ -1262,7 +1262,7 @@ impl MessageHandler> for DocumentMes OverlaysType::TransformCage => visibility_settings.transform_cage = visible, OverlaysType::HoverOutline => visibility_settings.hover_outline = visible, OverlaysType::SelectionOutline => visibility_settings.selection_outline = visible, - OverlaysType::BlueLayerOriginCross => visibility_settings.blue_layer_origin_cross = visible, + OverlaysType::LayerOriginCross => visibility_settings.layer_origin_cross = visible, OverlaysType::Pivot => visibility_settings.pivot = visible, OverlaysType::Origin => visibility_settings.origin = visible, OverlaysType::Path => visibility_settings.path = visible, @@ -2399,17 +2399,17 @@ impl DocumentMessageHandler { widgets: { let checkbox_id = CheckboxId::new(); vec![ - CheckboxInput::new(self.overlays_visibility_settings.blue_layer_origin_cross) + CheckboxInput::new(self.overlays_visibility_settings.layer_origin_cross) .on_update(|optional_input: &CheckboxInput| { DocumentMessage::SetOverlaysVisibility { visible: optional_input.checked, - overlays_type: Some(OverlaysType::BlueLayerOriginCross), + overlays_type: Some(OverlaysType::LayerOriginCross), } .into() }) .for_label(checkbox_id) .widget_instance(), - TextLabel::new("Blue Layer Origin Cross".to_string()).for_checkbox(checkbox_id).widget_instance(), + TextLabel::new("Layer Origin".to_string()).for_checkbox(checkbox_id).widget_instance(), ] }, }, diff --git a/editor/src/messages/portfolio/document/overlays/utility_types_native.rs b/editor/src/messages/portfolio/document/overlays/utility_types_native.rs index 5a3296fdf9..d23f077592 100644 --- a/editor/src/messages/portfolio/document/overlays/utility_types_native.rs +++ b/editor/src/messages/portfolio/document/overlays/utility_types_native.rs @@ -44,7 +44,7 @@ pub enum OverlaysType { TransformCage, HoverOutline, SelectionOutline, - BlueLayerOriginCross, + LayerOriginCross, Pivot, Origin, Path, @@ -64,7 +64,7 @@ pub struct OverlaysVisibilitySettings { pub transform_cage: bool, pub hover_outline: bool, pub selection_outline: bool, - pub blue_layer_origin_cross: bool, + pub layer_origin_cross: bool, pub pivot: bool, pub origin: bool, pub path: bool, @@ -84,7 +84,7 @@ impl Default for OverlaysVisibilitySettings { transform_cage: true, hover_outline: true, selection_outline: true, - blue_layer_origin_cross: true, + layer_origin_cross: true, pivot: true, origin: true, path: true, @@ -128,8 +128,8 @@ impl OverlaysVisibilitySettings { self.all && self.selection_outline } - pub fn blue_layer_origin_cross(&self) -> bool { - self.all && self.blue_layer_origin_cross + pub fn layer_origin_cross(&self) -> bool { + self.all && self.layer_origin_cross } pub fn pivot(&self) -> bool { diff --git a/editor/src/messages/portfolio/document/overlays/utility_types_web.rs b/editor/src/messages/portfolio/document/overlays/utility_types_web.rs index 80f10349af..f3545a901e 100644 --- a/editor/src/messages/portfolio/document/overlays/utility_types_web.rs +++ b/editor/src/messages/portfolio/document/overlays/utility_types_web.rs @@ -37,7 +37,7 @@ pub enum OverlaysType { TransformCage, HoverOutline, SelectionOutline, - BlueLayerOriginCross, + LayerOriginCross, Pivot, Origin, Path, @@ -56,7 +56,7 @@ pub struct OverlaysVisibilitySettings { pub transform_cage: bool, pub hover_outline: bool, pub selection_outline: bool, - pub blue_layer_origin_cross: bool, + pub layer_origin_cross: bool, pub pivot: bool, pub origin: bool, pub path: bool, @@ -75,7 +75,7 @@ impl Default for OverlaysVisibilitySettings { transform_cage: true, hover_outline: true, selection_outline: true, - blue_layer_origin_cross: true, + layer_origin_cross: true, pivot: true, origin: true, path: true, @@ -118,8 +118,8 @@ impl OverlaysVisibilitySettings { self.all && self.selection_outline } - pub fn blue_layer_origin_cross(&self) -> bool { - self.all && self.blue_layer_origin_cross + pub fn layer_origin_cross(&self) -> bool { + self.all && self.layer_origin_cross } pub fn pivot(&self) -> bool { diff --git a/editor/src/messages/tool/common_functionality/blue_layer_origin_cross.rs b/editor/src/messages/tool/common_functionality/layer_origin_cross.rs similarity index 62% rename from editor/src/messages/tool/common_functionality/blue_layer_origin_cross.rs rename to editor/src/messages/tool/common_functionality/layer_origin_cross.rs index 7f015156b1..51ed8d6687 100644 --- a/editor/src/messages/tool/common_functionality/blue_layer_origin_cross.rs +++ b/editor/src/messages/tool/common_functionality/layer_origin_cross.rs @@ -1,31 +1,30 @@ -//! Draws a blue cross overlay at the origin point of the layers in layer space. -//! -//! This cross is orientated based on the +X vector of the layer. - -use crate::consts::{BLUE_LAYER_ORIGIN_CROSS_DIAMETER, BLUE_LAYER_ORIGIN_CROSS_THICKNESS, COLOR_OVERLAY_BLUE}; +use crate::consts::{COLOR_OVERLAY_BLUE, LAYER_ORIGIN_CROSS_DIAMETER, LAYER_ORIGIN_CROSS_THICKNESS}; use crate::messages::portfolio::document::overlays::utility_types::OverlayContext; use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier; use crate::messages::tool::tool_messages::tool_prelude::DocumentMessageHandler; use glam::DVec2; +/// Draws a cross overlay at the origin point of the layers in layer space. +/// This cross is orientated based on the +X vector of the layer. pub fn draw_for_selected_layers(overlay_context: &mut OverlayContext, document: &DocumentMessageHandler) { - // Can be disabled - if !overlay_context.visibility_settings.blue_layer_origin_cross() { + // Don't draw if it is a disabled overlay + if !overlay_context.visibility_settings.layer_origin_cross() { return; } - // Only show visible and unlocked and selected and layers + + // Only show for layers that are visible, unlocked, and selected for layer in document.network_interface.selected_nodes().selected_visible_and_unlocked_layers(&document.network_interface) { - // Don't show artboards + // Don't show for artboards if document.network_interface.is_artboard(&layer.to_node(), &[]) { continue; } - // Don't crash if we accidentally have the root. + // Don't crash if we accidentally have the root if layer == LayerNodeIdentifier::ROOT_PARENT { continue; } - // Some layers such as groups don't have a local transform. + // Some layers such as groups don't have a local transform (although we'll likely design a fix for that fact later) if !document.metadata().local_transforms.contains_key(&layer.to_node()) { continue; } @@ -33,15 +32,15 @@ pub fn draw_for_selected_layers(overlay_context: &mut OverlayContext, document: // A transformation from the layer's local space to the viewport space (where overlays are drawn) let transform_to_viewport = document.metadata().transform_to_viewport(layer); - // The origin of the layer in viewport space which is the centre of the blue cross/ + // The origin of the layer in viewport space which is the center of the origin cross let origin_viewport = transform_to_viewport.transform_point2(DVec2::ZERO); - // The forward +X direction vector from layer space (used to orientate the blue orogin cross) + // The forward +X direction vector from layer space (used to orient the origin cross) let forward = transform_to_viewport.transform_vector2(DVec2::X).normalize_or_zero(); - // Draw the cross - let offsets = [forward + forward.perp(), forward - forward.perp()].map(|offset| offset * core::f64::consts::FRAC_1_SQRT_2 * BLUE_LAYER_ORIGIN_CROSS_DIAMETER / 2.); + // Draw the origin cross + let offsets = [forward + forward.perp(), forward - forward.perp()].map(|offset| offset * core::f64::consts::FRAC_1_SQRT_2 * LAYER_ORIGIN_CROSS_DIAMETER / 2.); for offset in offsets { - overlay_context.line(origin_viewport - offset, origin_viewport + offset, Some(COLOR_OVERLAY_BLUE), Some(BLUE_LAYER_ORIGIN_CROSS_THICKNESS)); + overlay_context.line(origin_viewport - offset, origin_viewport + offset, Some(COLOR_OVERLAY_BLUE), Some(LAYER_ORIGIN_CROSS_THICKNESS)); } } } diff --git a/editor/src/messages/tool/common_functionality/mod.rs b/editor/src/messages/tool/common_functionality/mod.rs index 4da1fe19be..acd0df472a 100644 --- a/editor/src/messages/tool/common_functionality/mod.rs +++ b/editor/src/messages/tool/common_functionality/mod.rs @@ -1,9 +1,9 @@ pub mod auto_panning; -pub mod blue_layer_origin_cross; pub mod color_selector; pub mod compass_rose; pub mod gizmos; pub mod graph_modification_utils; +pub mod layer_origin_cross; pub mod measure; pub mod pivot; pub mod resize; diff --git a/editor/src/messages/tool/common_functionality/pivot.rs b/editor/src/messages/tool/common_functionality/pivot.rs index 20013bf678..343c5d88a3 100644 --- a/editor/src/messages/tool/common_functionality/pivot.rs +++ b/editor/src/messages/tool/common_functionality/pivot.rs @@ -63,7 +63,7 @@ pub fn pivot_gizmo_type_widget(state: PivotGizmoState, source: PivotToolSource) .collect(); vec![ - CheckboxInput::new(!state.disabled) + CheckboxInput::new(state.enabled) .tooltip_label("Pivot Gizmo") .tooltip_description( " @@ -74,11 +74,11 @@ pub fn pivot_gizmo_type_widget(state: PivotGizmoState, source: PivotToolSource) ) .on_update(move |optional_input: &CheckboxInput| match source { PivotToolSource::Select => SelectToolMessage::SelectOptions { - options: SelectOptionsUpdate::TogglePivotGizmoType(optional_input.checked), + options: SelectOptionsUpdate::SetPivotGizmoEnabled(optional_input.checked), } .into(), PivotToolSource::Path => PathToolMessage::UpdateOptions { - options: PathOptionsUpdate::TogglePivotGizmoType(optional_input.checked), + options: PathOptionsUpdate::SetPivotGizmoEnabled(optional_input.checked), } .into(), }) @@ -101,7 +101,7 @@ pub fn pivot_gizmo_type_widget(state: PivotGizmoState, source: PivotToolSource) " .trim(), ) - .disabled(state.disabled) + .disabled(!state.enabled) .widget_instance(), ] } @@ -124,7 +124,7 @@ pub struct PivotGizmo { impl PivotGizmo { pub fn position(&self, document: &DocumentMessageHandler) -> DVec2 { let network = &document.network_interface; - (!self.state.disabled) + (self.state.enabled) .then_some({ match self.state.gizmo_type { PivotGizmoType::Average => Some(network.selected_nodes().selected_visible_and_unlocked_layers_mean_average_origin(network)), @@ -163,18 +163,18 @@ pub enum PivotGizmoType { #[derive(PartialEq, Eq, Clone, Copy, Default, Debug, Hash, serde::Serialize, serde::Deserialize, specta::Type)] pub struct PivotGizmoState { - pub disabled: bool, + pub enabled: bool, pub gizmo_type: PivotGizmoType, } impl PivotGizmoState { pub fn is_pivot_type(&self) -> bool { // A disabled pivot is considered a pivot-type gizmo that is always centered - self.gizmo_type == PivotGizmoType::Pivot || self.disabled + self.gizmo_type == PivotGizmoType::Pivot || !self.enabled } pub fn is_pivot(&self) -> bool { - self.gizmo_type == PivotGizmoType::Pivot && !self.disabled + self.gizmo_type == PivotGizmoType::Pivot && self.enabled } } diff --git a/editor/src/messages/tool/tool_messages/path_tool.rs b/editor/src/messages/tool/tool_messages/path_tool.rs index 89fabdd117..542a6f0a8c 100644 --- a/editor/src/messages/tool/tool_messages/path_tool.rs +++ b/editor/src/messages/tool/tool_messages/path_tool.rs @@ -183,7 +183,7 @@ pub enum PathOptionsUpdate { PointEditingMode { enabled: bool }, SegmentEditingMode { enabled: bool }, PivotGizmoType(PivotGizmoType), - TogglePivotGizmoType(bool), + SetPivotGizmoEnabled(bool), TogglePivotPinned, } @@ -397,7 +397,7 @@ impl<'a> MessageHandler> for Path responses.add(OverlaysMessage::Draw); } PathOptionsUpdate::PivotGizmoType(gizmo_type) => { - if !self.tool_data.pivot_gizmo.state.disabled { + if !self.tool_data.pivot_gizmo.state.enabled { self.tool_data.pivot_gizmo.state.gizmo_type = gizmo_type; responses.add(ToolMessage::UpdateHints); let pivot_gizmo = self.tool_data.pivot_gizmo(); @@ -406,8 +406,8 @@ impl<'a> MessageHandler> for Path self.send_layout(responses, LayoutTarget::ToolOptions); } } - PathOptionsUpdate::TogglePivotGizmoType(state) => { - self.tool_data.pivot_gizmo.state.disabled = !state; + PathOptionsUpdate::SetPivotGizmoEnabled(enabled) => { + self.tool_data.pivot_gizmo.state.enabled = enabled; responses.add(ToolMessage::UpdateHints); responses.add(NodeGraphMessage::RunDocumentGraph); self.send_layout(responses, LayoutTarget::ToolOptions); @@ -1571,7 +1571,7 @@ impl Fsm for PathToolFsmState { let ToolMessage::Path(event) = event else { return self }; // TODO(mTvare6): Remove once gizmos are implemented for path_tool - tool_data.pivot_gizmo.state.disabled = true; + tool_data.pivot_gizmo.state.enabled = false; match (self, event) { (_, PathToolMessage::SelectionChanged) => { diff --git a/editor/src/messages/tool/tool_messages/select_tool.rs b/editor/src/messages/tool/tool_messages/select_tool.rs index 7046090577..e5738e7770 100644 --- a/editor/src/messages/tool/tool_messages/select_tool.rs +++ b/editor/src/messages/tool/tool_messages/select_tool.rs @@ -46,7 +46,7 @@ pub struct SelectOptions { pub enum SelectOptionsUpdate { NestedSelectionBehavior(NestedSelectionBehavior), PivotGizmoType(PivotGizmoType), - TogglePivotGizmoType(bool), + SetPivotGizmoEnabled(bool), TogglePivotPinned, } @@ -240,7 +240,7 @@ impl LayoutHolder for SelectTool { widgets.push(Separator::new(SeparatorStyle::Related).widget_instance()); let pin_active = self.tool_data.pivot_gizmo.pin_active(); - let pin_enabled = self.tool_data.pivot_gizmo.pivot.old_pivot_position == ReferencePoint::None && !self.tool_data.pivot_gizmo.state.disabled; + let pin_enabled = self.tool_data.pivot_gizmo.pivot.old_pivot_position == ReferencePoint::None && self.tool_data.pivot_gizmo.state.enabled; if pin_active || pin_enabled { widgets.push(pin_pivot_widget(pin_active, pin_enabled, PivotToolSource::Select)); @@ -275,14 +275,14 @@ impl<'a> MessageHandler> for Sele let mut redraw_reference_pivot = false; if let ToolMessage::Select(SelectToolMessage::SelectOptions { options: ref option_update }) = message { - match option_update { + match *option_update { SelectOptionsUpdate::NestedSelectionBehavior(nested_selection_behavior) => { - self.tool_data.nested_selection_behavior = *nested_selection_behavior; + self.tool_data.nested_selection_behavior = nested_selection_behavior; responses.add(ToolMessage::UpdateHints); } SelectOptionsUpdate::PivotGizmoType(gizmo_type) => { - if !self.tool_data.pivot_gizmo.state.disabled { - self.tool_data.pivot_gizmo.state.gizmo_type = *gizmo_type; + if !self.tool_data.pivot_gizmo.state.enabled { + self.tool_data.pivot_gizmo.state.gizmo_type = gizmo_type; responses.add(ToolMessage::UpdateHints); let pivot_gizmo = self.tool_data.pivot_gizmo(); responses.add(TransformLayerMessage::SetPivotGizmo { pivot_gizmo }); @@ -290,8 +290,8 @@ impl<'a> MessageHandler> for Sele redraw_reference_pivot = true; } } - SelectOptionsUpdate::TogglePivotGizmoType(state) => { - self.tool_data.pivot_gizmo.state.disabled = !state; + SelectOptionsUpdate::SetPivotGizmoEnabled(enabled) => { + self.tool_data.pivot_gizmo.state.enabled = enabled; responses.add(ToolMessage::UpdateHints); responses.add(NodeGraphMessage::RunDocumentGraph); redraw_reference_pivot = true; @@ -610,7 +610,7 @@ impl Fsm for SelectToolFsmState { (_, SelectToolMessage::Overlays { context: mut overlay_context }) => { tool_data.snap_manager.draw_overlays(SnapData::new(document, input, viewport), &mut overlay_context); - crate::messages::tool::common_functionality::blue_layer_origin_cross::draw_for_selected_layers(&mut overlay_context, &document); + crate::messages::tool::common_functionality::layer_origin_cross::draw_for_selected_layers(&mut overlay_context, document); let selected_layers_count = document.network_interface.selected_nodes().selected_unlocked_layers(&document.network_interface).count(); tool_data.selected_layers_changed = selected_layers_count != tool_data.selected_layers_count; @@ -733,7 +733,7 @@ impl Fsm for SelectToolFsmState { if let Some(bounds) = bounds { let bounding_box_manager = tool_data.bounding_box_manager.get_or_insert(BoundingBoxManager::default()); - // TODO: It is very bad to bounding box calculations only here as the user can disable overlays which breaks the bounding box based resizing. + // TODO: Don't perform bounding box calculations here because the user can disable overlays which breaks bbox-based resizing bounding_box_manager.bounds = bounds; bounding_box_manager.transform = transform; bounding_box_manager.transform_tampered = transform_tampered; diff --git a/editor/src/messages/tool/transform_layer/transform_layer_message_handler.rs b/editor/src/messages/tool/transform_layer/transform_layer_message_handler.rs index cf872a9460..5c784b556e 100644 --- a/editor/src/messages/tool/transform_layer/transform_layer_message_handler.rs +++ b/editor/src/messages/tool/transform_layer/transform_layer_message_handler.rs @@ -686,7 +686,7 @@ fn calculate_pivot( }); gizmo.pivot.recalculate_pivot_for_layer(document, bounds); let position = || { - (if !gizmo.state.disabled { + (if gizmo.state.enabled { match gizmo.state.gizmo_type { PivotGizmoType::Average => None, PivotGizmoType::Active => gizmo.point.and_then(|p| get_location(&p)), diff --git a/frontend/index.html b/frontend/index.html index 852f040ab2..ccaf55e420 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -44,12 +44,6 @@ border: 4px solid #eee; border-color: #eee transparent #eee transparent; animation: spinning-loading-indicator 1s linear infinite; - - @media (prefers-reduced-motion) { - animation: none; - content: "Loading…"; - border: none; - } } @keyframes spinning-loading-indicator { diff --git a/node-graph/libraries/vector-types/src/subpath/lookup.rs b/node-graph/libraries/vector-types/src/subpath/lookup.rs index 7b48c23c63..64a400868c 100644 --- a/node-graph/libraries/vector-types/src/subpath/lookup.rs +++ b/node-graph/libraries/vector-types/src/subpath/lookup.rs @@ -121,8 +121,8 @@ mod test_centroid { #[test] fn centroid_rect() { let rect = Subpath::::new_rectangle(DVec2::new(100., 100.), DVec2::new(300., 200.)); - let (centre, area) = rect.area_centroid_and_area(Some(1e-3), Some(1e-3)).unwrap(); + let (center, area) = rect.area_centroid_and_area(Some(1e-3), Some(1e-3)).unwrap(); assert_eq!(area, 200. * 100.); - assert_eq!(centre, DVec2::new(200., 150.)) + assert_eq!(center, DVec2::new(200., 150.)) } }