mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-10-02 10:18:11 +08:00
Add Path node differential edit summary widget, and store imported SVG content in that VectorModification struct (#4036)
* Make paste/import SVG store as the Path node's VectorModification not Table<Vector> * Add a migration from Table<Vector> to VectorModification for existing documents * Add a VectorModification widget to visualize change counts * Refactor VectorModification to compute per-category counts for additions, removals, and modifications
This commit is contained in:
@@ -15,7 +15,7 @@ use graphene_std::table::Table;
|
||||
use graphene_std::text::{Font, TypesettingConfig};
|
||||
use graphene_std::vector::Vector;
|
||||
use graphene_std::vector::style::{Fill, Stroke};
|
||||
use graphene_std::vector::{PointId, VectorModificationType};
|
||||
use graphene_std::vector::{PointId, VectorModification, VectorModificationType};
|
||||
use graphene_std::{Artboard, Color, Graphic, NodeInputDecleration};
|
||||
|
||||
#[derive(PartialEq, Clone, Copy, Debug, serde::Serialize, serde::Deserialize)]
|
||||
@@ -211,11 +211,13 @@ impl<'a> ModifyInputsContext<'a> {
|
||||
}
|
||||
|
||||
pub fn insert_vector(&mut self, subpaths: Vec<Subpath<PointId>>, layer: LayerNodeIdentifier, include_transform: bool, include_fill: bool, include_stroke: bool) {
|
||||
let vector = Table::new_from_element(Vector::from_subpaths(subpaths, true));
|
||||
// Build a VectorModification that reproduces the geometry (same format the Pen tool uses)
|
||||
let vector = Vector::from_subpaths(subpaths, true);
|
||||
let modification = Box::new(VectorModification::create_from_vector(&vector));
|
||||
|
||||
let shape = resolve_network_node_type("Path")
|
||||
.expect("Path node does not exist")
|
||||
.node_template_input_override([Some(NodeInput::value(TaggedValue::Vector(vector), false))]);
|
||||
.node_template_input_override([None, Some(NodeInput::value(TaggedValue::VectorModification(modification), false))]);
|
||||
let shape_id = NodeId::new();
|
||||
self.network_interface.insert_node(shape_id, shape, &[]);
|
||||
self.network_interface.move_node_to_chain_start(&shape_id, layer, &[], self.import);
|
||||
|
||||
@@ -24,10 +24,10 @@ use graphene_std::raster::{
|
||||
use graphene_std::table::{Table, TableRow};
|
||||
use graphene_std::text::{Font, TextAlign};
|
||||
use graphene_std::transform::{Footprint, ReferencePoint, ScaleType, Transform};
|
||||
use graphene_std::vector::QRCodeErrorCorrectionLevel;
|
||||
use graphene_std::vector::misc::BooleanOperation;
|
||||
use graphene_std::vector::misc::{ArcType, CentroidType, ExtrudeJoiningAlgorithm, GridType, InterpolationDistribution, MergeByDistanceAlgorithm, PointSpacingType, RowsOrColumns, SpiralType};
|
||||
use graphene_std::vector::style::{Fill, FillChoice, FillType, GradientSpreadMethod, GradientStops, GradientType, PaintOrder, StrokeAlign, StrokeCap, StrokeJoin};
|
||||
use graphene_std::vector::{QRCodeErrorCorrectionLevel, VectorModification};
|
||||
|
||||
pub(crate) fn string_properties(text: &str) -> Vec<LayoutGroup> {
|
||||
let widget = TextLabel::new(text).widget_instance();
|
||||
@@ -230,6 +230,7 @@ pub(crate) fn property_from_type(
|
||||
Some(x) if x == TypeId::of::<Font>() => font_widget(default_info),
|
||||
Some(x) if x == TypeId::of::<Curve>() => curve_widget(default_info),
|
||||
Some(x) if x == TypeId::of::<Footprint>() => footprint_widget(default_info, &mut extra_widgets),
|
||||
Some(x) if x == TypeId::of::<Box<VectorModification>>() => vector_modification_widget(default_info).into(),
|
||||
// ===============================
|
||||
// MANUALLY IMPLEMENTED ENUM TYPES
|
||||
// ===============================
|
||||
@@ -398,6 +399,27 @@ pub fn reference_point_widget(parameter_widgets_info: ParameterWidgetsInfo, disa
|
||||
widgets
|
||||
}
|
||||
|
||||
pub fn vector_modification_widget(parameter_widgets_info: ParameterWidgetsInfo) -> Vec<WidgetInstance> {
|
||||
let ParameterWidgetsInfo { document_node, node_id: _, index, .. } = parameter_widgets_info;
|
||||
|
||||
let mut widgets = start_widgets(parameter_widgets_info);
|
||||
|
||||
let Some(document_node) = document_node else { return widgets };
|
||||
let Some(input) = document_node.inputs.get(index) else { return widgets };
|
||||
|
||||
if let Some(TaggedValue::VectorModification(modification)) = input.as_non_exposed_value() {
|
||||
let label = modification.summary_label();
|
||||
let tooltip = modification.summary_tooltip();
|
||||
|
||||
widgets.extend_from_slice(&[
|
||||
Separator::new(SeparatorStyle::Unrelated).widget_instance(),
|
||||
TextLabel::new(label).tooltip_label("Summary of Differential Edits").tooltip_description(tooltip).widget_instance(),
|
||||
]);
|
||||
}
|
||||
|
||||
widgets
|
||||
}
|
||||
|
||||
pub fn footprint_widget(parameter_widgets_info: ParameterWidgetsInfo, extra_widgets: &mut Vec<LayoutGroup>) -> LayoutGroup {
|
||||
let ParameterWidgetsInfo { document_node, node_id, index, .. } = parameter_widgets_info;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user