mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-19 02:48:12 +08:00
Store click targets in Arc (#3726)
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
|
||||
use super::utility_types::misc::{GroupFolderType, SnappingState};
|
||||
use crate::messages::input_mapper::utility_types::input_keyboard::Key;
|
||||
@@ -203,7 +204,7 @@ pub enum DocumentMessage {
|
||||
first_element_source_id: HashMap<NodeId, Option<NodeId>>,
|
||||
},
|
||||
UpdateClickTargets {
|
||||
click_targets: HashMap<NodeId, Vec<ClickTarget>>,
|
||||
click_targets: HashMap<NodeId, Vec<Arc<ClickTarget>>>,
|
||||
},
|
||||
UpdateClipTargets {
|
||||
clip_targets: HashSet<NodeId>,
|
||||
|
||||
@@ -42,6 +42,7 @@ use graphene_std::vector::misc::{dvec2_to_point, point_to_dvec2};
|
||||
use graphene_std::vector::style::RenderMode;
|
||||
use kurbo::{Affine, CubicBez, Line, ParamCurve, PathSeg, QuadBez};
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
||||
#[derive(ExtractField)]
|
||||
@@ -3071,7 +3072,14 @@ impl<'a> ClickXRayIter<'a> {
|
||||
}
|
||||
|
||||
/// Handles the checking of the layer where the target is a rect or path
|
||||
fn check_layer_area_target(&mut self, click_targets: Option<&Vec<ClickTarget>>, clip: bool, layer: LayerNodeIdentifier, path: Vec<path_bool_lib::PathSegment>, transform: DAffine2) -> XRayResult {
|
||||
fn check_layer_area_target(
|
||||
&mut self,
|
||||
click_targets: Option<&[Arc<ClickTarget>]>,
|
||||
clip: bool,
|
||||
layer: LayerNodeIdentifier,
|
||||
path: Vec<path_bool_lib::PathSegment>,
|
||||
transform: DAffine2,
|
||||
) -> XRayResult {
|
||||
// Convert back to Kurbo types for intersections
|
||||
let segment = |bezier: &path_bool_lib::PathSegment| match *bezier {
|
||||
path_bool_lib::PathSegment::Line(start, end) => PathSeg::Line(Line::new(dvec2_to_point(start), dvec2_to_point(end))),
|
||||
@@ -3088,7 +3096,7 @@ impl<'a> ClickXRayIter<'a> {
|
||||
// In the case of a clip path where the area partially intersects, it is necessary to do a boolean operation.
|
||||
// We do this on this using the target area to reduce computation (as the target area is usually very simple).
|
||||
if clip && intersects {
|
||||
let clip_path = click_targets_to_path_lib_segments(click_targets.iter().flat_map(|x| x.iter()), transform);
|
||||
let clip_path = click_targets_to_path_lib_segments(click_targets.iter().flat_map(|x| x.iter()).map(|x| x.as_ref()), transform);
|
||||
let subtracted = boolean_intersect(path, clip_path).into_iter().flatten().collect::<Vec<_>>();
|
||||
if subtracted.is_empty() {
|
||||
use_children = false;
|
||||
|
||||
@@ -13,6 +13,7 @@ use graphene_std::vector::click_target::{ClickTarget, ClickTargetType};
|
||||
use graphene_std::vector::{PointId, Vector};
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::num::NonZeroU64;
|
||||
use std::sync::Arc;
|
||||
|
||||
// ================
|
||||
// DocumentMetadata
|
||||
@@ -26,7 +27,7 @@ pub struct DocumentMetadata {
|
||||
pub local_transforms: HashMap<NodeId, DAffine2>,
|
||||
pub first_element_source_ids: HashMap<NodeId, Option<NodeId>>,
|
||||
pub structure: HashMap<LayerNodeIdentifier, NodeRelations>,
|
||||
pub click_targets: HashMap<LayerNodeIdentifier, Vec<ClickTarget>>,
|
||||
pub click_targets: HashMap<LayerNodeIdentifier, Vec<Arc<ClickTarget>>>,
|
||||
pub clip_targets: HashSet<NodeId>,
|
||||
pub vector_modify: HashMap<NodeId, Vector>,
|
||||
/// Transform from document space to viewport space.
|
||||
@@ -46,8 +47,8 @@ impl DocumentMetadata {
|
||||
self.structure.contains_key(&layer)
|
||||
}
|
||||
|
||||
pub fn click_targets(&self, layer: LayerNodeIdentifier) -> Option<&Vec<ClickTarget>> {
|
||||
self.click_targets.get(&layer)
|
||||
pub fn click_targets(&self, layer: LayerNodeIdentifier) -> Option<&[Arc<ClickTarget>]> {
|
||||
self.click_targets.get(&layer).map(|x| x.as_slice())
|
||||
}
|
||||
|
||||
/// Access the [`NodeRelations`] of a layer.
|
||||
@@ -206,7 +207,7 @@ impl DocumentMetadata {
|
||||
}
|
||||
|
||||
pub fn layer_outline(&self, layer: LayerNodeIdentifier) -> impl Iterator<Item = &subpath::Subpath<PointId>> {
|
||||
static EMPTY: Vec<ClickTarget> = Vec::new();
|
||||
static EMPTY: Vec<Arc<ClickTarget>> = Vec::new();
|
||||
let click_targets = self.click_targets.get(&layer).unwrap_or(&EMPTY);
|
||||
click_targets.iter().filter_map(|target| match target.target_type() {
|
||||
ClickTargetType::Subpath(subpath) => Some(subpath),
|
||||
@@ -215,7 +216,7 @@ impl DocumentMetadata {
|
||||
}
|
||||
|
||||
pub fn layer_with_free_points_outline(&self, layer: LayerNodeIdentifier) -> impl Iterator<Item = &ClickTargetType> {
|
||||
static EMPTY: Vec<ClickTarget> = Vec::new();
|
||||
static EMPTY: Vec<Arc<ClickTarget>> = Vec::new();
|
||||
let click_targets = self.click_targets.get(&layer).unwrap_or(&EMPTY);
|
||||
click_targets.iter().map(|target| target.target_type())
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ use serde_json::{Value, json};
|
||||
use std::collections::{HashMap, HashSet, VecDeque};
|
||||
use std::hash::Hash;
|
||||
use std::ops::Deref;
|
||||
use std::sync::Arc;
|
||||
|
||||
/// All network modifications should be done through this API, so the fields cannot be public. However, all fields within this struct can be public since it it not possible to have a public mutable reference.
|
||||
#[derive(Debug, Default, serde::Serialize, serde::Deserialize)]
|
||||
@@ -3078,7 +3079,7 @@ impl NodeNetworkInterface {
|
||||
self.document_metadata
|
||||
.click_targets
|
||||
.get(&layer)
|
||||
.map(|click| click.iter().map(ClickTarget::target_type))
|
||||
.map(|click| click.iter().map(|x| x.target_type()))
|
||||
.map(|target_types| Vector::from_target_types(target_types, true))
|
||||
}
|
||||
|
||||
@@ -3180,7 +3181,7 @@ impl NodeNetworkInterface {
|
||||
}
|
||||
|
||||
/// Update the cached click targets of the layers
|
||||
pub fn update_click_targets(&mut self, new_click_targets: HashMap<LayerNodeIdentifier, Vec<ClickTarget>>) {
|
||||
pub fn update_click_targets(&mut self, new_click_targets: HashMap<LayerNodeIdentifier, Vec<Arc<ClickTarget>>>) {
|
||||
self.document_metadata.click_targets = new_click_targets;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user