Skip to content
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
2 changes: 2 additions & 0 deletions editor/src/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 = 10.;
pub const BLUE_LAYER_ORIGIN_CROSS_THICKNESS: f64 = 1.;

// PIVOT
pub const PIVOT_CROSSHAIR_THICKNESS: f64 = 1.;
Expand Down
19 changes: 19 additions & 0 deletions editor/src/messages/portfolio/document/document_message_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1261,6 +1261,7 @@ impl MessageHandler<DocumentMessage, DocumentMessageContext<'_>> 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,
Expand Down Expand Up @@ -2420,6 +2421,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()],
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -41,13 +44,15 @@ pub enum OverlaysType {
TransformCage,
HoverOutline,
SelectionOutline,
BlueLayerOriginCross,
Pivot,
Origin,
Path,
Anchors,
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 {
Expand All @@ -59,13 +64,15 @@ 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,
pub anchors: bool,
pub handles: bool,
}

// TODO Remove duplicated definition of this in `utility_types_web.rs`
impl Default for OverlaysVisibilitySettings {
fn default() -> Self {
Self {
Expand All @@ -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,
Expand All @@ -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
Expand Down Expand Up @@ -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
}
Expand Down Expand Up @@ -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<LayerNodeIdentifier, Vec<SegmentId>>),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ pub enum OverlaysType {
TransformCage,
HoverOutline,
SelectionOutline,
BlueLayerOriginCross,
Pivot,
Origin,
Path,
Expand All @@ -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,
Expand All @@ -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,
Expand Down Expand Up @@ -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
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
//! 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::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
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;
}

// 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);

// 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));
}
}
}
1 change: 1 addition & 0 deletions editor/src/messages/tool/common_functionality/mod.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down
3 changes: 3 additions & 0 deletions editor/src/messages/tool/tool_messages/select_tool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -608,6 +608,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;
Expand Down Expand Up @@ -729,6 +731,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;
Expand Down
6 changes: 6 additions & 0 deletions frontend/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
Loading