mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-19 19:08:05 +08:00
Implement viewport selection (#178)
* Begin implementing viewport selection * Implement viewport click and drag selection for ellipse and rectangle * Begin implementing line selection * Remove debug prints * Run cargo format * Use DVec2 instead of kurbo::Point * Line and polyline intersection * Run cargo format * Add fix for missing layer panel update * Replace point selection with box selection * Formatting Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
@@ -19,12 +19,16 @@ pub use shape::Shape;
|
||||
|
||||
pub mod folder;
|
||||
use crate::DocumentError;
|
||||
use crate::LayerId;
|
||||
pub use folder::Folder;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
pub const SELECTION_TOLERANCE: f64 = 5.0;
|
||||
|
||||
pub trait LayerData {
|
||||
fn render(&mut self, svg: &mut String, transform: glam::DAffine2, style: style::PathStyle);
|
||||
fn to_kurbo_path(&mut self, transform: glam::DAffine2, style: style::PathStyle) -> BezPath;
|
||||
fn to_kurbo_path(&self, transform: glam::DAffine2, style: style::PathStyle) -> BezPath;
|
||||
fn intersects_quad(&self, quad: [DVec2; 4], path: &mut Vec<LayerId>, intersections: &mut Vec<Vec<LayerId>>, style: style::PathStyle);
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
|
||||
@@ -51,6 +55,15 @@ macro_rules! call_kurbo_path {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! call_intersects_quad {
|
||||
($self:ident.intersects_quad($quad:ident, $path:ident, $intersections:ident, $style:ident) { $($variant:ident),* }) => {
|
||||
match $self {
|
||||
$(Self::$variant(x) => x.intersects_quad($quad, $path, $intersections, $style)),*
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl LayerDataTypes {
|
||||
pub fn render(&mut self, svg: &mut String, transform: glam::DAffine2, style: style::PathStyle) {
|
||||
call_render! {
|
||||
@@ -64,7 +77,7 @@ impl LayerDataTypes {
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn to_kurbo_path(&mut self, transform: glam::DAffine2, style: style::PathStyle) -> BezPath {
|
||||
pub fn to_kurbo_path(&self, transform: glam::DAffine2, style: style::PathStyle) -> BezPath {
|
||||
call_kurbo_path! {
|
||||
self.to_kurbo_path(transform, style) {
|
||||
Folder,
|
||||
@@ -76,6 +89,19 @@ impl LayerDataTypes {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn intersects_quad(&self, quad: [DVec2; 4], path: &mut Vec<LayerId>, intersections: &mut Vec<Vec<LayerId>>, style: style::PathStyle) {
|
||||
call_intersects_quad! {
|
||||
self.intersects_quad(quad, path, intersections, style) {
|
||||
Folder,
|
||||
Ellipse,
|
||||
Rect,
|
||||
Line,
|
||||
PolyLine,
|
||||
Shape
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
@@ -122,6 +148,20 @@ impl Layer {
|
||||
self.cache.as_str()
|
||||
}
|
||||
|
||||
pub fn intersects_quad(&self, quad: [DVec2; 4], path: &mut Vec<LayerId>, intersections: &mut Vec<Vec<LayerId>>) {
|
||||
let inv_transform = self.transform.inverse();
|
||||
let transformed_quad = [
|
||||
inv_transform.transform_point2(quad[0]),
|
||||
inv_transform.transform_point2(quad[1]),
|
||||
inv_transform.transform_point2(quad[2]),
|
||||
inv_transform.transform_point2(quad[3]),
|
||||
];
|
||||
if !self.visible {
|
||||
return;
|
||||
}
|
||||
self.data.intersects_quad(transformed_quad, path, intersections, self.style)
|
||||
}
|
||||
|
||||
pub fn render_on(&mut self, svg: &mut String) {
|
||||
*svg += self.render();
|
||||
}
|
||||
@@ -129,12 +169,14 @@ impl Layer {
|
||||
pub fn to_kurbo_path(&mut self) -> BezPath {
|
||||
self.data.to_kurbo_path(self.transform, self.style)
|
||||
}
|
||||
|
||||
pub fn as_folder_mut(&mut self) -> Result<&mut Folder, DocumentError> {
|
||||
match &mut self.data {
|
||||
LayerDataTypes::Folder(f) => Ok(f),
|
||||
_ => Err(DocumentError::NotAFolder),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_folder(&self) -> Result<&Folder, DocumentError> {
|
||||
match &self.data {
|
||||
LayerDataTypes::Folder(f) => Ok(&f),
|
||||
|
||||
Reference in New Issue
Block a user