From 1a73a4ddc680937450fefe7464b383c73ebdd130 Mon Sep 17 00:00:00 2001 From: Jehan Date: Wed, 22 Oct 2025 19:11:58 +0200 Subject: [PATCH] app: edit vector layer with path tool as default edit action. - Getting rid of the dedicated vector layer options dialog (with fill and stroke settings) which appeared when double-clicking on a vector layer. This is a duplicated with the Path tool options. - Double-clicking a vector layer instead will simply start the Path tool (same as double-clicking a text layer starts the Text tool). - The path choice settings only is missing from the Path tool options. Instead of moving it there, I move it to the generic layer options dialog. I don't think it's the kind of setting you really change often (most of the time, you likely just make a new vector layer). - Offsets are ignored too and hidden for vector layers. - Also making sure that the path changes shows live when editing the setting in dialog, but it is properly reverted if canceling the attributes edition. - Also make sure the undo step changes the path back. --- app/actions/layers-actions.c | 4 +- app/actions/layers-commands.c | 62 +--- app/dialogs/layer-options-dialog.c | 239 +++++++++++----- app/dialogs/layer-options-dialog.h | 1 + app/dialogs/meson.build | 1 - app/dialogs/vector-layer-options-dialog.c | 326 ---------------------- app/dialogs/vector-layer-options-dialog.h | 34 --- app/path/gimpvectorlayer.c | 24 ++ app/path/gimpvectorlayer.h | 3 + app/tools/gimppathtool.c | 30 +- 10 files changed, 234 insertions(+), 490 deletions(-) delete mode 100644 app/dialogs/vector-layer-options-dialog.c delete mode 100644 app/dialogs/vector-layer-options-dialog.h diff --git a/app/actions/layers-actions.c b/app/actions/layers-actions.c index 2090cdc365..b76386b729 100644 --- a/app/actions/layers-actions.c +++ b/app/actions/layers-actions.c @@ -64,8 +64,8 @@ static const GimpActionEntry layers_actions[] = GIMP_HELP_LAYER_EDIT }, { "layers-edit-vector", GIMP_ICON_TOOL_PATH, - NC_("layers-action", "Path Tool"), NULL, { NULL }, - NC_("layers-action", "Activate the path tool on this vector layer's path"), + NC_("layers-action", "Edit Vector on Canvas"), NULL, { NULL }, + NC_("layers-action", "Activate the path tool on this vector layer"), layers_edit_vector_cmd_callback, GIMP_HELP_TOOL_PATH }, diff --git a/app/actions/layers-commands.c b/app/actions/layers-commands.c index 11bb53c7ee..6157a4ff24 100644 --- a/app/actions/layers-commands.c +++ b/app/actions/layers-commands.c @@ -87,7 +87,6 @@ #include "dialogs/layer-options-dialog.h" #include "dialogs/resize-dialog.h" #include "dialogs/scale-dialog.h" -#include "dialogs/vector-layer-options-dialog.h" #include "actions.h" #include "items-commands.h" @@ -110,6 +109,7 @@ static void layers_new_callback (GtkWidget *dialog, gdouble layer_opacity, GimpFillType layer_fill_type, GimpLink *link, + GimpPath *path, gint layer_width, gint layer_height, gint layer_offset_x, @@ -134,6 +134,7 @@ static void layers_edit_attributes_callback (GtkWidget *dialog, gdouble layer_opacity, GimpFillType layer_fill_type, GimpLink *link, + GimpPath *path, gint layer_width, gint layer_height, gint layer_offset_x, @@ -183,10 +184,6 @@ static gint layers_mode_index (GimpLayerMode layer_mode const GimpLayerMode *modes, gint n_modes); -static void layers_vector_show_fill_stroke (GimpAction *action, - GVariant *value, - gpointer data); - /* private variables */ @@ -212,17 +209,11 @@ layers_edit_cmd_callback (GimpAction *action, return; if (gimp_item_is_text_layer (GIMP_ITEM (layers->data))) - { - layers_edit_text_cmd_callback (action, value, data); - } + layers_edit_text_cmd_callback (action, value, data); else if (gimp_item_is_vector_layer (GIMP_ITEM (layers->data))) - { - layers_vector_show_fill_stroke (action, value, data); - } + layers_edit_vector_cmd_callback (action, value, data); else - { - layers_edit_attributes_cmd_callback (action, value, data); - } + layers_edit_attributes_cmd_callback (action, value, data); } void @@ -2359,6 +2350,7 @@ layers_new_callback (GtkWidget *dialog, gdouble layer_opacity, GimpFillType layer_fill_type, GimpLink *link, + GimpPath *path, gint layer_width, gint layer_height, gint layer_offset_x, @@ -2478,6 +2470,7 @@ layers_edit_attributes_callback (GtkWidget *dialog, gdouble layer_opacity, GimpFillType unused1, GimpLink *link, + GimpPath *path, gint unused2, gint unused3, gint layer_offset_x, @@ -2507,7 +2500,7 @@ layers_edit_attributes_callback (GtkWidget *dialog, layer_lock_position != gimp_item_get_lock_position (item) || layer_lock_visibility != gimp_item_get_lock_visibility (item) || layer_lock_alpha != gimp_layer_get_lock_alpha (layer) || - link) + link || path) { gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_ITEM_PROPERTIES, @@ -2541,8 +2534,9 @@ layers_edit_attributes_callback (GtkWidget *dialog, if (layer_opacity != gimp_layer_get_opacity (layer)) gimp_layer_set_opacity (layer, layer_opacity, TRUE); - if (layer_offset_x != gimp_item_get_offset_x (item) || - layer_offset_y != gimp_item_get_offset_y (item)) + if (! gimp_item_is_vector_layer (item) && + (layer_offset_x != gimp_item_get_offset_x (item) || + layer_offset_y != gimp_item_get_offset_y (item))) { gimp_item_translate (item, layer_offset_x - gimp_item_get_offset_x (item), @@ -2571,6 +2565,9 @@ layers_edit_attributes_callback (GtkWidget *dialog, if (GIMP_IS_LINK_LAYER (layer) && link) gimp_link_layer_set_link (GIMP_LINK_LAYER (layer), link, TRUE); + if (gimp_item_is_vector_layer (item) && path) + gimp_vector_layer_set_path (GIMP_VECTOR_LAYER (layer), path, TRUE); + gimp_image_undo_group_end (image); gimp_image_flush (image); } @@ -2754,34 +2751,3 @@ layers_mode_index (GimpLayerMode layer_mode, return i; } - -static void -layers_vector_show_fill_stroke (GimpAction *action, - GVariant *value, - gpointer data) -{ - GimpImage *image; - GimpLayer *layer; - GList *layers; - GtkWidget *widget; - return_if_no_layers (image, layers, data); - return_if_no_widget (widget, data); - - if (g_list_length (layers) != 1) - return; - - layer = layers->data; - - if (GIMP_IS_VECTOR_LAYER (layer)) - { - GtkWidget *dialog; - - dialog = vector_layer_options_dialog_new (GIMP_VECTOR_LAYER (layer), - action_data_get_context (data), - _("Fill / Stroke"), - "gimp-vector-layer-stroke", - GIMP_HELP_LAYER_VECTOR_FILL_STROKE, - widget); - gtk_widget_show (dialog); - } -} diff --git a/app/dialogs/layer-options-dialog.c b/app/dialogs/layer-options-dialog.c index 03e55c7b59..1ee42b95f5 100644 --- a/app/dialogs/layer-options-dialog.c +++ b/app/dialogs/layer-options-dialog.c @@ -35,10 +35,15 @@ #include "core/gimplink.h" #include "core/gimplinklayer.h" +#include "path/gimppath.h" +#include "path/gimpvectorlayer.h" + #include "text/gimptext.h" #include "text/gimptextlayer.h" +#include "widgets/gimpcontainercombobox.h" #include "widgets/gimpcontainerlistview.h" +#include "widgets/gimpcontainerview.h" #include "widgets/gimplayermodebox.h" #include "widgets/gimpopendialog.h" #include "widgets/gimpviewabledialog.h" @@ -74,6 +79,7 @@ struct _LayerOptionsDialog GtkWidget *offset_se; GimpLink *link; + GimpPath *initial_path; }; @@ -101,6 +107,8 @@ static void layer_options_dialog_rename_toggled (GtkWidget *widget, static void layer_options_file_set (GtkFileChooserButton *widget, LayerOptionsDialog *private); +static void layer_options_dialog_path_selected (GimpContainerView *view, + LayerOptionsDialog *private); /* public functions */ @@ -168,6 +176,7 @@ layer_options_dialog_new (GimpImage *image, private->user_data = user_data; private->link = NULL; + private->initial_path = NULL; if (layer && gimp_item_is_text_layer (GIMP_ITEM (layer))) private->rename_text_layers = GIMP_TEXT_LAYER (layer)->auto_rename; @@ -321,69 +330,72 @@ layer_options_dialog_new (GimpImage *image, row += 2; } - /* The offset labels */ - label = gtk_label_new (_("Offset X:")); - gtk_label_set_xalign (GTK_LABEL (label), 0.0); - gtk_grid_attach (GTK_GRID (grid), label, 0, row, 1, 1); - gtk_widget_show (label); - - label = gtk_label_new (_("Offset Y:")); - gtk_label_set_xalign (GTK_LABEL (label), 0.0); - gtk_grid_attach (GTK_GRID (grid), label, 0, row + 1, 1, 1); - gtk_widget_show (label); - - /* The offset sizeentry */ - adjustment = gtk_adjustment_new (0, 1, 1, 1, 10, 0); - spinbutton = gimp_spin_button_new (adjustment, 1.0, 2); - gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbutton), TRUE); - gtk_entry_set_width_chars (GTK_ENTRY (spinbutton), 10); - - private->offset_se = gimp_size_entry_new (1, gimp_unit_pixel (), "%a", - TRUE, TRUE, FALSE, 10, - GIMP_SIZE_ENTRY_UPDATE_SIZE); - - gimp_size_entry_add_field (GIMP_SIZE_ENTRY (private->offset_se), - GTK_SPIN_BUTTON (spinbutton), NULL); - gtk_grid_attach (GTK_GRID (private->offset_se), spinbutton, 1, 0, 1, 1); - gtk_widget_show (spinbutton); - - gtk_grid_attach (GTK_GRID (grid), private->offset_se, 1, row, 1, 2); - gtk_widget_show (private->offset_se); - - gimp_size_entry_set_unit (GIMP_SIZE_ENTRY (private->offset_se), - gimp_unit_pixel ()); - - gimp_size_entry_set_resolution (GIMP_SIZE_ENTRY (private->offset_se), 0, - xres, FALSE); - gimp_size_entry_set_resolution (GIMP_SIZE_ENTRY (private->offset_se), 1, - yres, FALSE); - - gimp_size_entry_set_refval_boundaries (GIMP_SIZE_ENTRY (private->offset_se), 0, - -GIMP_MAX_IMAGE_SIZE, - GIMP_MAX_IMAGE_SIZE); - gimp_size_entry_set_refval_boundaries (GIMP_SIZE_ENTRY (private->offset_se), 1, - -GIMP_MAX_IMAGE_SIZE, - GIMP_MAX_IMAGE_SIZE); - - gimp_size_entry_set_size (GIMP_SIZE_ENTRY (private->offset_se), 0, - 0, gimp_image_get_width (image)); - gimp_size_entry_set_size (GIMP_SIZE_ENTRY (private->offset_se), 1, - 0, gimp_image_get_height (image)); - - if (layer) + if (layer && ! gimp_item_is_vector_layer (GIMP_ITEM (layer))) { - gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (private->offset_se), 0, - gimp_item_get_offset_x (GIMP_ITEM (layer))); - gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (private->offset_se), 1, - gimp_item_get_offset_y (GIMP_ITEM (layer))); - } - else - { - gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (private->offset_se), 0, 0); - gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (private->offset_se), 1, 0); - } + /* The offset labels */ + label = gtk_label_new (_("Offset X:")); + gtk_label_set_xalign (GTK_LABEL (label), 0.0); + gtk_grid_attach (GTK_GRID (grid), label, 0, row, 1, 1); + gtk_widget_show (label); - row += 2; + label = gtk_label_new (_("Offset Y:")); + gtk_label_set_xalign (GTK_LABEL (label), 0.0); + gtk_grid_attach (GTK_GRID (grid), label, 0, row + 1, 1, 1); + gtk_widget_show (label); + + /* The offset sizeentry */ + adjustment = gtk_adjustment_new (0, 1, 1, 1, 10, 0); + spinbutton = gimp_spin_button_new (adjustment, 1.0, 2); + gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (spinbutton), TRUE); + gtk_entry_set_width_chars (GTK_ENTRY (spinbutton), 10); + + private->offset_se = gimp_size_entry_new (1, gimp_unit_pixel (), "%a", + TRUE, TRUE, FALSE, 10, + GIMP_SIZE_ENTRY_UPDATE_SIZE); + + gimp_size_entry_add_field (GIMP_SIZE_ENTRY (private->offset_se), + GTK_SPIN_BUTTON (spinbutton), NULL); + gtk_grid_attach (GTK_GRID (private->offset_se), spinbutton, 1, 0, 1, 1); + gtk_widget_show (spinbutton); + + gtk_grid_attach (GTK_GRID (grid), private->offset_se, 1, row, 1, 2); + gtk_widget_show (private->offset_se); + + gimp_size_entry_set_unit (GIMP_SIZE_ENTRY (private->offset_se), + gimp_unit_pixel ()); + + gimp_size_entry_set_resolution (GIMP_SIZE_ENTRY (private->offset_se), 0, + xres, FALSE); + gimp_size_entry_set_resolution (GIMP_SIZE_ENTRY (private->offset_se), 1, + yres, FALSE); + + gimp_size_entry_set_refval_boundaries (GIMP_SIZE_ENTRY (private->offset_se), 0, + -GIMP_MAX_IMAGE_SIZE, + GIMP_MAX_IMAGE_SIZE); + gimp_size_entry_set_refval_boundaries (GIMP_SIZE_ENTRY (private->offset_se), 1, + -GIMP_MAX_IMAGE_SIZE, + GIMP_MAX_IMAGE_SIZE); + + gimp_size_entry_set_size (GIMP_SIZE_ENTRY (private->offset_se), 0, + 0, gimp_image_get_width (image)); + gimp_size_entry_set_size (GIMP_SIZE_ENTRY (private->offset_se), 1, + 0, gimp_image_get_height (image)); + + if (layer) + { + gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (private->offset_se), 0, + gimp_item_get_offset_x (GIMP_ITEM (layer))); + gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (private->offset_se), 1, + gimp_item_get_offset_y (GIMP_ITEM (layer))); + } + else + { + gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (private->offset_se), 0, 0); + gimp_size_entry_set_refval (GIMP_SIZE_ENTRY (private->offset_se), 1, 0); + } + + row += 2; + } if (layer) { @@ -403,7 +415,7 @@ layer_options_dialog_new (GimpImage *image, gtk_container_add (GTK_CONTAINER (frame), view); gtk_widget_show (view); - if (GIMP_IS_LINK_LAYER (layer)) + if (gimp_item_is_link_layer (GIMP_ITEM (layer))) { GtkWidget *open_dialog; GimpLink *link; @@ -441,6 +453,20 @@ layer_options_dialog_new (GimpImage *image, G_BINDING_BIDIRECTIONAL); gtk_widget_set_visible (button, TRUE); } + else if (gimp_item_is_vector_layer (GIMP_ITEM (layer))) + { + combo = gimp_container_combo_box_new (gimp_image_get_paths (image), + context, GIMP_VIEW_SIZE_SMALL, 1); + gimp_container_view_set_1_selected (GIMP_CONTAINER_VIEW (combo), + GIMP_VIEWABLE (gimp_vector_layer_get_path (GIMP_VECTOR_LAYER (layer)))); + g_signal_connect (combo, "selection-changed", + G_CALLBACK (layer_options_dialog_path_selected), + private); + gimp_grid_attach_aligned (GTK_GRID (grid), 0, row++, + _("_Associated path:"), 0.0, 0.5, + combo, 2); + gtk_widget_set_visible (combo, TRUE); + } } else { @@ -463,10 +489,11 @@ layer_options_dialog_new (GimpImage *image, G_BINDING_SYNC_CREATE | G_BINDING_INVERT_BOOLEAN); - g_object_bind_property (G_OBJECT (button), "active", - G_OBJECT (private->offset_se), "sensitive", - G_BINDING_SYNC_CREATE | - G_BINDING_INVERT_BOOLEAN); + if (private->offset_se) + g_object_bind_property (G_OBJECT (button), "active", + G_OBJECT (private->offset_se), "sensitive", + G_BINDING_SYNC_CREATE | + G_BINDING_INVERT_BOOLEAN); button = item_options_dialog_add_switch (dialog, GIMP_ICON_LOCK_ALPHA, @@ -503,6 +530,20 @@ layer_options_dialog_new (GimpImage *image, static void layer_options_dialog_free (LayerOptionsDialog *private) { + /* If not cleared already, it means we cancel. + * Let's revert silently. + */ + if (private->initial_path) + { + GimpLayer *layer = private->layer; + + g_return_if_fail (GIMP_IS_VECTOR_LAYER (layer)); + + gimp_vector_layer_set_path (GIMP_VECTOR_LAYER (layer), private->initial_path, FALSE); + g_clear_object (&private->initial_path); + } + g_clear_object (&private->link); + g_slice_free (LayerOptionsDialog, private); } @@ -519,11 +560,12 @@ layer_options_dialog_callback (GtkWidget *dialog, gboolean item_lock_visibility, gpointer user_data) { - LayerOptionsDialog *private = user_data; - gint width = 0; - gint height = 0; - gint offset_x; - gint offset_y; + LayerOptionsDialog *private = user_data; + GimpPath *path = NULL; + gint width = 0; + gint height = 0; + gint offset_x = 0; + gint offset_y = 0; if (private->size_se) { @@ -535,12 +577,22 @@ layer_options_dialog_callback (GtkWidget *dialog, 1)); } - offset_x = - RINT (gimp_size_entry_get_refval (GIMP_SIZE_ENTRY (private->offset_se), - 0)); - offset_y = - RINT (gimp_size_entry_get_refval (GIMP_SIZE_ENTRY (private->offset_se), - 1)); + if (private->offset_se) + { + offset_x = + RINT (gimp_size_entry_get_refval (GIMP_SIZE_ENTRY (private->offset_se), + 0)); + offset_y = + RINT (gimp_size_entry_get_refval (GIMP_SIZE_ENTRY (private->offset_se), + 1)); + } + + if (gimp_item_is_vector_layer (item) && private->initial_path) + { + path = gimp_vector_layer_get_path (GIMP_VECTOR_LAYER (item)); + gimp_vector_layer_set_path (GIMP_VECTOR_LAYER (item), private->initial_path, FALSE); + g_clear_object (&private->initial_path); + } private->callback (dialog, image, @@ -554,6 +606,7 @@ layer_options_dialog_callback (GtkWidget *dialog, private->opacity / 100.0, private->fill_type, private->link, + path, width, height, offset_x, @@ -668,3 +721,35 @@ layer_options_file_set (GtkFileChooserButton *widget, } g_clear_object (&file); } + +static void +layer_options_dialog_path_selected (GimpContainerView *view, + LayerOptionsDialog *private) +{ + GimpViewable *item = gimp_container_view_get_1_selected (view); + GimpPath *new_path = NULL; + GimpPath *path; + GimpVectorLayer *layer; + + g_return_if_fail (GIMP_IS_VECTOR_LAYER (private->layer)); + + layer = GIMP_VECTOR_LAYER (private->layer); + + if (item) + new_path = GIMP_PATH (item); + + path = gimp_vector_layer_get_path (GIMP_VECTOR_LAYER (private->layer)); + + if (new_path && new_path != path) + { + g_return_if_fail (GIMP_IS_PATH (new_path)); + gimp_vector_layer_set_path (layer, new_path, FALSE); + + if (private->initial_path == new_path) + g_clear_object (&private->initial_path); + else if (private->initial_path == NULL) + private->initial_path = g_object_ref (path); + + gimp_vector_layer_refresh (layer); + } +} diff --git a/app/dialogs/layer-options-dialog.h b/app/dialogs/layer-options-dialog.h index 70d94f665f..528532d6c6 100644 --- a/app/dialogs/layer-options-dialog.h +++ b/app/dialogs/layer-options-dialog.h @@ -30,6 +30,7 @@ typedef void (* GimpLayerOptionsCallback) (GtkWidget *dialog, gdouble layer_opacity, GimpFillType layer_fill_type, GimpLink *link, + GimpPath *path, gint layer_width, gint layer_height, gint layer_offset_x, diff --git a/app/dialogs/meson.build b/app/dialogs/meson.build index a6fd8267d6..672cd934eb 100644 --- a/app/dialogs/meson.build +++ b/app/dialogs/meson.build @@ -56,7 +56,6 @@ libappdialogs_sources = [ 'tips-dialog.c', 'tips-parser.c', 'user-install-dialog.c', - 'vector-layer-options-dialog.c', 'welcome-dialog.c', gitversion_h, welcome_dialog_data_c, diff --git a/app/dialogs/vector-layer-options-dialog.c b/app/dialogs/vector-layer-options-dialog.c deleted file mode 100644 index 23028e87ed..0000000000 --- a/app/dialogs/vector-layer-options-dialog.c +++ /dev/null @@ -1,326 +0,0 @@ -/* GIMP - The GNU Image Manipulation Program - * Copyright (C) 1995 Spencer Kimball and Peter Mattis - * - * vector-layer-options-dialog.h - * - * Copyright 2006 Hendrik Boom - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "config.h" - -#include -#include - -#include "libgimpconfig/gimpconfig.h" -#include "libgimpwidgets/gimpwidgets.h" - -#include "dialogs-types.h" - -#include "core/gimp.h" -#include "core/gimpdrawable.h" -#include "core/gimpimage.h" -#include "core/gimpimage-undo-push.h" -#include "core/gimpstrokeoptions.h" - -#include "path/gimppath.h" -#include "path/gimpvectorlayer.h" -#include "path/gimpvectorlayeroptions.h" - -#include "widgets/gimpcolorpanel.h" -#include "widgets/gimpcontainercombobox.h" -#include "widgets/gimpcontainerview.h" -#include "widgets/gimppropwidgets.h" -#include "widgets/gimpviewabledialog.h" -#include "widgets/gimpstrokeeditor.h" - -#include "vector-layer-options-dialog.h" - -#include "gimp-intl.h" - - -#define RESPONSE_RESET 1 - - -/* local functions */ - -static void vector_layer_options_dialog_notify (GObject *options, - const GParamSpec *pspec, - GtkWidget *dialog); -static void vector_layer_options_dialog_response (GtkWidget *widget, - gint response_id, - GtkWidget *dialog); -static void vector_layer_options_dialog_path_selected (GimpContainerView *view, - GtkWidget *dialog); - - -/* public function */ - -GtkWidget * -vector_layer_options_dialog_new (GimpVectorLayer *layer, - GimpContext *context, - const gchar *title, - const gchar *icon_name, - const gchar *help_id, - GtkWidget *parent) -{ - GimpVectorLayerOptions *saved_options; - GimpFillOptions *fill_options; - GimpStrokeOptions *stroke_options; - GtkWidget *dialog; - GtkWidget *main_vbox; - GtkWidget *combo; - - g_return_val_if_fail (GIMP_IS_VECTOR_LAYER (layer), NULL); - g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL); - g_return_val_if_fail (icon_name != NULL, NULL); - g_return_val_if_fail (parent == NULL || GTK_IS_WIDGET (parent), NULL); - - saved_options = gimp_config_duplicate (GIMP_CONFIG (layer->options)); - fill_options = gimp_config_duplicate (GIMP_CONFIG (saved_options->fill_options)); - stroke_options = gimp_config_duplicate (GIMP_CONFIG (saved_options->stroke_options)); - - dialog = gimp_viewable_dialog_new (g_list_prepend (NULL, GIMP_VIEWABLE (layer)), - context, - title, "gimp-vectorlayer-options", - icon_name, - _("Edit Vector Layer Attributes"), - parent, - gimp_standard_help_func, - help_id, - _("_Reset"), RESPONSE_RESET, - _("_Cancel"), GTK_RESPONSE_CANCEL, - _("_Apply"), GTK_RESPONSE_OK, - - NULL); - - gimp_dialog_set_alternative_button_order (GTK_DIALOG (dialog), - RESPONSE_RESET, - GTK_RESPONSE_OK, - GTK_RESPONSE_CANCEL, - -1); - - gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE); - - g_signal_connect (dialog, "response", - G_CALLBACK (vector_layer_options_dialog_response), - dialog); - - g_object_set_data (G_OBJECT (dialog), "layer", layer); - - g_object_set_data_full (G_OBJECT (dialog), "saved-options", - saved_options, - (GDestroyNotify) g_object_unref); - g_object_set_data_full (G_OBJECT (dialog), "fill-options", - fill_options, - (GDestroyNotify) g_object_unref); - g_object_set_data_full (G_OBJECT (dialog), "stroke-options", - stroke_options, - (GDestroyNotify) g_object_unref); - - g_signal_connect_object (saved_options, "notify::enable-fill", - G_CALLBACK (vector_layer_options_dialog_notify), - dialog, 0); - g_signal_connect_object (saved_options, "notify::enable-stroke", - G_CALLBACK (vector_layer_options_dialog_notify), - dialog, 0); - - g_signal_connect_object (fill_options, "notify", - G_CALLBACK (vector_layer_options_dialog_notify), - dialog, 0); - g_signal_connect_object (stroke_options, "notify", - G_CALLBACK (vector_layer_options_dialog_notify), - dialog, 0); - - main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12); - gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 12); - gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), - main_vbox, TRUE, TRUE, 0); - gtk_widget_set_visible (main_vbox, TRUE); - - - combo = gimp_container_combo_box_new (gimp_image_get_paths (gimp_item_get_image (GIMP_ITEM (layer))), - context, - GIMP_VIEW_SIZE_SMALL, 1); - gimp_container_view_set_1_selected (GIMP_CONTAINER_VIEW (combo), - GIMP_VIEWABLE (saved_options->path)); - g_signal_connect_object (combo, "selection-changed", - G_CALLBACK (vector_layer_options_dialog_path_selected), - dialog, 0); - - gtk_box_pack_start (GTK_BOX (main_vbox), combo, FALSE, FALSE, 0); - gtk_widget_set_visible (combo, TRUE); - - /* The fill editor */ - { - GtkWidget *frame; - GtkWidget *fill_editor; - - fill_editor = gimp_fill_editor_new (fill_options, TRUE, TRUE); - gtk_widget_set_visible (fill_editor, TRUE); - - frame = gimp_prop_expanding_frame_new (G_OBJECT (saved_options), - "enable-fill", NULL, fill_editor, - NULL); - gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0); - } - - /* The stroke editor */ - { - GtkWidget *frame; - GtkWidget *stroke_editor; - gdouble xres; - gdouble yres; - - gimp_image_get_resolution (gimp_item_get_image (GIMP_ITEM (layer)), - &xres, &yres); - - stroke_editor = gimp_stroke_editor_new (stroke_options, yres, TRUE, TRUE); - gtk_widget_set_visible (stroke_editor, TRUE); - - frame = gimp_prop_expanding_frame_new (G_OBJECT (saved_options), - "enable-stroke", NULL, stroke_editor, - NULL); - gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0); - } - - return dialog; -} - -static void -vector_layer_options_dialog_notify (GObject *options, - const GParamSpec *pspec, - GtkWidget *dialog) -{ - GimpVectorLayer *layer; - GimpFillOptions *fill_options; - GimpStrokeOptions *stroke_options; - gboolean enable_fill; - gboolean enable_stroke; - - layer = g_object_get_data (G_OBJECT (dialog), "layer"); - - enable_fill = layer->options->enable_fill; - enable_stroke = layer->options->enable_stroke; - - fill_options = g_object_get_data (G_OBJECT (dialog), "fill-options"); - stroke_options = g_object_get_data (G_OBJECT (dialog), "stroke-options"); - - gimp_config_sync (G_OBJECT (fill_options), - G_OBJECT (layer->options->fill_options), 0); - gimp_config_sync (G_OBJECT (stroke_options), - G_OBJECT (layer->options->stroke_options), 0); - - if (! strcmp (pspec->name, "enable-fill") || - ! strcmp (pspec->name, "enable-stroke")) - { - GimpVectorLayerOptions *vector_options; - - vector_options = GIMP_VECTOR_LAYER_OPTIONS (options); - - layer->options->enable_fill = vector_options->enable_fill; - layer->options->enable_stroke = vector_options->enable_stroke; - } - - gimp_vector_layer_refresh (layer); - gimp_image_flush (gimp_item_get_image (GIMP_ITEM (layer))); - - layer->options->enable_fill = enable_fill; - layer->options->enable_stroke = enable_stroke; -} - -static void -vector_layer_options_dialog_response (GtkWidget *widget, - gint response_id, - GtkWidget *dialog) -{ - GimpVectorLayer *layer; - GimpPath *path; - GimpVectorLayerOptions *saved_options; - GimpFillOptions *fill_options; - GimpStrokeOptions *stroke_options; - - layer = g_object_get_data (G_OBJECT (dialog), "layer"); - - saved_options = g_object_get_data (G_OBJECT (dialog), "saved-options"); - fill_options = g_object_get_data (G_OBJECT (dialog), "fill-options"); - stroke_options = g_object_get_data (G_OBJECT (dialog), "stroke-options"); - - switch (response_id) - { - case GTK_RESPONSE_OK: - if (layer && layer->options) - { - layer->options->enable_fill = saved_options->enable_fill; - gimp_config_sync (G_OBJECT (saved_options->fill_options), - G_OBJECT (layer->options->fill_options), 0); - layer->options->enable_stroke = saved_options->enable_stroke; - gimp_config_sync (G_OBJECT (saved_options->stroke_options), - G_OBJECT (layer->options->stroke_options), 0); - - gimp_image_undo_push_vector_layer (gimp_item_get_image (GIMP_ITEM (layer)), - _("Fill/Stroke Vector Layer"), - layer, NULL); - - gimp_config_sync (G_OBJECT (fill_options), - G_OBJECT (layer->options->fill_options), 0); - gimp_config_sync (G_OBJECT (stroke_options), - G_OBJECT (layer->options->stroke_options), 0); - } - - gtk_widget_destroy (dialog); - break; - - default: - gimp_config_sync (G_OBJECT (saved_options->fill_options), - G_OBJECT (fill_options), 0); - gimp_config_sync (G_OBJECT (saved_options->stroke_options), - G_OBJECT (stroke_options), 0); - if (layer && layer->options) - { - g_object_get (saved_options, "path", &path, NULL); - g_object_set (layer->options, "path", path, NULL); - - gimp_vector_layer_refresh (layer); - gimp_image_flush (gimp_item_get_image (GIMP_ITEM (layer))); - } - - if (response_id != RESPONSE_RESET) - gtk_widget_destroy (dialog); - break; - } -} - -static void -vector_layer_options_dialog_path_selected (GimpContainerView *view, - GtkWidget *dialog) -{ - GimpViewable *item = gimp_container_view_get_1_selected (view); - GimpPath *path = NULL; - GimpVectorLayer *layer; - - layer = g_object_get_data (G_OBJECT (dialog), "layer"); - - if (item) - path = GIMP_PATH (item); - - if (path && GIMP_IS_PATH (path)) - { - g_object_set (layer->options, "path", path, NULL); - - gimp_vector_layer_refresh (layer); - gimp_image_flush (gimp_item_get_image (GIMP_ITEM (layer))); - } -} diff --git a/app/dialogs/vector-layer-options-dialog.h b/app/dialogs/vector-layer-options-dialog.h deleted file mode 100644 index e2ed040a1b..0000000000 --- a/app/dialogs/vector-layer-options-dialog.h +++ /dev/null @@ -1,34 +0,0 @@ -/* GIMP - The GNU Image Manipulation Program - * Copyright (C) 1995 Spencer Kimball and Peter Mattis - * - * vector-layer-options-dialog.h - * - * Copyright 2006 Hendrik Boom - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef __VECTOR_LAYER_OPTIONS_DIALOG_H__ -#define __VECTOR_LAYER_OPTIONS_DIALOG_H__ - - -GtkWidget * vector_layer_options_dialog_new (GimpVectorLayer *layer, - GimpContext *context, - const gchar *title, - const gchar *icon_name, - const gchar *help_id, - GtkWidget *parent); - - -#endif /* __VECTOR_LAYER_OPTIONS_DIALOG_H__ */ diff --git a/app/path/gimpvectorlayer.c b/app/path/gimpvectorlayer.c index 2e6a980cd9..9da241ea3f 100644 --- a/app/path/gimpvectorlayer.c +++ b/app/path/gimpvectorlayer.c @@ -618,6 +618,30 @@ gimp_vector_layer_new (GimpImage *image, return layer; } +void +gimp_vector_layer_set_path (GimpVectorLayer *layer, + GimpPath *path, + gboolean push_undo) +{ + GimpImage *image = gimp_item_get_image (GIMP_ITEM (layer)); + + if (push_undo) + { + GParamSpec *pspec; + + pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (layer->options), "path"); + gimp_image_undo_push_vector_layer (image, + _("Change Vector Layer Path"), + layer, pspec); + } + + g_object_set (layer->options, + "path", path, + NULL); + + gimp_image_flush (image); +} + /** * gimp_vector_layer_get_path: * @layer: a #GimpVectorLayer diff --git a/app/path/gimpvectorlayer.h b/app/path/gimpvectorlayer.h index 072832a96f..88a5711e3e 100644 --- a/app/path/gimpvectorlayer.h +++ b/app/path/gimpvectorlayer.h @@ -55,6 +55,9 @@ GimpVectorLayer * gimp_vector_layer_new (GimpImage *image, GimpPath *path, GimpContext *context); +void gimp_vector_layer_set_path (GimpVectorLayer *layer, + GimpPath *path, + gboolean push_undo); GimpPath * gimp_vector_layer_get_path (GimpVectorLayer *layer); GimpVectorLayerOptions * gimp_vector_layer_get_options (GimpVectorLayer *layer); diff --git a/app/tools/gimppathtool.c b/app/tools/gimppathtool.c index dd436d812b..3564a79d99 100644 --- a/app/tools/gimppathtool.c +++ b/app/tools/gimppathtool.c @@ -144,6 +144,12 @@ static void gimp_path_tool_to_selection_extended GdkModifierType state); static void gimp_path_tool_create_vector_layer(GimpPathTool *path_tool); + +static void gimp_path_tool_vector_layer_path_changed + (GimpVectorLayerOptions *options, + const GParamSpec *pspec, + GimpPathTool *tool); + static void gimp_path_tool_vector_change_notify (GObject *options, const GParamSpec *pspec, @@ -664,7 +670,8 @@ gimp_path_tool_set_path (GimpPathTool *path_tool, g_return_if_fail (path == NULL || GIMP_IS_PATH (path)); g_return_if_fail (layer == NULL || path == NULL); - tool = GIMP_TOOL (path_tool);options = GIMP_PATH_TOOL_GET_OPTIONS (path_tool); + tool = GIMP_TOOL (path_tool); + options = GIMP_PATH_TOOL_GET_OPTIONS (path_tool); if (layer != NULL) path = gimp_vector_layer_get_path (layer); @@ -884,6 +891,14 @@ gimp_path_tool_create_vector_layer (GimpPathTool *path_tool) path_tool); } +static void +gimp_path_tool_vector_layer_path_changed (GimpVectorLayerOptions *options, + const GParamSpec *pspec, + GimpPathTool *tool) +{ + gimp_path_tool_set_path (tool, tool->current_vector_layer, NULL); +} + static void gimp_path_tool_vector_change_notify (GObject *options, const GParamSpec *pspec, @@ -958,7 +973,8 @@ static void gimp_path_tool_set_layer (GimpPathTool *path_tool, GimpVectorLayer *vector_layer) { - GimpPathOptions *options; + GimpPathOptions *options; + GimpVectorLayerOptions *layer_options; g_return_if_fail (GIMP_IS_PATH_TOOL (path_tool)); @@ -966,6 +982,11 @@ gimp_path_tool_set_layer (GimpPathTool *path_tool, if (path_tool->current_vector_layer) { + layer_options = gimp_vector_layer_get_options (path_tool->current_vector_layer); + g_signal_handlers_disconnect_by_func (layer_options, + gimp_path_tool_vector_layer_path_changed, + path_tool); + g_signal_handlers_disconnect_by_func (options, gimp_path_tool_vector_change_notify, path_tool->current_vector_layer); @@ -986,6 +1007,11 @@ gimp_path_tool_set_layer (GimpPathTool *path_tool, if (vector_layer) { + layer_options = gimp_vector_layer_get_options (vector_layer); + g_signal_connect_object (layer_options, "notify::path", + G_CALLBACK (gimp_path_tool_vector_layer_path_changed), + path_tool, 0); + g_object_set (options, "enable-fill", vector_layer->options->enable_fill, "enable_stroke", vector_layer->options->enable_stroke,