mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-21 11:08:11 +08:00
Migrate demo artwork and fix all failing CI tests (#1459)
* Initial work on fixing tests * Fix formatting * Remove dead code to satisfy rustc warnings * Insert into an artboard * Load updated artwork in editor * Remove popup when importing image * Fix up demo art * Change transform app[lication method * Reduce number of enums called BlendMode * Finalize the demo artwork upgrade * Code review pass --------- Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
committed by
Keavon Chambers
co-authored by
Keavon Chambers
parent
719c96ecd8
commit
8a1cf3ad5d
@@ -1,6 +1,6 @@
|
||||
use glam::{DAffine2, DVec2};
|
||||
use graphene_core::renderer::ClickTarget;
|
||||
use std::collections::HashMap;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::num::NonZeroU64;
|
||||
|
||||
use graph_craft::document::{DocumentNode, NodeId, NodeNetwork};
|
||||
@@ -12,6 +12,8 @@ pub struct DocumentMetadata {
|
||||
transforms: HashMap<LayerNodeIdentifier, DAffine2>,
|
||||
upstream_transforms: HashMap<NodeId, DAffine2>,
|
||||
structure: HashMap<LayerNodeIdentifier, NodeRelations>,
|
||||
artboards: HashSet<LayerNodeIdentifier>,
|
||||
folders: HashSet<LayerNodeIdentifier>,
|
||||
click_targets: HashMap<LayerNodeIdentifier, Vec<ClickTarget>>,
|
||||
selected_nodes: Vec<NodeId>,
|
||||
/// Transform from document space to viewport space.
|
||||
@@ -25,6 +27,8 @@ impl Default for DocumentMetadata {
|
||||
upstream_transforms: HashMap::new(),
|
||||
click_targets: HashMap::new(),
|
||||
structure: HashMap::from_iter([(LayerNodeIdentifier::ROOT, NodeRelations::default())]),
|
||||
artboards: HashSet::new(),
|
||||
folders: HashSet::new(),
|
||||
selected_nodes: Vec::new(),
|
||||
document_to_viewport: DAffine2::IDENTITY,
|
||||
}
|
||||
@@ -67,12 +71,12 @@ impl DocumentMetadata {
|
||||
!self.selected_nodes.is_empty()
|
||||
}
|
||||
|
||||
/// Access the [`NodeRelations`] of a layer
|
||||
/// Access the [`NodeRelations`] of a layer.
|
||||
fn get_relations(&self, node_identifier: LayerNodeIdentifier) -> Option<&NodeRelations> {
|
||||
self.structure.get(&node_identifier)
|
||||
}
|
||||
|
||||
/// Mutably access the [`NodeRelations`] of a layer
|
||||
/// Mutably access the [`NodeRelations`] of a layer.
|
||||
fn get_structure_mut(&mut self, node_identifier: LayerNodeIdentifier) -> &mut NodeRelations {
|
||||
self.structure.entry(node_identifier).or_default()
|
||||
}
|
||||
@@ -92,25 +96,41 @@ impl DocumentMetadata {
|
||||
sorted_layers
|
||||
}
|
||||
|
||||
/// Ancestor that is shared by all layers and that is deepest (more nested). May be the root layer.
|
||||
pub fn deepest_common_ancestor(&self, layers: impl Iterator<Item = LayerNodeIdentifier>) -> LayerNodeIdentifier {
|
||||
/// Ancestor that is shared by all layers and that is deepest (more nested). Default may be the root.
|
||||
pub fn deepest_common_ancestor(&self, layers: impl Iterator<Item = LayerNodeIdentifier>) -> Option<LayerNodeIdentifier> {
|
||||
layers
|
||||
.map(|layer| {
|
||||
let mut layer_path = layer.ancestors(self).skip(1).collect::<Vec<_>>();
|
||||
let mut layer_path = layer.ancestors(self).collect::<Vec<_>>();
|
||||
layer_path.reverse();
|
||||
|
||||
if !self.folders.contains(&layer) {
|
||||
layer_path.pop();
|
||||
}
|
||||
|
||||
layer_path
|
||||
})
|
||||
.reduce(|mut a, b| {
|
||||
a.truncate(a.iter().zip(b.iter()).position(|(&a, &b)| a != b).unwrap_or_else(|| a.len().min(b.len())));
|
||||
a
|
||||
})
|
||||
.and_then(|path| path.last().copied())
|
||||
.unwrap_or(LayerNodeIdentifier::ROOT)
|
||||
.and_then(|layer| layer.last().copied())
|
||||
}
|
||||
|
||||
pub fn active_artboard(&self) -> LayerNodeIdentifier {
|
||||
self.artboards.iter().next().copied().unwrap_or(LayerNodeIdentifier::ROOT)
|
||||
}
|
||||
|
||||
pub fn is_folder(&self, layer: LayerNodeIdentifier) -> bool {
|
||||
self.folders.contains(&layer)
|
||||
}
|
||||
|
||||
pub fn is_artboard(&self, layer: LayerNodeIdentifier) -> bool {
|
||||
self.artboards.contains(&layer)
|
||||
}
|
||||
|
||||
/// Filter out non folder layers
|
||||
pub fn folders<'a>(&'a self, layers: impl Iterator<Item = LayerNodeIdentifier> + 'a) -> impl Iterator<Item = LayerNodeIdentifier> + 'a {
|
||||
layers.filter(|layer| layer.has_children(self))
|
||||
layers.filter(|layer| self.folders.contains(layer))
|
||||
}
|
||||
|
||||
/// Folders sorted from most nested to least nested
|
||||
@@ -146,6 +166,8 @@ impl DocumentMetadata {
|
||||
/// Loads the structure of layer nodes from a node graph.
|
||||
pub fn load_structure(&mut self, graph: &NodeNetwork) {
|
||||
self.structure = HashMap::from_iter([(LayerNodeIdentifier::ROOT, NodeRelations::default())]);
|
||||
self.folders = HashSet::new();
|
||||
self.artboards = HashSet::new();
|
||||
|
||||
let id = graph.outputs[0].node_id;
|
||||
let Some(output_node) = graph.nodes.get(&id) else {
|
||||
@@ -166,6 +188,13 @@ impl DocumentMetadata {
|
||||
if let Some((child_node, child_id)) = first_child_layer(graph, current_node) {
|
||||
stack.push((child_node, child_id, current_identifier));
|
||||
}
|
||||
|
||||
if is_artboard(current_identifier, graph) {
|
||||
self.artboards.insert(current_identifier);
|
||||
}
|
||||
if is_folder(current_identifier, graph) {
|
||||
self.folders.insert(current_identifier);
|
||||
}
|
||||
}
|
||||
|
||||
current = sibling_below(graph, current_node);
|
||||
@@ -210,6 +239,14 @@ fn is_artboard(layer: LayerNodeIdentifier, network: &NodeNetwork) -> bool {
|
||||
network.primary_flow_from_node(Some(layer.to_node())).any(|(node, _)| node.name == "Artboard")
|
||||
}
|
||||
|
||||
fn is_folder(layer: LayerNodeIdentifier, network: &NodeNetwork) -> bool {
|
||||
network.nodes.get(&layer.to_node()).and_then(|node| node.inputs.first()).is_some_and(|input| input.as_node().is_none())
|
||||
|| network
|
||||
.primary_flow_from_node(Some(layer.to_node()))
|
||||
.skip(1)
|
||||
.any(|(node, _)| node.name == "Artboard" || node.name == "Layer")
|
||||
}
|
||||
|
||||
// click targets
|
||||
impl DocumentMetadata {
|
||||
/// Update the cached click targets of the layers
|
||||
|
||||
Reference in New Issue
Block a user