mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-22 19:18:12 +08:00
Fix gradient tool
This commit is contained in:
committed by
Keavon Chambers
parent
6173662a40
commit
9a39c4a0cc
@@ -2,9 +2,10 @@ use crate::messages::portfolio::document::node_graph::VectorDataModification;
|
||||
use crate::messages::prelude::*;
|
||||
|
||||
use bezier_rs::{ManipulatorGroup, Subpath};
|
||||
use document_legacy::{document_metadata::LayerNodeIdentifier, LayerId, Operation};
|
||||
use document_legacy::{document::Document, document_metadata::LayerNodeIdentifier, LayerId, Operation};
|
||||
use graph_craft::document::{value::TaggedValue, DocumentNode, NodeId, NodeInput, NodeNetwork};
|
||||
use graphene_core::uuid::ManipulatorGroupId;
|
||||
use graphene_core::vector::style::{FillType, Gradient};
|
||||
|
||||
use glam::DAffine2;
|
||||
use std::collections::VecDeque;
|
||||
@@ -17,6 +18,7 @@ pub fn new_vector_layer(subpaths: Vec<Subpath<ManipulatorGroupId>>, layer_path:
|
||||
});
|
||||
}
|
||||
|
||||
/// Create a legacy node graph frame TODO: remove
|
||||
pub fn new_custom_layer(network: NodeNetwork, layer_path: Vec<LayerId>, responses: &mut VecDeque<Message>) {
|
||||
responses.add(DocumentMessage::DeselectAllLayers);
|
||||
responses.add(Operation::AddFrame {
|
||||
@@ -28,6 +30,7 @@ pub fn new_custom_layer(network: NodeNetwork, layer_path: Vec<LayerId>, response
|
||||
responses.add(DocumentMessage::InputFrameRasterizeRegionBelowLayer { layer_path });
|
||||
}
|
||||
|
||||
/// Batch set all of the manipulator groups to mirror on a specific layer
|
||||
pub fn set_manipulator_mirror_angle(manipulator_groups: &[ManipulatorGroup<ManipulatorGroupId>], layer_path: &[u64], mirror_angle: bool, responses: &mut VecDeque<Message>) {
|
||||
for manipulator_group in manipulator_groups {
|
||||
responses.add(GraphOperationMessage::Vector {
|
||||
@@ -40,6 +43,64 @@ pub fn set_manipulator_mirror_angle(manipulator_groups: &[ManipulatorGroup<Manip
|
||||
}
|
||||
}
|
||||
|
||||
/// Locate the subpaths from the shape nodes of a particular layer
|
||||
pub fn get_subpaths(layer: LayerNodeIdentifier, document: &Document) -> Option<&Vec<Subpath<ManipulatorGroupId>>> {
|
||||
if let TaggedValue::Subpaths(subpaths) = NodeGraphLayer::new(layer, document)?.find_input("Shape", 0)? {
|
||||
Some(subpaths)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the currently mirrored handles for a particular layer from the shape node
|
||||
pub fn get_mirror_handles(layer: LayerNodeIdentifier, document: &Document) -> Option<&Vec<ManipulatorGroupId>> {
|
||||
if let TaggedValue::ManipulatorGroupIds(mirror_handles) = NodeGraphLayer::new(layer, document)?.find_input("Shape", 1)? {
|
||||
Some(mirror_handles)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the current gradient of a layer from the closest fill node
|
||||
pub fn get_gradient(layer: LayerNodeIdentifier, document: &Document) -> Option<Gradient> {
|
||||
let inputs = NodeGraphLayer::new(layer, document)?.find_node_inputs("Fill")?;
|
||||
let TaggedValue::FillType(FillType::Gradient) = inputs.get(1)?.as_value()? else {
|
||||
return None;
|
||||
};
|
||||
let TaggedValue::GradientType(gradient_type) = inputs.get(3)?.as_value()? else {
|
||||
return None;
|
||||
};
|
||||
let TaggedValue::DVec2(start) = inputs.get(4)?.as_value()? else {
|
||||
return None;
|
||||
};
|
||||
let TaggedValue::DVec2(end) = inputs.get(5)?.as_value()? else {
|
||||
return None;
|
||||
};
|
||||
let TaggedValue::DAffine2(transform) = inputs.get(6)?.as_value()? else {
|
||||
return None;
|
||||
};
|
||||
let TaggedValue::GradientPositions(positions) = inputs.get(7)?.as_value()? else {
|
||||
return None;
|
||||
};
|
||||
Some(Gradient {
|
||||
start: start.clone(),
|
||||
end: end.clone(),
|
||||
transform: transform.clone(),
|
||||
positions: positions.clone(),
|
||||
gradient_type: gradient_type.clone(),
|
||||
})
|
||||
}
|
||||
|
||||
/// Convert subpaths to an iterator of manipulator groups
|
||||
pub fn get_manipulator_groups(subpaths: &[Subpath<ManipulatorGroupId>]) -> impl Iterator<Item = &bezier_rs::ManipulatorGroup<ManipulatorGroupId>> + DoubleEndedIterator {
|
||||
subpaths.iter().flat_map(|subpath| subpath.manipulator_groups())
|
||||
}
|
||||
|
||||
/// Find a manipulator group with a specific id from several subpaths
|
||||
pub fn get_manipulator_from_id(subpaths: &[Subpath<ManipulatorGroupId>], id: ManipulatorGroupId) -> Option<&bezier_rs::ManipulatorGroup<ManipulatorGroupId>> {
|
||||
subpaths.iter().find_map(|subpath| subpath.manipulator_from_id(id))
|
||||
}
|
||||
|
||||
/// An immutable reference to a layer within the document node graph for easy access.
|
||||
pub struct NodeGraphLayer<'a> {
|
||||
node_graph: &'a NodeNetwork,
|
||||
@@ -84,18 +145,18 @@ impl<'a> NodeGraphLayer<'a> {
|
||||
self.node_graph.primary_flow_from_opt(Some(self.layer_node))
|
||||
}
|
||||
|
||||
/// Find a specific input of a node within the layer's primary flow
|
||||
pub fn find_input(&self, node_name: &str, index: usize) -> Option<&'a TaggedValue> {
|
||||
/// Find all of the inputs of a specific node within the layer's primary flow
|
||||
pub fn find_node_inputs(&self, node_name: &str) -> Option<&'a Vec<NodeInput>> {
|
||||
for (node, _id) in self.primary_layer_flow() {
|
||||
if node.name == node_name {
|
||||
let subpaths_input = node.inputs.get(index)?;
|
||||
let NodeInput::Value { tagged_value, .. } = subpaths_input else {
|
||||
continue;
|
||||
};
|
||||
|
||||
return Some(tagged_value);
|
||||
return Some(&node.inputs);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
/// Find a specific input of a node within the layer's primary flow
|
||||
pub fn find_input(&self, node_name: &str, index: usize) -> Option<&'a TaggedValue> {
|
||||
self.find_node_inputs(node_name)?.get(index)?.as_value()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ use crate::application::generate_uuid;
|
||||
use crate::consts::VIEWPORT_GRID_ROUNDING_BIAS;
|
||||
use crate::consts::{COLOR_ACCENT, HIDE_HANDLE_DISTANCE, MANIPULATOR_GROUP_MARKER_SIZE, PATH_OUTLINE_WEIGHT};
|
||||
use crate::messages::prelude::*;
|
||||
use crate::messages::tool::tool_messages::pen_tool::{get_manipulator_groups, get_subpaths};
|
||||
use crate::messages::tool::common_functionality::graph_modification_utils::{get_manipulator_groups, get_subpaths};
|
||||
|
||||
use bezier_rs::ManipulatorGroup;
|
||||
use document_legacy::document::Document;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use crate::consts::DRAG_THRESHOLD;
|
||||
use crate::messages::portfolio::document::node_graph::VectorDataModification;
|
||||
use crate::messages::prelude::*;
|
||||
use crate::messages::tool::tool_messages::pen_tool::{get_manipulator_from_id, get_manipulator_groups, get_mirror_handles, get_subpaths};
|
||||
use crate::messages::tool::common_functionality::graph_modification_utils::{get_manipulator_from_id, get_manipulator_groups, get_mirror_handles, get_subpaths};
|
||||
|
||||
use bezier_rs::{Bezier, ManipulatorGroup, TValue};
|
||||
use document_legacy::document::Document;
|
||||
|
||||
Reference in New Issue
Block a user