From ff647fccb096ef5d3f92218ace774ed36282c030 Mon Sep 17 00:00:00 2001 From: Alx Sa Date: Tue, 17 Mar 2026 02:54:01 +0000 Subject: [PATCH] path, core: Create gimp_vector_layer_set () Currently to change vector layer properties, you need to grab the VectorLayerOptions and then grab its FillOptions or the StrokeOptions to make changes. To make this process more self-contained, this patch creates a gimp_vector_layer_set () function that operates in the same manner as gimp_text_layer_set (). This patch adds properties for Fill - Stroke properties will be added in a follow-up commit. This also adds automatic tracking for Undoing/Redoing vector property settings. A demonstration of its use in DnD colors and patterns onto the layer dock is included. --- app/core/core-enums.c | 2 ++ app/core/core-enums.h | 1 + app/path/gimpvectorlayer.c | 43 ++++++++++++++++++++++++ app/path/gimpvectorlayer.h | 5 +++ app/path/gimpvectorlayeroptions.c | 55 ++++++++++++++++++++++++++++++- app/widgets/gimplayertreeview.c | 51 ++++++++-------------------- 6 files changed, 119 insertions(+), 38 deletions(-) diff --git a/app/core/core-enums.c b/app/core/core-enums.c index 7f21288839..150b72a8bd 100644 --- a/app/core/core-enums.c +++ b/app/core/core-enums.c @@ -1224,6 +1224,7 @@ gimp_undo_type_get_type (void) { GIMP_UNDO_GROUP_EDIT_PASTE, "GIMP_UNDO_GROUP_EDIT_PASTE", "group-edit-paste" }, { GIMP_UNDO_GROUP_EDIT_CUT, "GIMP_UNDO_GROUP_EDIT_CUT", "group-edit-cut" }, { GIMP_UNDO_GROUP_TEXT, "GIMP_UNDO_GROUP_TEXT", "group-text" }, + { GIMP_UNDO_GROUP_VECTOR, "GIMP_UNDO_GROUP_VECTOR", "group-vector" }, { GIMP_UNDO_GROUP_TRANSFORM, "GIMP_UNDO_GROUP_TRANSFORM", "group-transform" }, { GIMP_UNDO_GROUP_PAINT, "GIMP_UNDO_GROUP_PAINT", "group-paint" }, { GIMP_UNDO_GROUP_PARASITE_ATTACH, "GIMP_UNDO_GROUP_PARASITE_ATTACH", "group-parasite-attach" }, @@ -1339,6 +1340,7 @@ gimp_undo_type_get_type (void) { GIMP_UNDO_GROUP_EDIT_PASTE, NC_("undo-type", "Paste"), NULL }, { GIMP_UNDO_GROUP_EDIT_CUT, NC_("undo-type", "Cut"), NULL }, { GIMP_UNDO_GROUP_TEXT, NC_("undo-type", "Text"), NULL }, + { GIMP_UNDO_GROUP_VECTOR, NC_("undo-type", "Vector"), NULL }, { GIMP_UNDO_GROUP_TRANSFORM, NC_("undo-type", "Transform"), NULL }, { GIMP_UNDO_GROUP_PAINT, NC_("undo-type", "Paint"), NULL }, { GIMP_UNDO_GROUP_PARASITE_ATTACH, NC_("undo-type", "Attach parasite"), NULL }, diff --git a/app/core/core-enums.h b/app/core/core-enums.h index 062634c504..84ef7374b1 100644 --- a/app/core/core-enums.h +++ b/app/core/core-enums.h @@ -571,6 +571,7 @@ typedef enum /*< pdb-skip >*/ GIMP_UNDO_GROUP_EDIT_PASTE, /*< desc="Paste" >*/ GIMP_UNDO_GROUP_EDIT_CUT, /*< desc="Cut" >*/ GIMP_UNDO_GROUP_TEXT, /*< desc="Text" >*/ + GIMP_UNDO_GROUP_VECTOR, /*< desc="Vector" >*/ GIMP_UNDO_GROUP_TRANSFORM, /*< desc="Transform" >*/ GIMP_UNDO_GROUP_PAINT, /*< desc="Paint" >*/ GIMP_UNDO_GROUP_PARASITE_ATTACH, /*< desc="Attach parasite" >*/ diff --git a/app/path/gimpvectorlayer.c b/app/path/gimpvectorlayer.c index a0b3675333..8d78d983fb 100644 --- a/app/path/gimpvectorlayer.c +++ b/app/path/gimpvectorlayer.c @@ -702,6 +702,49 @@ gimp_vector_layer_get_options (GimpVectorLayer *layer) return NULL; } +void +gimp_vector_layer_set (GimpVectorLayer *layer, + const gchar *undo_desc, + const gchar *first_property_name, + ...) +{ + GimpImage *image; + GimpVectorLayerOptions *options; + va_list var_args; + + g_return_if_fail (gimp_item_is_vector_layer (GIMP_ITEM (layer))); + g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (layer))); + + options = layer->options; + + if (! options) + return; + + image = gimp_item_get_image (GIMP_ITEM (layer)); + + gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_VECTOR, undo_desc); + + g_object_freeze_notify (G_OBJECT (layer)); + + if (gimp_rasterizable_is_rasterized (GIMP_RASTERIZABLE (layer))) + gimp_image_undo_push_drawable_mod (image, NULL, + GIMP_DRAWABLE (layer), TRUE); + + gimp_image_undo_push_vector_layer (image, undo_desc, layer, NULL); + + va_start (var_args, first_property_name); + g_object_set_valist (G_OBJECT (options), first_property_name, + var_args); + va_end (var_args); + + if (gimp_rasterizable_is_rasterized (GIMP_RASTERIZABLE (layer))) + gimp_rasterizable_restore (GIMP_RASTERIZABLE (layer)); + + g_object_thaw_notify (G_OBJECT (layer)); + + gimp_image_undo_group_end (image); +} + void gimp_vector_layer_refresh (GimpVectorLayer *layer) { diff --git a/app/path/gimpvectorlayer.h b/app/path/gimpvectorlayer.h index e9b88ba144..5b2e5f647a 100644 --- a/app/path/gimpvectorlayer.h +++ b/app/path/gimpvectorlayer.h @@ -62,6 +62,11 @@ GimpPath * gimp_vector_layer_get_path (GimpVectorLayer *layer) GimpVectorLayerOptions * gimp_vector_layer_get_options (GimpVectorLayer *layer); +void gimp_vector_layer_set (GimpVectorLayer *layer, + const gchar *undo_desc, + const gchar *first_property_name, + ...) G_GNUC_NULL_TERMINATED; + void gimp_vector_layer_refresh (GimpVectorLayer *layer); gboolean gimp_item_is_vector_layer (GimpItem *item); diff --git a/app/path/gimpvectorlayeroptions.c b/app/path/gimpvectorlayeroptions.c index eda0f68ab5..268d08fb9d 100644 --- a/app/path/gimpvectorlayeroptions.c +++ b/app/path/gimpvectorlayeroptions.c @@ -32,7 +32,9 @@ #include "path-types.h" #include "core/gimp.h" +#include "core/gimpfilloptions.h" #include "core/gimpimage.h" +#include "core/gimppattern.h" #include "core/gimpstrokeoptions.h" #include "gimppath.h" @@ -51,7 +53,11 @@ enum PROP_ENABLE_FILL, PROP_FILL_OPTIONS, PROP_ENABLE_STROKE, - PROP_STROKE_OPTIONS + PROP_STROKE_OPTIONS, + /* Individual Fill Options */ + PROP_FILL_STYLE, + PROP_FILL_COLOR, + PROP_FILL_PATTERN }; @@ -85,6 +91,7 @@ static void gimp_vector_layer_options_class_init (GimpVectorLayerOptionsClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); + GeglColor *black = gegl_color_new ("black"); object_class->constructor = gimp_vector_layer_options_constructor; object_class->finalize = gimp_vector_layer_options_finalize; @@ -132,6 +139,28 @@ gimp_vector_layer_options_class_init (GimpVectorLayerOptionsClass *klass) GIMP_TYPE_STROKE_OPTIONS, G_PARAM_STATIC_STRINGS | GIMP_CONFIG_PARAM_AGGREGATE); + + /* Alias for fill properties */ + GIMP_CONFIG_PROP_ENUM (object_class, PROP_FILL_STYLE, + "fill-style", + NULL, NULL, + GIMP_TYPE_CUSTOM_STYLE, + GIMP_CUSTOM_STYLE_SOLID_COLOR, + GIMP_PARAM_STATIC_STRINGS); + + GIMP_CONFIG_PROP_COLOR (object_class, PROP_FILL_COLOR, + "fill-color", + NULL, NULL, + FALSE, black, + GIMP_PARAM_STATIC_STRINGS); + + GIMP_CONFIG_PROP_OBJECT (object_class, PROP_FILL_PATTERN, + "fill-pattern", + NULL, NULL, + GIMP_TYPE_PATTERN, + GIMP_PARAM_STATIC_STRINGS); + + g_object_unref (black); } static void @@ -218,6 +247,12 @@ gimp_vector_layer_options_get_property (GObject *object, g_value_set_object (value, options->stroke_options); break; + /* Alias for fill properties */ + case PROP_FILL_STYLE: + case PROP_FILL_COLOR: + case PROP_FILL_PATTERN: + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; @@ -301,6 +336,24 @@ gimp_vector_layer_options_set_property (GObject *object, } break; + /* Alias for fill properties */ + case PROP_FILL_STYLE: + if (options->fill_options) + g_object_set (GIMP_FILL_OPTIONS (options->fill_options), + "custom-style", g_value_get_enum (value), + NULL); + break; + + case PROP_FILL_COLOR: + gimp_context_set_foreground (GIMP_CONTEXT (options->fill_options), + g_value_get_object (value)); + break; + + case PROP_FILL_PATTERN: + gimp_context_set_pattern (GIMP_CONTEXT (options->fill_options), + g_value_get_object (value)); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; diff --git a/app/widgets/gimplayertreeview.c b/app/widgets/gimplayertreeview.c index 19aba2acb0..481c0dc136 100644 --- a/app/widgets/gimplayertreeview.c +++ b/app/widgets/gimplayertreeview.c @@ -40,7 +40,6 @@ #include "core/gimpchannel.h" #include "core/gimpcontainer.h" #include "core/gimpcontext.h" -#include "core/gimpfilloptions.h" #include "core/gimpimage-undo.h" #include "core/gimpimage-undo-push.h" #include "core/gimpimage.h" @@ -53,7 +52,6 @@ #include "core/gimptreehandler.h" #include "path/gimpvectorlayer.h" -#include "path/gimpvectorlayeroptions.h" #include "text/gimptextlayer.h" @@ -757,25 +755,14 @@ gimp_layer_tree_view_drop_viewables (GimpContainerTreeView *view, gimp_item_is_vector_layer (GIMP_ITEM (dest_viewable)) && GIMP_IS_PATTERN (src_viewable)) { - GimpVectorLayerOptions *vector_options = NULL; - GimpFillOptions *vector_fill = NULL; + gimp_vector_layer_set (GIMP_VECTOR_LAYER (dest_viewable), NULL, + "fill-style", GIMP_CUSTOM_STYLE_PATTERN, + "fill-pattern", GIMP_PATTERN (src_viewable), + NULL); - vector_options = - gimp_vector_layer_get_options (GIMP_VECTOR_LAYER (dest_viewable)); - if (vector_options) - vector_fill = vector_options->fill_options; - - if (vector_fill) - { - gimp_context_set_pattern (GIMP_CONTEXT (vector_fill), - GIMP_PATTERN (src_viewable)); - gimp_fill_options_set_custom_style (vector_fill, - GIMP_CUSTOM_STYLE_PATTERN); - - gimp_vector_layer_refresh (GIMP_VECTOR_LAYER (dest_viewable)); - gimp_image_flush (gimp_item_tree_view_get_image (item_view)); - return; - } + gimp_vector_layer_refresh (GIMP_VECTOR_LAYER (dest_viewable)); + gimp_image_flush (gimp_item_tree_view_get_image (item_view)); + return; } } @@ -803,24 +790,14 @@ gimp_layer_tree_view_drop_color (GimpContainerTreeView *view, } else if (gimp_item_is_vector_layer (GIMP_ITEM (dest_viewable))) { - GimpVectorLayerOptions *vector_options = NULL; - GimpFillOptions *vector_fill = NULL; + gimp_vector_layer_set (GIMP_VECTOR_LAYER (dest_viewable), NULL, + "fill-style", GIMP_CUSTOM_STYLE_SOLID_COLOR, + "fill-color", color, + NULL); - vector_options = - gimp_vector_layer_get_options (GIMP_VECTOR_LAYER (dest_viewable)); - if (vector_options) - vector_fill = vector_options->fill_options; - - if (vector_fill) - { - gimp_context_set_foreground (GIMP_CONTEXT (vector_fill), color); - gimp_fill_options_set_custom_style (vector_fill, - GIMP_CUSTOM_STYLE_SOLID_COLOR); - - gimp_vector_layer_refresh (GIMP_VECTOR_LAYER (dest_viewable)); - gimp_image_flush (gimp_item_tree_view_get_image (item_view)); - return; - } + gimp_vector_layer_refresh (GIMP_VECTOR_LAYER (dest_viewable)); + gimp_image_flush (gimp_item_tree_view_get_image (item_view)); + return; } GIMP_CONTAINER_TREE_VIEW_CLASS (parent_class)->drop_color (view, color,