Skip to content

Commit ddcc238

Browse files
committed
WIP conversion to messages
1 parent 28fb9aa commit ddcc238

File tree

2 files changed

+54
-34
lines changed

2 files changed

+54
-34
lines changed

editor/src/tool/snapping.rs

Lines changed: 49 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
use std::f64::consts::PI;
1+
use std::{collections::HashMap, f64::consts::PI};
22

3+
use super::DocumentMessageHandler;
34
use glam::{DAffine2, DVec2};
45
use graphene::{
56
layers::style::{self, Stroke},
@@ -11,41 +12,40 @@ use crate::{
1112
message_prelude::*,
1213
};
1314

14-
use super::DocumentMessageHandler;
15-
1615
#[derive(Debug, Clone, Default)]
1716
pub struct SnapHandler {
17+
enabled: bool,
18+
document: DocumentMessageHandler,
1819
snap_targets: Option<(Vec<f64>, Vec<f64>)>,
20+
snappables: HashMap<Vec<LayerId>, Vec<Vec<LayerId>>>,
21+
overlay_messages: Vec<Message>,
22+
1923
overlay_paths: Vec<Vec<LayerId>>,
2024
}
2125

2226
impl SnapHandler {
23-
fn add_overlays(&mut self, responses: &mut VecDeque<Message>, viewport_bounds: DVec2) {
24-
fn add_overlay_line(responses: &mut VecDeque<Message>, transform: DAffine2) -> Vec<LayerId> {
25-
let layer_path = vec![generate_uuid()];
26-
27-
let operation = Operation::AddOverlayLine {
28-
path: layer_path.clone(),
29-
transform: transform.to_cols_array(),
30-
style: style::PathStyle::new(Some(Stroke::new(COLOR_ACCENT, 1.0)), None),
31-
};
32-
responses.push_back(DocumentMessage::Overlay(operation.into()).into());
33-
34-
layer_path
35-
}
27+
fn add_overlay_line(&mut self, transform: DAffine2) -> Vec<LayerId> {
28+
let layer_path = vec![generate_uuid()];
29+
30+
let operation = Operation::AddOverlayLine {
31+
path: layer_path.clone(),
32+
transform: transform.to_cols_array(),
33+
style: style::PathStyle::new(Some(Stroke::new(COLOR_ACCENT, 1.0)), None),
34+
};
35+
self.overlay_messages.push(DocumentMessage::Overlay(operation.into()).into());
36+
37+
layer_path
38+
}
3639

40+
fn add_overlays(&mut self, viewport_bounds: DVec2) {
3741
if let Some((x_targets, y_targets)) = &self.snap_targets {
3842
for x_target in x_targets {
39-
self.overlay_paths.push(add_overlay_line(
40-
responses,
41-
DAffine2::from_scale_angle_translation(DVec2::new(viewport_bounds.y, 1.), PI / 2., DVec2::new(x_target.round(), 0.)),
42-
));
43+
self.overlay_paths
44+
.push(self.add_overlay_line(DAffine2::from_scale_angle_translation(DVec2::new(viewport_bounds.y, 1.), PI / 2., DVec2::new(x_target.round(), 0.))));
4345
}
4446
for y_target in y_targets {
45-
self.overlay_paths.push(add_overlay_line(
46-
responses,
47-
DAffine2::from_scale_angle_translation(DVec2::new(viewport_bounds.x, 1.), 0., DVec2::new(0., y_target.round())),
48-
));
47+
self.overlay_paths
48+
.push(self.add_overlay_line(DAffine2::from_scale_angle_translation(DVec2::new(viewport_bounds.x, 1.), 0., DVec2::new(0., y_target.round()))));
4949
}
5050
}
5151
}
@@ -58,29 +58,30 @@ impl SnapHandler {
5858

5959
/// Gets a list of snap targets for the X and Y axes in Viewport coords for the target layers (usually all layers or all non-selected layers.)
6060
/// This should be called at the start of a drag.
61-
pub fn start_snap(&mut self, responses: &mut VecDeque<Message>, viewport_bounds: DVec2, document_message_handler: &DocumentMessageHandler, target_layers: Vec<Vec<LayerId>>) {
62-
if document_message_handler.snapping_enabled {
61+
pub fn start_snap(&mut self, viewport_bounds: DVec2, target_layers: Vec<Vec<LayerId>>) {
62+
if self.document.snapping_enabled {
6363
// Could be made into sorted Vec or a HashSet for more performant lookups.
6464
self.snap_targets = Some(
6565
target_layers
6666
.iter()
67-
.filter_map(|path| document_message_handler.graphene_document.viewport_bounding_box(path).ok()?)
67+
.filter_map(|path| self.document.graphene_document.viewport_bounding_box(path).ok()?)
6868
.flat_map(|[bound1, bound2]| [bound1, bound2, ((bound1 + bound2) / 2.)])
6969
.map(|vec| vec.into())
7070
.unzip(),
7171
);
72-
self.add_overlays(responses, viewport_bounds);
72+
self.add_overlays(viewport_bounds);
7373
}
7474
}
7575

7676
/// Finds the closest snap from an array of layers to the specified snap targets in viewport coords.
7777
/// Returns 0 for each axis that there is no snap less than the snap tolerance.
78-
pub fn snap_layers(&self, document_message_handler: &DocumentMessageHandler, selected_layers: &[Vec<LayerId>], mouse_delta: DVec2) -> DVec2 {
79-
if document_message_handler.snapping_enabled {
78+
pub fn snap_layers(&self, mouse_delta: DVec2) -> DVec2 {
79+
if self.enabled {
8080
if let Some((targets_x, targets_y)) = &self.snap_targets {
81-
let (snap_x, snap_y): (Vec<f64>, Vec<f64>) = selected_layers
81+
let (snap_x, snap_y): (Vec<f64>, Vec<f64>) = self
82+
.snappables
8283
.iter()
83-
.filter_map(|path| document_message_handler.graphene_document.viewport_bounding_box(path).ok()?)
84+
.filter_map(|(path, _)| self.document.graphene_document.viewport_bounding_box(path).ok()?)
8485
.flat_map(|[bound1, bound2]| [bound1, bound2, (bound1 + bound2) / 2.])
8586
.map(|vec| vec.into())
8687
.unzip();
@@ -112,8 +113,8 @@ impl SnapHandler {
112113
}
113114

114115
/// Handles snapping of a viewport position, returning another viewport position.
115-
pub fn snap_position(&self, document_message_handler: &DocumentMessageHandler, position_viewport: DVec2) -> DVec2 {
116-
if document_message_handler.snapping_enabled {
116+
pub fn snap_position(&self, position_viewport: DVec2) -> DVec2 {
117+
if self.document.snapping_enabled {
117118
if let Some((targets_x, targets_y)) = &self.snap_targets {
118119
// For each list of snap targets, find the shortest distance to move the point to that target.
119120
let closest_move = DVec2::new(
@@ -148,4 +149,18 @@ impl SnapHandler {
148149
self.remove_overlays(responses);
149150
self.snap_targets = None;
150151
}
152+
153+
// ---
154+
pub fn add_snappable(&mut self, layer: Vec<LayerId>) {
155+
self.snappables.insert(layer, vec![]);
156+
}
157+
158+
pub fn remove_snappable(&mut self, layer: Vec<LayerId>) {
159+
self.snappables.remove(&layer);
160+
}
161+
162+
pub fn process_overlays(&mut self, responses: &mut VecDeque<Message>) {
163+
responses.extend(self.overlay_messages.into_iter());
164+
self.overlay_messages.clear();
165+
}
151166
}

editor/src/tool/tool_message_handler.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::message_prelude::*;
2+
use glam::DVec2;
23
use graphene::color::Color;
34

45
use crate::input::InputPreprocessor;
@@ -21,6 +22,10 @@ pub enum ToolMessage {
2122
DocumentIsDirty,
2223
UpdateHints,
2324
SetToolOptions(ToolType, ToolOptions),
25+
SetSnapping(bool),
26+
AddSnappable(Vec<LayerId>),
27+
RemoveSnappable(Vec<LayerId>),
28+
SnapLayer(Vec<LayerId>),
2429
#[child]
2530
Fill(FillMessage),
2631
#[child]

0 commit comments

Comments
 (0)