mirror of
https://gitlab.gnome.org/GNOME/gimp.git
synced 2025-10-06 01:12:40 +02:00
path, tools, pdb: UX updates to vector layers
This patch improves vector layer UX based on feedback. In summary: * Makes vector layer editable from the Path tool * Adds initial PDB for creating vector layers in scripts * Size vector layers to the path size, rather than image * Transform tools utilize the path for resizing * Path tool automatically selects vector layer path
This commit is contained in:
@@ -33,7 +33,7 @@
|
||||
|
||||
#include "text/gimptextlayer.h"
|
||||
|
||||
#include "vectors/gimpvectorlayer.h"
|
||||
#include "path/gimpvectorlayer.h"
|
||||
|
||||
#include "widgets/gimphelp-ids.h"
|
||||
#include "widgets/gimpactiongroup.h"
|
||||
@@ -999,7 +999,7 @@ layers_actions_update (GimpActionGroup *group,
|
||||
gimp_action_group_set_action_active (group, action, TRUE);
|
||||
|
||||
text_layer = gimp_item_is_text_layer (GIMP_ITEM (layer));
|
||||
vector_layer = gimp_drawable_is_vector_layer (GIMP_DRAWABLE (layer));
|
||||
vector_layer = gimp_item_is_vector_layer (GIMP_ITEM (layer));
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -74,8 +74,8 @@
|
||||
#include "display/gimpdisplayshell.h"
|
||||
#include "display/gimpimagewindow.h"
|
||||
|
||||
#include "tools/gimppathtool.h"
|
||||
#include "tools/gimptexttool.h"
|
||||
#include "tools/gimpvectortool.h"
|
||||
#include "tools/tool_manager.h"
|
||||
|
||||
#include "dialogs/dialogs.h"
|
||||
@@ -204,6 +204,10 @@ layers_edit_cmd_callback (GimpAction *action,
|
||||
{
|
||||
layers_edit_text_cmd_callback (action, value, data);
|
||||
}
|
||||
else if (gimp_item_is_vector_layer (GIMP_ITEM (layers->data)))
|
||||
{
|
||||
layers_vector_fill_stroke_cmd_callback (action, value, data);
|
||||
}
|
||||
else
|
||||
{
|
||||
layers_edit_attributes_cmd_callback (action, value, data);
|
||||
@@ -273,7 +277,7 @@ layers_edit_vector_cmd_callback (GimpAction *action,
|
||||
|
||||
layer = layers->data;
|
||||
|
||||
if (! gimp_drawable_is_vector_layer (GIMP_DRAWABLE (layer)))
|
||||
if (! gimp_item_is_vector_layer (GIMP_ITEM (layer)))
|
||||
{
|
||||
layers_edit_attributes_cmd_callback (action, value, data);
|
||||
return;
|
||||
@@ -281,13 +285,13 @@ layers_edit_vector_cmd_callback (GimpAction *action,
|
||||
|
||||
active_tool = tool_manager_get_active (image->gimp);
|
||||
|
||||
if (! GIMP_IS_VECTOR_TOOL (active_tool))
|
||||
if (! GIMP_IS_PATH_TOOL (active_tool))
|
||||
{
|
||||
GimpToolInfo *tool_info;
|
||||
|
||||
tool_info = (GimpToolInfo *)
|
||||
gimp_container_get_child_by_name (image->gimp->tool_info_list,
|
||||
"gimp-vector-tool");
|
||||
"gimp-path-tool");
|
||||
|
||||
if (GIMP_IS_TOOL_INFO (tool_info))
|
||||
{
|
||||
@@ -296,9 +300,9 @@ layers_edit_vector_cmd_callback (GimpAction *action,
|
||||
}
|
||||
}
|
||||
|
||||
if (GIMP_IS_VECTOR_TOOL (active_tool))
|
||||
gimp_vector_tool_set_vectors (GIMP_VECTOR_TOOL (active_tool),
|
||||
GIMP_VECTOR_LAYER (layer)->options->path);
|
||||
if (GIMP_IS_PATH_TOOL (active_tool))
|
||||
gimp_path_tool_set_path (GIMP_PATH_TOOL (active_tool),
|
||||
GIMP_VECTOR_LAYER (layer)->options->path);
|
||||
}
|
||||
|
||||
void
|
||||
|
@@ -470,6 +470,7 @@ paths_delete_cmd_callback (GimpAction *action,
|
||||
{
|
||||
GimpImage *image;
|
||||
GList *paths;
|
||||
gboolean attached_to_vector_layer = FALSE;
|
||||
return_if_no_paths (image, paths, data);
|
||||
|
||||
paths = g_list_copy (paths);
|
||||
@@ -479,11 +480,21 @@ paths_delete_cmd_callback (GimpAction *action,
|
||||
_("Remove Paths"));
|
||||
|
||||
for (GList *iter = paths; iter; iter = iter->next)
|
||||
gimp_image_remove_path (image, iter->data, TRUE, NULL);
|
||||
{
|
||||
/* Verify path is not attached to vector layer */
|
||||
if (! gimp_path_attached_to_vector_layer (GIMP_PATH (iter->data), image))
|
||||
gimp_image_remove_path (image, iter->data, TRUE, NULL);
|
||||
else
|
||||
attached_to_vector_layer = TRUE;
|
||||
}
|
||||
|
||||
gimp_image_undo_group_end (image);
|
||||
gimp_image_flush (image);
|
||||
g_list_free (paths);
|
||||
|
||||
if (attached_to_vector_layer)
|
||||
gimp_message_literal (image->gimp, NULL, GIMP_MESSAGE_WARNING,
|
||||
_("Paths attached to vector layers weren't deleted"));
|
||||
}
|
||||
|
||||
void
|
||||
|
@@ -1267,6 +1267,8 @@ gimp_undo_type_get_type (void)
|
||||
{ GIMP_UNDO_TEXT_LAYER, "GIMP_UNDO_TEXT_LAYER", "text-layer" },
|
||||
{ GIMP_UNDO_TEXT_LAYER_MODIFIED, "GIMP_UNDO_TEXT_LAYER_MODIFIED", "text-layer-modified" },
|
||||
{ GIMP_UNDO_TEXT_LAYER_CONVERT, "GIMP_UNDO_TEXT_LAYER_CONVERT", "text-layer-convert" },
|
||||
{ GIMP_UNDO_VECTOR_LAYER, "GIMP_UNDO_VECTOR_LAYER", "vector-layer" },
|
||||
{ GIMP_UNDO_VECTOR_LAYER_MODIFIED, "GIMP_UNDO_VECTOR_LAYER_MODIFIED", "vector-layer-modified" },
|
||||
{ GIMP_UNDO_LAYER_MASK_ADD, "GIMP_UNDO_LAYER_MASK_ADD", "layer-mask-add" },
|
||||
{ GIMP_UNDO_LAYER_MASK_REMOVE, "GIMP_UNDO_LAYER_MASK_REMOVE", "layer-mask-remove" },
|
||||
{ GIMP_UNDO_LAYER_MASK_APPLY, "GIMP_UNDO_LAYER_MASK_APPLY", "layer-mask-apply" },
|
||||
@@ -1380,6 +1382,8 @@ gimp_undo_type_get_type (void)
|
||||
{ GIMP_UNDO_TEXT_LAYER, NC_("undo-type", "Text layer"), NULL },
|
||||
{ GIMP_UNDO_TEXT_LAYER_MODIFIED, NC_("undo-type", "Text layer modification"), NULL },
|
||||
{ GIMP_UNDO_TEXT_LAYER_CONVERT, NC_("undo-type", "Convert text layer"), NULL },
|
||||
{ GIMP_UNDO_VECTOR_LAYER, NC_("undo-type", "Vector layer"), NULL },
|
||||
{ GIMP_UNDO_VECTOR_LAYER_MODIFIED, NC_("undo-type", "Vector layer modification"), NULL },
|
||||
{ GIMP_UNDO_LAYER_MASK_ADD, NC_("undo-type", "Add layer masks"), NULL },
|
||||
{ GIMP_UNDO_LAYER_MASK_REMOVE, NC_("undo-type", "Delete layer masks"), NULL },
|
||||
{ GIMP_UNDO_LAYER_MASK_APPLY, NC_("undo-type", "Apply layer masks"), NULL },
|
||||
|
@@ -619,6 +619,8 @@ typedef enum /*< pdb-skip >*/
|
||||
GIMP_UNDO_TEXT_LAYER, /*< desc="Text layer" >*/
|
||||
GIMP_UNDO_TEXT_LAYER_MODIFIED, /*< desc="Text layer modification" >*/
|
||||
GIMP_UNDO_TEXT_LAYER_CONVERT, /*< desc="Convert text layer" >*/
|
||||
GIMP_UNDO_VECTOR_LAYER, /*< desc="Vector layer" >*/
|
||||
GIMP_UNDO_VECTOR_LAYER_MODIFIED, /*< desc="Vector layer modification" >*/
|
||||
GIMP_UNDO_LAYER_MASK_ADD, /*< desc="Add layer masks" >*/
|
||||
GIMP_UNDO_LAYER_MASK_REMOVE, /*< desc="Delete layer masks" >*/
|
||||
GIMP_UNDO_LAYER_MASK_APPLY, /*< desc="Apply layer masks" >*/
|
||||
|
@@ -57,6 +57,8 @@
|
||||
#include "path/gimppathmodundo.h"
|
||||
#include "path/gimppathpropundo.h"
|
||||
#include "path/gimppathundo.h"
|
||||
#include "path/gimpvectorlayer.h"
|
||||
#include "path/gimpvectorlayerundo.h"
|
||||
|
||||
#include "text/gimptextlayer.h"
|
||||
#include "text/gimptextundo.h"
|
||||
@@ -877,6 +879,45 @@ gimp_image_undo_push_text_layer_convert (GimpImage *image,
|
||||
}
|
||||
|
||||
|
||||
/************************/
|
||||
/* Vector Layer Undos */
|
||||
/************************/
|
||||
|
||||
GimpUndo *
|
||||
gimp_image_undo_push_vector_layer (GimpImage *image,
|
||||
const gchar *undo_desc,
|
||||
GimpVectorLayer *layer,
|
||||
const GParamSpec *pspec)
|
||||
{
|
||||
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
|
||||
g_return_val_if_fail (GIMP_IS_VECTOR_LAYER (layer), NULL);
|
||||
g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (layer)), NULL);
|
||||
|
||||
return gimp_image_undo_push (image, GIMP_TYPE_VECTOR_LAYER_UNDO,
|
||||
GIMP_UNDO_VECTOR_LAYER, undo_desc,
|
||||
GIMP_DIRTY_ITEM | GIMP_DIRTY_DRAWABLE,
|
||||
"item", layer,
|
||||
"param", pspec,
|
||||
NULL);
|
||||
}
|
||||
|
||||
GimpUndo *
|
||||
gimp_image_undo_push_vector_layer_modified (GimpImage *image,
|
||||
const gchar *undo_desc,
|
||||
GimpVectorLayer *layer)
|
||||
{
|
||||
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
|
||||
g_return_val_if_fail (GIMP_IS_VECTOR_LAYER (layer), NULL);
|
||||
g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (layer)), NULL);
|
||||
|
||||
return gimp_image_undo_push (image, GIMP_TYPE_VECTOR_LAYER_UNDO,
|
||||
GIMP_UNDO_VECTOR_LAYER_MODIFIED, undo_desc,
|
||||
GIMP_DIRTY_ITEM_META,
|
||||
"item", layer,
|
||||
NULL);
|
||||
}
|
||||
|
||||
|
||||
/**********************/
|
||||
/* Layer Mask Undos */
|
||||
/**********************/
|
||||
|
@@ -215,6 +215,17 @@ GimpUndo * gimp_image_undo_push_text_layer_convert (GimpImage *image,
|
||||
GimpTextLayer *layer);
|
||||
|
||||
|
||||
/* vector layer undos */
|
||||
|
||||
GimpUndo * gimp_image_undo_push_vector_layer (GimpImage *image,
|
||||
const gchar *undo_desc,
|
||||
GimpVectorLayer *layer,
|
||||
const GParamSpec *pspec);
|
||||
GimpUndo * gimp_image_undo_push_vector_layer_modified
|
||||
(GimpImage *image,
|
||||
const gchar *undo_desc,
|
||||
GimpVectorLayer *layer);
|
||||
|
||||
/* layer mask undos */
|
||||
|
||||
GimpUndo * gimp_image_undo_push_layer_mask_add (GimpImage *image,
|
||||
|
@@ -87,6 +87,7 @@
|
||||
#include "text/gimptextlayer.h"
|
||||
|
||||
#include "path/gimppath.h"
|
||||
#include "path/gimpvectorlayer.h"
|
||||
|
||||
#include "gimp-log.h"
|
||||
#include "gimp-intl.h"
|
||||
@@ -5457,6 +5458,17 @@ gimp_image_add_layer (GimpImage *image,
|
||||
gimp_drawable_attach_floating_sel (gimp_layer_get_floating_sel_drawable (layer),
|
||||
layer);
|
||||
|
||||
/* If the layer is a vector layer, also add its path to the image */
|
||||
if (gimp_item_is_vector_layer (GIMP_ITEM (layer)))
|
||||
{
|
||||
GimpPath *path = gimp_vector_layer_get_path (GIMP_VECTOR_LAYER (layer));
|
||||
|
||||
if (path &&
|
||||
(! gimp_item_is_attached (GIMP_ITEM (path))) &&
|
||||
gimp_item_get_image (GIMP_ITEM (path)) == image)
|
||||
gimp_image_add_path (image, path, NULL, -1, FALSE);
|
||||
}
|
||||
|
||||
if (old_has_alpha != gimp_image_has_alpha (image))
|
||||
private->flush_accum.alpha_changed = TRUE;
|
||||
|
||||
|
@@ -42,6 +42,7 @@
|
||||
#include "gimpselection.h"
|
||||
|
||||
#include "path/gimppath.h"
|
||||
#include "path/gimpvectorlayer.h"
|
||||
|
||||
#include "text/gimpfont.h"
|
||||
#include "text/gimptextlayer.h"
|
||||
|
@@ -1,248 +1,326 @@
|
||||
/* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <gegl.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#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 "widgets/gimpcolorpanel.h"
|
||||
#include "widgets/gimppropwidgets.h"
|
||||
#include "widgets/gimpviewabledialog.h"
|
||||
#include "widgets/gimpstrokeeditor.h"
|
||||
|
||||
#include "vectors/gimpvectorlayer.h"
|
||||
#include "vectors/gimpvectorlayeroptions.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);
|
||||
|
||||
|
||||
/* 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;
|
||||
|
||||
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,
|
||||
_("Choose vector layer options"),
|
||||
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 (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);
|
||||
|
||||
/* The fill editor */
|
||||
{
|
||||
GtkWidget *frame;
|
||||
GtkWidget *fill_editor;
|
||||
|
||||
frame = gimp_frame_new (_("Fill Style"));
|
||||
gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
|
||||
gtk_widget_set_visible (frame, TRUE);
|
||||
|
||||
fill_editor = gimp_fill_editor_new (fill_options, TRUE, TRUE);
|
||||
gtk_container_add (GTK_CONTAINER (frame), fill_editor);
|
||||
gtk_widget_set_visible (fill_editor, TRUE);
|
||||
}
|
||||
|
||||
/* The stroke editor */
|
||||
{
|
||||
GtkWidget *frame;
|
||||
GtkWidget *stroke_editor;
|
||||
gdouble xres;
|
||||
gdouble yres;
|
||||
|
||||
frame = gimp_frame_new (_("Stroke Style"));
|
||||
gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
|
||||
gtk_widget_set_visible (frame, TRUE);
|
||||
|
||||
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_container_add (GTK_CONTAINER (frame), stroke_editor);
|
||||
gtk_widget_set_visible (stroke_editor, TRUE);
|
||||
}
|
||||
|
||||
return dialog;
|
||||
}
|
||||
|
||||
static void
|
||||
vector_layer_options_dialog_notify (GObject *options,
|
||||
const GParamSpec *pspec,
|
||||
GtkWidget *dialog)
|
||||
{
|
||||
GimpVectorLayer *layer;
|
||||
GimpFillOptions *fill_options;
|
||||
GimpStrokeOptions *stroke_options;
|
||||
|
||||
layer = g_object_get_data (G_OBJECT (dialog), "layer");
|
||||
|
||||
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);
|
||||
|
||||
gimp_vector_layer_refresh (layer);
|
||||
gimp_image_flush (gimp_item_get_image (GIMP_ITEM (layer)));
|
||||
}
|
||||
|
||||
static void
|
||||
vector_layer_options_dialog_response (GtkWidget *widget,
|
||||
gint response_id,
|
||||
GtkWidget *dialog)
|
||||
{
|
||||
GimpVectorLayer *layer;
|
||||
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 )
|
||||
{
|
||||
gimp_config_sync (G_OBJECT (saved_options->fill_options),
|
||||
G_OBJECT (layer->options->fill_options), 0);
|
||||
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 (response_id != RESPONSE_RESET)
|
||||
gtk_widget_destroy (dialog);
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <gegl.h>
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#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)));
|
||||
}
|
||||
}
|
||||
|
@@ -1,34 +1,34 @@
|
||||
/* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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__ */
|
||||
/* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#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__ */
|
||||
|
@@ -34,6 +34,8 @@
|
||||
#include "core/gimpgrid.h"
|
||||
#include "core/gimplayer.h"
|
||||
|
||||
#include "path/gimpvectorlayer.h"
|
||||
|
||||
#include "gimpcanvas.h"
|
||||
#include "gimpcanvas-style.h"
|
||||
|
||||
@@ -431,6 +433,15 @@ gimp_canvas_set_layer_style (GtkWidget *canvas,
|
||||
pattern = gimp_cairo_pattern_create_stipple (layer_group_fg, layer_group_bg, 0,
|
||||
offset_x, offset_y, render_space);
|
||||
}
|
||||
else if (gimp_item_is_vector_layer (GIMP_ITEM (layer)))
|
||||
{
|
||||
GeglColor *transparent = gegl_color_new ("transparent");
|
||||
|
||||
pattern = gimp_cairo_pattern_create_stipple (transparent, transparent, 0,
|
||||
offset_x, offset_y, render_space);
|
||||
|
||||
g_clear_object (&transparent);
|
||||
}
|
||||
else
|
||||
{
|
||||
pattern = gimp_cairo_pattern_create_stipple (layer_fg, layer_bg, 0,
|
||||
|
@@ -398,6 +398,7 @@ EXPORTS
|
||||
gimp_item_get_visible
|
||||
gimp_item_height
|
||||
gimp_item_is_text_layer
|
||||
gimp_item_is_vector_layer
|
||||
gimp_item_offsets
|
||||
gimp_item_rename
|
||||
gimp_item_resize
|
||||
@@ -450,7 +451,7 @@ EXPORTS
|
||||
gimp_marshal_VOID__OBJECT_OBJECT
|
||||
gimp_marshal_VOID__OBJECT_POINTER
|
||||
gimp_marshal_VOID__POINTER_BOXED
|
||||
gimp_marshal_VOID__POINTER_ENUM
|
||||
gimp_marshal_VOID__POINTER_ENUM
|
||||
gimp_marshal_VOID__STRING_BOOLEAN_UINT_FLAGS
|
||||
gimp_marshal_VOID__STRING_FLAGS
|
||||
gimp_message
|
||||
|
@@ -40,6 +40,7 @@
|
||||
#include "core/gimperror.h"
|
||||
#include "core/gimpimage.h"
|
||||
#include "core/gimpimage-undo-push.h"
|
||||
#include "core/gimpitemstack.h"
|
||||
#include "core/gimppaintinfo.h"
|
||||
#include "core/gimpstrokeoptions.h"
|
||||
|
||||
@@ -50,6 +51,8 @@
|
||||
#include "gimppath.h"
|
||||
#include "gimppath-preview.h"
|
||||
#include "gimpstroke.h"
|
||||
#include "gimpvectorlayer.h"
|
||||
#include "gimpvectorlayeroptions.h"
|
||||
|
||||
#include "gimp-intl.h"
|
||||
|
||||
@@ -164,6 +167,10 @@ static gint gimp_path_real_interpolate (GimpPath *path,
|
||||
gint max_points,
|
||||
GimpCoords *ret_coords);
|
||||
|
||||
static gboolean gimp_path_attached_to_vector_layer_rec
|
||||
(GimpPath *path,
|
||||
GList *layers);
|
||||
|
||||
static GimpBezierDesc * gimp_path_make_bezier (GimpPath *path);
|
||||
static GimpBezierDesc * gimp_path_real_make_bezier (GimpPath *path);
|
||||
|
||||
@@ -1200,6 +1207,84 @@ gimp_path_real_interpolate (GimpPath *path,
|
||||
return 0;
|
||||
}
|
||||
|
||||
gboolean
|
||||
gimp_path_attached_to_vector_layer (GimpPath *path,
|
||||
GimpImage *image)
|
||||
{
|
||||
GList *layers;
|
||||
GList *list;
|
||||
|
||||
g_return_val_if_fail (GIMP_IS_PATH (path), FALSE);
|
||||
g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE);
|
||||
|
||||
layers = gimp_image_get_layer_iter (image);
|
||||
|
||||
for (list = layers; list; list = g_list_next (list))
|
||||
{
|
||||
if (GIMP_IS_VECTOR_LAYER (list->data))
|
||||
{
|
||||
GimpVectorLayer *vector_layer = GIMP_VECTOR_LAYER (list->data);
|
||||
|
||||
if (vector_layer->options &&
|
||||
vector_layer->options->path &&
|
||||
(path == vector_layer->options->path))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (gimp_viewable_get_children (GIMP_VIEWABLE (list->data)))
|
||||
{
|
||||
GimpContainer *container;
|
||||
GList *iter2;
|
||||
|
||||
container = gimp_viewable_get_children (GIMP_VIEWABLE (list->data));
|
||||
|
||||
iter2 =
|
||||
gimp_item_stack_get_item_iter (GIMP_ITEM_STACK (container));
|
||||
|
||||
if (gimp_path_attached_to_vector_layer_rec (path, iter2))
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gimp_path_attached_to_vector_layer_rec (GimpPath *path,
|
||||
GList *layers)
|
||||
{
|
||||
GList *list;
|
||||
|
||||
for (list = layers; list; list = g_list_next (list))
|
||||
{
|
||||
if (GIMP_IS_VECTOR_LAYER (list->data))
|
||||
{
|
||||
GimpVectorLayer *vector_layer = GIMP_VECTOR_LAYER (list->data);
|
||||
|
||||
if (vector_layer->options &&
|
||||
vector_layer->options->path &&
|
||||
(path == vector_layer->options->path))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (gimp_viewable_get_children (GIMP_VIEWABLE (list->data)))
|
||||
{
|
||||
GimpContainer *container;
|
||||
GList *iter2;
|
||||
|
||||
container = gimp_viewable_get_children (GIMP_VIEWABLE (list->data));
|
||||
|
||||
iter2 =
|
||||
gimp_item_stack_get_item_iter (GIMP_ITEM_STACK (container));
|
||||
|
||||
if (gimp_path_attached_to_vector_layer_rec (path, iter2))
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
const GimpBezierDesc *
|
||||
gimp_path_get_bezier (GimpPath *path)
|
||||
{
|
||||
|
@@ -175,6 +175,9 @@ gint gimp_path_interpolate (GimpPath *path,
|
||||
gint max_points,
|
||||
GimpCoords *ret_coords);
|
||||
|
||||
gboolean gimp_path_attached_to_vector_layer
|
||||
(GimpPath *path,
|
||||
GimpImage *image);
|
||||
/* usually overloaded */
|
||||
|
||||
/* returns a bezier representation */
|
||||
|
172
app/path/gimpvectorlayer-xcf.c
Normal file
172
app/path/gimpvectorlayer-xcf.c
Normal file
@@ -0,0 +1,172 @@
|
||||
/* GIMP - The GNU Image Manipulation Program
|
||||
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||||
*
|
||||
* gimpvectorlayer-xcf.c
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
#include <gio/gio.h>
|
||||
#include <gegl.h>
|
||||
|
||||
#include "libgimpbase/gimpbase.h"
|
||||
|
||||
#include "path-types.h"
|
||||
|
||||
#include "core/gimp.h"
|
||||
#include "core/gimpimage.h"
|
||||
#include "core/gimpparasitelist.h"
|
||||
|
||||
#include "gimpvectorlayeroptions.h"
|
||||
#include "gimpvectorlayeroptions-parasite.h"
|
||||
#include "gimpvectorlayer.h"
|
||||
#include "gimpvectorlayer-xcf.h"
|
||||
|
||||
#include "gimp-intl.h"
|
||||
|
||||
|
||||
static GimpLayer * gimp_vector_layer_from_layer (GimpLayer *layer,
|
||||
GimpVectorLayerOptions *options);
|
||||
|
||||
|
||||
gboolean
|
||||
gimp_vector_layer_xcf_load_hack (GimpLayer **layer)
|
||||
{
|
||||
const gchar *name;
|
||||
GimpVectorLayerOptions *options = NULL;
|
||||
const GimpParasite *parasite;
|
||||
|
||||
g_return_val_if_fail (layer != NULL, FALSE);
|
||||
g_return_val_if_fail (GIMP_IS_LAYER (*layer), FALSE);
|
||||
|
||||
name = gimp_vector_layer_options_parasite_name ();
|
||||
parasite = gimp_item_parasite_find (GIMP_ITEM (*layer), name);
|
||||
|
||||
if (parasite)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
||||
options = gimp_vector_layer_options_from_parasite (
|
||||
parasite, &error, gimp_item_get_image (GIMP_ITEM (*layer))->gimp);
|
||||
|
||||
g_object_set (G_OBJECT (options),
|
||||
"path", gimp_image_get_path_by_tattoo (
|
||||
gimp_item_get_image (GIMP_ITEM (*layer)),
|
||||
options->path_tattoo),
|
||||
NULL);
|
||||
|
||||
if (error)
|
||||
{
|
||||
g_message (_("Problems parsing the vector layer parasite for layer '%s':\n"
|
||||
"%s\n\n"
|
||||
"Some vector layer properties may be wrong. "),
|
||||
gimp_object_get_name (GIMP_OBJECT (*layer)),
|
||||
error->message);
|
||||
|
||||
g_error_free (error);
|
||||
}
|
||||
}
|
||||
|
||||
if (options)
|
||||
{
|
||||
*layer = gimp_vector_layer_from_layer (*layer, options);
|
||||
|
||||
/* let the text layer know what parasite was used to create it */
|
||||
GIMP_VECTOR_LAYER (*layer)->parasite = name;
|
||||
}
|
||||
|
||||
return (options != NULL);
|
||||
}
|
||||
|
||||
void
|
||||
gimp_vector_layer_xcf_save_prepare (GimpVectorLayer *layer)
|
||||
{
|
||||
GimpVectorLayerOptions *options;
|
||||
|
||||
g_return_if_fail (GIMP_IS_VECTOR_LAYER (layer));
|
||||
|
||||
/* If the layer has a text parasite already, it wasn't changed and we
|
||||
* can simply save the original parasite back which is still attached.
|
||||
*/
|
||||
if (layer->parasite)
|
||||
return;
|
||||
|
||||
g_object_get (layer, "vector-layer-options", &options, NULL);
|
||||
if (options)
|
||||
{
|
||||
GimpParasite *parasite = gimp_vector_layer_options_to_parasite (options);
|
||||
|
||||
gimp_parasite_list_add (gimp_item_get_parasites (GIMP_ITEM (layer)), parasite);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gimp_vector_layer_from_layer:
|
||||
* @layer: a #GimpLayer object
|
||||
* @options: a #GimpVectorLayerOptions object
|
||||
*
|
||||
* Converts a standard #GimpLayer and a #GimpVectorLayerOptions object
|
||||
* into a #GimpVectorLayer. The new vector layer takes ownership of the
|
||||
* @options and @layer objects. The @layer object is rendered unusable
|
||||
* by this function. Don't even try to use it afterwards!
|
||||
*
|
||||
* This is a gross hack that is needed in order to load vector layers
|
||||
* from XCF files in a backwards-compatible way. Please don't use it
|
||||
* for anything else!
|
||||
*
|
||||
* Return value: a newly allocated #GimpVectorLayer object
|
||||
**/
|
||||
static GimpLayer *
|
||||
gimp_vector_layer_from_layer (GimpLayer *layer,
|
||||
GimpVectorLayerOptions *options)
|
||||
{
|
||||
GimpVectorLayer *vector_layer;
|
||||
GimpDrawable *drawable;
|
||||
|
||||
g_return_val_if_fail (GIMP_IS_LAYER (layer), NULL);
|
||||
g_return_val_if_fail (GIMP_IS_VECTOR_LAYER_OPTIONS (options), NULL);
|
||||
|
||||
vector_layer = g_object_new (GIMP_TYPE_VECTOR_LAYER,
|
||||
"image", gimp_item_get_image (GIMP_ITEM (layer)),
|
||||
"vector-layer-options", options,
|
||||
NULL);
|
||||
|
||||
gimp_item_replace_item (GIMP_ITEM (vector_layer), GIMP_ITEM (layer));
|
||||
|
||||
drawable = GIMP_DRAWABLE (vector_layer);
|
||||
gimp_drawable_steal_buffer (drawable, GIMP_DRAWABLE (layer));
|
||||
|
||||
gimp_layer_set_opacity (GIMP_LAYER (vector_layer),
|
||||
gimp_layer_get_opacity (layer), FALSE);
|
||||
gimp_layer_set_mode (GIMP_LAYER (vector_layer),
|
||||
gimp_layer_get_mode (layer), FALSE);
|
||||
gimp_layer_set_blend_space (GIMP_LAYER (vector_layer),
|
||||
gimp_layer_get_blend_space (layer), FALSE);
|
||||
gimp_layer_set_composite_space (GIMP_LAYER (vector_layer),
|
||||
gimp_layer_get_composite_space (layer), FALSE);
|
||||
gimp_layer_set_composite_mode (GIMP_LAYER (vector_layer),
|
||||
gimp_layer_get_composite_mode (layer), FALSE);
|
||||
gimp_layer_set_lock_alpha (GIMP_LAYER (vector_layer),
|
||||
gimp_layer_get_lock_alpha (layer), FALSE);
|
||||
|
||||
g_object_unref (options);
|
||||
g_object_unref (layer);
|
||||
|
||||
return GIMP_LAYER (vector_layer);
|
||||
}
|
33
app/path/gimpvectorlayer-xcf.h
Normal file
33
app/path/gimpvectorlayer-xcf.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/* GIMP - The GNU Image Manipulation Program
|
||||
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||||
*
|
||||
* gimpvectorlayer-xcf.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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GIMP_VECTOR_LAYER_XCF_H__
|
||||
#define __GIMP_VECTOR_LAYER_XCF_H__
|
||||
|
||||
|
||||
const gchar * gimp_vector_layer_vector_parasite_name (void) G_GNUC_CONST;
|
||||
const gchar * gimp_vector_layer_fill_parasite_name (void) G_GNUC_CONST;
|
||||
const gchar * gimp_vector_layer_stroke_parasite_name (void) G_GNUC_CONST;
|
||||
gboolean gimp_vector_layer_xcf_load_hack (GimpLayer **layer);
|
||||
void gimp_vector_layer_xcf_save_prepare (GimpVectorLayer *layer);
|
||||
|
||||
|
||||
#endif /* __GIMP_VECTOR_LAYER_XCF_H__ */
|
801
app/path/gimpvectorlayer.c
Normal file
801
app/path/gimpvectorlayer.c
Normal file
@@ -0,0 +1,801 @@
|
||||
/* GIMP - The GNU Image Manipulation Program
|
||||
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||||
*
|
||||
* gimpvectorlayer.c
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <cairo.h>
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
#include <gegl.h>
|
||||
|
||||
#include "libgimpcolor/gimpcolor.h"
|
||||
#include "libgimpconfig/gimpconfig.h"
|
||||
|
||||
#include "path-types.h"
|
||||
|
||||
#include "core/gimp.h"
|
||||
#include "core/gimpdrawable-fill.h"
|
||||
#include "core/gimpdrawable-stroke.h"
|
||||
#include "core/gimpimage.h"
|
||||
#include "core/gimpselection.h"
|
||||
#include "core/gimpimage-undo.h"
|
||||
#include "core/gimpimage-undo-push.h"
|
||||
#include "core/gimpstrokeoptions.h"
|
||||
#include "core/gimpparasitelist.h"
|
||||
|
||||
#include "gimpvectorlayer.h"
|
||||
#include "gimpvectorlayeroptions.h"
|
||||
#include "gimppath.h"
|
||||
|
||||
#include "gimp-intl.h"
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_VECTOR_LAYER_OPTIONS,
|
||||
PROP_MODIFIED
|
||||
};
|
||||
|
||||
|
||||
/* local function declarations */
|
||||
|
||||
static void gimp_vector_layer_finalize (GObject *object);
|
||||
static void gimp_vector_layer_get_property (GObject *object,
|
||||
guint property_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static void gimp_vector_layer_set_property (GObject *object,
|
||||
guint property_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static void gimp_vector_layer_set_vector_options
|
||||
(GimpVectorLayer *layer,
|
||||
GimpVectorLayerOptions *options);
|
||||
|
||||
static void gimp_vector_layer_set_buffer (GimpDrawable *drawable,
|
||||
gboolean push_undo,
|
||||
const gchar *undo_desc,
|
||||
GeglBuffer *buffer,
|
||||
const GeglRectangle *bounds);
|
||||
static void gimp_vector_layer_push_undo (GimpDrawable *drawable,
|
||||
const gchar *undo_desc,
|
||||
GeglBuffer *buffer,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height);
|
||||
|
||||
static gint64 gimp_vector_layer_get_memsize (GimpObject *object,
|
||||
gint64 *gui_size);
|
||||
|
||||
static GimpItem * gimp_vector_layer_duplicate (GimpItem *item,
|
||||
GType new_type);
|
||||
|
||||
static void gimp_vector_layer_translate (GimpLayer *layer,
|
||||
gint offset_x,
|
||||
gint offset_y);
|
||||
static void gimp_vector_layer_scale (GimpItem *item,
|
||||
gint new_width,
|
||||
gint new_height,
|
||||
gint new_offset_x,
|
||||
gint new_offset_y,
|
||||
GimpInterpolationType interp_type,
|
||||
GimpProgress *progress);
|
||||
static void gimp_vector_layer_flip (GimpItem *item,
|
||||
GimpContext *context,
|
||||
GimpOrientationType flip_type,
|
||||
gdouble axis,
|
||||
gboolean clip_result);
|
||||
static void gimp_vector_layer_rotate (GimpItem *item,
|
||||
GimpContext *context,
|
||||
GimpRotationType rotate_type,
|
||||
gdouble center_x,
|
||||
gdouble center_y,
|
||||
gboolean clip_result);
|
||||
static void gimp_vector_layer_transform (GimpItem *item,
|
||||
GimpContext *context,
|
||||
const GimpMatrix3 *matrix,
|
||||
GimpTransformDirection direction,
|
||||
GimpInterpolationType interp_type,
|
||||
GimpTransformResize clip_result,
|
||||
GimpProgress *progress);
|
||||
|
||||
static gboolean gimp_vector_layer_render (GimpVectorLayer *layer);
|
||||
static void gimp_vector_layer_render_path (GimpVectorLayer *layer);
|
||||
static void gimp_vector_layer_changed_options (GimpVectorLayer *layer);
|
||||
|
||||
static void gimp_vector_layer_removed (GimpItem *item);
|
||||
|
||||
static void gimp_vector_layer_removed_options_path
|
||||
(GimpVectorLayer *layer);
|
||||
|
||||
|
||||
G_DEFINE_TYPE (GimpVectorLayer, gimp_vector_layer, GIMP_TYPE_LAYER)
|
||||
|
||||
#define parent_class gimp_vector_layer_parent_class
|
||||
|
||||
|
||||
static void
|
||||
gimp_vector_layer_class_init (GimpVectorLayerClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GimpObjectClass *gimp_object_class = GIMP_OBJECT_CLASS (klass);
|
||||
GimpViewableClass *viewable_class = GIMP_VIEWABLE_CLASS (klass);
|
||||
GimpItemClass *item_class = GIMP_ITEM_CLASS (klass);
|
||||
GimpDrawableClass *drawable_class = GIMP_DRAWABLE_CLASS (klass);
|
||||
GimpLayerClass *layer_class = GIMP_LAYER_CLASS (klass);
|
||||
|
||||
drawable_class->set_buffer = gimp_vector_layer_set_buffer;
|
||||
drawable_class->push_undo = gimp_vector_layer_push_undo;
|
||||
|
||||
object_class->finalize = gimp_vector_layer_finalize;
|
||||
object_class->set_property = gimp_vector_layer_set_property;
|
||||
object_class->get_property = gimp_vector_layer_get_property;
|
||||
|
||||
gimp_object_class->get_memsize = gimp_vector_layer_get_memsize;
|
||||
|
||||
viewable_class->default_icon_name = "gimp-vector-layer";
|
||||
viewable_class->default_name = _("Vector Layer");
|
||||
|
||||
layer_class->translate = gimp_vector_layer_translate;
|
||||
|
||||
item_class->removed = gimp_vector_layer_removed;
|
||||
item_class->duplicate = gimp_vector_layer_duplicate;
|
||||
item_class->scale = gimp_vector_layer_scale;
|
||||
item_class->flip = gimp_vector_layer_flip;
|
||||
item_class->rotate = gimp_vector_layer_rotate;
|
||||
item_class->transform = gimp_vector_layer_transform;
|
||||
item_class->rename_desc = _("Rename Vector Layer");
|
||||
item_class->translate_desc = _("Move Vector Layer");
|
||||
item_class->scale_desc = _("Scale Vector Layer");
|
||||
item_class->resize_desc = _("Resize Vector Layer");
|
||||
item_class->flip_desc = _("Flip Vector Layer");
|
||||
item_class->rotate_desc = _("Rotate Vector Layer");
|
||||
item_class->transform_desc = _("Transform Vector Layer");
|
||||
|
||||
GIMP_CONFIG_PROP_OBJECT (object_class, PROP_VECTOR_LAYER_OPTIONS,
|
||||
"vector-layer-options", NULL, NULL,
|
||||
GIMP_TYPE_VECTOR_LAYER_OPTIONS,
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_MODIFIED,
|
||||
"modified",
|
||||
NULL, NULL,
|
||||
FALSE,
|
||||
GIMP_PARAM_STATIC_STRINGS);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_vector_layer_init (GimpVectorLayer *layer)
|
||||
{
|
||||
layer->options = NULL;
|
||||
layer->parasite = NULL;
|
||||
layer->modified = FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_vector_layer_finalize (GObject *object)
|
||||
{
|
||||
GimpVectorLayer *layer = GIMP_VECTOR_LAYER (object);
|
||||
|
||||
if (layer->options)
|
||||
{
|
||||
g_object_unref (layer->options);
|
||||
layer->options = NULL;
|
||||
}
|
||||
|
||||
if (layer->parasite)
|
||||
{
|
||||
gimp_parasite_list_remove (gimp_item_get_parasites (GIMP_ITEM (layer)),
|
||||
layer->parasite);
|
||||
layer->parasite = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_vector_layer_get_property (GObject *object,
|
||||
guint property_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GimpVectorLayer *vector_layer = GIMP_VECTOR_LAYER (object);
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_VECTOR_LAYER_OPTIONS:
|
||||
g_value_set_object (value, vector_layer->options);
|
||||
break;
|
||||
case PROP_MODIFIED:
|
||||
g_value_set_boolean (value, vector_layer->modified);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_vector_layer_set_property (GObject *object,
|
||||
guint property_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GimpVectorLayer *vector_layer = GIMP_VECTOR_LAYER (object);
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_VECTOR_LAYER_OPTIONS:
|
||||
if (vector_layer->options)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (vector_layer->options,
|
||||
G_CALLBACK (gimp_vector_layer_changed_options),
|
||||
vector_layer);
|
||||
if (vector_layer->options->path)
|
||||
g_signal_handlers_disconnect_by_func (vector_layer->options->path,
|
||||
G_CALLBACK (gimp_vector_layer_removed_options_path),
|
||||
vector_layer);
|
||||
|
||||
g_object_unref (vector_layer->options);
|
||||
}
|
||||
|
||||
vector_layer->options = g_value_dup_object (value);
|
||||
|
||||
if (vector_layer->options)
|
||||
{
|
||||
if (vector_layer->options->path)
|
||||
g_signal_connect_object (vector_layer->options->path, "removed",
|
||||
G_CALLBACK (gimp_vector_layer_removed_options_path),
|
||||
vector_layer, G_CONNECT_SWAPPED);
|
||||
|
||||
g_signal_connect_object (vector_layer->options, "notify",
|
||||
G_CALLBACK (gimp_vector_layer_changed_options),
|
||||
vector_layer, G_CONNECT_SWAPPED);
|
||||
|
||||
}
|
||||
break;
|
||||
case PROP_MODIFIED:
|
||||
vector_layer->modified = g_value_get_boolean (value);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_vector_layer_set_vector_options (GimpVectorLayer *layer,
|
||||
GimpVectorLayerOptions *options)
|
||||
{
|
||||
if (layer->options)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (layer->options,
|
||||
G_CALLBACK (gimp_vector_layer_changed_options),
|
||||
layer);
|
||||
g_object_unref (layer->options);
|
||||
}
|
||||
|
||||
layer->options = options;
|
||||
gimp_vector_layer_changed_options (layer);
|
||||
|
||||
if (layer->options)
|
||||
g_signal_connect_object (layer->options, "notify",
|
||||
G_CALLBACK (gimp_vector_layer_changed_options),
|
||||
layer, G_CONNECT_SWAPPED);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_vector_layer_set_buffer (GimpDrawable *drawable,
|
||||
gboolean push_undo,
|
||||
const gchar *undo_desc,
|
||||
GeglBuffer *buffer,
|
||||
const GeglRectangle *bounds)
|
||||
{
|
||||
GimpVectorLayer *layer = GIMP_VECTOR_LAYER (drawable);
|
||||
GimpImage *image = gimp_item_get_image (GIMP_ITEM (layer));
|
||||
|
||||
if (push_undo && ! layer->modified)
|
||||
gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_DRAWABLE_MOD,
|
||||
undo_desc);
|
||||
|
||||
GIMP_DRAWABLE_CLASS (parent_class)->set_buffer (drawable,
|
||||
push_undo, undo_desc,
|
||||
buffer, bounds);
|
||||
|
||||
if (push_undo && ! layer->modified)
|
||||
{
|
||||
gimp_image_undo_push_vector_layer_modified (image, NULL, layer);
|
||||
|
||||
g_object_set (drawable, "modified", TRUE, NULL);
|
||||
|
||||
gimp_image_undo_group_end (image);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_vector_layer_push_undo (GimpDrawable *drawable,
|
||||
const gchar *undo_desc,
|
||||
GeglBuffer *buffer,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
GimpVectorLayer *layer = GIMP_VECTOR_LAYER (drawable);
|
||||
GimpImage *image = gimp_item_get_image (GIMP_ITEM (layer));
|
||||
|
||||
if (! layer->modified)
|
||||
gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_DRAWABLE, undo_desc);
|
||||
|
||||
GIMP_DRAWABLE_CLASS (parent_class)->push_undo (drawable, undo_desc,
|
||||
buffer,
|
||||
x, y, width, height);
|
||||
|
||||
if (! layer->modified)
|
||||
{
|
||||
gimp_image_undo_push_vector_layer_modified (image, NULL, layer);
|
||||
|
||||
g_object_set (drawable, "modified", TRUE, NULL);
|
||||
|
||||
gimp_image_undo_group_end (image);
|
||||
}
|
||||
}
|
||||
|
||||
static gint64
|
||||
gimp_vector_layer_get_memsize (GimpObject *object,
|
||||
gint64 *gui_size)
|
||||
{
|
||||
GimpVectorLayer *vector_layer = GIMP_VECTOR_LAYER (object);
|
||||
gint64 memsize = 0;
|
||||
|
||||
memsize += gimp_object_get_memsize (GIMP_OBJECT (vector_layer->options),
|
||||
gui_size);
|
||||
|
||||
return memsize + GIMP_OBJECT_CLASS (parent_class)->get_memsize (object,
|
||||
gui_size);
|
||||
}
|
||||
|
||||
static GimpItem *
|
||||
gimp_vector_layer_duplicate (GimpItem *item,
|
||||
GType new_type)
|
||||
{
|
||||
GimpItem *new_item;
|
||||
|
||||
g_return_val_if_fail (g_type_is_a (new_type, GIMP_TYPE_DRAWABLE), NULL);
|
||||
|
||||
new_item = GIMP_ITEM_CLASS (parent_class)->duplicate (item, new_type);
|
||||
|
||||
if (GIMP_IS_VECTOR_LAYER (new_item))
|
||||
{
|
||||
GimpVectorLayer *vector_layer = GIMP_VECTOR_LAYER (item);
|
||||
GimpVectorLayer *new_vector_layer = GIMP_VECTOR_LAYER (new_item);
|
||||
|
||||
if (vector_layer->options)
|
||||
{
|
||||
GimpVectorLayerOptions *new_options =
|
||||
gimp_config_duplicate (GIMP_CONFIG (vector_layer->options));
|
||||
|
||||
if (vector_layer->options->path)
|
||||
{
|
||||
GimpPath *path = gimp_vector_layer_get_path (vector_layer);
|
||||
GimpPath *new_path;
|
||||
|
||||
new_path = GIMP_PATH (gimp_item_duplicate (GIMP_ITEM (path),
|
||||
G_TYPE_FROM_INSTANCE (GIMP_ITEM (path))));
|
||||
|
||||
g_object_set (new_options, "path", new_path, NULL);
|
||||
}
|
||||
|
||||
g_object_set (new_vector_layer,
|
||||
"vector-layer-options", new_options,
|
||||
NULL);
|
||||
g_object_unref (new_options);
|
||||
}
|
||||
}
|
||||
|
||||
return new_item;
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_vector_layer_translate (GimpLayer *layer,
|
||||
gint offset_x,
|
||||
gint offset_y)
|
||||
{
|
||||
GimpVectorLayer *vector_layer = GIMP_VECTOR_LAYER (layer);
|
||||
|
||||
if (vector_layer->options && vector_layer->options->path)
|
||||
{
|
||||
gimp_item_translate (GIMP_ITEM (vector_layer->options->path),
|
||||
offset_x, offset_y, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
GIMP_LAYER_CLASS (parent_class)->translate (layer, offset_x, offset_y);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_vector_layer_scale (GimpItem *item,
|
||||
gint new_width,
|
||||
gint new_height,
|
||||
gint new_offset_x,
|
||||
gint new_offset_y,
|
||||
GimpInterpolationType interp_type,
|
||||
GimpProgress *progress)
|
||||
{
|
||||
GimpVectorLayer *vector_layer = GIMP_VECTOR_LAYER (item);
|
||||
|
||||
if (vector_layer->options && vector_layer->options->path)
|
||||
{
|
||||
gimp_item_scale (GIMP_ITEM (vector_layer->options->path),
|
||||
new_width, new_height, new_offset_x, new_offset_y,
|
||||
interp_type, progress);
|
||||
}
|
||||
else
|
||||
{
|
||||
GIMP_ITEM_CLASS (parent_class)->scale (item, new_width, new_height,
|
||||
new_offset_x, new_offset_y,
|
||||
interp_type, progress);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_vector_layer_flip (GimpItem *item,
|
||||
GimpContext *context,
|
||||
GimpOrientationType flip_type,
|
||||
gdouble axis,
|
||||
gboolean clip_result)
|
||||
{
|
||||
GimpVectorLayer *vector_layer = GIMP_VECTOR_LAYER (item);
|
||||
|
||||
if (vector_layer->options && vector_layer->options->path)
|
||||
{
|
||||
gimp_item_flip (GIMP_ITEM (vector_layer->options->path),
|
||||
context, flip_type, axis, clip_result);
|
||||
}
|
||||
else
|
||||
{
|
||||
GIMP_ITEM_CLASS (parent_class)->flip (item, context, flip_type,
|
||||
axis, clip_result);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_vector_layer_rotate (GimpItem *item,
|
||||
GimpContext *context,
|
||||
GimpRotationType rotate_type,
|
||||
gdouble center_x,
|
||||
gdouble center_y,
|
||||
gboolean clip_result)
|
||||
{
|
||||
GimpVectorLayer *vector_layer = GIMP_VECTOR_LAYER (item);
|
||||
|
||||
if (vector_layer->options && vector_layer->options->path)
|
||||
{
|
||||
gimp_item_rotate (GIMP_ITEM (vector_layer->options->path),
|
||||
context, rotate_type, center_x, center_y, clip_result);
|
||||
}
|
||||
else
|
||||
{
|
||||
GIMP_ITEM_CLASS (parent_class)->rotate (item, context, rotate_type,
|
||||
center_x, center_y, clip_result);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_vector_layer_transform (GimpItem *item,
|
||||
GimpContext *context,
|
||||
const GimpMatrix3 *matrix,
|
||||
GimpTransformDirection direction,
|
||||
GimpInterpolationType interp_type,
|
||||
GimpTransformResize clip_result,
|
||||
GimpProgress *progress)
|
||||
{
|
||||
GimpVectorLayer *vector_layer = GIMP_VECTOR_LAYER (item);
|
||||
|
||||
if (vector_layer->options && vector_layer->options->path)
|
||||
{
|
||||
gimp_item_transform (GIMP_ITEM (vector_layer->options->path),
|
||||
context, matrix, direction, interp_type,
|
||||
clip_result, progress);
|
||||
}
|
||||
else
|
||||
{
|
||||
GIMP_ITEM_CLASS (parent_class)->transform (item, context, matrix,
|
||||
direction, interp_type,
|
||||
clip_result, progress);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_vector_layer_removed_options_path (GimpVectorLayer *layer)
|
||||
{
|
||||
if (layer->options)
|
||||
{
|
||||
gimp_image_undo_push_vector_layer (gimp_item_get_image (GIMP_ITEM (layer)),
|
||||
_("Discard Vector Informations"),
|
||||
layer, NULL);
|
||||
|
||||
g_object_set (layer->options, "path", NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_vector_layer_removed (GimpItem *item)
|
||||
{
|
||||
GimpVectorLayer *vector_layer = GIMP_VECTOR_LAYER (item);
|
||||
|
||||
if (vector_layer->options && vector_layer->options->path)
|
||||
g_signal_handlers_disconnect_by_func (vector_layer->options->path,
|
||||
G_CALLBACK (gimp_vector_layer_removed_options_path),
|
||||
vector_layer);
|
||||
|
||||
GIMP_ITEM_CLASS (parent_class)->removed (item);
|
||||
}
|
||||
|
||||
|
||||
/* public functions */
|
||||
|
||||
/**
|
||||
* gimp_vector_layer_new:
|
||||
* @image: the #GimpImage the layer should belong to
|
||||
* @path: the #GimpPath object the layer should render
|
||||
* @context: the #GimpContext from which to pull context properties
|
||||
*
|
||||
* Creates a new vector layer.
|
||||
*
|
||||
* Return value: a new #GimpVectorLayer or %NULL in case of a problem
|
||||
**/
|
||||
GimpVectorLayer *
|
||||
gimp_vector_layer_new (GimpImage *image,
|
||||
GimpPath *path,
|
||||
GimpContext *context)
|
||||
{
|
||||
GimpVectorLayer *layer;
|
||||
GimpVectorLayerOptions *options;
|
||||
gint x = 0;
|
||||
gint y = 0;
|
||||
gint width = gimp_image_get_width (image);
|
||||
gint height = gimp_image_get_height (image);
|
||||
|
||||
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
|
||||
g_return_val_if_fail (GIMP_IS_PATH (path), NULL);
|
||||
g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
|
||||
|
||||
options = gimp_vector_layer_options_new (image, path, context);
|
||||
|
||||
gimp_item_bounds (GIMP_ITEM (path), &x, &y, &width, &height);
|
||||
|
||||
/* Set boundaries to image size if it's a blank path */
|
||||
if (width == 0 || height == 0)
|
||||
{
|
||||
width = gimp_image_get_width (image);
|
||||
height = gimp_image_get_height (image);
|
||||
}
|
||||
|
||||
layer =
|
||||
GIMP_VECTOR_LAYER (gimp_drawable_new (GIMP_TYPE_VECTOR_LAYER,
|
||||
image, NULL,
|
||||
x, y, width, height,
|
||||
gimp_image_get_layer_format (image,
|
||||
TRUE)));
|
||||
|
||||
gimp_object_set_name (GIMP_OBJECT (layer),
|
||||
gimp_object_get_name (GIMP_OBJECT (path)));
|
||||
|
||||
gimp_layer_set_mode (GIMP_LAYER (layer),
|
||||
gimp_image_get_default_new_layer_mode (image),
|
||||
FALSE);
|
||||
|
||||
gimp_vector_layer_set_vector_options (layer, options);
|
||||
|
||||
return layer;
|
||||
}
|
||||
|
||||
/**
|
||||
* gimp_vector_layer_get_path:
|
||||
* @layer: a #GimpVectorLayer
|
||||
*
|
||||
* Gets the path from @layer if one is associated with it.
|
||||
*
|
||||
* Return value: a #GimpPath or %NULL if no path is set.
|
||||
*/
|
||||
GimpPath *
|
||||
gimp_vector_layer_get_path (GimpVectorLayer *layer)
|
||||
{
|
||||
g_return_val_if_fail (GIMP_IS_VECTOR_LAYER (layer), NULL);
|
||||
|
||||
if (gimp_item_is_vector_layer (GIMP_ITEM (layer)))
|
||||
return layer->options->path;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
gimp_vector_layer_refresh (GimpVectorLayer *layer)
|
||||
{
|
||||
if (layer->options)
|
||||
gimp_vector_layer_render (layer);
|
||||
}
|
||||
|
||||
/**
|
||||
* gimp_vector_layer_discard:
|
||||
* @layer: a #GimpVectorLayer
|
||||
*
|
||||
* Discards the vector information. This makes @layer behave like a
|
||||
* normal layer.
|
||||
*/
|
||||
void
|
||||
gimp_vector_layer_discard (GimpVectorLayer *layer)
|
||||
{
|
||||
g_return_if_fail (GIMP_IS_VECTOR_LAYER (layer));
|
||||
g_return_if_fail (gimp_item_is_attached (GIMP_ITEM (layer)));
|
||||
|
||||
if (! layer->options)
|
||||
return;
|
||||
|
||||
if (layer->options->path)
|
||||
gimp_image_undo_push_vector_layer (gimp_item_get_image (GIMP_ITEM (layer)),
|
||||
_("Discard Vector Information"),
|
||||
layer, NULL);
|
||||
|
||||
g_object_set (layer, "vector-layer-options", NULL, NULL);
|
||||
|
||||
gimp_viewable_invalidate_preview (GIMP_VIEWABLE (layer));
|
||||
gimp_image_flush (gimp_item_get_image (GIMP_ITEM (layer)));
|
||||
}
|
||||
|
||||
gboolean
|
||||
gimp_item_is_vector_layer (GimpItem *item)
|
||||
{
|
||||
return (GIMP_IS_VECTOR_LAYER (item) &&
|
||||
GIMP_VECTOR_LAYER (item)->options);
|
||||
}
|
||||
|
||||
|
||||
/* private functions */
|
||||
|
||||
static gboolean
|
||||
gimp_vector_layer_render (GimpVectorLayer *layer)
|
||||
{
|
||||
GimpDrawable *drawable = GIMP_DRAWABLE (layer);
|
||||
GeglBuffer *buffer = NULL;
|
||||
GimpItem *item = GIMP_ITEM (layer);
|
||||
GimpImage *image = gimp_item_get_image (item);
|
||||
gint layer_x = 0;
|
||||
gint layer_y = 0;
|
||||
gint x = 0;
|
||||
gint y = 0;
|
||||
gint width = gimp_image_get_width (image);
|
||||
gint height = gimp_image_get_height (image);
|
||||
gdouble stroke = 0;
|
||||
|
||||
g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)), FALSE);
|
||||
|
||||
g_object_freeze_notify (G_OBJECT (drawable));
|
||||
|
||||
if (layer->options->enable_stroke)
|
||||
stroke = gimp_stroke_options_get_width (layer->options->stroke_options);
|
||||
|
||||
/* Resize layer according to path size */
|
||||
gimp_item_get_offset (GIMP_ITEM (layer), &layer_x, &layer_y);
|
||||
gimp_item_bounds (GIMP_ITEM (layer->options->path), &x, &y, &width, &height);
|
||||
|
||||
buffer = gegl_buffer_new (GEGL_RECTANGLE (0, 0,
|
||||
width + stroke, height + stroke),
|
||||
gimp_drawable_get_format (drawable));
|
||||
gimp_drawable_set_buffer (drawable, FALSE, NULL, buffer);
|
||||
g_object_unref (buffer);
|
||||
|
||||
gimp_item_set_offset (GIMP_ITEM (layer), x - (stroke / 2), y - (stroke / 2));
|
||||
|
||||
/* make the layer background transparent */
|
||||
gimp_drawable_fill (GIMP_DRAWABLE (layer),
|
||||
gimp_get_user_context (image->gimp),
|
||||
GIMP_FILL_TRANSPARENT);
|
||||
|
||||
/* render path to the layer */
|
||||
gimp_vector_layer_render_path (layer);
|
||||
|
||||
g_object_thaw_notify (G_OBJECT (drawable));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_vector_layer_render_path (GimpVectorLayer *layer)
|
||||
{
|
||||
GimpImage *image = gimp_item_get_image (GIMP_ITEM (layer));
|
||||
GimpVectorLayerOptions *options = layer->options;
|
||||
GimpPath *path = NULL;
|
||||
GimpChannel *selection = gimp_image_get_mask (image);
|
||||
GList *drawables;
|
||||
GimpCustomStyle style;
|
||||
|
||||
if (options)
|
||||
path = options->path;
|
||||
|
||||
/* Don't mask these fill/stroke operations */
|
||||
gimp_selection_suspend (GIMP_SELECTION (selection));
|
||||
|
||||
/* Convert from custom to standard styles */
|
||||
style = gimp_fill_options_get_custom_style (options->fill_options);
|
||||
if (style == GIMP_CUSTOM_STYLE_SOLID_COLOR ||
|
||||
! gimp_context_get_pattern (GIMP_CONTEXT (options->fill_options)))
|
||||
gimp_fill_options_set_style (options->fill_options,
|
||||
GIMP_FILL_STYLE_FG_COLOR);
|
||||
else
|
||||
gimp_fill_options_set_style (options->fill_options,
|
||||
GIMP_FILL_STYLE_PATTERN);
|
||||
|
||||
style =
|
||||
gimp_fill_options_get_custom_style (GIMP_FILL_OPTIONS (options->stroke_options));
|
||||
if (style == GIMP_CUSTOM_STYLE_SOLID_COLOR ||
|
||||
! gimp_context_get_pattern (GIMP_CONTEXT (options->stroke_options)))
|
||||
gimp_fill_options_set_style (GIMP_FILL_OPTIONS (options->stroke_options),
|
||||
GIMP_FILL_STYLE_FG_COLOR);
|
||||
else
|
||||
gimp_fill_options_set_style (GIMP_FILL_OPTIONS (options->stroke_options),
|
||||
GIMP_FILL_STYLE_PATTERN);
|
||||
|
||||
/* Fill the path object onto the layer */
|
||||
if (options->enable_fill)
|
||||
gimp_drawable_fill_path (GIMP_DRAWABLE (layer),
|
||||
options->fill_options,
|
||||
path, FALSE, NULL);
|
||||
|
||||
drawables = g_list_prepend (NULL, GIMP_DRAWABLE (layer));
|
||||
/* stroke the path object onto the layer */
|
||||
if (options->enable_stroke && gimp_item_is_attached (GIMP_ITEM (path)))
|
||||
gimp_item_stroke (GIMP_ITEM (path), drawables,
|
||||
gimp_get_user_context (image->gimp),
|
||||
options->stroke_options,
|
||||
FALSE, FALSE,
|
||||
NULL, NULL);
|
||||
|
||||
g_list_free (drawables);
|
||||
|
||||
gimp_selection_resume (GIMP_SELECTION (selection));
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_vector_layer_changed_options (GimpVectorLayer *layer)
|
||||
{
|
||||
GimpItem *item = GIMP_ITEM (layer);
|
||||
|
||||
if (layer->parasite)
|
||||
{
|
||||
/* parasite is out of date, discard it */
|
||||
gimp_parasite_list_remove (gimp_item_get_parasites (GIMP_ITEM (layer)),
|
||||
layer->parasite);
|
||||
layer->parasite = NULL;
|
||||
}
|
||||
|
||||
if (layer->options && !layer->options->path)
|
||||
gimp_vector_layer_discard (layer);
|
||||
else if (gimp_item_is_attached (item))
|
||||
gimp_vector_layer_refresh (layer);
|
||||
}
|
69
app/path/gimpvectorlayer.h
Normal file
69
app/path/gimpvectorlayer.h
Normal file
@@ -0,0 +1,69 @@
|
||||
/* GIMP - The GNU Image Manipulation Program
|
||||
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||||
*
|
||||
* gimpvectorlayer.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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GIMP_VECTOR_LAYER_H__
|
||||
#define __GIMP_VECTOR_LAYER_H__
|
||||
|
||||
|
||||
#include "core/gimplayer.h"
|
||||
|
||||
|
||||
#define GIMP_TYPE_VECTOR_LAYER (gimp_vector_layer_get_type ())
|
||||
#define GIMP_VECTOR_LAYER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_VECTOR_LAYER, GimpVectorLayer))
|
||||
#define GIMP_VECTOR_LAYER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_VECTOR_LAYER, GimpVectorLayerClass))
|
||||
#define GIMP_IS_VECTOR_LAYER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_VECTOR_LAYER))
|
||||
#define GIMP_IS_VECTOR_LAYER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_VECTOR_LAYER))
|
||||
#define GIMP_VECTOR_LAYER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_VECTOR_LAYER, GimpVectorLayerClass))
|
||||
|
||||
|
||||
typedef struct _GimpVectorLayerClass GimpVectorLayerClass;
|
||||
|
||||
struct _GimpVectorLayer
|
||||
{
|
||||
GimpLayer parent_instance;
|
||||
|
||||
GimpVectorLayerOptions *options;
|
||||
const gchar *parasite;
|
||||
|
||||
gboolean modified;
|
||||
};
|
||||
|
||||
struct _GimpVectorLayerClass
|
||||
{
|
||||
GimpLayerClass parent_class;
|
||||
};
|
||||
|
||||
|
||||
GType gimp_vector_layer_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GimpVectorLayer * gimp_vector_layer_new (GimpImage *image,
|
||||
GimpPath *path,
|
||||
GimpContext *context);
|
||||
|
||||
GimpPath * gimp_vector_layer_get_path (GimpVectorLayer *layer);
|
||||
|
||||
void gimp_vector_layer_refresh (GimpVectorLayer *layer);
|
||||
void gimp_vector_layer_discard (GimpVectorLayer *layer);
|
||||
|
||||
gboolean gimp_item_is_vector_layer (GimpItem *item);
|
||||
|
||||
|
||||
#endif /* __GIMP_VECTOR_LAYER_H__ */
|
95
app/path/gimpvectorlayeroptions-parasite.c
Normal file
95
app/path/gimpvectorlayeroptions-parasite.c
Normal file
@@ -0,0 +1,95 @@
|
||||
/* GIMP - The GNU Image Manipulation Program
|
||||
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||||
*
|
||||
* gimpvectorlayeroptions-parasite.c
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <gio/gio.h>
|
||||
|
||||
#include "libgimpbase/gimpbase.h"
|
||||
#include "libgimpconfig/gimpconfig.h"
|
||||
|
||||
#include "path-types.h"
|
||||
|
||||
#include "gimpvectorlayeroptions.h"
|
||||
#include "gimpvectorlayeroptions-parasite.h"
|
||||
|
||||
#include "gimp-intl.h"
|
||||
|
||||
|
||||
const gchar *
|
||||
gimp_vector_layer_options_parasite_name (void)
|
||||
{
|
||||
return "gimp-vector-layer-options";
|
||||
}
|
||||
|
||||
GimpParasite *
|
||||
gimp_vector_layer_options_to_parasite (GimpVectorLayerOptions *options)
|
||||
{
|
||||
GimpParasite *parasite;
|
||||
gchar *str;
|
||||
|
||||
g_return_val_if_fail (GIMP_IS_VECTOR_LAYER_OPTIONS (options), NULL);
|
||||
|
||||
str = gimp_config_serialize_to_string (GIMP_CONFIG (options), NULL);
|
||||
g_return_val_if_fail (str != NULL, NULL);
|
||||
|
||||
parasite = gimp_parasite_new (gimp_vector_layer_options_parasite_name (),
|
||||
GIMP_PARASITE_PERSISTENT,
|
||||
strlen (str) + 1, str);
|
||||
g_free (str);
|
||||
|
||||
return parasite;
|
||||
}
|
||||
|
||||
GimpVectorLayerOptions *
|
||||
gimp_vector_layer_options_from_parasite (const GimpParasite *parasite,
|
||||
GError **error,
|
||||
Gimp *gimp)
|
||||
{
|
||||
GimpVectorLayerOptions *options;
|
||||
const gchar *str;
|
||||
guint32 parasite_length;
|
||||
|
||||
g_return_val_if_fail (parasite != NULL, NULL);
|
||||
g_return_val_if_fail (strcmp (gimp_parasite_get_name (parasite),
|
||||
gimp_vector_layer_options_parasite_name ()) == 0,
|
||||
NULL);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
||||
|
||||
str = gimp_parasite_get_data (parasite, ¶site_length);
|
||||
g_return_val_if_fail (str != NULL, NULL);
|
||||
|
||||
options = g_object_new (GIMP_TYPE_VECTOR_LAYER_OPTIONS,
|
||||
"gimp", gimp,
|
||||
NULL);
|
||||
|
||||
gimp_config_deserialize_string (GIMP_CONFIG (options),
|
||||
str,
|
||||
parasite_length,
|
||||
NULL,
|
||||
error);
|
||||
|
||||
return options;
|
||||
}
|
33
app/path/gimpvectorlayeroptions-parasite.h
Normal file
33
app/path/gimpvectorlayeroptions-parasite.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/* GIMP - The GNU Image Manipulation Program
|
||||
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||||
*
|
||||
* gimpvectorlayeroptions-parasite.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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GIMP_VECTOR_LAYER_OPTIONS_PARASITE_H__
|
||||
#define __GIMP_VECTOR_LAYER_OPTIONS_PARASITE_H__
|
||||
|
||||
|
||||
const gchar * gimp_vector_layer_options_parasite_name (void) G_GNUC_CONST;
|
||||
GimpParasite * gimp_vector_layer_options_to_parasite (GimpVectorLayerOptions *text);
|
||||
GimpVectorLayerOptions * gimp_vector_layer_options_from_parasite (const GimpParasite *parasite,
|
||||
GError **error,
|
||||
Gimp *gimp);
|
||||
|
||||
|
||||
#endif /* __GIMP_VECTOR_LAYER_OPTIONS_PARASITE_H__ */
|
364
app/path/gimpvectorlayeroptions.c
Normal file
364
app/path/gimpvectorlayeroptions.c
Normal file
@@ -0,0 +1,364 @@
|
||||
/* GIMP - The GNU Image Manipulation Program
|
||||
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||||
*
|
||||
* gimpvectorlayers.c
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <cairo.h>
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
#include <gegl.h>
|
||||
|
||||
#include "libgimpbase/gimpbase.h"
|
||||
#include "libgimpconfig/gimpconfig.h"
|
||||
#include "libgimpcolor/gimpcolor.h"
|
||||
|
||||
#include "path-types.h"
|
||||
|
||||
#include "core/gimp.h"
|
||||
#include "core/gimpimage.h"
|
||||
#include "core/gimpstrokeoptions.h"
|
||||
|
||||
#include "gimppath.h"
|
||||
#include "gimpvectorlayer.h"
|
||||
#include "gimpvectorlayeroptions.h"
|
||||
|
||||
#include "gimp-intl.h"
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_GIMP,
|
||||
PROP_PATH,
|
||||
PROP_PATH_TATTOO,
|
||||
PROP_ENABLE_FILL,
|
||||
PROP_FILL_OPTIONS,
|
||||
PROP_ENABLE_STROKE,
|
||||
PROP_STROKE_OPTIONS
|
||||
};
|
||||
|
||||
|
||||
/* local function declarations */
|
||||
|
||||
static GObject *gimp_vector_layer_options_constructor (GType type,
|
||||
guint n_params,
|
||||
GObjectConstructParam *params);
|
||||
static void gimp_vector_layer_options_finalize (GObject *object);
|
||||
|
||||
static void gimp_vector_layer_options_get_property (GObject *object,
|
||||
guint property_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static void gimp_vector_layer_options_set_property (GObject *object,
|
||||
guint property_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static void gimp_vector_layer_options_path_changed (GimpVectorLayerOptions *options);
|
||||
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (GimpVectorLayerOptions,
|
||||
gimp_vector_layer_options,
|
||||
GIMP_TYPE_OBJECT,
|
||||
G_IMPLEMENT_INTERFACE (GIMP_TYPE_CONFIG, NULL))
|
||||
|
||||
#define parent_class gimp_vector_layer_options_parent_class
|
||||
|
||||
|
||||
static void
|
||||
gimp_vector_layer_options_class_init (GimpVectorLayerOptionsClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->constructor = gimp_vector_layer_options_constructor;
|
||||
object_class->finalize = gimp_vector_layer_options_finalize;
|
||||
object_class->set_property = gimp_vector_layer_options_set_property;
|
||||
object_class->get_property = gimp_vector_layer_options_get_property;
|
||||
|
||||
g_object_class_install_property (object_class, PROP_GIMP,
|
||||
g_param_spec_object ("gimp",
|
||||
NULL, NULL,
|
||||
GIMP_TYPE_GIMP,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY));
|
||||
|
||||
GIMP_CONFIG_PROP_OBJECT (object_class, PROP_PATH,
|
||||
"path", NULL, NULL,
|
||||
GIMP_TYPE_PATH,
|
||||
GIMP_PARAM_READWRITE |
|
||||
GIMP_PARAM_STATIC_STRINGS);
|
||||
|
||||
GIMP_CONFIG_PROP_UINT (object_class, PROP_PATH_TATTOO,
|
||||
"path-tattoo", NULL, NULL,
|
||||
0, G_MAXUINT32, 0,
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_ENABLE_FILL,
|
||||
"enable-fill",
|
||||
_("Fill Style"), NULL,
|
||||
TRUE,
|
||||
GIMP_PARAM_STATIC_STRINGS);
|
||||
|
||||
GIMP_CONFIG_PROP_OBJECT (object_class, PROP_FILL_OPTIONS,
|
||||
"fill-options", NULL, NULL,
|
||||
GIMP_TYPE_FILL_OPTIONS,
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
GIMP_CONFIG_PARAM_AGGREGATE);
|
||||
|
||||
GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_ENABLE_STROKE,
|
||||
"enable-stroke",
|
||||
_("Stroke Style"), NULL,
|
||||
TRUE,
|
||||
GIMP_PARAM_STATIC_STRINGS);
|
||||
|
||||
GIMP_CONFIG_PROP_OBJECT (object_class, PROP_STROKE_OPTIONS,
|
||||
"stroke-options", NULL, NULL,
|
||||
GIMP_TYPE_STROKE_OPTIONS,
|
||||
G_PARAM_STATIC_STRINGS |
|
||||
GIMP_CONFIG_PARAM_AGGREGATE);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_vector_layer_options_init (GimpVectorLayerOptions *options)
|
||||
{
|
||||
options->path = NULL;
|
||||
options->path_tattoo = 0;
|
||||
}
|
||||
|
||||
static GObject *
|
||||
gimp_vector_layer_options_constructor (GType type,
|
||||
guint n_params,
|
||||
GObjectConstructParam *params)
|
||||
{
|
||||
GObject *object;
|
||||
GimpVectorLayerOptions *options;
|
||||
|
||||
object = G_OBJECT_CLASS (parent_class)->constructor (type, n_params, params);
|
||||
|
||||
options = GIMP_VECTOR_LAYER_OPTIONS (object);
|
||||
g_assert (GIMP_IS_GIMP (options->gimp));
|
||||
|
||||
options->fill_options = gimp_fill_options_new (options->gimp, NULL, FALSE);
|
||||
options->stroke_options = gimp_stroke_options_new (options->gimp, NULL, FALSE);
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_vector_layer_options_finalize (GObject *object)
|
||||
{
|
||||
GimpVectorLayerOptions *options = GIMP_VECTOR_LAYER_OPTIONS (object);
|
||||
|
||||
if (options->path)
|
||||
{
|
||||
g_object_unref (options->path);
|
||||
options->path = NULL;
|
||||
}
|
||||
|
||||
if (options->fill_options)
|
||||
{
|
||||
g_object_unref (options->fill_options);
|
||||
options->fill_options = NULL;
|
||||
}
|
||||
|
||||
if (options->stroke_options)
|
||||
{
|
||||
g_object_unref (options->stroke_options);
|
||||
options->stroke_options = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_vector_layer_options_get_property (GObject *object,
|
||||
guint property_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GimpVectorLayerOptions *options = GIMP_VECTOR_LAYER_OPTIONS (object);
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_GIMP:
|
||||
g_value_set_object (value, options->gimp);
|
||||
break;
|
||||
case PROP_PATH:
|
||||
g_value_set_object (value, options->path);
|
||||
break;
|
||||
case PROP_PATH_TATTOO:
|
||||
g_value_set_uint (value, options->path_tattoo);
|
||||
break;
|
||||
case PROP_ENABLE_FILL:
|
||||
g_value_set_boolean (value, options->enable_fill);
|
||||
break;
|
||||
case PROP_FILL_OPTIONS:
|
||||
g_value_set_object (value, options->fill_options);
|
||||
break;
|
||||
case PROP_ENABLE_STROKE:
|
||||
g_value_set_boolean (value, options->enable_stroke);
|
||||
break;
|
||||
case PROP_STROKE_OPTIONS:
|
||||
g_value_set_object (value, options->stroke_options);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_vector_layer_options_set_property (GObject *object,
|
||||
guint property_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GimpVectorLayerOptions *options = GIMP_VECTOR_LAYER_OPTIONS (object);
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_GIMP:
|
||||
options->gimp = g_value_get_object (value);
|
||||
break;
|
||||
|
||||
case PROP_PATH:
|
||||
if (options->path)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (options->path,
|
||||
G_CALLBACK (gimp_vector_layer_options_path_changed),
|
||||
options);
|
||||
g_object_unref (options->path);
|
||||
}
|
||||
|
||||
options->path = g_value_dup_object (value);
|
||||
|
||||
if (options->path)
|
||||
{
|
||||
g_signal_connect_object (options->path, "invalidate-preview",
|
||||
G_CALLBACK (gimp_vector_layer_options_path_changed),
|
||||
options, G_CONNECT_SWAPPED);
|
||||
g_signal_connect_object (options->path, "name-changed",
|
||||
G_CALLBACK (gimp_vector_layer_options_path_changed),
|
||||
options, G_CONNECT_SWAPPED);
|
||||
|
||||
/* update the tattoo */
|
||||
options->path_tattoo = gimp_item_get_tattoo (GIMP_ITEM (options->path));
|
||||
}
|
||||
break;
|
||||
|
||||
case PROP_PATH_TATTOO:
|
||||
options->path_tattoo = g_value_get_uint (value);
|
||||
|
||||
if (options->path &&
|
||||
gimp_item_get_tattoo (GIMP_ITEM (options->path)) != options->path_tattoo)
|
||||
{
|
||||
GimpImage *image = gimp_item_get_image (GIMP_ITEM (options->path));
|
||||
|
||||
g_object_set (options,
|
||||
"path", gimp_image_get_path_by_tattoo
|
||||
(image, options->path_tattoo),
|
||||
NULL);
|
||||
}
|
||||
break;
|
||||
|
||||
case PROP_ENABLE_FILL:
|
||||
options->enable_fill = g_value_get_boolean (value);
|
||||
break;
|
||||
|
||||
case PROP_FILL_OPTIONS:
|
||||
if (g_value_get_object (value))
|
||||
gimp_config_sync (g_value_get_object (value),
|
||||
G_OBJECT (options->fill_options), 0);
|
||||
break;
|
||||
|
||||
case PROP_ENABLE_STROKE:
|
||||
options->enable_stroke = g_value_get_boolean (value);
|
||||
break;
|
||||
|
||||
case PROP_STROKE_OPTIONS:
|
||||
if (g_value_get_object (value))
|
||||
{
|
||||
if (options->stroke_options)
|
||||
g_object_unref (options->stroke_options);
|
||||
options->stroke_options = gimp_config_duplicate (g_value_get_object (value));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_vector_layer_options_path_changed (GimpVectorLayerOptions *options)
|
||||
{
|
||||
g_object_notify (G_OBJECT (options), "path");
|
||||
}
|
||||
|
||||
|
||||
/* public functions */
|
||||
|
||||
/**
|
||||
* gimp_vector_layer_options_new:
|
||||
* @image: the #GimpImage the layer belongs to
|
||||
* @path: the #GimpPath object for the layer to render
|
||||
* @context: the #GimpContext from which to pull context properties
|
||||
*
|
||||
* Creates a new vector layer options.
|
||||
*
|
||||
* Return value: a new #GimpVectorLayerOptions or %NULL in case of a problem
|
||||
**/
|
||||
GimpVectorLayerOptions *
|
||||
gimp_vector_layer_options_new (GimpImage *image,
|
||||
GimpPath *path,
|
||||
GimpContext *context)
|
||||
{
|
||||
GimpVectorLayerOptions *options;
|
||||
GimpPattern *pattern;
|
||||
GeglColor *stroke_color;
|
||||
GeglColor *fill_color;
|
||||
|
||||
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
|
||||
g_return_val_if_fail (GIMP_IS_PATH (path), NULL);
|
||||
g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
|
||||
|
||||
options = g_object_new (GIMP_TYPE_VECTOR_LAYER_OPTIONS,
|
||||
"gimp", image->gimp,
|
||||
NULL);
|
||||
|
||||
stroke_color = gimp_context_get_foreground (context);
|
||||
fill_color = gimp_context_get_background (context);
|
||||
pattern = gimp_context_get_pattern (context);
|
||||
|
||||
gimp_context_set_foreground (GIMP_CONTEXT (options->fill_options),
|
||||
fill_color);
|
||||
gimp_context_set_pattern (GIMP_CONTEXT (options->fill_options), pattern);
|
||||
|
||||
gimp_context_set_foreground (GIMP_CONTEXT (options->stroke_options),
|
||||
stroke_color);
|
||||
gimp_context_set_pattern (GIMP_CONTEXT (options->stroke_options), pattern);
|
||||
|
||||
g_object_set (options,
|
||||
"path", path,
|
||||
NULL);
|
||||
|
||||
return options;
|
||||
}
|
66
app/path/gimpvectorlayeroptions.h
Normal file
66
app/path/gimpvectorlayeroptions.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/* GIMP - The GNU Image Manipulation Program
|
||||
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||||
*
|
||||
* gimpvectorlayeroptions.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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GIMP_VECTOR_LAYER_OPTIONS_H__
|
||||
#define __GIMP_VECTOR_LAYER_OPTIONS_H__
|
||||
|
||||
|
||||
#include "core/gimpobject.h"
|
||||
|
||||
|
||||
#define GIMP_TYPE_VECTOR_LAYER_OPTIONS (gimp_vector_layer_options_get_type ())
|
||||
#define GIMP_VECTOR_LAYER_OPTIONS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_VECTOR_LAYER_OPTIONS, GimpVectorLayerOptions))
|
||||
#define GIMP_VECTOR_LAYER_OPTIONS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_VECTOR_LAYER_OPTIONS, GimpVectorLayerOptionsClass))
|
||||
#define GIMP_IS_VECTOR_LAYER_OPTIONS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_VECTOR_LAYER_OPTIONS))
|
||||
#define GIMP_IS_VECTOR_LAYER_OPTIONS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_VECTOR_LAYER_OPTIONS))
|
||||
#define GIMP_VECTOR_LAYER_OPTIONS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_VECTOR_LAYER_OPTIONS, GimpVectorLayerOptionsClass))
|
||||
|
||||
|
||||
typedef struct _GimpVectorLayerOptionsClass GimpVectorLayerOptionsClass;
|
||||
|
||||
struct _GimpVectorLayerOptions
|
||||
{
|
||||
GimpObject parent_instance;
|
||||
|
||||
Gimp *gimp;
|
||||
|
||||
GimpTattoo path_tattoo;
|
||||
GimpPath *path;
|
||||
|
||||
gboolean enable_fill;
|
||||
gboolean enable_stroke;
|
||||
GimpFillOptions *fill_options;
|
||||
GimpStrokeOptions *stroke_options;
|
||||
};
|
||||
|
||||
struct _GimpVectorLayerOptionsClass
|
||||
{
|
||||
GimpObjectClass parent_class;
|
||||
};
|
||||
|
||||
GType gimp_vector_layer_options_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GimpVectorLayerOptions * gimp_vector_layer_options_new (GimpImage *image,
|
||||
GimpPath *path,
|
||||
GimpContext *context);
|
||||
|
||||
|
||||
#endif /* __GIMP_VECTOR_LAYER_OPTIONS_H__ */
|
288
app/path/gimpvectorlayerundo.c
Normal file
288
app/path/gimpvectorlayerundo.c
Normal file
@@ -0,0 +1,288 @@
|
||||
/* GIMP - The GNU Image Manipulation Program
|
||||
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||||
*
|
||||
* gimpvectorlayerundo.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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
#include <gio/gio.h>
|
||||
#include <gegl.h>
|
||||
|
||||
#include "libgimpconfig/gimpconfig.h"
|
||||
|
||||
#include "path-types.h"
|
||||
|
||||
#include "core/gimp-memsize.h"
|
||||
#include "core/gimpitem.h"
|
||||
#include "core/gimpitemundo.h"
|
||||
#include "core/gimp-utils.h"
|
||||
|
||||
#include "gimpvectorlayer.h"
|
||||
#include "gimpvectorlayeroptions.h"
|
||||
#include "gimpvectorlayerundo.h"
|
||||
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_PARAM
|
||||
};
|
||||
|
||||
|
||||
static void gimp_vector_layer_undo_constructed (GObject *object);
|
||||
static void gimp_vector_layer_undo_set_property (GObject *object,
|
||||
guint property_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static void gimp_vector_layer_undo_get_property (GObject *object,
|
||||
guint property_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static gint64 gimp_vector_layer_undo_get_memsize (GimpObject *object,
|
||||
gint64 *gui_size);
|
||||
static void gimp_vector_layer_undo_pop (GimpUndo *undo,
|
||||
GimpUndoMode undo_mode,
|
||||
GimpUndoAccumulator *accum);
|
||||
static void gimp_vector_layer_undo_free (GimpUndo *undo,
|
||||
GimpUndoMode undo_mode);
|
||||
|
||||
|
||||
|
||||
G_DEFINE_TYPE (GimpVectorLayerUndo, gimp_vector_layer_undo, GIMP_TYPE_ITEM_UNDO)
|
||||
|
||||
#define parent_class gimp_vector_layer_undo_parent_class
|
||||
|
||||
|
||||
static void
|
||||
gimp_vector_layer_undo_class_init (GimpVectorLayerUndoClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GimpObjectClass *gimp_object_class = GIMP_OBJECT_CLASS (klass);
|
||||
GimpUndoClass *undo_class = GIMP_UNDO_CLASS (klass);
|
||||
|
||||
object_class->constructed = gimp_vector_layer_undo_constructed;
|
||||
object_class->set_property = gimp_vector_layer_undo_set_property;
|
||||
object_class->get_property = gimp_vector_layer_undo_get_property;
|
||||
|
||||
gimp_object_class->get_memsize = gimp_vector_layer_undo_get_memsize;
|
||||
|
||||
undo_class->pop = gimp_vector_layer_undo_pop;
|
||||
undo_class->free = gimp_vector_layer_undo_free;
|
||||
|
||||
g_object_class_install_property (object_class, PROP_PARAM,
|
||||
g_param_spec_param ("param", NULL, NULL,
|
||||
G_TYPE_PARAM,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY));
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_vector_layer_undo_init (GimpVectorLayerUndo *undo)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_vector_layer_undo_constructed (GObject *object)
|
||||
{
|
||||
GimpVectorLayerUndo *vector_undo = GIMP_VECTOR_LAYER_UNDO (object);
|
||||
GimpVectorLayer *vector_layer;
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->constructed (object);
|
||||
|
||||
g_assert (GIMP_IS_VECTOR_LAYER (GIMP_ITEM_UNDO (vector_undo)->item));
|
||||
|
||||
vector_layer = GIMP_VECTOR_LAYER (GIMP_ITEM_UNDO (vector_undo)->item);
|
||||
|
||||
switch (GIMP_UNDO (object)->undo_type)
|
||||
{
|
||||
case GIMP_UNDO_VECTOR_LAYER:
|
||||
if (vector_undo->pspec)
|
||||
{
|
||||
g_assert (vector_undo->pspec->owner_type == GIMP_TYPE_VECTOR_LAYER_OPTIONS);
|
||||
|
||||
vector_undo->value = g_slice_new0 (GValue);
|
||||
|
||||
g_value_init (vector_undo->value, vector_undo->pspec->value_type);
|
||||
g_object_get_property (G_OBJECT (vector_layer->options),
|
||||
vector_undo->pspec->name, vector_undo->value);
|
||||
}
|
||||
else if (vector_layer->options)
|
||||
{
|
||||
vector_undo->vector_layer_options = gimp_config_duplicate (GIMP_CONFIG (vector_layer->options));
|
||||
}
|
||||
break;
|
||||
|
||||
case GIMP_UNDO_VECTOR_LAYER_MODIFIED:
|
||||
vector_undo->modified = vector_layer->modified;
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_vector_layer_undo_set_property (GObject *object,
|
||||
guint property_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GimpVectorLayerUndo *vector_undo = GIMP_VECTOR_LAYER_UNDO (object);
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_PARAM:
|
||||
vector_undo->pspec = g_value_get_param (value);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_vector_layer_undo_get_property (GObject *object,
|
||||
guint property_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GimpVectorLayerUndo *vector_undo = GIMP_VECTOR_LAYER_UNDO (object);
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case PROP_PARAM:
|
||||
g_value_set_param (value, (GParamSpec *) vector_undo->pspec);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static gint64
|
||||
gimp_vector_layer_undo_get_memsize (GimpObject *object,
|
||||
gint64 *gui_size)
|
||||
{
|
||||
GimpVectorLayerUndo *undo = GIMP_VECTOR_LAYER_UNDO (object);
|
||||
gint64 memsize = 0;
|
||||
|
||||
memsize += gimp_g_value_get_memsize (undo->value);
|
||||
memsize += gimp_object_get_memsize (GIMP_OBJECT (undo->vector_layer_options), NULL);
|
||||
|
||||
return memsize + GIMP_OBJECT_CLASS (parent_class)->get_memsize (object,
|
||||
gui_size);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_vector_layer_undo_pop (GimpUndo *undo,
|
||||
GimpUndoMode undo_mode,
|
||||
GimpUndoAccumulator *accum)
|
||||
{
|
||||
GimpVectorLayerUndo *vector_undo = GIMP_VECTOR_LAYER_UNDO (undo);
|
||||
GimpVectorLayer *vector_layer = GIMP_VECTOR_LAYER (GIMP_ITEM_UNDO (undo)->item);
|
||||
|
||||
GIMP_UNDO_CLASS (parent_class)->pop (undo, undo_mode, accum);
|
||||
|
||||
switch (undo->undo_type)
|
||||
{
|
||||
case GIMP_UNDO_VECTOR_LAYER:
|
||||
if (vector_undo->pspec)
|
||||
{
|
||||
GValue *value;
|
||||
|
||||
g_return_if_fail (vector_layer->options != NULL);
|
||||
|
||||
value = g_slice_new0 (GValue);
|
||||
g_value_init (value, vector_undo->pspec->value_type);
|
||||
|
||||
g_object_get_property (G_OBJECT (vector_layer->options),
|
||||
vector_undo->pspec->name, value);
|
||||
|
||||
g_object_set_property (G_OBJECT (vector_layer->options),
|
||||
vector_undo->pspec->name, vector_undo->value);
|
||||
|
||||
g_value_unset (vector_undo->value);
|
||||
g_slice_free (GValue, vector_undo->value);
|
||||
|
||||
vector_undo->value = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
GimpVectorLayerOptions *vector_layer_options;
|
||||
|
||||
vector_layer_options = (vector_layer->options ?
|
||||
gimp_config_duplicate (GIMP_CONFIG (vector_layer->options)) : NULL);
|
||||
|
||||
if (vector_layer->options && vector_undo->vector_layer_options)
|
||||
gimp_config_sync (G_OBJECT (vector_undo->vector_layer_options),
|
||||
G_OBJECT (vector_layer->options), 0);
|
||||
else
|
||||
g_object_set (vector_layer,
|
||||
"vector-layer-options", vector_undo->vector_layer_options,
|
||||
NULL);
|
||||
|
||||
if (vector_undo->vector_layer_options)
|
||||
g_object_unref (vector_undo->vector_layer_options);
|
||||
|
||||
vector_undo->vector_layer_options = vector_layer_options;
|
||||
}
|
||||
break;
|
||||
|
||||
case GIMP_UNDO_VECTOR_LAYER_MODIFIED:
|
||||
{
|
||||
gboolean modified;
|
||||
|
||||
modified = vector_layer->modified;
|
||||
g_object_set (vector_layer, "modified", vector_undo->modified, NULL);
|
||||
vector_undo->modified = modified;
|
||||
|
||||
gimp_viewable_invalidate_preview (GIMP_VIEWABLE (vector_layer));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_vector_layer_undo_free (GimpUndo *undo,
|
||||
GimpUndoMode undo_mode)
|
||||
{
|
||||
GimpVectorLayerUndo *vector_undo = GIMP_VECTOR_LAYER_UNDO (undo);
|
||||
|
||||
if (vector_undo->vector_layer_options)
|
||||
{
|
||||
g_object_unref (vector_undo->vector_layer_options);
|
||||
vector_undo->vector_layer_options = NULL;
|
||||
}
|
||||
|
||||
if (vector_undo->pspec)
|
||||
{
|
||||
g_value_unset (vector_undo->value);
|
||||
g_slice_free (GValue, vector_undo->value);
|
||||
|
||||
vector_undo->value = NULL;
|
||||
vector_undo->pspec = NULL;
|
||||
}
|
||||
|
||||
GIMP_UNDO_CLASS (parent_class)->free (undo, undo_mode);
|
||||
}
|
58
app/path/gimpvectorlayerundo.h
Normal file
58
app/path/gimpvectorlayerundo.h
Normal file
@@ -0,0 +1,58 @@
|
||||
/* GIMP - The GNU Image Manipulation Program
|
||||
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||||
*
|
||||
* gimpvectorlayerundo.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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GIMP_VECTOR_LAYER_UNDO_H__
|
||||
#define __GIMP_VECTOR_LAYER_UNDO_H__
|
||||
|
||||
|
||||
#include "core/gimpitemundo.h"
|
||||
|
||||
|
||||
#define GIMP_TYPE_VECTOR_LAYER_UNDO (gimp_vector_layer_undo_get_type ())
|
||||
#define GIMP_VECTOR_LAYER_UNDO(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_VECTOR_LAYER_UNDO, GimpVectorLayerUndo))
|
||||
#define GIMP_VECTOR_LAYER_UNDO_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_VECTOR_LAYER_UNDO, GimpVectorLayerUndoClass))
|
||||
#define GIMP_IS_VECTOR_LAYER_UNDO(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_VECTOR_LAYER_UNDO))
|
||||
#define GIMP_IS_VECTOR_LAYER_UNDO_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_VECTOR_LAYER_UNDO))
|
||||
#define GIMP_VECTOR_LAYER_UNDO_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_VECTOR_LAYER_UNDO, GimpVectorLayerUndoClass))
|
||||
|
||||
|
||||
typedef struct _GimpVectorLayerUndoClass GimpVectorLayerUndoClass;
|
||||
|
||||
struct _GimpVectorLayerUndo
|
||||
{
|
||||
GimpItemUndo parent_instance;
|
||||
|
||||
GimpVectorLayerOptions *vector_layer_options;
|
||||
const GParamSpec *pspec;
|
||||
GValue *value;
|
||||
gboolean modified;
|
||||
};
|
||||
|
||||
struct _GimpVectorLayerUndoClass
|
||||
{
|
||||
GimpItemClass parent_class;
|
||||
};
|
||||
|
||||
|
||||
GType gimp_vector_layer_undo_get_type (void) G_GNUC_CONST;
|
||||
|
||||
|
||||
#endif /* __GIMP_VECTOR_LAYER_UNDO_H__ */
|
@@ -12,6 +12,11 @@ libapppath_sources = [
|
||||
'gimppathundo.c',
|
||||
'gimpstroke-new.c',
|
||||
'gimpstroke.c',
|
||||
'gimpvectorlayer.c',
|
||||
'gimpvectorlayer-xcf.c',
|
||||
'gimpvectorlayeroptions.c',
|
||||
'gimpvectorlayeroptions-parasite.c',
|
||||
'gimpvectorlayerundo.c',
|
||||
]
|
||||
|
||||
libapppath = static_library('apppath',
|
||||
|
@@ -25,8 +25,12 @@
|
||||
#include "path-enums.h"
|
||||
|
||||
|
||||
typedef struct _GimpAnchor GimpAnchor;
|
||||
typedef struct _GimpAnchor GimpAnchor;
|
||||
|
||||
typedef struct _GimpPath GimpPath;
|
||||
typedef struct _GimpStroke GimpStroke;
|
||||
typedef struct _GimpBezierStroke GimpBezierStroke;
|
||||
typedef struct _GimpPath GimpPath;
|
||||
typedef struct _GimpStroke GimpStroke;
|
||||
typedef struct _GimpBezierStroke GimpBezierStroke;
|
||||
|
||||
typedef struct _GimpVectorLayer GimpVectorLayer;
|
||||
typedef struct _GimpVectorLayerOptions GimpVectorLayerOptions;
|
||||
typedef struct _GimpVectorLayerUndo GimpVectorLayerUndo;
|
||||
|
@@ -30,7 +30,7 @@
|
||||
#include "internal-procs.h"
|
||||
|
||||
|
||||
/* 721 procedures registered total */
|
||||
/* 725 procedures registered total */
|
||||
|
||||
void
|
||||
internal_procs_init (GimpPDB *pdb)
|
||||
@@ -94,4 +94,5 @@ internal_procs_init (GimpPDB *pdb)
|
||||
register_text_layer_procs (pdb);
|
||||
register_text_tool_procs (pdb);
|
||||
register_unit_procs (pdb);
|
||||
register_vector_layer_procs (pdb);
|
||||
}
|
||||
|
@@ -81,3 +81,4 @@ void register_selection_procs (GimpPDB *pdb);
|
||||
void register_text_layer_procs (GimpPDB *pdb);
|
||||
void register_text_tool_procs (GimpPDB *pdb);
|
||||
void register_unit_procs (GimpPDB *pdb);
|
||||
void register_vector_layer_procs (GimpPDB *pdb);
|
||||
|
@@ -39,6 +39,7 @@
|
||||
#include "core/gimpparamspecs.h"
|
||||
#include "core/gimpselection.h"
|
||||
#include "path/gimppath.h"
|
||||
#include "path/gimpvectorlayer.h"
|
||||
#include "text/gimptextlayer.h"
|
||||
|
||||
#include "gimppdb.h"
|
||||
@@ -179,6 +180,39 @@ item_id_is_text_layer_invoker (GimpProcedure *procedure,
|
||||
return return_vals;
|
||||
}
|
||||
|
||||
static GimpValueArray *
|
||||
item_id_is_vector_layer_invoker (GimpProcedure *procedure,
|
||||
Gimp *gimp,
|
||||
GimpContext *context,
|
||||
GimpProgress *progress,
|
||||
const GimpValueArray *args,
|
||||
GError **error)
|
||||
{
|
||||
gboolean success = TRUE;
|
||||
GimpValueArray *return_vals;
|
||||
gint item_id;
|
||||
gboolean vector_layer = FALSE;
|
||||
|
||||
item_id = g_value_get_int (gimp_value_array_index (args, 0));
|
||||
|
||||
if (success)
|
||||
{
|
||||
GimpItem *item = gimp_item_get_by_id (gimp, item_id);
|
||||
|
||||
vector_layer = (GIMP_IS_LAYER (item) &&
|
||||
! gimp_item_is_removed (item) &&
|
||||
gimp_item_is_vector_layer (item));
|
||||
}
|
||||
|
||||
return_vals = gimp_procedure_get_return_values (procedure, success,
|
||||
error ? *error : NULL);
|
||||
|
||||
if (success)
|
||||
g_value_set_boolean (gimp_value_array_index (return_vals, 1), vector_layer);
|
||||
|
||||
return return_vals;
|
||||
}
|
||||
|
||||
static GimpValueArray *
|
||||
item_id_is_group_layer_invoker (GimpProcedure *procedure,
|
||||
Gimp *gimp,
|
||||
@@ -1191,6 +1225,37 @@ register_item_procs (GimpPDB *pdb)
|
||||
gimp_pdb_register_procedure (pdb, procedure);
|
||||
g_object_unref (procedure);
|
||||
|
||||
/*
|
||||
* gimp-item-id-is-vector-layer
|
||||
*/
|
||||
procedure = gimp_procedure_new (item_id_is_vector_layer_invoker, FALSE);
|
||||
gimp_object_set_static_name (GIMP_OBJECT (procedure),
|
||||
"gimp-item-id-is-vector-layer");
|
||||
gimp_procedure_set_static_help (procedure,
|
||||
"Returns whether the item ID is a vector layer.",
|
||||
"This procedure returns %TRUE if the specified item ID is a vector layer.\n"
|
||||
"\n"
|
||||
"*Note*: in most use cases, you should not use this function. See [func@Gimp.Item.id_is_layer] for a discussion on alternatives.",
|
||||
NULL);
|
||||
gimp_procedure_set_static_attribution (procedure,
|
||||
"Alex S.",
|
||||
"Alex S.",
|
||||
"2025");
|
||||
gimp_procedure_add_argument (procedure,
|
||||
g_param_spec_int ("item-id",
|
||||
"item id",
|
||||
"The item ID",
|
||||
G_MININT32, G_MAXINT32, 0,
|
||||
GIMP_PARAM_READWRITE));
|
||||
gimp_procedure_add_return_value (procedure,
|
||||
g_param_spec_boolean ("vector-layer",
|
||||
"vector layer",
|
||||
"TRUE if the item is a vector layer, FALSE otherwise.",
|
||||
FALSE,
|
||||
GIMP_PARAM_READWRITE));
|
||||
gimp_pdb_register_procedure (pdb, procedure);
|
||||
g_object_unref (procedure);
|
||||
|
||||
/*
|
||||
* gimp-item-id-is-group-layer
|
||||
*/
|
||||
|
@@ -66,6 +66,7 @@ libappinternalprocs_sources = [
|
||||
'text-layer-cmds.c',
|
||||
'text-tool-cmds.c',
|
||||
'unit-cmds.c',
|
||||
'vector-layer-cmds.c',
|
||||
]
|
||||
|
||||
libapppdb = static_library('apppdb',
|
||||
|
232
app/pdb/vector-layer-cmds.c
Normal file
232
app/pdb/vector-layer-cmds.c
Normal file
@@ -0,0 +1,232 @@
|
||||
/* GIMP - The GNU Image Manipulation Program
|
||||
* Copyright (C) 1995-2003 Spencer Kimball and Peter Mattis
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* NOTE: This file is auto-generated by pdbgen.pl. */
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "stamp-pdbgen.h"
|
||||
|
||||
#include <gegl.h>
|
||||
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
|
||||
#include "libgimpbase/gimpbase.h"
|
||||
|
||||
#include "libgimpbase/gimpbase.h"
|
||||
|
||||
#include "pdb-types.h"
|
||||
|
||||
#include "core/gimpcontext.h"
|
||||
#include "core/gimpimage.h"
|
||||
#include "core/gimpparamspecs.h"
|
||||
#include "path/gimppath.h"
|
||||
#include "path/gimpvectorlayer.h"
|
||||
|
||||
#include "gimppdb.h"
|
||||
#include "gimppdberror.h"
|
||||
#include "gimppdb-utils.h"
|
||||
#include "gimpprocedure.h"
|
||||
#include "internal-procs.h"
|
||||
|
||||
#include "gimp-intl.h"
|
||||
|
||||
|
||||
static GimpValueArray *
|
||||
vector_layer_new_invoker (GimpProcedure *procedure,
|
||||
Gimp *gimp,
|
||||
GimpContext *context,
|
||||
GimpProgress *progress,
|
||||
const GimpValueArray *args,
|
||||
GError **error)
|
||||
{
|
||||
gboolean success = TRUE;
|
||||
GimpValueArray *return_vals;
|
||||
GimpImage *image;
|
||||
GimpPath *path;
|
||||
GimpVectorLayer *layer = NULL;
|
||||
|
||||
image = g_value_get_object (gimp_value_array_index (args, 0));
|
||||
path = g_value_get_object (gimp_value_array_index (args, 1));
|
||||
|
||||
if (success)
|
||||
{
|
||||
if (path == NULL)
|
||||
{
|
||||
g_set_error (error, GIMP_PDB_ERROR, GIMP_PDB_ERROR_INVALID_ARGUMENT,
|
||||
_("Failed to create vector layer"));
|
||||
|
||||
success = FALSE;
|
||||
}
|
||||
|
||||
if (success)
|
||||
{
|
||||
layer = GIMP_VECTOR_LAYER (gimp_vector_layer_new (image, path, context));
|
||||
|
||||
if (! layer)
|
||||
{
|
||||
g_set_error (error, GIMP_PDB_ERROR, GIMP_PDB_ERROR_INVALID_ARGUMENT,
|
||||
_("Failed to create vector layer"));
|
||||
|
||||
success = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return_vals = gimp_procedure_get_return_values (procedure, success,
|
||||
error ? *error : NULL);
|
||||
|
||||
if (success)
|
||||
g_value_set_object (gimp_value_array_index (return_vals, 1), layer);
|
||||
|
||||
return return_vals;
|
||||
}
|
||||
|
||||
static GimpValueArray *
|
||||
vector_layer_refresh_invoker (GimpProcedure *procedure,
|
||||
Gimp *gimp,
|
||||
GimpContext *context,
|
||||
GimpProgress *progress,
|
||||
const GimpValueArray *args,
|
||||
GError **error)
|
||||
{
|
||||
gboolean success = TRUE;
|
||||
GimpVectorLayer *layer;
|
||||
|
||||
layer = g_value_get_object (gimp_value_array_index (args, 0));
|
||||
|
||||
if (success)
|
||||
{
|
||||
gimp_vector_layer_refresh (layer);
|
||||
}
|
||||
|
||||
return gimp_procedure_get_return_values (procedure, success,
|
||||
error ? *error : NULL);
|
||||
}
|
||||
|
||||
static GimpValueArray *
|
||||
vector_layer_discard_invoker (GimpProcedure *procedure,
|
||||
Gimp *gimp,
|
||||
GimpContext *context,
|
||||
GimpProgress *progress,
|
||||
const GimpValueArray *args,
|
||||
GError **error)
|
||||
{
|
||||
gboolean success = TRUE;
|
||||
GimpVectorLayer *layer;
|
||||
|
||||
layer = g_value_get_object (gimp_value_array_index (args, 0));
|
||||
|
||||
if (success)
|
||||
{
|
||||
gimp_vector_layer_discard (layer);
|
||||
}
|
||||
|
||||
return gimp_procedure_get_return_values (procedure, success,
|
||||
error ? *error : NULL);
|
||||
}
|
||||
|
||||
void
|
||||
register_vector_layer_procs (GimpPDB *pdb)
|
||||
{
|
||||
GimpProcedure *procedure;
|
||||
|
||||
/*
|
||||
* gimp-vector-layer-new
|
||||
*/
|
||||
procedure = gimp_procedure_new (vector_layer_new_invoker, FALSE);
|
||||
gimp_object_set_static_name (GIMP_OBJECT (procedure),
|
||||
"gimp-vector-layer-new");
|
||||
gimp_procedure_set_static_help (procedure,
|
||||
"Creates a new vector layer.",
|
||||
"This procedure creates a new path layer displaying the specified @path. By default, the fill and stroke properties will be defined by the context.\n"
|
||||
"\n"
|
||||
"The new layer still needs to be added to the image as this is not automatic. Add the new layer with the [method@Image.insert_layer] method.\n"
|
||||
"\n"
|
||||
"The arguments are kept as simple as necessary for the basic case. All vector attributes, however, can be modified with the appropriate `gimp_vector_layer_set_*()` procedures.",
|
||||
NULL);
|
||||
gimp_procedure_set_static_attribution (procedure,
|
||||
"Alex S.",
|
||||
"Alex S.",
|
||||
"2025");
|
||||
gimp_procedure_add_argument (procedure,
|
||||
gimp_param_spec_image ("image",
|
||||
"image",
|
||||
"The image",
|
||||
FALSE,
|
||||
GIMP_PARAM_READWRITE));
|
||||
gimp_procedure_add_argument (procedure,
|
||||
gimp_param_spec_path ("path",
|
||||
"path",
|
||||
"The path to create the layer from",
|
||||
FALSE,
|
||||
GIMP_PARAM_READWRITE));
|
||||
gimp_procedure_add_return_value (procedure,
|
||||
gimp_param_spec_vector_layer ("layer",
|
||||
"layer",
|
||||
"The new vector layer. The object belongs to libgimp and you should not free it.",
|
||||
FALSE,
|
||||
GIMP_PARAM_READWRITE));
|
||||
gimp_pdb_register_procedure (pdb, procedure);
|
||||
g_object_unref (procedure);
|
||||
|
||||
/*
|
||||
* gimp-vector-layer-refresh
|
||||
*/
|
||||
procedure = gimp_procedure_new (vector_layer_refresh_invoker, FALSE);
|
||||
gimp_object_set_static_name (GIMP_OBJECT (procedure),
|
||||
"gimp-vector-layer-refresh");
|
||||
gimp_procedure_set_static_help (procedure,
|
||||
"Rerender the vector layer",
|
||||
"This procedure causes the vector layer to refresh itself after changes.",
|
||||
NULL);
|
||||
gimp_procedure_set_static_attribution (procedure,
|
||||
"Alex S.",
|
||||
"Alex S.",
|
||||
"2025");
|
||||
gimp_procedure_add_argument (procedure,
|
||||
gimp_param_spec_vector_layer ("layer",
|
||||
"layer",
|
||||
"The vector layer",
|
||||
FALSE,
|
||||
GIMP_PARAM_READWRITE));
|
||||
gimp_pdb_register_procedure (pdb, procedure);
|
||||
g_object_unref (procedure);
|
||||
|
||||
/*
|
||||
* gimp-vector-layer-discard
|
||||
*/
|
||||
procedure = gimp_procedure_new (vector_layer_discard_invoker, FALSE);
|
||||
gimp_object_set_static_name (GIMP_OBJECT (procedure),
|
||||
"gimp-vector-layer-discard");
|
||||
gimp_procedure_set_static_help (procedure,
|
||||
"Discard the vector layer information.",
|
||||
"Discards the vector information. This makes the layer behave like a normal layer.",
|
||||
NULL);
|
||||
gimp_procedure_set_static_attribution (procedure,
|
||||
"Alex S.",
|
||||
"Alex S.",
|
||||
"2025");
|
||||
gimp_procedure_add_argument (procedure,
|
||||
gimp_param_spec_vector_layer ("layer",
|
||||
"layer",
|
||||
"The vector layer",
|
||||
FALSE,
|
||||
GIMP_PARAM_READWRITE));
|
||||
gimp_pdb_register_procedure (pdb, procedure);
|
||||
g_object_unref (procedure);
|
||||
}
|
@@ -46,6 +46,7 @@
|
||||
#include "core/gimpunit.h"
|
||||
|
||||
#include "path/gimppath.h"
|
||||
#include "path/gimpvectorlayer.h"
|
||||
|
||||
#include "text/gimpfont.h"
|
||||
#include "text/gimptextlayer.h"
|
||||
|
@@ -41,6 +41,8 @@
|
||||
#include "paint/gimppaintcore.h"
|
||||
#include "paint/gimppaintoptions.h"
|
||||
|
||||
#include "path/gimpvectorlayer.h"
|
||||
|
||||
#include "widgets/gimpdevices.h"
|
||||
#include "widgets/gimpwidgets-utils.h"
|
||||
|
||||
@@ -342,6 +344,24 @@ gimp_paint_tool_button_press (GimpTool *tool,
|
||||
}
|
||||
}
|
||||
|
||||
if (gimp_item_is_vector_layer (GIMP_ITEM (drawable)))
|
||||
{
|
||||
gboolean constrain_only;
|
||||
|
||||
/* Allow vector layers to be set as sources */
|
||||
constrain_only = (state & gimp_get_constrain_behavior_mask () &&
|
||||
! (state & gimp_get_extend_selection_mask ()));
|
||||
if (! (GIMP_IS_SOURCE_TOOL (tool) && constrain_only))
|
||||
{
|
||||
gimp_tool_message_literal (tool, display,
|
||||
_("Vector layers must be rasterized "
|
||||
"before they can be painted on."));
|
||||
g_list_free (drawables);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (! gimp_paint_tool_check_alpha (paint_tool, drawable, display, &error))
|
||||
{
|
||||
GtkWidget *options_gui;
|
||||
|
@@ -24,12 +24,21 @@
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include "libgimpbase/gimpbase.h"
|
||||
#include "libgimpcolor/gimpcolor.h"
|
||||
#include "libgimpconfig/gimpconfig.h"
|
||||
#include "libgimpwidgets/gimpwidgets.h"
|
||||
|
||||
#include "tools-types.h"
|
||||
|
||||
#include "core/gimp.h"
|
||||
#include "core/gimpcontainer.h"
|
||||
#include "core/gimpdatafactory.h"
|
||||
#include "core/gimppattern.h"
|
||||
#include "core/gimpstrokeoptions.h"
|
||||
|
||||
#include "widgets/gimphelp-ids.h"
|
||||
#include "widgets/gimppropwidgets.h"
|
||||
#include "widgets/gimpstrokeeditor.h"
|
||||
#include "widgets/gimpwidgets-utils.h"
|
||||
|
||||
#include "gimppathoptions.h"
|
||||
@@ -42,28 +51,68 @@ enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_PATH_EDIT_MODE,
|
||||
PROP_PATH_POLYGONAL
|
||||
PROP_PATH_POLYGONAL,
|
||||
PROP_ENABLE_FILL,
|
||||
PROP_ENABLE_STROKE,
|
||||
PROP_FILL_STYLE,
|
||||
PROP_FILL_FOREGROUND,
|
||||
PROP_FILL_PATTERN,
|
||||
PROP_FILL_ANTIALIAS,
|
||||
PROP_STROKE_STYLE,
|
||||
PROP_STROKE_FOREGROUND,
|
||||
PROP_STROKE_PATTERN,
|
||||
PROP_STROKE_WIDTH,
|
||||
PROP_STROKE_UNIT,
|
||||
PROP_STROKE_ANTIALIAS,
|
||||
PROP_STROKE_CAP_STYLE,
|
||||
PROP_STROKE_JOIN_STYLE,
|
||||
PROP_STROKE_MITER_LIMIT,
|
||||
PROP_STROKE_DASH_OFFSET
|
||||
};
|
||||
|
||||
static void gimp_path_options_config_iface_init (GimpConfigInterface *config_iface);
|
||||
static gboolean gimp_path_options_serialize_property (GimpConfig *config,
|
||||
guint property_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec,
|
||||
GimpConfigWriter *writer);
|
||||
static gboolean gimp_path_options_deserialize_property (GimpConfig *config,
|
||||
guint property_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec,
|
||||
GScanner *scanner,
|
||||
GTokenType *expected);
|
||||
|
||||
static void gimp_path_options_set_property (GObject *object,
|
||||
guint property_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static void gimp_path_options_get_property (GObject *object,
|
||||
guint property_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static void gimp_path_options_finalize (GObject *object);
|
||||
static void gimp_path_options_set_property (GObject *object,
|
||||
guint property_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec);
|
||||
static void gimp_path_options_get_property (GObject *object,
|
||||
guint property_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec);
|
||||
|
||||
|
||||
G_DEFINE_TYPE (GimpPathOptions, gimp_path_options, GIMP_TYPE_TOOL_OPTIONS)
|
||||
G_DEFINE_TYPE_WITH_CODE (GimpPathOptions, gimp_path_options,
|
||||
GIMP_TYPE_TOOL_OPTIONS,
|
||||
G_IMPLEMENT_INTERFACE (GIMP_TYPE_CONFIG,
|
||||
gimp_path_options_config_iface_init))
|
||||
|
||||
|
||||
#define parent_class gimp_path_options_parent_class
|
||||
|
||||
static GimpConfigInterface *parent_config_iface = NULL;
|
||||
|
||||
|
||||
static void
|
||||
gimp_path_options_class_init (GimpPathOptionsClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GeglColor *black = gegl_color_new ("black");
|
||||
GeglColor *white = gegl_color_new ("white");
|
||||
|
||||
object_class->finalize = gimp_path_options_finalize;
|
||||
object_class->set_property = gimp_path_options_set_property;
|
||||
object_class->get_property = gimp_path_options_get_property;
|
||||
|
||||
@@ -81,11 +130,140 @@ gimp_path_options_class_init (GimpPathOptionsClass *klass)
|
||||
_("Restrict editing to polygons"),
|
||||
FALSE,
|
||||
GIMP_PARAM_STATIC_STRINGS);
|
||||
|
||||
/* Vector layer specific properties */
|
||||
GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_ENABLE_FILL,
|
||||
"enable-fill",
|
||||
_("Enable Fill"), NULL,
|
||||
TRUE,
|
||||
GIMP_PARAM_STATIC_STRINGS);
|
||||
|
||||
GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_ENABLE_STROKE,
|
||||
"enable-stroke",
|
||||
_("Enable Stroke"), NULL,
|
||||
TRUE,
|
||||
GIMP_PARAM_STATIC_STRINGS);
|
||||
|
||||
GIMP_CONFIG_PROP_ENUM (object_class, PROP_FILL_STYLE,
|
||||
"fill-custom-style",
|
||||
NULL, NULL,
|
||||
GIMP_TYPE_CUSTOM_STYLE,
|
||||
GIMP_CUSTOM_STYLE_SOLID_COLOR,
|
||||
GIMP_PARAM_STATIC_STRINGS);
|
||||
|
||||
GIMP_CONFIG_PROP_COLOR (object_class, PROP_FILL_FOREGROUND,
|
||||
"fill-foreground",
|
||||
NULL, NULL,
|
||||
TRUE, white,
|
||||
GIMP_PARAM_STATIC_STRINGS);
|
||||
|
||||
GIMP_CONFIG_PROP_OBJECT (object_class, PROP_FILL_PATTERN,
|
||||
"fill-pattern",
|
||||
NULL, NULL,
|
||||
GIMP_TYPE_PATTERN,
|
||||
GIMP_PARAM_STATIC_STRINGS);
|
||||
|
||||
GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_FILL_ANTIALIAS,
|
||||
"fill-antialias",
|
||||
NULL, NULL,
|
||||
TRUE,
|
||||
GIMP_PARAM_STATIC_STRINGS);
|
||||
|
||||
GIMP_CONFIG_PROP_ENUM (object_class, PROP_STROKE_STYLE,
|
||||
"stroke-custom-style",
|
||||
NULL, NULL,
|
||||
GIMP_TYPE_CUSTOM_STYLE,
|
||||
GIMP_CUSTOM_STYLE_SOLID_COLOR,
|
||||
GIMP_PARAM_STATIC_STRINGS);
|
||||
|
||||
GIMP_CONFIG_PROP_COLOR (object_class, PROP_STROKE_FOREGROUND,
|
||||
"stroke-foreground",
|
||||
NULL, NULL,
|
||||
TRUE, black,
|
||||
GIMP_PARAM_STATIC_STRINGS);
|
||||
|
||||
GIMP_CONFIG_PROP_OBJECT (object_class, PROP_STROKE_PATTERN,
|
||||
"stroke-pattern",
|
||||
NULL, NULL,
|
||||
GIMP_TYPE_PATTERN,
|
||||
GIMP_PARAM_STATIC_STRINGS);
|
||||
|
||||
GIMP_CONFIG_PROP_DOUBLE (object_class, PROP_STROKE_WIDTH,
|
||||
"stroke-width",
|
||||
NULL, NULL,
|
||||
0.0, 2000.0, 6.0,
|
||||
GIMP_PARAM_STATIC_STRINGS);
|
||||
|
||||
GIMP_CONFIG_PROP_UNIT (object_class, PROP_STROKE_UNIT,
|
||||
"stroke-unit",
|
||||
NULL, NULL,
|
||||
TRUE, FALSE, gimp_unit_pixel (),
|
||||
GIMP_PARAM_STATIC_STRINGS);
|
||||
|
||||
GIMP_CONFIG_PROP_BOOLEAN (object_class, PROP_STROKE_ANTIALIAS,
|
||||
"stroke-antialias",
|
||||
NULL, NULL,
|
||||
TRUE,
|
||||
GIMP_PARAM_STATIC_STRINGS);
|
||||
|
||||
GIMP_CONFIG_PROP_ENUM (object_class, PROP_STROKE_CAP_STYLE,
|
||||
"stroke-cap-style",
|
||||
NULL, NULL,
|
||||
GIMP_TYPE_CAP_STYLE, GIMP_CAP_BUTT,
|
||||
GIMP_PARAM_STATIC_STRINGS);
|
||||
|
||||
GIMP_CONFIG_PROP_ENUM (object_class, PROP_STROKE_JOIN_STYLE,
|
||||
"stroke-join-style",
|
||||
NULL, NULL,
|
||||
GIMP_TYPE_JOIN_STYLE, GIMP_JOIN_MITER,
|
||||
GIMP_PARAM_STATIC_STRINGS);
|
||||
|
||||
GIMP_CONFIG_PROP_DOUBLE (object_class, PROP_STROKE_MITER_LIMIT,
|
||||
"stroke-miter-limit",
|
||||
NULL, NULL,
|
||||
0.0, 100.0, 10.0,
|
||||
GIMP_PARAM_STATIC_STRINGS);
|
||||
|
||||
GIMP_CONFIG_PROP_DOUBLE (object_class, PROP_STROKE_DASH_OFFSET,
|
||||
"stroke-dash-offset",
|
||||
NULL, NULL,
|
||||
0.0, 2000.0, 0.0,
|
||||
GIMP_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_clear_object (&white);
|
||||
g_clear_object (&black);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_path_options_config_iface_init (GimpConfigInterface *config_iface)
|
||||
{
|
||||
parent_config_iface = g_type_interface_peek_parent (config_iface);
|
||||
|
||||
config_iface->serialize_property = gimp_path_options_serialize_property;
|
||||
config_iface->deserialize_property = gimp_path_options_deserialize_property;
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_path_options_init (GimpPathOptions *options)
|
||||
{
|
||||
GeglColor *black = gegl_color_new ("black");
|
||||
GeglColor *white = gegl_color_new ("white");
|
||||
|
||||
options->fill_foreground = white;
|
||||
options->stroke_foreground = black;
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_path_options_finalize (GObject *object)
|
||||
{
|
||||
GimpPathOptions *options = GIMP_PATH_OPTIONS (object);
|
||||
|
||||
g_clear_object (&options->fill_options);
|
||||
g_clear_object (&options->stroke_options);
|
||||
g_clear_object (&options->fill_foreground);
|
||||
g_clear_object (&options->stroke_foreground);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -104,13 +282,84 @@ gimp_path_options_set_property (GObject *object,
|
||||
case PROP_PATH_POLYGONAL:
|
||||
options->polygonal = g_value_get_boolean (value);
|
||||
break;
|
||||
|
||||
case PROP_ENABLE_FILL:
|
||||
options->enable_fill = g_value_get_boolean (value);
|
||||
break;
|
||||
case PROP_ENABLE_STROKE:
|
||||
options->enable_stroke = g_value_get_boolean (value);
|
||||
break;
|
||||
|
||||
case PROP_FILL_STYLE:
|
||||
options->fill_style = g_value_get_enum (value);
|
||||
break;
|
||||
case PROP_FILL_FOREGROUND:
|
||||
g_set_object (&options->fill_foreground, g_value_get_object (value));
|
||||
break;
|
||||
case PROP_FILL_PATTERN:
|
||||
{
|
||||
GimpPattern *pattern = g_value_get_object (value);
|
||||
|
||||
if (options->fill_pattern != pattern)
|
||||
{
|
||||
if (options->fill_pattern)
|
||||
g_object_unref (options->fill_pattern);
|
||||
|
||||
options->fill_pattern = pattern ? g_object_ref (pattern) : pattern;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PROP_FILL_ANTIALIAS:
|
||||
options->fill_antialias = g_value_get_boolean (value);
|
||||
break;
|
||||
case PROP_STROKE_STYLE:
|
||||
options->stroke_style = g_value_get_enum (value);
|
||||
break;
|
||||
case PROP_STROKE_FOREGROUND:
|
||||
g_set_object (&options->stroke_foreground, g_value_get_object (value));
|
||||
break;
|
||||
case PROP_STROKE_PATTERN:
|
||||
{
|
||||
GimpPattern *pattern = g_value_get_object (value);
|
||||
|
||||
if (options->stroke_pattern != pattern)
|
||||
{
|
||||
if (options->stroke_pattern)
|
||||
g_object_unref (options->stroke_pattern);
|
||||
|
||||
options->stroke_pattern = pattern ?
|
||||
g_object_ref (pattern) : pattern;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PROP_STROKE_WIDTH:
|
||||
options->stroke_width = g_value_get_double (value);
|
||||
break;
|
||||
case PROP_STROKE_UNIT:
|
||||
options->stroke_unit = g_value_get_object (value);
|
||||
break;
|
||||
case PROP_STROKE_ANTIALIAS:
|
||||
options->stroke_antialias = g_value_get_boolean (value);
|
||||
break;
|
||||
case PROP_STROKE_CAP_STYLE:
|
||||
options->stroke_cap_style = g_value_get_enum (value);
|
||||
break;
|
||||
case PROP_STROKE_JOIN_STYLE:
|
||||
options->stroke_join_style = g_value_get_enum (value);
|
||||
break;
|
||||
case PROP_STROKE_MITER_LIMIT:
|
||||
options->stroke_miter_limit = g_value_get_double (value);
|
||||
break;
|
||||
case PROP_STROKE_DASH_OFFSET:
|
||||
options->stroke_dash_offset = g_value_get_double (value);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gimp_path_options_get_property (GObject *object,
|
||||
guint property_id,
|
||||
@@ -127,12 +376,138 @@ gimp_path_options_get_property (GObject *object,
|
||||
case PROP_PATH_POLYGONAL:
|
||||
g_value_set_boolean (value, options->polygonal);
|
||||
break;
|
||||
|
||||
case PROP_ENABLE_FILL:
|
||||
g_value_set_boolean (value, options->enable_fill);
|
||||
break;
|
||||
case PROP_ENABLE_STROKE:
|
||||
g_value_set_boolean (value, options->enable_stroke);
|
||||
break;
|
||||
|
||||
case PROP_FILL_STYLE:
|
||||
g_value_set_enum (value, options->fill_style);
|
||||
break;
|
||||
case PROP_FILL_FOREGROUND:
|
||||
g_value_set_object (value, options->fill_foreground);
|
||||
break;
|
||||
case PROP_FILL_PATTERN:
|
||||
g_value_set_object (value, options->fill_pattern);
|
||||
break;
|
||||
case PROP_FILL_ANTIALIAS:
|
||||
g_value_set_boolean (value, options->fill_antialias);
|
||||
break;
|
||||
case PROP_STROKE_STYLE:
|
||||
g_value_set_enum (value, options->stroke_style);
|
||||
break;
|
||||
case PROP_STROKE_FOREGROUND:
|
||||
g_value_set_object (value, options->stroke_foreground);
|
||||
break;
|
||||
case PROP_STROKE_PATTERN:
|
||||
g_value_set_object (value, options->stroke_pattern);
|
||||
break;
|
||||
case PROP_STROKE_WIDTH:
|
||||
g_value_set_double (value, options->stroke_width);
|
||||
break;
|
||||
case PROP_STROKE_UNIT:
|
||||
g_value_set_object (value, options->stroke_unit);
|
||||
break;
|
||||
case PROP_STROKE_ANTIALIAS:
|
||||
g_value_set_boolean (value, options->stroke_antialias);
|
||||
break;
|
||||
case PROP_STROKE_CAP_STYLE:
|
||||
g_value_set_enum (value, options->stroke_cap_style);
|
||||
break;
|
||||
case PROP_STROKE_JOIN_STYLE:
|
||||
g_value_set_enum (value, options->stroke_join_style);
|
||||
break;
|
||||
case PROP_STROKE_MITER_LIMIT:
|
||||
g_value_set_double (value, options->stroke_miter_limit);
|
||||
break;
|
||||
case PROP_STROKE_DASH_OFFSET:
|
||||
g_value_set_double (value, options->stroke_dash_offset);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gimp_path_options_serialize_property (GimpConfig *config,
|
||||
guint property_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec,
|
||||
GimpConfigWriter *writer)
|
||||
{
|
||||
if (property_id == PROP_FILL_PATTERN ||
|
||||
property_id == PROP_STROKE_PATTERN)
|
||||
{
|
||||
GimpObject *serialize_obj = g_value_get_object (value);
|
||||
|
||||
gimp_config_writer_open (writer, pspec->name);
|
||||
|
||||
if (serialize_obj)
|
||||
gimp_config_writer_string (writer,
|
||||
gimp_object_get_name (serialize_obj));
|
||||
else
|
||||
gimp_config_writer_print (writer, "NULL", 4);
|
||||
|
||||
gimp_config_writer_close (writer);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gimp_path_options_deserialize_property (GimpConfig *object,
|
||||
guint property_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec,
|
||||
GScanner *scanner,
|
||||
GTokenType *expected)
|
||||
{
|
||||
if (property_id == PROP_FILL_PATTERN ||
|
||||
property_id == PROP_STROKE_PATTERN)
|
||||
{
|
||||
gchar *object_name;
|
||||
|
||||
if (gimp_scanner_parse_identifier (scanner, "NULL"))
|
||||
{
|
||||
g_value_set_object (value, NULL);
|
||||
}
|
||||
else if (gimp_scanner_parse_string (scanner, &object_name))
|
||||
{
|
||||
GimpContext *context = GIMP_CONTEXT (object);
|
||||
GimpContainer *container;
|
||||
GimpObject *deserialize_obj;
|
||||
|
||||
if (! object_name)
|
||||
object_name = g_strdup ("");
|
||||
|
||||
container =
|
||||
gimp_data_factory_get_container (context->gimp->pattern_factory);
|
||||
|
||||
deserialize_obj = gimp_container_get_child_by_name (container,
|
||||
object_name);
|
||||
|
||||
g_value_set_object (value, deserialize_obj);
|
||||
|
||||
g_free (object_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
*expected = G_TOKEN_STRING;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
button_append_modifier (GtkWidget *button,
|
||||
GdkModifierType modifiers)
|
||||
@@ -149,7 +524,7 @@ GtkWidget *
|
||||
gimp_path_options_gui (GimpToolOptions *tool_options)
|
||||
{
|
||||
GObject *config = G_OBJECT (tool_options);
|
||||
GimpPathOptions *options = GIMP_PATH_OPTIONS (tool_options);
|
||||
GimpPathOptions *options = GIMP_PATH_OPTIONS (tool_options);
|
||||
GtkWidget *vbox = gimp_tool_options_gui (tool_options);
|
||||
GtkWidget *frame;
|
||||
GtkWidget *button;
|
||||
@@ -198,23 +573,7 @@ gimp_path_options_gui (GimpToolOptions *tool_options)
|
||||
|
||||
options->to_selection_button = button;
|
||||
|
||||
button = gtk_button_new_with_label (_("Fill Path"));
|
||||
gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
|
||||
gtk_widget_set_sensitive (button, FALSE);
|
||||
gimp_help_set_help_data (button, NULL, GIMP_HELP_PATH_FILL);
|
||||
gtk_widget_set_visible (button, TRUE);
|
||||
|
||||
options->fill_button = button;
|
||||
|
||||
button = gtk_button_new_with_label (_("Stroke Path"));
|
||||
gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
|
||||
gtk_widget_set_sensitive (button, FALSE);
|
||||
gimp_help_set_help_data (button, NULL, GIMP_HELP_PATH_STROKE);
|
||||
gtk_widget_set_visible (button, TRUE);
|
||||
|
||||
options->stroke_button = button;
|
||||
|
||||
button = gtk_button_new_with_label (_("Create Vector Layer"));
|
||||
button = gtk_button_new_with_label (_("Create New Vector Layer"));
|
||||
gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
|
||||
gtk_widget_set_sensitive (button, FALSE);
|
||||
gimp_help_set_help_data (button, NULL, NULL);
|
||||
@@ -222,5 +581,64 @@ gimp_path_options_gui (GimpToolOptions *tool_options)
|
||||
|
||||
options->vector_layer_button = button;
|
||||
|
||||
/* The fill editor */
|
||||
{
|
||||
GtkWidget *frame;
|
||||
GtkWidget *fill_editor;
|
||||
|
||||
options->fill_options =
|
||||
gimp_fill_options_new (GIMP_CONTEXT (options)->gimp,
|
||||
NULL, FALSE);
|
||||
|
||||
#define FILL_BIND(a) \
|
||||
g_object_bind_property (options, "fill-" #a, \
|
||||
options->fill_options, #a, \
|
||||
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE)
|
||||
FILL_BIND (custom-style);
|
||||
FILL_BIND (foreground);
|
||||
FILL_BIND (pattern);
|
||||
|
||||
fill_editor = gimp_fill_editor_new (options->fill_options,
|
||||
TRUE, TRUE);
|
||||
gtk_widget_set_visible (fill_editor, TRUE);
|
||||
|
||||
frame = gimp_prop_expanding_frame_new (config, "enable-fill", NULL,
|
||||
fill_editor, NULL);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
|
||||
}
|
||||
|
||||
/* The stroke editor */
|
||||
{
|
||||
GtkWidget *frame;
|
||||
GtkWidget *stroke_editor;
|
||||
|
||||
options->stroke_options =
|
||||
gimp_stroke_options_new (GIMP_CONTEXT (options)->gimp,
|
||||
NULL, FALSE);
|
||||
|
||||
#define STROKE_BIND(a) \
|
||||
g_object_bind_property (options, "stroke-" #a, \
|
||||
options->stroke_options, #a, \
|
||||
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE)
|
||||
STROKE_BIND (custom-style);
|
||||
STROKE_BIND (foreground);
|
||||
STROKE_BIND (pattern);
|
||||
STROKE_BIND (width);
|
||||
STROKE_BIND (unit);
|
||||
STROKE_BIND (cap-style);
|
||||
STROKE_BIND (join-style);
|
||||
STROKE_BIND (miter-limit);
|
||||
STROKE_BIND (antialias);
|
||||
STROKE_BIND (dash-offset);
|
||||
|
||||
stroke_editor = gimp_stroke_editor_new (options->stroke_options, 72.0,
|
||||
TRUE, TRUE);
|
||||
gtk_widget_set_visible (stroke_editor, TRUE);
|
||||
|
||||
frame = gimp_prop_expanding_frame_new (config, "enable-stroke", NULL,
|
||||
stroke_editor, NULL);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
|
||||
}
|
||||
|
||||
return vbox;
|
||||
}
|
||||
|
@@ -28,20 +28,41 @@
|
||||
#define GIMP_PATH_OPTIONS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_PATH_OPTIONS, GimpPathOptionsClass))
|
||||
|
||||
|
||||
typedef struct _GimpPathOptions GimpPathOptions;
|
||||
typedef struct _GimpPathOptions GimpPathOptions;
|
||||
typedef struct _GimpToolOptionsClass GimpPathOptionsClass;
|
||||
|
||||
struct _GimpPathOptions
|
||||
{
|
||||
GimpToolOptions parent_instance;
|
||||
GimpToolOptions parent_instance;
|
||||
|
||||
GimpPathMode edit_mode;
|
||||
gboolean polygonal;
|
||||
GimpPathMode edit_mode;
|
||||
gboolean polygonal;
|
||||
|
||||
/* vector layer */
|
||||
gboolean enable_fill;
|
||||
gboolean enable_stroke;
|
||||
GimpFillOptions *fill_options;
|
||||
GimpStrokeOptions *stroke_options;
|
||||
|
||||
GimpCustomStyle fill_style;
|
||||
GeglColor *fill_foreground;
|
||||
GimpPattern *fill_pattern;
|
||||
gboolean fill_antialias;
|
||||
|
||||
GimpCustomStyle stroke_style;
|
||||
GeglColor *stroke_foreground;
|
||||
GimpPattern *stroke_pattern;
|
||||
gboolean stroke_antialias;
|
||||
gdouble stroke_width;
|
||||
GimpUnit *stroke_unit;
|
||||
GimpCapStyle stroke_cap_style;
|
||||
GimpJoinStyle stroke_join_style;
|
||||
gdouble stroke_miter_limit;
|
||||
gdouble stroke_dash_offset;
|
||||
|
||||
/* options gui */
|
||||
GtkWidget *to_selection_button;
|
||||
GtkWidget *fill_button;
|
||||
GtkWidget *stroke_button;
|
||||
GtkWidget *to_selection_button;
|
||||
GtkWidget *vector_layer_button;
|
||||
};
|
||||
|
||||
|
||||
|
@@ -35,12 +35,15 @@
|
||||
#include "core/gimpimage-pick-item.h"
|
||||
#include "core/gimpimage-undo.h"
|
||||
#include "core/gimpimage-undo-push.h"
|
||||
#include "core/gimpstrokeoptions.h"
|
||||
#include "core/gimptoolinfo.h"
|
||||
#include "core/gimpundostack.h"
|
||||
|
||||
#include "paint/gimppaintoptions.h" /* GIMP_PAINT_OPTIONS_CONTEXT_MASK */
|
||||
|
||||
#include "path/gimppath.h"
|
||||
#include "path/gimpvectorlayer.h"
|
||||
#include "path/gimpvectorlayeroptions.h"
|
||||
|
||||
#include "widgets/gimpdialogfactory.h"
|
||||
#include "widgets/gimpdockcontainer.h"
|
||||
@@ -70,6 +73,7 @@
|
||||
|
||||
/* local function prototypes */
|
||||
|
||||
static void gimp_path_tool_constructed (GObject *object);
|
||||
static void gimp_path_tool_dispose (GObject *object);
|
||||
|
||||
static void gimp_path_tool_control (GimpTool *tool,
|
||||
@@ -106,6 +110,12 @@ static void gimp_path_tool_start (GimpPathTool *path_t
|
||||
GimpDisplay *display);
|
||||
static void gimp_path_tool_halt (GimpPathTool *path_tool);
|
||||
|
||||
static void gimp_path_tool_image_changed (GimpPathTool *path_tool,
|
||||
GimpImage *image,
|
||||
GimpContext *context);
|
||||
static void gimp_path_tool_image_selected_layers_changed
|
||||
(GimpPathTool *path_tool);
|
||||
|
||||
static void gimp_path_tool_tool_path_changed (GimpToolWidget *tool_path,
|
||||
GimpPathTool *path_tool);
|
||||
static void gimp_path_tool_tool_path_begin_change
|
||||
@@ -130,23 +140,12 @@ static void gimp_path_tool_to_selection_extended
|
||||
(GimpPathTool *path_tool,
|
||||
GdkModifierType state);
|
||||
|
||||
static void gimp_path_tool_fill_path (GimpPathTool *path_tool,
|
||||
GtkWidget *button);
|
||||
static void gimp_path_tool_fill_callback (GtkWidget *dialog,
|
||||
GList *items,
|
||||
GList *drawables,
|
||||
GimpContext *context,
|
||||
GimpFillOptions *options,
|
||||
gpointer data);
|
||||
|
||||
static void gimp_path_tool_stroke_path (GimpPathTool *path_tool,
|
||||
GtkWidget *button);
|
||||
static void gimp_path_tool_stroke_callback (GtkWidget *dialog,
|
||||
GList *items,
|
||||
GList *drawables,
|
||||
GimpContext *context,
|
||||
GimpStrokeOptions *options,
|
||||
gpointer data);
|
||||
static void gimp_path_tool_create_vector_layer(GimpPathTool *path_tool,
|
||||
GtkWidget *button);
|
||||
static void gimp_path_tool_vector_change_notify
|
||||
(GObject *options,
|
||||
const GParamSpec *pspec,
|
||||
GimpVectorLayer *layer);
|
||||
|
||||
|
||||
G_DEFINE_TYPE (GimpPathTool, gimp_path_tool, GIMP_TYPE_DRAW_TOOL)
|
||||
@@ -179,6 +178,7 @@ gimp_path_tool_class_init (GimpPathToolClass *klass)
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GimpToolClass *tool_class = GIMP_TOOL_CLASS (klass);
|
||||
|
||||
object_class->constructed = gimp_path_tool_constructed;
|
||||
object_class->dispose = gimp_path_tool_dispose;
|
||||
|
||||
tool_class->control = gimp_path_tool_control;
|
||||
@@ -203,6 +203,28 @@ gimp_path_tool_init (GimpPathTool *path_tool)
|
||||
path_tool->saved_mode = GIMP_PATH_MODE_DESIGN;
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_path_tool_constructed (GObject *object)
|
||||
{
|
||||
GimpPathTool *path_tool = GIMP_PATH_TOOL (object);
|
||||
GimpContext *context;
|
||||
GimpToolInfo *tool_info;
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->constructed (object);
|
||||
|
||||
tool_info = GIMP_TOOL (path_tool)->tool_info;
|
||||
|
||||
context = gimp_get_user_context (tool_info->gimp);
|
||||
|
||||
g_signal_connect_object (context, "image-changed",
|
||||
G_CALLBACK (gimp_path_tool_image_changed),
|
||||
path_tool, G_CONNECT_SWAPPED);
|
||||
|
||||
gimp_path_tool_image_changed (path_tool,
|
||||
gimp_context_get_image (context),
|
||||
context);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_path_tool_dispose (GObject *object)
|
||||
{
|
||||
@@ -211,6 +233,8 @@ gimp_path_tool_dispose (GObject *object)
|
||||
gimp_path_tool_set_path (path_tool, NULL);
|
||||
g_clear_object (&path_tool->widget);
|
||||
|
||||
gimp_path_tool_image_changed (path_tool, NULL, NULL);
|
||||
|
||||
G_OBJECT_CLASS (parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
@@ -445,6 +469,87 @@ gimp_path_tool_halt (GimpPathTool *path_tool)
|
||||
tool->display = NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_path_tool_image_changed (GimpPathTool *path_tool,
|
||||
GimpImage *image,
|
||||
GimpContext *context)
|
||||
{
|
||||
if (path_tool->current_image)
|
||||
g_signal_handlers_disconnect_by_func (path_tool->current_image,
|
||||
gimp_path_tool_image_selected_layers_changed,
|
||||
NULL);
|
||||
|
||||
g_set_weak_pointer (&path_tool->current_image, image);
|
||||
|
||||
if (path_tool->current_image)
|
||||
g_signal_connect_object (path_tool->current_image, "selected-layers-changed",
|
||||
G_CALLBACK (gimp_path_tool_image_selected_layers_changed),
|
||||
path_tool, G_CONNECT_SWAPPED);
|
||||
|
||||
gimp_path_tool_image_selected_layers_changed (path_tool);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_path_tool_image_selected_layers_changed (GimpPathTool *path_tool)
|
||||
{
|
||||
GimpPathOptions *options = GIMP_PATH_TOOL_GET_OPTIONS (path_tool);
|
||||
GList *current_layers = NULL;
|
||||
|
||||
if (path_tool->current_vector_layer)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (options,
|
||||
gimp_path_tool_vector_change_notify,
|
||||
path_tool->current_vector_layer);
|
||||
g_signal_handlers_disconnect_by_func (options->fill_options,
|
||||
gimp_path_tool_vector_change_notify,
|
||||
path_tool->current_vector_layer);
|
||||
g_signal_handlers_disconnect_by_func (options->stroke_options,
|
||||
gimp_path_tool_vector_change_notify,
|
||||
path_tool->current_vector_layer);
|
||||
|
||||
path_tool->current_vector_layer = NULL;
|
||||
gimp_path_tool_set_path (path_tool, NULL);
|
||||
}
|
||||
|
||||
if (path_tool->current_image)
|
||||
current_layers = gimp_image_get_selected_layers (path_tool->current_image);
|
||||
|
||||
/* If we've selected a single vector layer, make its path editable */
|
||||
if (current_layers &&
|
||||
g_list_length (current_layers) == 1 &&
|
||||
gimp_item_is_vector_layer (GIMP_ITEM (current_layers->data)))
|
||||
{
|
||||
GimpVectorLayer *vector_layer = current_layers->data;
|
||||
|
||||
gimp_path_tool_set_path (path_tool,
|
||||
gimp_vector_layer_get_path (vector_layer));
|
||||
|
||||
g_object_set (options,
|
||||
"enable-fill", vector_layer->options->enable_fill,
|
||||
"enable_stroke", vector_layer->options->enable_stroke,
|
||||
NULL);
|
||||
gimp_config_sync (G_OBJECT (vector_layer->options->stroke_options),
|
||||
G_OBJECT (options->stroke_options), 0);
|
||||
gimp_config_sync (G_OBJECT (vector_layer->options->fill_options),
|
||||
G_OBJECT (options->fill_options), 0);
|
||||
|
||||
g_signal_connect_object (options, "notify::enable-fill",
|
||||
G_CALLBACK (gimp_path_tool_vector_change_notify),
|
||||
vector_layer, 0);
|
||||
g_signal_connect_object (options, "notify::enable-stroke",
|
||||
G_CALLBACK (gimp_path_tool_vector_change_notify),
|
||||
vector_layer, 0);
|
||||
g_signal_connect_object (options->fill_options, "notify",
|
||||
G_CALLBACK (gimp_path_tool_vector_change_notify),
|
||||
vector_layer, 0);
|
||||
g_signal_connect_object (options->stroke_options, "notify",
|
||||
G_CALLBACK (gimp_path_tool_vector_change_notify),
|
||||
vector_layer, 0);
|
||||
|
||||
path_tool->current_vector_layer = vector_layer;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_path_tool_tool_path_changed (GimpToolWidget *tool_path,
|
||||
GimpPathTool *path_tool)
|
||||
@@ -453,9 +558,7 @@ gimp_path_tool_tool_path_changed (GimpToolWidget *tool_path,
|
||||
GimpImage *image = gimp_display_get_image (shell->display);
|
||||
GimpPath *path;
|
||||
|
||||
g_object_get (tool_path,
|
||||
"path", &path,
|
||||
NULL);
|
||||
g_object_get (tool_path, "path", &path, NULL);
|
||||
|
||||
if (path != path_tool->path)
|
||||
{
|
||||
@@ -595,19 +698,11 @@ gimp_path_tool_set_path (GimpPathTool *path_tool,
|
||||
tool);
|
||||
}
|
||||
|
||||
if (options->fill_button)
|
||||
if (options->vector_layer_button)
|
||||
{
|
||||
gtk_widget_set_sensitive (options->fill_button, FALSE);
|
||||
g_signal_handlers_disconnect_by_func (options->fill_button,
|
||||
gimp_path_tool_fill_path,
|
||||
tool);
|
||||
}
|
||||
|
||||
if (options->stroke_button)
|
||||
{
|
||||
gtk_widget_set_sensitive (options->stroke_button, FALSE);
|
||||
g_signal_handlers_disconnect_by_func (options->stroke_button,
|
||||
gimp_path_tool_stroke_path,
|
||||
gtk_widget_set_sensitive (options->vector_layer_button, FALSE);
|
||||
g_signal_handlers_disconnect_by_func (options->vector_layer_button,
|
||||
gimp_path_tool_create_vector_layer,
|
||||
tool);
|
||||
}
|
||||
}
|
||||
@@ -642,20 +737,13 @@ gimp_path_tool_set_path (GimpPathTool *path_tool,
|
||||
gtk_widget_set_sensitive (options->to_selection_button, TRUE);
|
||||
}
|
||||
|
||||
if (options->fill_button)
|
||||
if (options->vector_layer_button)
|
||||
{
|
||||
g_signal_connect_swapped (options->fill_button, "clicked",
|
||||
G_CALLBACK (gimp_path_tool_fill_path),
|
||||
tool);
|
||||
gtk_widget_set_sensitive (options->fill_button, TRUE);
|
||||
}
|
||||
g_signal_connect_swapped (options->vector_layer_button, "clicked",
|
||||
G_CALLBACK (gimp_path_tool_create_vector_layer),
|
||||
tool);
|
||||
|
||||
if (options->stroke_button)
|
||||
{
|
||||
g_signal_connect_swapped (options->stroke_button, "clicked",
|
||||
G_CALLBACK (gimp_path_tool_stroke_path),
|
||||
tool);
|
||||
gtk_widget_set_sensitive (options->stroke_button, TRUE);
|
||||
gtk_widget_set_sensitive (options->vector_layer_button, TRUE);
|
||||
}
|
||||
|
||||
if (tool->display)
|
||||
@@ -722,180 +810,126 @@ gimp_path_tool_to_selection_extended (GimpPathTool *path_tool,
|
||||
gimp_image_flush (image);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gimp_path_tool_fill_path (GimpPathTool *path_tool,
|
||||
GtkWidget *button)
|
||||
gimp_path_tool_create_vector_layer (GimpPathTool *path_tool,
|
||||
GtkWidget *button)
|
||||
{
|
||||
GimpDialogConfig *config;
|
||||
GimpImage *image;
|
||||
GList *drawables;
|
||||
GList *path_list = NULL;
|
||||
GtkWidget *dialog;
|
||||
GimpImage *image;
|
||||
GimpVectorLayer *layer;
|
||||
GimpPathOptions *options = GIMP_PATH_TOOL_GET_OPTIONS (path_tool);
|
||||
|
||||
if (! path_tool->path)
|
||||
return;
|
||||
|
||||
image = gimp_item_get_image (GIMP_ITEM (path_tool->path));
|
||||
|
||||
config = GIMP_DIALOG_CONFIG (image->gimp->config);
|
||||
g_signal_handlers_block_by_func (image,
|
||||
gimp_path_tool_image_selected_layers_changed,
|
||||
path_tool);
|
||||
|
||||
drawables = gimp_image_get_selected_drawables (image);
|
||||
|
||||
if (! drawables)
|
||||
/* If there's already an active vector layer, create a new blank path */
|
||||
if (path_tool->current_vector_layer)
|
||||
{
|
||||
gimp_tool_message (GIMP_TOOL (path_tool),
|
||||
GIMP_TOOL (path_tool)->display,
|
||||
_("There are no selected layers or channels to fill."));
|
||||
return;
|
||||
GimpPath *new_path = gimp_path_new (image, _("Vector Layer"));
|
||||
|
||||
gimp_image_add_path (image, new_path, GIMP_IMAGE_ACTIVE_PARENT, -1,
|
||||
TRUE);
|
||||
|
||||
g_signal_handlers_disconnect_by_func (options,
|
||||
gimp_path_tool_vector_change_notify,
|
||||
path_tool->current_vector_layer);
|
||||
g_signal_handlers_disconnect_by_func (options->fill_options,
|
||||
gimp_path_tool_vector_change_notify,
|
||||
path_tool->current_vector_layer);
|
||||
g_signal_handlers_disconnect_by_func (options->stroke_options,
|
||||
gimp_path_tool_vector_change_notify,
|
||||
path_tool->current_vector_layer);
|
||||
}
|
||||
|
||||
if (g_list_length (drawables) == 1 &&
|
||||
gimp_item_is_content_locked (GIMP_ITEM (drawables->data), NULL))
|
||||
{
|
||||
gimp_tool_message (GIMP_TOOL (path_tool),
|
||||
GIMP_TOOL (path_tool)->display,
|
||||
_("A selected layer's pixels are locked."));
|
||||
return;
|
||||
}
|
||||
layer = gimp_vector_layer_new (image, path_tool->path,
|
||||
gimp_get_user_context (image->gimp));
|
||||
path_tool->current_vector_layer = layer;
|
||||
|
||||
path_list = g_list_prepend (NULL, path_tool->path);
|
||||
dialog = fill_dialog_new (path_list, drawables,
|
||||
GIMP_CONTEXT (GIMP_TOOL_GET_OPTIONS (path_tool)),
|
||||
_("Fill Path"),
|
||||
GIMP_ICON_TOOL_BUCKET_FILL,
|
||||
GIMP_HELP_PATH_FILL,
|
||||
button,
|
||||
config->fill_options,
|
||||
gimp_path_tool_fill_callback,
|
||||
path_tool);
|
||||
gtk_widget_show (dialog);
|
||||
g_list_free (path_list);
|
||||
g_list_free (drawables);
|
||||
}
|
||||
gimp_image_add_layer (image,
|
||||
GIMP_LAYER (layer),
|
||||
GIMP_IMAGE_ACTIVE_PARENT,
|
||||
-1,
|
||||
TRUE);
|
||||
|
||||
static void
|
||||
gimp_path_tool_fill_callback (GtkWidget *dialog,
|
||||
GList *items,
|
||||
GList *drawables,
|
||||
GimpContext *context,
|
||||
GimpFillOptions *options,
|
||||
gpointer data)
|
||||
{
|
||||
GimpDialogConfig *config = GIMP_DIALOG_CONFIG (context->gimp->config);
|
||||
GimpImage *image = gimp_item_get_image (items->data);
|
||||
GError *error = NULL;
|
||||
g_object_set (layer->options,
|
||||
"enable-fill", options->enable_fill,
|
||||
"enable-stroke", options->enable_stroke,
|
||||
NULL);
|
||||
|
||||
gimp_config_sync (G_OBJECT (options),
|
||||
G_OBJECT (config->fill_options), 0);
|
||||
gimp_config_sync (G_OBJECT (options->fill_options),
|
||||
G_OBJECT (layer->options->fill_options), 0);
|
||||
gimp_config_sync (G_OBJECT (options->stroke_options),
|
||||
G_OBJECT (layer->options->stroke_options), 0);
|
||||
|
||||
gimp_image_undo_group_start (image,
|
||||
GIMP_UNDO_GROUP_DRAWABLE_MOD,
|
||||
"Fill");
|
||||
g_signal_connect_object (options, "notify::enable-fill",
|
||||
G_CALLBACK (gimp_path_tool_vector_change_notify),
|
||||
layer, 0);
|
||||
g_signal_connect_object (options, "notify::enable-stroke",
|
||||
G_CALLBACK (gimp_path_tool_vector_change_notify),
|
||||
layer, 0);
|
||||
g_signal_connect_object (options->fill_options, "notify",
|
||||
G_CALLBACK (gimp_path_tool_vector_change_notify),
|
||||
layer, 0);
|
||||
g_signal_connect_object (options->stroke_options, "notify",
|
||||
G_CALLBACK (gimp_path_tool_vector_change_notify),
|
||||
layer, 0);
|
||||
|
||||
for (GList *iter = items; iter; iter = iter->next)
|
||||
if (! gimp_item_fill (iter->data, drawables, options,
|
||||
TRUE, NULL, &error))
|
||||
{
|
||||
gimp_message_literal (context->gimp,
|
||||
G_OBJECT (dialog),
|
||||
GIMP_MESSAGE_WARNING,
|
||||
error ? error->message : "NULL");
|
||||
|
||||
g_clear_error (&error);
|
||||
break;
|
||||
}
|
||||
|
||||
gimp_image_undo_group_end (image);
|
||||
gimp_vector_layer_refresh (layer);
|
||||
gimp_image_flush (image);
|
||||
gtk_widget_destroy (dialog);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gimp_path_tool_stroke_path (GimpPathTool *path_tool,
|
||||
GtkWidget *button)
|
||||
{
|
||||
GimpDialogConfig *config;
|
||||
GimpImage *image;
|
||||
GList *drawables;
|
||||
GList *path_list = NULL;
|
||||
GtkWidget *dialog;
|
||||
|
||||
if (! path_tool->path)
|
||||
return;
|
||||
|
||||
image = gimp_item_get_image (GIMP_ITEM (path_tool->path));
|
||||
|
||||
config = GIMP_DIALOG_CONFIG (image->gimp->config);
|
||||
|
||||
drawables = gimp_image_get_selected_drawables (image);
|
||||
|
||||
if (! drawables)
|
||||
{
|
||||
gimp_tool_message (GIMP_TOOL (path_tool),
|
||||
GIMP_TOOL (path_tool)->display,
|
||||
_("There are no selected layers or channels to stroke to."));
|
||||
return;
|
||||
}
|
||||
|
||||
if (g_list_length (drawables) == 1 &&
|
||||
gimp_item_is_content_locked (GIMP_ITEM (drawables->data), NULL))
|
||||
{
|
||||
gimp_tool_message (GIMP_TOOL (path_tool),
|
||||
GIMP_TOOL (path_tool)->display,
|
||||
_("A selected layer's pixels are locked."));
|
||||
return;
|
||||
}
|
||||
|
||||
path_list = g_list_prepend (NULL, path_tool->path);
|
||||
dialog = stroke_dialog_new (path_list, drawables,
|
||||
GIMP_CONTEXT (GIMP_TOOL_GET_OPTIONS (path_tool)),
|
||||
_("Stroke Path"),
|
||||
GIMP_ICON_PATH_STROKE,
|
||||
GIMP_HELP_PATH_STROKE,
|
||||
button,
|
||||
config->stroke_options,
|
||||
gimp_path_tool_stroke_callback,
|
||||
path_tool);
|
||||
gtk_widget_show (dialog);
|
||||
g_list_free (path_list);
|
||||
g_list_free (drawables);
|
||||
g_signal_handlers_unblock_by_func (image,
|
||||
gimp_path_tool_image_selected_layers_changed,
|
||||
path_tool);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_path_tool_stroke_callback (GtkWidget *dialog,
|
||||
GList *items,
|
||||
GList *drawables,
|
||||
GimpContext *context,
|
||||
GimpStrokeOptions *options,
|
||||
gpointer data)
|
||||
gimp_path_tool_vector_change_notify (GObject *options,
|
||||
const GParamSpec *pspec,
|
||||
GimpVectorLayer *layer)
|
||||
{
|
||||
GimpDialogConfig *config = GIMP_DIALOG_CONFIG (context->gimp->config);
|
||||
GimpImage *image = gimp_item_get_image (items->data);
|
||||
GError *error = NULL;
|
||||
GimpImage *image;
|
||||
gboolean needs_update = FALSE;
|
||||
|
||||
gimp_config_sync (G_OBJECT (options),
|
||||
G_OBJECT (config->stroke_options), 0);
|
||||
image = gimp_item_get_image (GIMP_ITEM (layer));
|
||||
|
||||
gimp_image_undo_group_start (image,
|
||||
GIMP_UNDO_GROUP_DRAWABLE_MOD,
|
||||
"Stroke");
|
||||
if (GIMP_IS_STROKE_OPTIONS (options))
|
||||
{
|
||||
GimpStrokeOptions *stroke_options = GIMP_STROKE_OPTIONS (options);
|
||||
|
||||
for (GList *iter = items; iter; iter = iter->next)
|
||||
if (! gimp_item_stroke (iter->data, drawables, context, options, NULL,
|
||||
TRUE, NULL, &error))
|
||||
{
|
||||
gimp_message_literal (context->gimp,
|
||||
G_OBJECT (dialog),
|
||||
GIMP_MESSAGE_WARNING,
|
||||
error ? error->message : "NULL");
|
||||
gimp_config_sync (G_OBJECT (stroke_options),
|
||||
G_OBJECT (layer->options->stroke_options), 0);
|
||||
|
||||
g_clear_error (&error);
|
||||
break;
|
||||
}
|
||||
needs_update = TRUE;
|
||||
}
|
||||
else if (GIMP_IS_FILL_OPTIONS (options))
|
||||
{
|
||||
GimpFillOptions *fill_options = GIMP_FILL_OPTIONS (options);
|
||||
|
||||
gimp_image_undo_group_end (image);
|
||||
gimp_image_flush (image);
|
||||
gtk_widget_destroy (dialog);
|
||||
gimp_config_sync (G_OBJECT (fill_options),
|
||||
G_OBJECT (layer->options->fill_options), 0);
|
||||
|
||||
needs_update = TRUE;
|
||||
}
|
||||
else if (GIMP_IS_PATH_OPTIONS (options))
|
||||
{
|
||||
GimpPathOptions *path_options = GIMP_PATH_OPTIONS (options);
|
||||
|
||||
g_object_set (layer->options,
|
||||
"enable-fill", path_options->enable_fill,
|
||||
"enable-stroke", path_options->enable_stroke,
|
||||
NULL);
|
||||
|
||||
needs_update = TRUE;
|
||||
}
|
||||
|
||||
if (needs_update)
|
||||
{
|
||||
gimp_vector_layer_refresh (layer);
|
||||
gimp_image_flush (image);
|
||||
}
|
||||
}
|
||||
|
@@ -38,13 +38,16 @@ typedef struct _GimpPathToolClass GimpPathToolClass;
|
||||
|
||||
struct _GimpPathTool
|
||||
{
|
||||
GimpDrawTool parent_instance;
|
||||
GimpDrawTool parent_instance;
|
||||
|
||||
GimpPath *path; /* the current Path data */
|
||||
GimpPathMode saved_mode; /* used by modifier_key() */
|
||||
GimpImage *current_image;
|
||||
GimpVectorLayer *current_vector_layer;
|
||||
|
||||
GimpToolWidget *widget;
|
||||
GimpToolWidget *grab_widget;
|
||||
GimpPath *path; /* the current Path data */
|
||||
GimpPathMode saved_mode; /* used by modifier_key() */
|
||||
|
||||
GimpToolWidget *widget;
|
||||
GimpToolWidget *grab_widget;
|
||||
};
|
||||
|
||||
struct _GimpPathToolClass
|
||||
|
@@ -449,6 +449,7 @@ gimp_main (GType plug_in_type,
|
||||
GIMP_TYPE_DRAWABLE, GIMP_TYPE_PARAM_DRAWABLE,
|
||||
GIMP_TYPE_LAYER, GIMP_TYPE_PARAM_LAYER,
|
||||
GIMP_TYPE_TEXT_LAYER, GIMP_TYPE_PARAM_TEXT_LAYER,
|
||||
GIMP_TYPE_VECTOR_LAYER, GIMP_TYPE_PARAM_VECTOR_LAYER,
|
||||
GIMP_TYPE_GROUP_LAYER, GIMP_TYPE_PARAM_GROUP_LAYER,
|
||||
GIMP_TYPE_CHANNEL, GIMP_TYPE_PARAM_CHANNEL,
|
||||
GIMP_TYPE_LAYER_MASK, GIMP_TYPE_PARAM_LAYER_MASK,
|
||||
|
@@ -601,6 +601,7 @@ EXPORTS
|
||||
gimp_item_id_is_selection
|
||||
gimp_item_id_is_text_layer
|
||||
gimp_item_id_is_valid
|
||||
gimp_item_id_is_vector_layer
|
||||
gimp_item_is_channel
|
||||
gimp_item_is_drawable
|
||||
gimp_item_is_group
|
||||
@@ -749,7 +750,9 @@ EXPORTS
|
||||
gimp_param_spec_resource_none_allowed
|
||||
gimp_param_spec_selection
|
||||
gimp_param_spec_text_layer
|
||||
gimp_param_spec_vector_layer
|
||||
gimp_param_text_layer_get_type
|
||||
gimp_param_vector_layer_get_type
|
||||
gimp_path_bezier_stroke_conicto
|
||||
gimp_path_bezier_stroke_cubicto
|
||||
gimp_path_bezier_stroke_lineto
|
||||
@@ -912,6 +915,9 @@ EXPORTS
|
||||
gimp_procedure_add_unit_argument
|
||||
gimp_procedure_add_unit_aux_argument
|
||||
gimp_procedure_add_unit_return_value
|
||||
gimp_procedure_add_vector_layer_argument
|
||||
gimp_procedure_add_vector_layer_aux_argument
|
||||
gimp_procedure_add_vector_layer_return_value
|
||||
gimp_procedure_config_get_choice_id
|
||||
gimp_procedure_config_get_color_array
|
||||
gimp_procedure_config_get_core_object_array
|
||||
@@ -1063,6 +1069,11 @@ EXPORTS
|
||||
gimp_unit_new
|
||||
gimp_update_metadata
|
||||
gimp_user_time
|
||||
gimp_vector_layer_discard
|
||||
gimp_vector_layer_get_by_id
|
||||
gimp_vector_layer_get_type
|
||||
gimp_vector_layer_new
|
||||
gimp_vector_layer_refresh
|
||||
gimp_vector_load_procedure_extract_dimensions
|
||||
gimp_vector_load_procedure_get_type
|
||||
gimp_vector_load_procedure_new
|
||||
|
@@ -71,6 +71,7 @@
|
||||
#include <libgimp/gimpselection.h>
|
||||
#include <libgimp/gimptextlayer.h>
|
||||
#include <libgimp/gimpthumbnailprocedure.h>
|
||||
#include <libgimp/gimpvectorlayer.h>
|
||||
#include <libgimp/gimpvectorloadprocedure.h>
|
||||
|
||||
#include <libgimp/gimp_pdb_headers.h>
|
||||
|
@@ -82,5 +82,6 @@
|
||||
#include <libgimp/gimptextlayer_pdb.h>
|
||||
#include <libgimp/gimptexttool_pdb.h>
|
||||
#include <libgimp/gimpunit_pdb.h>
|
||||
#include <libgimp/gimpvectorlayer_pdb.h>
|
||||
|
||||
#endif /* __GIMP_PDB_HEADERS_H__ */
|
||||
|
@@ -284,6 +284,11 @@ _gimp_gp_param_def_to_param_spec (const GPParamDef *param_def)
|
||||
param_def->meta.m_id.none_ok,
|
||||
flags);
|
||||
|
||||
if (! strcmp (param_def->type_name, "GimpParamVectorLayer"))
|
||||
return gimp_param_spec_vector_layer (name, nick, blurb,
|
||||
param_def->meta.m_id.none_ok,
|
||||
flags);
|
||||
|
||||
if (! strcmp (param_def->type_name, "GimpParamGroupLayer"))
|
||||
return gimp_param_spec_group_layer (name, nick, blurb,
|
||||
param_def->meta.m_id.none_ok,
|
||||
@@ -716,6 +721,10 @@ _gimp_param_spec_to_gp_param_def (GParamSpec *pspec,
|
||||
{
|
||||
type_name = "GimpParamTextLayer";
|
||||
}
|
||||
else if (value_type == GIMP_TYPE_VECTOR_LAYER)
|
||||
{
|
||||
type_name = "GimpParamVectorLayer";
|
||||
}
|
||||
else if (value_type == GIMP_TYPE_GROUP_LAYER)
|
||||
{
|
||||
type_name = "GimpParamGroupLayer";
|
||||
|
@@ -211,6 +211,46 @@ gimp_item_id_is_text_layer (gint item_id)
|
||||
return text_layer;
|
||||
}
|
||||
|
||||
/**
|
||||
* gimp_item_id_is_vector_layer:
|
||||
* @item_id: The item ID.
|
||||
*
|
||||
* Returns whether the item ID is a vector layer.
|
||||
*
|
||||
* This procedure returns %TRUE if the specified item ID is a vector
|
||||
* layer.
|
||||
*
|
||||
* *Note*: in most use cases, you should not use this function. See
|
||||
* [func@Gimp.Item.id_is_layer] for a discussion on alternatives.
|
||||
*
|
||||
* Returns: TRUE if the item is a vector layer, FALSE otherwise.
|
||||
*
|
||||
* Since: 3.2
|
||||
**/
|
||||
gboolean
|
||||
gimp_item_id_is_vector_layer (gint item_id)
|
||||
{
|
||||
GimpValueArray *args;
|
||||
GimpValueArray *return_vals;
|
||||
gboolean vector_layer = FALSE;
|
||||
|
||||
args = gimp_value_array_new_from_types (NULL,
|
||||
G_TYPE_INT, item_id,
|
||||
G_TYPE_NONE);
|
||||
|
||||
return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
|
||||
"gimp-item-id-is-vector-layer",
|
||||
args);
|
||||
gimp_value_array_unref (args);
|
||||
|
||||
if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
|
||||
vector_layer = GIMP_VALUES_GET_BOOLEAN (return_vals, 1);
|
||||
|
||||
gimp_value_array_unref (return_vals);
|
||||
|
||||
return vector_layer;
|
||||
}
|
||||
|
||||
/**
|
||||
* gimp_item_id_is_group_layer:
|
||||
* @item_id: The item ID.
|
||||
|
@@ -36,6 +36,7 @@ gboolean gimp_item_id_is_valid (gint item_id);
|
||||
gboolean gimp_item_id_is_drawable (gint item_id);
|
||||
gboolean gimp_item_id_is_layer (gint item_id);
|
||||
gboolean gimp_item_id_is_text_layer (gint item_id);
|
||||
gboolean gimp_item_id_is_vector_layer (gint item_id);
|
||||
gboolean gimp_item_id_is_group_layer (gint item_id);
|
||||
gboolean gimp_item_id_is_channel (gint item_id);
|
||||
gboolean gimp_item_id_is_layer_mask (gint item_id);
|
||||
|
@@ -532,6 +532,86 @@ gimp_param_spec_text_layer (const gchar *name,
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* GIMP_TYPE_PARAM_VECTOR_LAYER
|
||||
*/
|
||||
|
||||
static void gimp_param_vector_layer_class_init (GParamSpecClass *klass);
|
||||
static void gimp_param_vector_layer_init (GParamSpec *pspec);
|
||||
|
||||
GType
|
||||
gimp_param_vector_layer_get_type (void)
|
||||
{
|
||||
static GType type = 0;
|
||||
|
||||
if (! type)
|
||||
{
|
||||
const GTypeInfo info =
|
||||
{
|
||||
sizeof (GParamSpecClass),
|
||||
NULL, NULL,
|
||||
(GClassInitFunc) gimp_param_vector_layer_class_init,
|
||||
NULL, NULL,
|
||||
sizeof (GimpParamSpecItem),
|
||||
0,
|
||||
(GInstanceInitFunc) gimp_param_vector_layer_init
|
||||
};
|
||||
|
||||
type = g_type_register_static (GIMP_TYPE_PARAM_LAYER,
|
||||
"GimpParamVectorLayer", &info, 0);
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_param_vector_layer_class_init (GParamSpecClass *klass)
|
||||
{
|
||||
klass->value_type = GIMP_TYPE_VECTOR_LAYER;
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_param_vector_layer_init (GParamSpec *pspec)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* gimp_param_spec_vector_layer:
|
||||
* @name: Canonical name of the property specified.
|
||||
* @nick: Nick name of the property specified.
|
||||
* @blurb: Description of the property specified.
|
||||
* @none_ok: Whether no is a valid value.
|
||||
* @flags: Flags for the property specified.
|
||||
*
|
||||
* Creates a new #GimpParamSpecVectorLayer specifying a
|
||||
* [type@VectorLayer] property.
|
||||
*
|
||||
* See g_param_spec_internal() for details on property names.
|
||||
*
|
||||
* Returns: (transfer floating): The newly created #GimpParamSpecVectorLayer.
|
||||
*
|
||||
* Since: 3.2
|
||||
**/
|
||||
GParamSpec *
|
||||
gimp_param_spec_vector_layer (const gchar *name,
|
||||
const gchar *nick,
|
||||
const gchar *blurb,
|
||||
gboolean none_ok,
|
||||
GParamFlags flags)
|
||||
{
|
||||
GimpParamSpecItem *ispec;
|
||||
|
||||
ispec = g_param_spec_internal (GIMP_TYPE_PARAM_VECTOR_LAYER,
|
||||
name, nick, blurb, flags);
|
||||
|
||||
g_return_val_if_fail (ispec, NULL);
|
||||
|
||||
ispec->none_ok = none_ok ? TRUE : FALSE;
|
||||
|
||||
return G_PARAM_SPEC (ispec);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* GIMP_TYPE_PARAM_GROUP_LAYER
|
||||
*/
|
||||
|
@@ -129,6 +129,25 @@ GParamSpec * gimp_param_spec_text_layer (const gchar *name,
|
||||
GParamFlags flags);
|
||||
|
||||
|
||||
/*
|
||||
* GIMP_TYPE_PARAM_VECTOR_LAYER
|
||||
*/
|
||||
|
||||
#define GIMP_VALUE_HOLDS_VECTOR_LAYER(value) (G_TYPE_CHECK_VALUE_TYPE ((value),\
|
||||
GIMP_TYPE_VECTOR_LAYER))
|
||||
|
||||
#define GIMP_TYPE_PARAM_VECTOR_LAYER (gimp_param_vector_layer_get_type ())
|
||||
#define GIMP_IS_PARAM_SPEC_VECTOR_LAYER(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), GIMP_TYPE_PARAM_VECTOR_LAYER))
|
||||
|
||||
GType gimp_param_vector_layer_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GParamSpec * gimp_param_spec_vector_layer (const gchar *name,
|
||||
const gchar *nick,
|
||||
const gchar *blurb,
|
||||
gboolean none_ok,
|
||||
GParamFlags flags);
|
||||
|
||||
|
||||
/*
|
||||
* GIMP_TYPE_PARAM_GROUP_LAYER
|
||||
*/
|
||||
|
@@ -1801,6 +1801,12 @@ _gimp_plug_in_get_item (GimpPlugIn *plug_in,
|
||||
"id", item_id,
|
||||
NULL);
|
||||
}
|
||||
else if (gimp_item_id_is_vector_layer (item_id))
|
||||
{
|
||||
item = g_object_new (GIMP_TYPE_VECTOR_LAYER,
|
||||
"id", item_id,
|
||||
NULL);
|
||||
}
|
||||
else if (gimp_item_id_is_group_layer (item_id))
|
||||
{
|
||||
item = g_object_new (GIMP_TYPE_GROUP_LAYER,
|
||||
|
@@ -1884,6 +1884,84 @@ gimp_procedure_add_text_layer_return_value (GimpProcedure *procedure,
|
||||
none_ok, flags));
|
||||
}
|
||||
|
||||
/**
|
||||
* gimp_procedure_add_vector_layer_argument:
|
||||
* @procedure: the #GimpProcedure.
|
||||
* @name: the name of the argument to be created.
|
||||
* @nick: the label used in #GimpProcedureDialog.
|
||||
* @blurb: (nullable): a more detailed help description.
|
||||
* @none_ok: Whether no is a valid value.
|
||||
* @flags: argument flags.
|
||||
*
|
||||
* Add a new #GimpVectorLayer argument to @procedure.
|
||||
*
|
||||
* Since: 3.0
|
||||
**/
|
||||
void
|
||||
gimp_procedure_add_vector_layer_argument (GimpProcedure *procedure,
|
||||
const gchar *name,
|
||||
const gchar *nick,
|
||||
const gchar *blurb,
|
||||
gboolean none_ok,
|
||||
GParamFlags flags)
|
||||
{
|
||||
_gimp_procedure_add_argument (procedure,
|
||||
gimp_param_spec_vector_layer (name, nick, blurb,
|
||||
none_ok, flags));
|
||||
}
|
||||
|
||||
/**
|
||||
* gimp_procedure_add_vector_layer_aux_argument:
|
||||
* @procedure: the #GimpProcedure.
|
||||
* @name: the name of the argument to be created.
|
||||
* @nick: the label used in #GimpProcedureDialog.
|
||||
* @blurb: (nullable): a more detailed help description.
|
||||
* @none_ok: Whether no is a valid value.
|
||||
* @flags: argument flags.
|
||||
*
|
||||
* Add a new #GimpVectorLayer auxiliary argument to @procedure.
|
||||
*
|
||||
* Since: 3.0
|
||||
**/
|
||||
void
|
||||
gimp_procedure_add_vector_layer_aux_argument (GimpProcedure *procedure,
|
||||
const gchar *name,
|
||||
const gchar *nick,
|
||||
const gchar *blurb,
|
||||
gboolean none_ok,
|
||||
GParamFlags flags)
|
||||
{
|
||||
_gimp_procedure_add_aux_argument (procedure,
|
||||
gimp_param_spec_vector_layer (name, nick, blurb,
|
||||
none_ok, flags));
|
||||
}
|
||||
|
||||
/**
|
||||
* gimp_procedure_add_vector_layer_return_value:
|
||||
* @procedure: the #GimpProcedure.
|
||||
* @name: the name of the argument to be created.
|
||||
* @nick: the label used in #GimpProcedureDialog.
|
||||
* @blurb: (nullable): a more detailed help description.
|
||||
* @none_ok: Whether no is a valid value.
|
||||
* @flags: argument flags.
|
||||
*
|
||||
* Add a new #GimpVectorLayer return value to @procedure.
|
||||
*
|
||||
* Since: 3.0
|
||||
**/
|
||||
void
|
||||
gimp_procedure_add_vector_layer_return_value (GimpProcedure *procedure,
|
||||
const gchar *name,
|
||||
const gchar *nick,
|
||||
const gchar *blurb,
|
||||
gboolean none_ok,
|
||||
GParamFlags flags)
|
||||
{
|
||||
_gimp_procedure_add_return_value (procedure,
|
||||
gimp_param_spec_vector_layer (name, nick, blurb,
|
||||
none_ok, flags));
|
||||
}
|
||||
|
||||
/**
|
||||
* gimp_procedure_add_group_layer_argument:
|
||||
* @procedure: the #GimpProcedure.
|
||||
|
@@ -313,6 +313,18 @@ G_BEGIN_DECLS
|
||||
g_value_set_object (gimp_value_array_index (args, n), value)
|
||||
|
||||
|
||||
/* vector layer */
|
||||
|
||||
#define GIMP_VALUES_GET_VECTOR_LAYER(args, n) \
|
||||
g_value_get_object (gimp_value_array_index (args, n))
|
||||
|
||||
#define GIMP_VALUES_GET_VECTOR_LAYER_ID(args, n) \
|
||||
gimp_item_get_id (g_value_get_object (gimp_value_array_index (args, n)))
|
||||
|
||||
#define GIMP_VALUES_SET_VECTOR_LAYER(args, n, value) \
|
||||
g_value_set_object (gimp_value_array_index (args, n), value)
|
||||
|
||||
|
||||
/* group layer */
|
||||
|
||||
#define GIMP_VALUES_GET_GROUP_LAYER(args, n) \
|
||||
@@ -899,6 +911,25 @@ void gimp_procedure_add_text_layer_return_value (GimpProcedure *procedure
|
||||
gboolean none_ok,
|
||||
GParamFlags flags);
|
||||
|
||||
void gimp_procedure_add_vector_layer_argument (GimpProcedure *procedure,
|
||||
const gchar *name,
|
||||
const gchar *nick,
|
||||
const gchar *blurb,
|
||||
gboolean none_ok,
|
||||
GParamFlags flags);
|
||||
void gimp_procedure_add_vector_layer_aux_argument (GimpProcedure *procedure,
|
||||
const gchar *name,
|
||||
const gchar *nick,
|
||||
const gchar *blurb,
|
||||
gboolean none_ok,
|
||||
GParamFlags flags);
|
||||
void gimp_procedure_add_vector_layer_return_value (GimpProcedure *procedure,
|
||||
const gchar *name,
|
||||
const gchar *nick,
|
||||
const gchar *blurb,
|
||||
gboolean none_ok,
|
||||
GParamFlags flags);
|
||||
|
||||
void gimp_procedure_add_group_layer_argument (GimpProcedure *procedure,
|
||||
const gchar *name,
|
||||
const gchar *nick,
|
||||
|
@@ -52,6 +52,7 @@ typedef struct _GimpTextLayer GimpTextLayer;
|
||||
typedef struct _GimpPath GimpPath;
|
||||
typedef struct _GimpDrawableFilter GimpDrawableFilter;
|
||||
typedef struct _GimpDrawableFilterConfig GimpDrawableFilterConfig;
|
||||
typedef struct _GimpVectorLayer GimpVectorLayer;
|
||||
|
||||
typedef struct _GimpDisplay GimpDisplay;
|
||||
|
||||
|
75
libgimp/gimpvectorlayer.c
Normal file
75
libgimp/gimpvectorlayer.c
Normal file
@@ -0,0 +1,75 @@
|
||||
/* LIBGIMP - The GIMP Library
|
||||
* Copyright (C) 1995-2000 Peter Mattis and Spencer Kimball
|
||||
*
|
||||
* gimpvectorlayer.c
|
||||
*
|
||||
* This library is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gimp.h"
|
||||
|
||||
|
||||
struct _GimpVectorLayer
|
||||
{
|
||||
GimpLayer parent_instance;
|
||||
};
|
||||
|
||||
|
||||
|
||||
G_DEFINE_TYPE (GimpVectorLayer, gimp_vector_layer, GIMP_TYPE_LAYER)
|
||||
|
||||
#define parent_class gimp_vector_layer_parent_class
|
||||
|
||||
|
||||
static void
|
||||
gimp_vector_layer_class_init (GimpVectorLayerClass *klass)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_vector_layer_init (GimpVectorLayer *layer)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/* Public API. */
|
||||
|
||||
/**
|
||||
* gimp_vector_layer_get_by_id:
|
||||
* @layer_id: The layer id.
|
||||
*
|
||||
* Returns a #GimpVectorLayer representing @layer_id. This function calls
|
||||
* gimp_item_get_by_id() and returns the item if it is layer or %NULL
|
||||
* otherwise.
|
||||
*
|
||||
* Returns: (nullable) (transfer none): a #GimpVectorLayer for @layer_id or
|
||||
* %NULL if @layer_id does not represent a valid layer. The
|
||||
* object belongs to libgimp and you must not modify or unref
|
||||
* it.
|
||||
*
|
||||
* Since: 3.0
|
||||
**/
|
||||
GimpVectorLayer *
|
||||
gimp_vector_layer_get_by_id (gint32 layer_id)
|
||||
{
|
||||
GimpItem *item = gimp_item_get_by_id (layer_id);
|
||||
|
||||
if (GIMP_IS_VECTOR_LAYER (item))
|
||||
return (GimpVectorLayer *) item;
|
||||
|
||||
return NULL;
|
||||
}
|
45
libgimp/gimpvectorlayer.h
Normal file
45
libgimp/gimpvectorlayer.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/* LIBGIMP - The GIMP Library
|
||||
* Copyright (C) 1995-2000 Peter Mattis and Spencer Kimball
|
||||
*
|
||||
* gimpvectorlayer.h
|
||||
*
|
||||
* This library is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if !defined (__GIMP_H_INSIDE__) && !defined (GIMP_COMPILATION)
|
||||
#error "Only <libgimp/gimp.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __GIMP_VECTOR_LAYER_H__
|
||||
#define __GIMP_VECTOR_LAYER_H__
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/* For information look into the C source or the html documentation */
|
||||
|
||||
|
||||
#include <libgimp/gimplayer.h>
|
||||
|
||||
|
||||
#define GIMP_TYPE_VECTOR_LAYER (gimp_vector_layer_get_type ())
|
||||
G_DECLARE_FINAL_TYPE (GimpVectorLayer, gimp_vector_layer, GIMP, VECTOR_LAYER, GimpLayer)
|
||||
|
||||
|
||||
GimpVectorLayer * gimp_vector_layer_get_by_id (gint32 layer_id);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GIMP_VECTOR_LAYER_H__ */
|
159
libgimp/gimpvectorlayer_pdb.c
Normal file
159
libgimp/gimpvectorlayer_pdb.c
Normal file
@@ -0,0 +1,159 @@
|
||||
/* LIBGIMP - The GIMP Library
|
||||
* Copyright (C) 1995-2003 Peter Mattis and Spencer Kimball
|
||||
*
|
||||
* gimpvectorlayer_pdb.c
|
||||
*
|
||||
* This library is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* NOTE: This file is auto-generated by pdbgen.pl */
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "stamp-pdbgen.h"
|
||||
|
||||
#include "gimp.h"
|
||||
|
||||
|
||||
/**
|
||||
* SECTION: gimpvectorlayer
|
||||
* @title: gimpvectorlayer
|
||||
* @short_description: Functions for querying and manipulating vector layers.
|
||||
*
|
||||
* Functions for querying and manipulating vector layers.
|
||||
**/
|
||||
|
||||
|
||||
/**
|
||||
* gimp_vector_layer_new:
|
||||
* @image: The image.
|
||||
* @path: The path to create the layer from.
|
||||
*
|
||||
* Creates a new vector layer.
|
||||
*
|
||||
* This procedure creates a new path layer displaying the specified
|
||||
* @path. By default, the fill and stroke properties will be defined by
|
||||
* the context.
|
||||
*
|
||||
* The new layer still needs to be added to the image as this is not
|
||||
* automatic. Add the new layer with the [method@Image.insert_layer]
|
||||
* method.
|
||||
*
|
||||
* The arguments are kept as simple as necessary for the basic case.
|
||||
* All vector attributes, however, can be modified with the appropriate
|
||||
* `gimp_vector_layer_set_*()` procedures.
|
||||
*
|
||||
* Returns: (transfer none):
|
||||
* The new vector layer. The object belongs to libgimp and you should not free it.
|
||||
*
|
||||
* Since: 3.2
|
||||
**/
|
||||
GimpVectorLayer *
|
||||
gimp_vector_layer_new (GimpImage *image,
|
||||
GimpPath *path)
|
||||
{
|
||||
GimpValueArray *args;
|
||||
GimpValueArray *return_vals;
|
||||
GimpVectorLayer *layer = NULL;
|
||||
|
||||
args = gimp_value_array_new_from_types (NULL,
|
||||
GIMP_TYPE_IMAGE, image,
|
||||
GIMP_TYPE_PATH, path,
|
||||
G_TYPE_NONE);
|
||||
|
||||
return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
|
||||
"gimp-vector-layer-new",
|
||||
args);
|
||||
gimp_value_array_unref (args);
|
||||
|
||||
if (GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS)
|
||||
layer = GIMP_VALUES_GET_VECTOR_LAYER (return_vals, 1);
|
||||
|
||||
gimp_value_array_unref (return_vals);
|
||||
|
||||
return layer;
|
||||
}
|
||||
|
||||
/**
|
||||
* gimp_vector_layer_refresh:
|
||||
* @layer: The vector layer.
|
||||
*
|
||||
* Rerender the vector layer
|
||||
*
|
||||
* This procedure causes the vector layer to refresh itself after
|
||||
* changes.
|
||||
*
|
||||
* Returns: TRUE on success.
|
||||
*
|
||||
* Since: 3.2
|
||||
**/
|
||||
gboolean
|
||||
gimp_vector_layer_refresh (GimpVectorLayer *layer)
|
||||
{
|
||||
GimpValueArray *args;
|
||||
GimpValueArray *return_vals;
|
||||
gboolean success = TRUE;
|
||||
|
||||
args = gimp_value_array_new_from_types (NULL,
|
||||
GIMP_TYPE_VECTOR_LAYER, layer,
|
||||
G_TYPE_NONE);
|
||||
|
||||
return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
|
||||
"gimp-vector-layer-refresh",
|
||||
args);
|
||||
gimp_value_array_unref (args);
|
||||
|
||||
success = GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS;
|
||||
|
||||
gimp_value_array_unref (return_vals);
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
* gimp_vector_layer_discard:
|
||||
* @layer: The vector layer.
|
||||
*
|
||||
* Discard the vector layer information.
|
||||
*
|
||||
* Discards the vector information. This makes the layer behave like a
|
||||
* normal layer.
|
||||
*
|
||||
* Returns: TRUE on success.
|
||||
*
|
||||
* Since: 3.2
|
||||
**/
|
||||
gboolean
|
||||
gimp_vector_layer_discard (GimpVectorLayer *layer)
|
||||
{
|
||||
GimpValueArray *args;
|
||||
GimpValueArray *return_vals;
|
||||
gboolean success = TRUE;
|
||||
|
||||
args = gimp_value_array_new_from_types (NULL,
|
||||
GIMP_TYPE_VECTOR_LAYER, layer,
|
||||
G_TYPE_NONE);
|
||||
|
||||
return_vals = _gimp_pdb_run_procedure_array (gimp_get_pdb (),
|
||||
"gimp-vector-layer-discard",
|
||||
args);
|
||||
gimp_value_array_unref (args);
|
||||
|
||||
success = GIMP_VALUES_GET_ENUM (return_vals, 0) == GIMP_PDB_SUCCESS;
|
||||
|
||||
gimp_value_array_unref (return_vals);
|
||||
|
||||
return success;
|
||||
}
|
43
libgimp/gimpvectorlayer_pdb.h
Normal file
43
libgimp/gimpvectorlayer_pdb.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/* LIBGIMP - The GIMP Library
|
||||
* Copyright (C) 1995-2003 Peter Mattis and Spencer Kimball
|
||||
*
|
||||
* gimpvectorlayer_pdb.h
|
||||
*
|
||||
* This library is free software: you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see
|
||||
* <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* NOTE: This file is auto-generated by pdbgen.pl */
|
||||
|
||||
#if !defined (__GIMP_H_INSIDE__) && !defined (GIMP_COMPILATION)
|
||||
#error "Only <libgimp/gimp.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __GIMP_VECTOR_LAYER_PDB_H__
|
||||
#define __GIMP_VECTOR_LAYER_PDB_H__
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
/* For information look into the C source or the html documentation */
|
||||
|
||||
|
||||
GimpVectorLayer* gimp_vector_layer_new (GimpImage *image,
|
||||
GimpPath *path);
|
||||
gboolean gimp_vector_layer_refresh (GimpVectorLayer *layer);
|
||||
gboolean gimp_vector_layer_discard (GimpVectorLayer *layer);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GIMP_VECTOR_LAYER_PDB_H__ */
|
@@ -114,6 +114,7 @@ pdb_wrappers_sources = [
|
||||
'gimptextlayer_pdb.c',
|
||||
'gimptexttool_pdb.c',
|
||||
'gimpunit_pdb.c',
|
||||
'gimpvectorlayer_pdb.c',
|
||||
]
|
||||
|
||||
pdb_wrappers_headers = [
|
||||
@@ -173,6 +174,7 @@ pdb_wrappers_headers = [
|
||||
'gimptextlayer_pdb.h',
|
||||
'gimptexttool_pdb.h',
|
||||
'gimpunit_pdb.h',
|
||||
'gimpvectorlayer_pdb.h',
|
||||
]
|
||||
|
||||
libgimp_sources_introspectable = [
|
||||
@@ -214,6 +216,7 @@ libgimp_sources_introspectable = [
|
||||
'gimpselection.c',
|
||||
'gimptextlayer.c',
|
||||
'gimpthumbnailprocedure.c',
|
||||
'gimpvectorlayer.c',
|
||||
'gimpvectorloadprocedure.c',
|
||||
gimpenums,
|
||||
pdb_wrappers_sources,
|
||||
@@ -276,6 +279,7 @@ libgimp_headers_introspectable = [
|
||||
'gimpselection.h',
|
||||
'gimptextlayer.h',
|
||||
'gimpthumbnailprocedure.h',
|
||||
'gimpvectorlayer.h',
|
||||
'gimpvectorloadprocedure.h',
|
||||
pdb_wrappers_headers,
|
||||
]
|
||||
|
10
pdb/app.pl
10
pdb/app.pl
@@ -381,6 +381,16 @@ gimp_param_spec_text_layer ("$name",
|
||||
"$blurb",
|
||||
$none_ok,
|
||||
$flags)
|
||||
CODE
|
||||
}
|
||||
elsif ($pdbtype eq 'vector_layer') {
|
||||
$none_ok = exists $arg->{none_ok} ? 'TRUE' : 'FALSE';
|
||||
$pspec = <<CODE;
|
||||
gimp_param_spec_vector_layer ("$name",
|
||||
"$nick",
|
||||
"$blurb",
|
||||
$none_ok,
|
||||
$flags)
|
||||
CODE
|
||||
}
|
||||
elsif ($pdbtype eq 'layer') {
|
||||
|
@@ -57,4 +57,5 @@
|
||||
text_layer
|
||||
text_tool
|
||||
unit
|
||||
vector_layer
|
||||
);
|
||||
|
@@ -178,6 +178,42 @@ CODE
|
||||
);
|
||||
}
|
||||
|
||||
sub item_id_is_vector_layer {
|
||||
$blurb = 'Returns whether the item ID is a vector layer.';
|
||||
|
||||
$help = <<'HELP';
|
||||
This procedure returns %TRUE if the specified item ID is a vector layer.
|
||||
|
||||
|
||||
*Note*: in most use cases, you should not use this function. See
|
||||
[func@Gimp.Item.id_is_layer] for a discussion on alternatives.
|
||||
HELP
|
||||
|
||||
&alxsa_pdb_misc('2025', '3.2');
|
||||
|
||||
@inargs = (
|
||||
{ name => 'item_id', type => 'int32',
|
||||
desc => 'The item ID' }
|
||||
);
|
||||
|
||||
@outargs = (
|
||||
{ name => 'vector_layer', type => 'boolean',
|
||||
desc => 'TRUE if the item is a vector layer, FALSE otherwise.' }
|
||||
);
|
||||
|
||||
%invoke = (
|
||||
code => <<'CODE'
|
||||
{
|
||||
GimpItem *item = gimp_item_get_by_id (gimp, item_id);
|
||||
|
||||
vector_layer = (GIMP_IS_LAYER (item) &&
|
||||
! gimp_item_is_removed (item) &&
|
||||
gimp_item_is_vector_layer (item));
|
||||
}
|
||||
CODE
|
||||
);
|
||||
}
|
||||
|
||||
sub item_id_is_group_layer {
|
||||
$blurb = 'Returns whether the item ID is a group layer.';
|
||||
|
||||
@@ -1056,7 +1092,8 @@ CODE
|
||||
"core/gimplayermask.h"
|
||||
"core/gimplist.h"
|
||||
"core/gimpselection.h"
|
||||
"path/gimppath.h"
|
||||
"path/gimppath.h"
|
||||
"path/gimpvectorlayer.h"
|
||||
"text/gimptextlayer.h"
|
||||
"gimppdb-utils.h"
|
||||
"gimppdbcontext.h"
|
||||
@@ -1066,6 +1103,7 @@ CODE
|
||||
item_id_is_drawable
|
||||
item_id_is_layer
|
||||
item_id_is_text_layer
|
||||
item_id_is_vector_layer
|
||||
item_id_is_group_layer
|
||||
item_id_is_channel
|
||||
item_id_is_layer_mask
|
||||
|
144
pdb/groups/vector_layer.pdb
Normal file
144
pdb/groups/vector_layer.pdb
Normal file
@@ -0,0 +1,144 @@
|
||||
# GIMP - The GNU Image Manipulation Program
|
||||
# Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
||||
|
||||
# New Vector Layer PDB API
|
||||
|
||||
# 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
sub vector_layer_new {
|
||||
$blurb = 'Creates a new vector layer.';
|
||||
|
||||
$help = <<'HELP';
|
||||
This procedure creates a new path layer displaying the specified @path. By
|
||||
default, the fill and stroke properties will be defined by the context.
|
||||
|
||||
|
||||
The new layer still needs to be added to the image as this is not
|
||||
automatic. Add the new layer with the [method@Image.insert_layer]
|
||||
method.
|
||||
|
||||
|
||||
The arguments are kept as simple as necessary for the basic case. All
|
||||
vector attributes, however, can be modified with the appropriate
|
||||
`gimp_vector_layer_set_*()` procedures.
|
||||
HELP
|
||||
|
||||
&alxsa_pdb_misc('2025', '3.2');
|
||||
|
||||
@inargs = (
|
||||
{ name => 'image', type => 'image',
|
||||
desc => 'The image' },
|
||||
{ name => 'path', type => 'path',
|
||||
desc => 'The path to create the layer from' }
|
||||
);
|
||||
|
||||
@outargs = (
|
||||
{ name => 'layer', type => 'vector_layer',
|
||||
desc => 'The new vector layer. The object belongs to libgimp and you should not free it.' }
|
||||
);
|
||||
|
||||
%invoke = (
|
||||
code => <<'CODE'
|
||||
{
|
||||
if (path == NULL)
|
||||
{
|
||||
g_set_error (error, GIMP_PDB_ERROR, GIMP_PDB_ERROR_INVALID_ARGUMENT,
|
||||
_("Failed to create vector layer"));
|
||||
|
||||
success = FALSE;
|
||||
}
|
||||
|
||||
if (success)
|
||||
{
|
||||
layer = GIMP_VECTOR_LAYER (gimp_vector_layer_new (image, path, context));
|
||||
|
||||
if (! layer)
|
||||
{
|
||||
g_set_error (error, GIMP_PDB_ERROR, GIMP_PDB_ERROR_INVALID_ARGUMENT,
|
||||
_("Failed to create vector layer"));
|
||||
|
||||
success = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
CODE
|
||||
);
|
||||
}
|
||||
|
||||
sub vector_layer_refresh {
|
||||
$blurb = 'Rerender the vector layer';
|
||||
|
||||
$help = <<'HELP';
|
||||
This procedure causes the vector layer to refresh itself after changes.
|
||||
HELP
|
||||
|
||||
&alxsa_pdb_misc('2025', '3.2');
|
||||
|
||||
@inargs = (
|
||||
{ name => 'layer', type => 'vector_layer',
|
||||
desc => 'The vector layer' }
|
||||
);
|
||||
|
||||
%invoke = (
|
||||
code => <<'CODE'
|
||||
{
|
||||
gimp_vector_layer_refresh (layer);
|
||||
}
|
||||
CODE
|
||||
);
|
||||
}
|
||||
|
||||
sub vector_layer_discard {
|
||||
$blurb = 'Discard the vector layer information.';
|
||||
|
||||
$help = <<'HELP';
|
||||
Discards the vector information. This makes the layer behave like a normal layer.
|
||||
HELP
|
||||
|
||||
&alxsa_pdb_misc('2025', '3.2');
|
||||
|
||||
@inargs = (
|
||||
{ name => 'layer', type => 'vector_layer',
|
||||
desc => 'The vector layer' }
|
||||
);
|
||||
|
||||
%invoke = (
|
||||
code => <<'CODE'
|
||||
{
|
||||
gimp_vector_layer_discard (layer);
|
||||
}
|
||||
CODE
|
||||
);
|
||||
}
|
||||
|
||||
@headers = qw("libgimpbase/gimpbase.h"
|
||||
"core/gimpcontext.h"
|
||||
"path/gimpvectorlayer.h"
|
||||
"gimppdb-utils.h"
|
||||
"gimppdberror.h"
|
||||
"gimp-intl.h");
|
||||
|
||||
@procs = qw(vector_layer_new
|
||||
vector_layer_refresh
|
||||
vector_layer_discard);
|
||||
|
||||
%exports = (app => [@procs], lib => [@procs]);
|
||||
|
||||
$desc = 'Vector layer procedures';
|
||||
$doc_title = 'gimpvectorlayer';
|
||||
$doc_short_desc = 'Functions for querying and manipulating vector layers.';
|
||||
$doc_long_desc = 'Functions for querying and manipulating vector layers.';
|
||||
|
||||
1;
|
@@ -59,6 +59,7 @@ pdb_names = [
|
||||
'text_layer',
|
||||
'text_tool',
|
||||
'unit',
|
||||
'vector_layer',
|
||||
]
|
||||
|
||||
pdb_sources = []
|
||||
|
12
pdb/pdb.pl
12
pdb/pdb.pl
@@ -371,6 +371,18 @@ package Gimp::CodeGen::pdb;
|
||||
take_value_func => 'g_value_set_object ($value, $var)',
|
||||
headers => [ qw("text/gimptextlayer.h") ] },
|
||||
|
||||
vector_layer => { name => 'VECTOR_LAYER',
|
||||
gtype => 'GIMP_TYPE_VECTOR_LAYER',
|
||||
type => 'GimpVectorLayer *',
|
||||
const_type => 'GimpVectorLayer *',
|
||||
init_value => 'NULL',
|
||||
out_annotate => '(transfer none)',
|
||||
get_value_func => '$var = g_value_get_object ($value)',
|
||||
dup_value_func => '$var = GIMP_VALUES_GET_VECTOR_LAYER ($value)',
|
||||
set_value_func => 'g_value_set_object ($value, $var)',
|
||||
take_value_func => 'g_value_set_object ($value, $var)',
|
||||
headers => [ qw("path/gimpvectorlayer.h") ] },
|
||||
|
||||
group_layer => { name => 'GROUP_LAYER',
|
||||
gtype => 'GIMP_TYPE_GROUP_LAYER',
|
||||
type => 'GimpGroupLayer *',
|
||||
|
Reference in New Issue
Block a user