1
1
mirror of https://gitlab.gnome.org/GNOME/gimp.git synced 2025-10-06 01:12:40 +02:00

Compare commits

...

1 Commits

Author SHA1 Message Date
Jacob Boerema
fb0a8b6163 Vector Layers from GSoC 2006 by Hendrik Boom
Adaption of patch 1 from issue #282.
Author according to patch: Martin Nordholts <martinn@src.gnome.org>

A whole lot of changes needed to be made to make it build on master.
Several assumptions have been made, parts have been disabled, just
to make it compile - Wormnest.

January 2022:
There's a large #if 0 part in app/tools/gimpvectortool.c. I think most of
that code was already integrated into GIMP in app/display/gimptoolpath.c,
but I didn't get around to checking if that is true for all of it.
2022-01-12 12:26:38 -05:00
29 changed files with 2847 additions and 59 deletions

View File

@@ -33,6 +33,8 @@
#include "text/gimptextlayer.h"
#include "vectors/gimpvectorlayer.h"
#include "widgets/gimphelp-ids.h"
#include "widgets/gimpactiongroup.h"
#include "widgets/gimpwidgets-utils.h"
@@ -97,6 +99,13 @@ static const GimpActionEntry layers_actions[] =
layers_edit_text_cmd_callback,
GIMP_HELP_LAYER_EDIT },
{ "layers-edit-vector", GIMP_ICON_TOOL_PATH,
NC_("layers-action", "Edit Vector layer"), NULL,
NC_("layers-action",
"Activate the path tool to edit this vector layer's path"),
layers_edit_vector_cmd_callback,
GIMP_HELP_TOOL_PATH },
{ "layers-edit-attributes", GIMP_ICON_EDIT,
NC_("layers-action", "_Edit Layer Attributes..."), NULL,
NC_("layers-action", "Edit the layer's name"),
@@ -228,6 +237,18 @@ static const GimpActionEntry layers_actions[] =
layers_text_along_vectors_cmd_callback,
GIMP_HELP_LAYER_TEXT_ALONG_PATH },
{ "layers-vector-fill-stroke", NULL,
N_("Fill / Stroke"), NULL,
N_("Edit the fill and stroke of this vector layer"),
layers_vector_fill_stroke_cmd_callback,
NULL },
{ "layers-vector-discard", NULL,
N_("Discard Vector Information"), NULL,
N_("Turn this vector layer into a normal layer"),
layers_vector_discard_cmd_callback,
NULL },
{ "layers-resize", GIMP_ICON_OBJECT_RESIZE,
NC_("layers-action", "Layer B_oundary Size..."), NULL,
NC_("layers-action", "Adjust the layer dimensions"),
@@ -766,6 +787,7 @@ layers_actions_update (GimpActionGroup *group,
gboolean lock_alpha = TRUE;
gboolean can_lock_alpha = FALSE;
gboolean text_layer = FALSE;
gboolean vector_layer = FALSE;
gboolean bs_mutable = FALSE; /* At least 1 selected layers' blend space is mutable. */
gboolean cs_mutable = FALSE; /* At least 1 selected layers' composite space is mutable. */
gboolean cm_mutable = FALSE; /* At least 1 selected layers' composite mode is mutable. */
@@ -983,8 +1005,9 @@ layers_actions_update (GimpActionGroup *group,
gimp_action_group_set_action_active (group, action, TRUE);
text_layer = gimp_item_is_text_layer (GIMP_ITEM (layer));
}
text_layer = gimp_item_is_text_layer (GIMP_ITEM (layer));
vector_layer = gimp_item_is_vector_layer (GIMP_ITEM (layer));
}
}
#define SET_VISIBLE(action,condition) \
@@ -996,9 +1019,11 @@ layers_actions_update (GimpActionGroup *group,
#define SET_LABEL(action,label) \
gimp_action_group_set_action_label (group, action, label)
SET_SENSITIVE ("layers-edit", !ac && ((layer && !fs) || text_layer));
SET_SENSITIVE ("layers-edit", !ac && ((layer && !fs) || text_layer || vector_layer));
SET_VISIBLE ("layers-edit-text", text_layer && !ac);
SET_SENSITIVE ("layers-edit-text", text_layer && !ac);
SET_VISIBLE ("layers-edit-vector", vector_layer && !ac);
SET_SENSITIVE ("layers-edit-vector", vector_layer && !ac);
SET_SENSITIVE ("layers-edit-attributes", layer && !fs && !ac);
if (layer && gimp_layer_is_floating_sel (layer))
@@ -1048,6 +1073,9 @@ layers_actions_update (GimpActionGroup *group,
SET_VISIBLE ("layers-text-to-vectors", text_layer && !ac);
SET_VISIBLE ("layers-text-along-vectors", text_layer && !ac);
SET_VISIBLE ("layers-vector-fill-stroke", vector_layer && !ac);
SET_VISIBLE ("layers-vector-discard", vector_layer && !ac);
SET_SENSITIVE ("layers-resize", n_selected_layers == 1 && all_writable && all_movable && !ac);
SET_SENSITIVE ("layers-resize-to-image", all_writable && all_movable && !ac);
SET_SENSITIVE ("layers-scale", n_selected_layers == 1 && all_writable && all_movable && !ac);

View File

@@ -59,6 +59,8 @@
#include "text/gimptextlayer.h"
#include "vectors/gimpstroke.h"
#include "vectors/gimpvectorlayer.h"
#include "vectors/gimpvectorlayeroptions.h"
#include "vectors/gimpvectors.h"
#include "vectors/gimpvectors-warp.h"
@@ -72,6 +74,7 @@
#include "display/gimpimagewindow.h"
#include "tools/gimptexttool.h"
#include "tools/gimpvectortool.h"
#include "tools/tool_manager.h"
#include "dialogs/dialogs.h"
@@ -79,6 +82,7 @@
#include "dialogs/layer-options-dialog.h"
#include "dialogs/resize-dialog.h"
#include "dialogs/scale-dialog.h"
#include "dialogs/vector-layer-options-dialog.h"
#include "actions.h"
#include "items-commands.h"
@@ -240,10 +244,55 @@ layers_edit_text_cmd_callback (GimpAction *action,
}
}
void
layers_edit_vector_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data)
{
GimpImage *image;
GimpLayer *layer;
GtkWidget *widget;
GimpTool *active_tool;
return_if_no_layer (image, layer, data);
return_if_no_widget (widget, data);
g_return_if_fail (gimp_item_is_vector_layer (GIMP_ITEM (layer)));
/*if (! gimp_drawable_is_vector_layer (GIMP_DRAWABLE (layer)))
{
layers_edit_attributes_cmd_callback (action, value, data);
return;
}*/
active_tool = tool_manager_get_active (image->gimp);
if (! GIMP_IS_VECTOR_TOOL (active_tool))
{
/*GimpToolInfo *tool_info;
tool_info = (GimpToolInfo *)
gimp_container_get_child_by_name (image->gimp->tool_info_list,
"gimp-vector-tool");*/
GimpToolInfo *tool_info = gimp_get_tool_info (image->gimp,
"gimp-vector-tool");
if (GIMP_IS_TOOL_INFO (tool_info))
{
gimp_context_set_tool (action_data_get_context (data), tool_info);
active_tool = tool_manager_get_active (image->gimp);
}
}
if (GIMP_IS_VECTOR_TOOL (active_tool))
gimp_vector_tool_set_vectors (GIMP_VECTOR_TOOL (active_tool),
GIMP_VECTOR_LAYER (layer)->options->vectors);
// layer->options->vectors);
}
void
layers_edit_attributes_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data)
gpointer data)
{
GimpImage *image;
GimpLayer *layer;
@@ -1058,10 +1107,48 @@ layers_text_along_vectors_cmd_callback (GimpAction *action,
}
}
void
layers_vector_fill_stroke_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data)
{
GimpImage *image;
GimpLayer *layer;
GtkWidget *widget;
return_if_no_layer (image, layer, data);
return_if_no_widget (widget, data);
if (GIMP_IS_VECTOR_LAYER (layer))
{
GtkWidget *dialog;
dialog = vector_layer_options_dialog_new (GIMP_VECTOR_LAYER (layer),
action_data_get_context (data),
_("Fill / Stroke"),
_("_OK"),
NULL, /* FIXME: help id */
widget);
gtk_widget_show (dialog);
}
}
void
layers_vector_discard_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data)
{
GimpImage *image;
GimpLayer *layer;
return_if_no_layer (image, layer, data);
if (GIMP_IS_VECTOR_LAYER (layer))
gimp_vector_layer_discard (GIMP_VECTOR_LAYER (layer));
}
void
layers_resize_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data)
gpointer data)
{
GimpImage *image;
GimpLayer *layer;

View File

@@ -25,6 +25,9 @@ void layers_edit_cmd_callback (GimpAction *action,
void layers_edit_text_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data);
void layers_edit_vector_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data);
void layers_edit_attributes_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data);
@@ -84,6 +87,12 @@ void layers_text_to_vectors_cmd_callback (GimpAction *action,
void layers_text_along_vectors_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data);
void layers_vector_fill_stroke_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data);
void layers_vector_discard_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data);
void layers_resize_cmd_callback (GimpAction *action,
GVariant *value,

View File

@@ -157,7 +157,12 @@ static const GimpActionEntry vectors_actions[] =
{ "vectors-import", GIMP_ICON_DOCUMENT_OPEN,
NC_("vectors-action", "I_mport Path..."), "", NULL,
vectors_import_cmd_callback,
GIMP_HELP_PATH_IMPORT }
GIMP_HELP_PATH_IMPORT },
{ "vectors-to-vector-layer", NULL,
N_("Path to Vector Layer"), "", NULL,
vectors_to_vector_layer_cmd_callback,
NULL }
};
static const GimpToggleActionEntry vectors_toggle_actions[] =
@@ -427,6 +432,9 @@ vectors_actions_update (GimpActionGroup *group,
SET_SENSITIVE ("vectors-export", n_selected_vectors == 1);
SET_SENSITIVE ("vectors-import", image);
/* Wormnest: not sure if the condition here is correct (it was vectors) */
SET_SENSITIVE ("vectors-to-vector-layer", n_selected_vectors > 0);
SET_SENSITIVE ("vectors-selection-to-vectors", image && !mask_empty);
SET_SENSITIVE ("vectors-selection-to-vectors-short", image && !mask_empty);
SET_SENSITIVE ("vectors-selection-to-vectors-advanced", image && !mask_empty);

View File

@@ -47,6 +47,7 @@
#include "vectors/gimpvectors.h"
#include "vectors/gimpvectors-export.h"
#include "vectors/gimpvectors-import.h"
#include "vectors/gimpvectorlayer.h"
#include "widgets/gimpaction.h"
#include "widgets/gimpclipboard.h"
@@ -348,10 +349,32 @@ vectors_merge_visible_cmd_callback (GimpAction *action,
gimp_image_flush (image);
}
void
vectors_to_vector_layer_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data)
{
GimpImage *image;
GimpVectors *vectors;
GimpVectorLayer *layer;
return_if_no_vectors (image, vectors, data);
layer = gimp_vector_layer_new (image, vectors,
gimp_get_user_context (image->gimp));
gimp_image_add_layer (image,
GIMP_LAYER (layer),
GIMP_IMAGE_ACTIVE_PARENT,
-1,
TRUE);
gimp_vector_layer_refresh (layer);
gimp_image_flush (image);
}
void
vectors_to_selection_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data)
gpointer data)
{
GimpImage *image;
GimpVectors *vectors;

View File

@@ -54,12 +54,21 @@ void vectors_delete_cmd_callback (GimpAction *action,
void vectors_merge_visible_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data);
void vectors_to_vector_layer_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data);
void vectors_to_selection_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data);
void vectors_selection_to_vectors_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data);
void vectors_stroke_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data);
void vectors_stroke_last_vals_cmd_callback (GimpAction *action,
GVariant *value,
gpointer data);
void vectors_fill_cmd_callback (GimpAction *action,
GVariant *value,

View File

@@ -97,6 +97,8 @@ libappdialogs_a_sources = \
tips-parser.h \
user-install-dialog.c \
user-install-dialog.h \
vector-layer-options-dialog.c \
vector-layer-options-dialog.h \
vectors-export-dialog.c \
vectors-export-dialog.h \
vectors-import-dialog.c \

View File

@@ -40,6 +40,8 @@ libappdialogs_sources = [
'tips-dialog.c',
'tips-parser.c',
'user-install-dialog.c',
'vector-layer-options-dialog.c',
'vector-layer-options-dialog.h',
'vectors-export-dialog.c',
'vectors-import-dialog.c',
'vectors-options-dialog.c',

View File

@@ -0,0 +1,237 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* Copyright (C) 2006 Henk 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 2 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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#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/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 *stock_id,
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 (stock_id != NULL, NULL);
/* g_return_val_if_fail (help_id != NULL, NULL); */
g_return_val_if_fail (parent == NULL || GTK_IS_WIDGET (parent), NULL);
g_printerr ("--> vector_layer_options_dialog_new\n");
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, layer),
context,
title, "gimp-vectorlayer-options",
stock_id,
_("Choose vector layer options"),
parent,
gimp_standard_help_func,
help_id,
_("_Reset"), RESPONSE_RESET,
_("_Cancel"), GTK_RESPONSE_CANCEL,
stock_id, GTK_RESPONSE_OK,
NULL);
gtk_dialog_set_default_response (GTK_DIALOG (dialog), RESPONSE_RESET);
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);
// Wormnest - next copied, check last 3 parameters!
// gtk_box_pack_start (GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (dialog))),
// main_vbox, TRUE, TRUE, 0);
//gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->box), main_vbox);
gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (GTK_DIALOG (dialog))), main_vbox);
gtk_widget_show (main_vbox);
/* 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_show (frame);
fill_editor = gimp_fill_editor_new (fill_options, TRUE);
gtk_container_add (GTK_CONTAINER (frame), fill_editor);
gtk_widget_show (fill_editor);
}
/* 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_show (frame);
gimp_image_get_resolution (gimp_item_get_image (GIMP_ITEM (layer)),
&xres, &yres);
stroke_editor = gimp_stroke_editor_new (stroke_options, yres, TRUE);
gtk_container_add (GTK_CONTAINER (frame), stroke_editor);
gtk_widget_show (stroke_editor);
}
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:
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;
}
}

View File

@@ -0,0 +1,33 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* Copyright (C) 2006 Henk 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 2 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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#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 *stock_id,
const gchar *help_id,
GtkWidget *parent);
#endif /* __VECTOR_LAYER_OPTIONS_DIALOG_H__ */

View File

@@ -88,29 +88,6 @@ gimp_vector_options_init (GimpVectorOptions *options)
{
}
static void
gimp_vector_options_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GimpVectorOptions *options = GIMP_VECTOR_OPTIONS (object);
switch (property_id)
{
case PROP_VECTORS_EDIT_MODE:
options->edit_mode = g_value_get_enum (value);
break;
case PROP_VECTORS_POLYGONAL:
options->polygonal = g_value_get_boolean (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gimp_vector_options_get_property (GObject *object,
guint property_id,
@@ -133,6 +110,28 @@ gimp_vector_options_get_property (GObject *object,
}
}
static void
gimp_vector_options_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GimpVectorOptions *options = GIMP_VECTOR_OPTIONS (object);
switch (property_id)
{
case PROP_VECTORS_EDIT_MODE:
options->edit_mode = g_value_get_enum (value);
break;
case PROP_VECTORS_POLYGONAL:
options->polygonal = g_value_get_boolean (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
button_append_modifier (GtkWidget *button,
GdkModifierType modifiers)
@@ -214,5 +213,13 @@ gimp_vector_options_gui (GimpToolOptions *tool_options)
options->stroke_button = button;
button = gtk_button_new_with_label (_("Create 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 /* FIXME */);
gtk_widget_show (button);
options->vector_layer_button = button;
return vbox;
}

View File

@@ -44,6 +44,7 @@ struct _GimpVectorOptions
GtkWidget *to_selection_button;
GtkWidget *fill_button;
GtkWidget *stroke_button;
GtkWidget *vector_layer_button;
};

View File

@@ -40,6 +40,7 @@
#include "paint/gimppaintoptions.h" /* GIMP_PAINT_OPTIONS_CONTEXT_MASK */
#include "vectors/gimpvectorlayer.h"
#include "vectors/gimpvectors.h"
#include "widgets/gimpdialogfactory.h"
@@ -147,6 +148,8 @@ static void gimp_vector_tool_stroke_callback (GtkWidget *dialog,
GimpStrokeOptions *options,
gpointer data);
static void gimp_vector_tool_create_vector_layer (GimpVectorTool *vector_tool,
GtkWidget *button);
G_DEFINE_TYPE (GimpVectorTool, gimp_vector_tool, GIMP_TYPE_DRAW_TOOL)
@@ -558,6 +561,897 @@ gimp_vector_tool_set_vectors (GimpVectorTool *vector_tool,
if (vectors == vector_tool->vectors)
return;
#if 0
if (!vector_tool->modifier_lock)
{
if (state & TOGGLE_MASK)
{
vector_tool->restriction = GIMP_ANCHOR_FEATURE_SYMMETRIC;
}
else
{
vector_tool->restriction = GIMP_ANCHOR_FEATURE_NONE;
}
}
switch (vector_tool->function)
{
case VECTORS_MOVE_ANCHOR:
case VECTORS_MOVE_HANDLE:
anchor = vector_tool->cur_anchor;
if (anchor)
{
gimp_stroke_anchor_move_absolute (vector_tool->cur_stroke,
vector_tool->cur_anchor,
&position,
vector_tool->restriction);
vector_tool->undo_motion = TRUE;
}
break;
case VECTORS_MOVE_CURVE:
if (options->polygonal)
{
gimp_vector_tool_move_selected_anchors (vector_tool,
coords->x - vector_tool->last_x,
coords->y - vector_tool->last_y);
vector_tool->undo_motion = TRUE;
}
else
{
gimp_stroke_point_move_absolute (vector_tool->cur_stroke,
vector_tool->cur_anchor,
vector_tool->cur_position,
&position,
vector_tool->restriction);
vector_tool->undo_motion = TRUE;
}
break;
case VECTORS_MOVE_ANCHORSET:
gimp_vector_tool_move_selected_anchors (vector_tool,
coords->x - vector_tool->last_x,
coords->y - vector_tool->last_y);
vector_tool->undo_motion = TRUE;
break;
case VECTORS_MOVE_STROKE:
if (vector_tool->cur_stroke)
{
gimp_stroke_translate (vector_tool->cur_stroke,
coords->x - vector_tool->last_x,
coords->y - vector_tool->last_y);
vector_tool->undo_motion = TRUE;
}
else if (vector_tool->sel_stroke)
{
gimp_stroke_translate (vector_tool->sel_stroke,
coords->x - vector_tool->last_x,
coords->y - vector_tool->last_y);
vector_tool->undo_motion = TRUE;
}
break;
case VECTORS_MOVE_VECTORS:
gimp_item_translate (GIMP_ITEM (vector_tool->vectors),
coords->x - vector_tool->last_x,
coords->y - vector_tool->last_y, FALSE);
vector_tool->undo_motion = TRUE;
break;
default:
break;
}
vector_tool->last_x = coords->x;
vector_tool->last_y = coords->y;
gimp_vectors_thaw (vector_tool->vectors);
image = gimp_item_get_image (GIMP_ITEM (vector_tool->vectors));
gimp_image_flush (image);
}
static gboolean
gimp_vector_tool_key_press (GimpTool *tool,
GdkEventKey *kevent,
GimpDisplay *display)
{
GimpVectorTool *vector_tool = GIMP_VECTOR_TOOL (tool);
GimpDrawTool *draw_tool = GIMP_DRAW_TOOL (tool);
GimpVectorOptions *options = GIMP_VECTOR_TOOL_GET_OPTIONS (tool);
GimpDisplayShell *shell;
gdouble xdist, ydist;
gdouble pixels = 1.0;
if (! vector_tool->vectors)
return FALSE;
if (display != draw_tool->display)
return FALSE;
shell = GIMP_DISPLAY_SHELL (draw_tool->display->shell);
if (kevent->state & GDK_SHIFT_MASK)
pixels = 10.0;
if (kevent->state & GDK_CONTROL_MASK)
pixels = 50.0;
switch (kevent->keyval)
{
case GDK_Return:
case GDK_KP_Enter:
case GDK_ISO_Enter:
gimp_vector_tool_to_selection_extended (vector_tool, kevent->state);
break;
case GDK_BackSpace:
case GDK_Delete:
gimp_vector_tool_delete_selected_anchors (vector_tool);
break;
case GDK_Left:
case GDK_Right:
case GDK_Up:
case GDK_Down:
xdist = FUNSCALEX (shell, pixels);
ydist = FUNSCALEY (shell, pixels);
gimp_vector_tool_undo_push (vector_tool, _("Move Anchors"));
gimp_vectors_freeze (vector_tool->vectors);
switch (kevent->keyval)
{
case GDK_Left:
gimp_vector_tool_move_selected_anchors (vector_tool, -xdist, 0);
break;
case GDK_Right:
gimp_vector_tool_move_selected_anchors (vector_tool, xdist, 0);
break;
case GDK_Up:
gimp_vector_tool_move_selected_anchors (vector_tool, 0, -ydist);
break;
case GDK_Down:
gimp_vector_tool_move_selected_anchors (vector_tool, 0, ydist);
break;
default:
break;
}
gimp_vectors_thaw (vector_tool->vectors);
vector_tool->have_undo = FALSE;
break;
case GDK_Escape:
if (options->edit_mode != GIMP_VECTOR_MODE_DESIGN)
g_object_set (options, "vectors-edit-mode",
GIMP_VECTOR_MODE_DESIGN, NULL);
break;
default:
return FALSE;
}
gimp_image_flush (display->image);
return TRUE;
}
static void
gimp_vector_tool_modifier_key (GimpTool *tool,
GdkModifierType key,
gboolean press,
GdkModifierType state,
GimpDisplay *display)
{
GimpVectorTool *vector_tool = GIMP_VECTOR_TOOL (tool);
GimpVectorOptions *options = GIMP_VECTOR_TOOL_GET_OPTIONS (tool);
if (key == TOGGLE_MASK)
return;
if (key == INSDEL_MASK || key == MOVE_MASK)
{
GimpVectorMode button_mode = options->edit_mode;
if (press)
{
if (key == (state & (INSDEL_MASK | MOVE_MASK)))
{
/* first modifier pressed */
vector_tool->saved_mode = options->edit_mode;
}
}
else
{
if (! (state & (INSDEL_MASK | MOVE_MASK)))
{
/* last modifier released */
button_mode = vector_tool->saved_mode;
}
}
if (state & MOVE_MASK)
{
button_mode = GIMP_VECTOR_MODE_MOVE;
}
else if (state & INSDEL_MASK)
{
button_mode = GIMP_VECTOR_MODE_EDIT;
}
if (button_mode != options->edit_mode)
{
g_object_set (options, "vectors-edit-mode", button_mode, NULL);
}
}
}
static void
gimp_vector_tool_oper_update (GimpTool *tool,
const GimpCoords *coords,
GdkModifierType state,
gboolean proximity,
GimpDisplay *display)
{
GimpVectorTool *vector_tool = GIMP_VECTOR_TOOL (tool);
GimpDrawTool *draw_tool = GIMP_DRAW_TOOL (tool);
GimpVectorOptions *options = GIMP_VECTOR_TOOL_GET_OPTIONS (tool);
GimpAnchor *anchor = NULL;
GimpAnchor *anchor2 = NULL;
GimpStroke *stroke = NULL;
gdouble position = -1;
gboolean on_handle = FALSE;
gboolean on_curve = FALSE;
gboolean on_vectors = FALSE;
vector_tool->modifier_lock = FALSE;
/* are we hovering the current vectors on the current display? */
if (vector_tool->vectors && GIMP_DRAW_TOOL (tool)->display == display)
{
on_handle = gimp_draw_tool_on_vectors_handle (GIMP_DRAW_TOOL (tool),
display,
vector_tool->vectors,
coords,
TARGET, TARGET,
GIMP_ANCHOR_ANCHOR,
vector_tool->sel_count > 2,
&anchor, &stroke);
if (! on_handle)
on_curve = gimp_draw_tool_on_vectors_curve (GIMP_DRAW_TOOL (tool),
display,
vector_tool->vectors,
coords,
TARGET, TARGET,
NULL,
&position, &anchor,
&anchor2, &stroke);
}
if (on_handle || on_curve)
{
vector_tool->cur_vectors = NULL;
}
else
{
on_vectors = gimp_draw_tool_on_vectors (draw_tool, display, coords,
TARGET, TARGET,
NULL, NULL, NULL, NULL, NULL,
&(vector_tool->cur_vectors));
}
vector_tool->cur_position = position;
vector_tool->cur_anchor = anchor;
vector_tool->cur_anchor2 = anchor2;
vector_tool->cur_stroke = stroke;
switch (options->edit_mode)
{
case GIMP_VECTOR_MODE_DESIGN:
if (! vector_tool->vectors || GIMP_DRAW_TOOL (tool)->display != display)
{
if (on_vectors)
{
vector_tool->function = VECTORS_SELECT_VECTOR;
}
else
{
vector_tool->function = VECTORS_CREATE_VECTOR;
vector_tool->restriction = GIMP_ANCHOR_FEATURE_SYMMETRIC;
vector_tool->modifier_lock = TRUE;
}
}
else if (on_handle)
{
if (anchor->type == GIMP_ANCHOR_ANCHOR)
{
if (state & TOGGLE_MASK)
{
vector_tool->function = VECTORS_MOVE_ANCHORSET;
}
else
{
if (vector_tool->sel_count >= 2 && anchor->selected)
vector_tool->function = VECTORS_MOVE_ANCHORSET;
else
vector_tool->function = VECTORS_MOVE_ANCHOR;
}
}
else
{
vector_tool->function = VECTORS_MOVE_HANDLE;
if (state & TOGGLE_MASK)
vector_tool->restriction = GIMP_ANCHOR_FEATURE_SYMMETRIC;
else
vector_tool->restriction = GIMP_ANCHOR_FEATURE_NONE;
}
}
else if (on_curve)
{
if (gimp_stroke_point_is_movable (stroke, anchor, position))
{
vector_tool->function = VECTORS_MOVE_CURVE;
if (state & TOGGLE_MASK)
vector_tool->restriction = GIMP_ANCHOR_FEATURE_SYMMETRIC;
else
vector_tool->restriction = GIMP_ANCHOR_FEATURE_NONE;
}
else
{
vector_tool->function = VECTORS_FINISHED;
}
}
else
{
if (vector_tool->sel_stroke && vector_tool->sel_anchor &&
gimp_stroke_is_extendable (vector_tool->sel_stroke,
vector_tool->sel_anchor) &&
!(state & TOGGLE_MASK))
vector_tool->function = VECTORS_ADD_ANCHOR;
else
vector_tool->function = VECTORS_CREATE_STROKE;
vector_tool->restriction = GIMP_ANCHOR_FEATURE_SYMMETRIC;
vector_tool->modifier_lock = TRUE;
}
break;
case GIMP_VECTOR_MODE_EDIT:
if (! vector_tool->vectors || GIMP_DRAW_TOOL (tool)->display != display)
{
if (on_vectors)
{
vector_tool->function = VECTORS_SELECT_VECTOR;
}
else
{
vector_tool->function = VECTORS_FINISHED;
}
}
else if (on_handle)
{
if (anchor->type == GIMP_ANCHOR_ANCHOR)
{
if (!(state & TOGGLE_MASK) && vector_tool->sel_anchor &&
vector_tool->sel_anchor != anchor &&
gimp_stroke_is_extendable (vector_tool->sel_stroke,
vector_tool->sel_anchor) &&
gimp_stroke_is_extendable (stroke, anchor))
{
vector_tool->function = VECTORS_CONNECT_STROKES;
}
else
{
if (state & TOGGLE_MASK)
{
vector_tool->function = VECTORS_DELETE_ANCHOR;
}
else
{
if (options->polygonal)
vector_tool->function = VECTORS_MOVE_ANCHOR;
else
vector_tool->function = VECTORS_MOVE_HANDLE;
}
}
}
else
{
if (state & TOGGLE_MASK)
vector_tool->function = VECTORS_CONVERT_EDGE;
else
vector_tool->function = VECTORS_MOVE_HANDLE;
}
}
else if (on_curve)
{
if (state & TOGGLE_MASK)
{
vector_tool->function = VECTORS_DELETE_SEGMENT;
}
else if (gimp_stroke_anchor_is_insertable (stroke, anchor, position))
{
vector_tool->function = VECTORS_INSERT_ANCHOR;
}
else
{
vector_tool->function = VECTORS_FINISHED;
}
}
else
{
vector_tool->function = VECTORS_FINISHED;
}
break;
case GIMP_VECTOR_MODE_MOVE:
if (! vector_tool->vectors || GIMP_DRAW_TOOL (tool)->display != display)
{
if (on_vectors)
{
vector_tool->function = VECTORS_SELECT_VECTOR;
}
else
{
vector_tool->function = VECTORS_FINISHED;
}
}
else if (on_handle || on_curve)
{
if (state & TOGGLE_MASK)
{
vector_tool->function = VECTORS_MOVE_VECTORS;
}
else
{
vector_tool->function = VECTORS_MOVE_STROKE;
}
}
else
{
if (on_vectors)
{
vector_tool->function = VECTORS_SELECT_VECTOR;
}
else
{
vector_tool->function = VECTORS_MOVE_VECTORS;
}
}
break;
}
gimp_vector_tool_status_update (tool, display, state, proximity);
}
static void
gimp_vector_tool_status_update (GimpTool *tool,
GimpDisplay *display,
GdkModifierType state,
gboolean proximity)
{
GimpVectorTool *vector_tool = GIMP_VECTOR_TOOL (tool);
GimpVectorOptions *options = GIMP_VECTOR_TOOL_GET_OPTIONS (tool);
gimp_tool_pop_status (tool, display);
if (proximity)
{
const gchar *status = NULL;
gboolean free_status = FALSE;
switch (vector_tool->function)
{
case VECTORS_SELECT_VECTOR:
status = _("Click to pick path to edit");
break;
case VECTORS_CREATE_VECTOR:
status = _("Click to create a new path");
break;
case VECTORS_CREATE_STROKE:
status = _("Click to create a new component of the path");
break;
case VECTORS_ADD_ANCHOR:
status = gimp_suggest_modifiers (_("Click or Click-Drag to create "
"a new anchor"),
GDK_SHIFT_MASK & ~state,
NULL, NULL, NULL);
free_status = TRUE;
break;
case VECTORS_MOVE_ANCHOR:
if (options->edit_mode != GIMP_VECTOR_MODE_EDIT)
{
status = gimp_suggest_modifiers (_("Click-Drag to move the "
"anchor around"),
GDK_CONTROL_MASK & ~state,
NULL, NULL, NULL);
free_status = TRUE;
}
else
status = _("Click-Drag to move the anchor around");
break;
case VECTORS_MOVE_ANCHORSET:
status = _("Click-Drag to move the anchors around");
break;
case VECTORS_MOVE_HANDLE:
status = gimp_suggest_modifiers (_("Click-Drag to move the handle "
"around"),
GDK_SHIFT_MASK & ~state,
NULL, NULL, NULL);
free_status = TRUE;
break;
case VECTORS_MOVE_CURVE:
if (GIMP_VECTOR_TOOL_GET_OPTIONS (tool)->polygonal)
status = gimp_suggest_modifiers (_("Click-Drag to move the "
"anchors around"),
GDK_SHIFT_MASK & ~state,
NULL, NULL, NULL);
else
status = gimp_suggest_modifiers (_("Click-Drag to change the "
"shape of the curve"),
GDK_SHIFT_MASK & ~state,
_("%s: symmetrical"), NULL, NULL);
free_status = TRUE;
break;
case VECTORS_MOVE_STROKE:
status = gimp_suggest_modifiers (_("Click-Drag to move the "
"component around"),
GDK_SHIFT_MASK & ~state,
NULL, NULL, NULL);
free_status = TRUE;
break;
case VECTORS_MOVE_VECTORS:
status = _("Click-Drag to move the path around");
break;
case VECTORS_INSERT_ANCHOR:
status = gimp_suggest_modifiers (_("Click-Drag to insert an anchor "
"on the path"),
GDK_SHIFT_MASK & ~state,
NULL, NULL, NULL);
free_status = TRUE;
break;
case VECTORS_DELETE_ANCHOR:
status = _("Click to delete this anchor");
break;
case VECTORS_CONNECT_STROKES:
status = _("Click to connect this anchor "
"with the selected endpoint");
break;
case VECTORS_DELETE_SEGMENT:
status = _("Click to open up the path");
break;
case VECTORS_CONVERT_EDGE:
status = _("Click to make this node angular");
break;
case VECTORS_FINISHED:
status = NULL;
break;
}
if (status)
gimp_tool_push_status (tool, display, "%s", status);
if (free_status)
g_free ((gchar *) status);
}
}
static void
gimp_vector_tool_cursor_update (GimpTool *tool,
const GimpCoords *coords,
GdkModifierType state,
GimpDisplay *display)
{
GimpVectorTool *vector_tool = GIMP_VECTOR_TOOL (tool);
GimpToolCursorType tool_cursor = GIMP_TOOL_CURSOR_PATHS;
GimpCursorModifier modifier = GIMP_CURSOR_MODIFIER_NONE;
switch (vector_tool->function)
{
case VECTORS_SELECT_VECTOR:
tool_cursor = GIMP_TOOL_CURSOR_HAND;
break;
case VECTORS_CREATE_VECTOR:
case VECTORS_CREATE_STROKE:
modifier = GIMP_CURSOR_MODIFIER_CONTROL;
break;
case VECTORS_ADD_ANCHOR:
case VECTORS_INSERT_ANCHOR:
tool_cursor = GIMP_TOOL_CURSOR_PATHS_ANCHOR;
modifier = GIMP_CURSOR_MODIFIER_PLUS;
break;
case VECTORS_DELETE_ANCHOR:
tool_cursor = GIMP_TOOL_CURSOR_PATHS_ANCHOR;
modifier = GIMP_CURSOR_MODIFIER_MINUS;
break;
case VECTORS_DELETE_SEGMENT:
tool_cursor = GIMP_TOOL_CURSOR_PATHS_SEGMENT;
modifier = GIMP_CURSOR_MODIFIER_MINUS;
break;
case VECTORS_MOVE_HANDLE:
tool_cursor = GIMP_TOOL_CURSOR_PATHS_CONTROL;
modifier = GIMP_CURSOR_MODIFIER_MOVE;
break;
case VECTORS_CONVERT_EDGE:
tool_cursor = GIMP_TOOL_CURSOR_PATHS_CONTROL;
modifier = GIMP_CURSOR_MODIFIER_MINUS;
break;
case VECTORS_MOVE_ANCHOR:
tool_cursor = GIMP_TOOL_CURSOR_PATHS_ANCHOR;
modifier = GIMP_CURSOR_MODIFIER_MOVE;
break;
case VECTORS_MOVE_CURVE:
tool_cursor = GIMP_TOOL_CURSOR_PATHS_SEGMENT;
modifier = GIMP_CURSOR_MODIFIER_MOVE;
break;
case VECTORS_MOVE_STROKE:
case VECTORS_MOVE_VECTORS:
modifier = GIMP_CURSOR_MODIFIER_MOVE;
break;
case VECTORS_MOVE_ANCHORSET:
tool_cursor = GIMP_TOOL_CURSOR_PATHS_ANCHOR;
modifier = GIMP_CURSOR_MODIFIER_MOVE;
break;
case VECTORS_CONNECT_STROKES:
tool_cursor = GIMP_TOOL_CURSOR_PATHS_SEGMENT;
modifier = GIMP_CURSOR_MODIFIER_JOIN;
break;
default:
modifier = GIMP_CURSOR_MODIFIER_BAD;
break;
}
gimp_tool_control_set_tool_cursor (tool->control, tool_cursor);
gimp_tool_control_set_cursor_modifier (tool->control, modifier);
GIMP_TOOL_CLASS (parent_class)->cursor_update (tool, coords, state, display);
}
static void
gimp_vector_tool_draw (GimpDrawTool *draw_tool)
{
GimpVectorTool *vector_tool = GIMP_VECTOR_TOOL (draw_tool);
GimpAnchor *cur_anchor = NULL;
GimpStroke *cur_stroke = NULL;
GimpVectors *vectors;
GArray *coords;
gboolean closed;
GList *draw_anchors;
GList *list;
vectors = vector_tool->vectors;
if (!vectors)
return;
while ((cur_stroke = gimp_vectors_stroke_get_next (vectors, cur_stroke)))
{
/* anchor handles */
draw_anchors = gimp_stroke_get_draw_anchors (cur_stroke);
for (list = draw_anchors; list; list = g_list_next (list))
{
cur_anchor = GIMP_ANCHOR (list->data);
if (cur_anchor->type == GIMP_ANCHOR_ANCHOR)
{
gimp_draw_tool_draw_handle (draw_tool,
cur_anchor->selected ?
GIMP_HANDLE_CIRCLE :
GIMP_HANDLE_FILLED_CIRCLE,
cur_anchor->position.x,
cur_anchor->position.y,
TARGET,
TARGET,
GTK_ANCHOR_CENTER,
FALSE);
}
}
g_list_free (draw_anchors);
if (vector_tool->sel_count <= 2)
{
/* control handles */
draw_anchors = gimp_stroke_get_draw_controls (cur_stroke);
for (list = draw_anchors; list; list = g_list_next (list))
{
cur_anchor = GIMP_ANCHOR (list->data);
gimp_draw_tool_draw_handle (draw_tool,
GIMP_HANDLE_SQUARE,
cur_anchor->position.x,
cur_anchor->position.y,
TARGET - 3,
TARGET - 3,
GTK_ANCHOR_CENTER,
FALSE);
}
g_list_free (draw_anchors);
/* the lines to the control handles */
coords = gimp_stroke_get_draw_lines (cur_stroke);
if (coords)
{
if (coords->len % 2 == 0)
{
gint i;
for (i = 0; i < coords->len; i += 2)
{
gimp_draw_tool_draw_dashed_line (draw_tool,
g_array_index (coords, GimpCoords, i).x,
g_array_index (coords, GimpCoords, i).y,
g_array_index (coords, GimpCoords, i + 1).x,
g_array_index (coords, GimpCoords, i + 1).y,
FALSE);
}
}
g_array_free (coords, TRUE);
}
}
/* the stroke itself */
if (! gimp_item_get_visible (GIMP_ITEM (vectors)))
{
coords = gimp_stroke_interpolate (cur_stroke, 1.0, &closed);
if (coords)
{
if (coords->len)
gimp_draw_tool_draw_strokes (draw_tool,
&g_array_index (coords,
GimpCoords, 0),
coords->len, FALSE, FALSE);
g_array_free (coords, TRUE);
}
}
}
}
static void
gimp_vector_tool_vectors_changed (GimpImage *image,
GimpVectorTool *vector_tool)
{
gimp_vector_tool_set_vectors (vector_tool,
gimp_image_get_active_vectors (image));
}
static void
gimp_vector_tool_vectors_removed (GimpVectors *vectors,
GimpVectorTool *vector_tool)
{
gimp_vector_tool_set_vectors (vector_tool, NULL);
}
static void
gimp_vector_tool_vectors_visible (GimpVectors *vectors,
GimpVectorTool *vector_tool)
{
GimpDrawTool *draw_tool = GIMP_DRAW_TOOL (vector_tool);
if (gimp_draw_tool_is_active (draw_tool) && draw_tool->paused_count == 0)
{
GimpStroke *stroke = NULL;
while ((stroke = gimp_vectors_stroke_get_next (vectors, stroke)))
{
GArray *coords;
gboolean closed;
coords = gimp_stroke_interpolate (stroke, 1.0, &closed);
if (coords)
{
if (coords->len)
gimp_draw_tool_draw_strokes (draw_tool,
&g_array_index (coords,
GimpCoords, 0),
coords->len, FALSE, FALSE);
g_array_free (coords, TRUE);
}
}
}
}
static void
gimp_vector_tool_vectors_freeze (GimpVectors *vectors,
GimpVectorTool *vector_tool)
{
gimp_draw_tool_pause (GIMP_DRAW_TOOL (vector_tool));
}
static void
gimp_vector_tool_vectors_thaw (GimpVectors *vectors,
GimpVectorTool *vector_tool)
{
/* Ok, the vector might have changed externally (e.g. Undo)
* we need to validate our internal state. */
gimp_vector_tool_verify_state (vector_tool);
gimp_draw_tool_resume (GIMP_DRAW_TOOL (vector_tool));
}
void
gimp_vector_tool_set_vectors (GimpVectorTool *vector_tool,
GimpVectors *vectors)
{
GimpDrawTool *draw_tool;
GimpTool *tool;
GimpItem *item = NULL;
GimpVectorOptions *options;
g_return_if_fail (GIMP_IS_VECTOR_TOOL (vector_tool));
g_return_if_fail (vectors == NULL || GIMP_IS_VECTORS (vectors));
draw_tool = GIMP_DRAW_TOOL (vector_tool);
tool = GIMP_TOOL (vector_tool);
options = GIMP_VECTOR_TOOL_GET_OPTIONS (vector_tool);
if (vectors)
item = GIMP_ITEM (vectors);
if (vectors == vector_tool->vectors)
return;
gimp_draw_tool_pause (draw_tool);
if (gimp_draw_tool_is_active (draw_tool) &&
(! vectors || draw_tool->display->image != gimp_item_get_image (item)))
{
gimp_draw_tool_stop (draw_tool);
}
#endif
if (vector_tool->vectors)
{
GimpImage *old_image;
@@ -599,6 +1493,14 @@ gimp_vector_tool_set_vectors (GimpVectorTool *vector_tool,
gimp_vector_tool_stroke_vectors,
tool);
}
if (options->vector_layer_button)
{
gtk_widget_set_sensitive (options->vector_layer_button, FALSE);
g_signal_handlers_disconnect_by_func (options->vector_layer_button,
gimp_vector_tool_create_vector_layer,
tool);
}
}
if (! vectors ||
@@ -647,6 +1549,15 @@ gimp_vector_tool_set_vectors (GimpVectorTool *vector_tool,
gtk_widget_set_sensitive (options->stroke_button, TRUE);
}
if (options->vector_layer_button)
{
g_signal_connect_swapped (options->vector_layer_button, "clicked",
G_CALLBACK (gimp_vector_tool_create_vector_layer),
tool);
gtk_widget_set_sensitive (options->vector_layer_button, TRUE);
}
if (tool->display)
{
gimp_tool_path_set_vectors (GIMP_TOOL_PATH (vector_tool->widget), vectors);
@@ -857,3 +1768,30 @@ gimp_vector_tool_stroke_callback (GtkWidget *dialog,
gtk_widget_destroy (dialog);
}
static void
gimp_vector_tool_create_vector_layer (GimpVectorTool *vector_tool,
GtkWidget *button)
{
GimpImage *image;
//GtkWidget *dialog;
GimpVectorLayer *layer;
if (! vector_tool->vectors)
return;
image = gimp_item_get_image (GIMP_ITEM (vector_tool->vectors));
layer = gimp_vector_layer_new (image, vector_tool->vectors,
gimp_get_user_context (image->gimp));
gimp_image_add_layer (image,
GIMP_LAYER (layer),
GIMP_IMAGE_ACTIVE_PARENT,
-1,
TRUE);
gimp_vector_layer_refresh (layer);
gimp_image_flush (image);
}

View File

@@ -14,31 +14,39 @@ AM_CPPFLAGS = \
noinst_LIBRARIES = libappvectors.a
libappvectors_a_SOURCES = \
vectors-enums.h \
vectors-types.h \
gimpanchor.c \
gimpanchor.h \
gimpbezierstroke.h \
gimpbezierstroke.c \
gimpstroke.h \
gimpstroke.c \
gimpstroke-new.h \
gimpstroke-new.c \
gimpvectors.c \
gimpvectors.h \
gimpvectors-compat.c \
gimpvectors-compat.h \
gimpvectors-export.c \
gimpvectors-export.h \
gimpvectors-import.c \
gimpvectors-import.h \
gimpvectors-preview.c \
gimpvectors-preview.h \
gimpvectors-warp.c \
gimpvectors-warp.h \
gimpvectorsmodundo.c \
gimpvectorsmodundo.h \
gimpvectorspropundo.c \
gimpvectorspropundo.h \
gimpvectorsundo.c \
vectors-enums.h \
vectors-types.h \
gimpanchor.c \
gimpanchor.h \
gimpbezierstroke.h \
gimpbezierstroke.c \
gimpstroke.h \
gimpstroke.c \
gimpstroke-new.h \
gimpstroke-new.c \
gimpvectorlayer.h \
gimpvectorlayer.c \
gimpvectorlayer-xcf.h \
gimpvectorlayer-xcf.c \
gimpvectorlayeroptions.h \
gimpvectorlayeroptions.c \
gimpvectorlayeroptions-parasite.h \
gimpvectorlayeroptions-parasite.c \
gimpvectors.c \
gimpvectors.h \
gimpvectors-compat.c \
gimpvectors-compat.h \
gimpvectors-export.c \
gimpvectors-export.h \
gimpvectors-import.c \
gimpvectors-import.h \
gimpvectors-preview.c \
gimpvectors-preview.h \
gimpvectors-warp.c \
gimpvectors-warp.h \
gimpvectorsmodundo.c \
gimpvectorsmodundo.h \
gimpvectorspropundo.c \
gimpvectorspropundo.h \
gimpvectorsundo.c \
gimpvectorsundo.h

View File

@@ -0,0 +1,255 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* GimpVectorLayer-xcf
* Copyright (C) 2003 Sven Neumann <sven@gimp.org>
* Copyright (C) 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 2 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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "config.h"
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gio/gio.h>
#include <gegl.h>
#include "libgimpbase/gimpbase.h"
#include "vectors-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"
/* FIXME Maybe TextLayer and VectorLayers should have a common ancestor?
* There is a lot of duplicate code between the two - Wormnest.
*/
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),
"vectors", gimp_image_get_vectors_by_tattoo (
gimp_item_get_image (GIMP_ITEM (*layer)),
options->vectors_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 vector 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 vector 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);
// Wormnest: changed to the way TextLayer does it, not sure of implications yet!
/* Don't push an undo because the parasite only exists temporarily
* while the text layer is saved to XCF.
*/
gimp_item_parasite_attach (GIMP_ITEM (layer), parasite, FALSE);
gimp_parasite_free (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 if 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!
*
* Returns: a newly allocated #GimpVectorLayer object
**/
static GimpLayer *
gimp_vector_layer_from_layer (GimpLayer *layer,
GimpVectorLayerOptions *options)
{
GimpVectorLayer *vector_layer;
// GimpItem *item;
GimpDrawable *drawable;
// gint offset_x, offset_y;
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,
// "vector-layer-options", options,
// NULL);
// Wormnest: text layer uses the below form instead, lets follow that for now:
vector_layer = g_object_new (GIMP_TYPE_VECTOR_LAYER,
"image", gimp_item_get_image (GIMP_ITEM (layer)),
NULL);
gimp_item_replace_item (GIMP_ITEM (vector_layer), GIMP_ITEM (layer));
// item = GIMP_ITEM (vector_layer);
drawable = GIMP_DRAWABLE (vector_layer);
gimp_drawable_steal_buffer (drawable, GIMP_DRAWABLE (layer));
/* Wormnest: replacing this with what text layer does...
gimp_object_set_name (GIMP_OBJECT (vector_layer),
gimp_object_get_name (GIMP_OBJECT (layer)));
//item->ID = gimp_item_get_ID (GIMP_ITEM (layer));
//item->tattoo = gimp_item_get_tattoo (GIMP_ITEM (layer));
gimp_item_set_tattoo (GIMP_ITEM (item),
gimp_item_get_tattoo (GIMP_ITEM (layer)));
// item->image = gimp_item_get_image (GIMP_ITEM (layer));
gimp_item_set_image (GIMP_ITEM (item),
gimp_item_get_image (GIMP_ITEM (layer)));
gimp_item_set_image (GIMP_ITEM (layer), NULL);
// Wormnest: is this still necessary or does GimpItem handle this internally?
g_hash_table_replace (item->image->gimp->item_table,
GINT_TO_POINTER (item->ID),
item);
//item->parasites = GIMP_ITEM (layer)->parasites;
//GIMP_ITEM (layer)->parasites = NULL;
gimp_item_set_parasites (GIMP_ITEM (item),
gimp_item_get_parasites (GIMP_ITEM (layer)));
gimp_item_set_parasites (GIMP_ITEM (layer), NULL);
//item->width = gimp_item_get_width (GIMP_ITEM (layer));
//item->height = gimp_item_get_height (GIMP_ITEM (layer));
gimp_item_set_size (GIMP_ITEM (item),
gimp_item_get_width (GIMP_ITEM (layer)),
gimp_item_get_height (GIMP_ITEM (layer)));
gimp_item_get_offset (GIMP_ITEM (layer), &offset_x, &offset_y);
gimp_item_set_offset (GIMP_ITEM (item), offset_x, offset_y);
//item->visible = gimp_item_get_visible (GIMP_ITEM (layer));
//item->linked = gimp_item_get_linked (GIMP_ITEM (layer));
gimp_item_set_visible (GIMP_ITEM (item),
gimp_item_get_visible (GIMP_ITEM (layer)),
FALSE);
gimp_item_set_linked (GIMP_ITEM (item),
gimp_item_get_linked (GIMP_ITEM (layer)),
FALSE);
gimp_drawable_set_tiles (drawable,
FALSE,
NULL,
gimp_drawable_get_tiles (GIMP_DRAWABLE (layer)),
gimp_drawable_type (GIMP_DRAWABLE (layer)));
gimp_drawable_set_tiles (GIMP_DRAWABLE (layer),
FALSE,
NULL,
NULL,
gimp_drawable_type (GIMP_DRAWABLE (layer)));
drawable->bytes = gimp_drawable_bytes (GIMP_DRAWABLE (layer));
drawable->type = gimp_drawable_type (GIMP_DRAWABLE (layer));
drawable->has_alpha = gimp_drawable_has_alpha (GIMP_DRAWABLE (layer));
GIMP_LAYER (vector_layer)->opacity = gimp_layer_get_opacity (layer);
GIMP_LAYER (vector_layer)->mode = gimp_layer_get_mode (layer);
GIMP_LAYER (vector_layer)->lock_alpha = gimp_layer_get_lock_alpha (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);
/* Wormnest: FIXME below add version for vector layer
* Needs get/set functions in gimpvectorlayer like for gimptextlayer */
//gimp_text_layer_set_text (text_layer, text);
g_object_unref (options);
g_object_unref (layer);
return GIMP_LAYER (vector_layer);
}

View File

@@ -0,0 +1,34 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* GimpVectorLayer-xcf
* Copyright (C) 2003 Sven Neumann <sven@gimp.org>
* Copyright (C) 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 2 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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#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__ */

View File

@@ -0,0 +1,442 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* GimpVectorLayer
* Copyright (C) 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 2 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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "config.h"
#include <stdio.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gio/gio.h>
#include <cairo.h>
#include <gegl.h>
#include "libgimpbase/gimpbase.h"
#include "libgimpcolor/gimpcolor.h"
#include "libgimpconfig/gimpconfig.h"
#include "vectors-types.h"
// #include "base/tile-manager.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/gimpstrokeoptions.h"
#include "core/gimpparasitelist.h"
#include "gimpvectorlayer.h"
#include "gimpvectorlayeroptions.h"
#include "gimpvectors.h"
#include "vectors-types.h"
#include "gimp-intl.h"
enum
{
PROP_0,
PROP_VECTOR_LAYER_OPTIONS
};
/* 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 GimpItem * gimp_vector_layer_duplicate (GimpItem *item,
GType new_type);
static gboolean gimp_vector_layer_render (GimpVectorLayer *layer);
static void gimp_vector_layer_render_vectors (GimpVectorLayer *layer,
GimpVectors *vectors);
static void gimp_vector_layer_refresh_name (GimpVectorLayer *layer);
static void gimp_vector_layer_changed_options (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);
GimpViewableClass *viewable_class = GIMP_VIEWABLE_CLASS (klass);
GimpItemClass *item_class = GIMP_ITEM_CLASS (klass);
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;
viewable_class->default_icon_name = "gimp-vector-layer";
item_class->duplicate = gimp_vector_layer_duplicate;
item_class->default_name = _("Vector Layer");
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,
GIMP_PARAM_STATIC_STRINGS);
}
static void
gimp_vector_layer_init (GimpVectorLayer *layer)
{
layer->options = NULL;
layer->parasite = NULL;
}
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;
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);
g_object_unref (vector_layer->options);
}
vector_layer->options = g_value_dup_object (value);
gimp_vector_layer_changed_options (vector_layer);
if (vector_layer->options)
g_signal_connect_object (vector_layer->options, "notify",
G_CALLBACK (gimp_vector_layer_changed_options),
vector_layer, G_CONNECT_SWAPPED);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
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);
GimpVectorLayerOptions *new_options;
new_options = gimp_config_duplicate (GIMP_CONFIG (vector_layer->options));
g_object_set (new_vector_layer,
"vector-layer-options", new_options,
NULL);
g_object_unref (new_options);
}
return new_item;
}
/* public functions */
/**
* gimp_vector_layer_new:
* @image: the #GimpImage the layer should belong to
* @vectors: the #GimpVectors object the layer should render
* @context: the #GimpContext from which to pull context properties
*
* Creates a new vector layer.
*
* Returns: (nullable) a new #GimpVectorLayer or %NULL in case of a problem
**/
GimpVectorLayer *
gimp_vector_layer_new (GimpImage *image,
GimpVectors *vectors,
GimpContext *context)
{
GimpVectorLayer *layer;
GimpVectorLayerOptions *options;
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
g_return_val_if_fail (GIMP_IS_VECTORS (vectors), NULL);
g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
options = gimp_vector_layer_options_new (image, vectors, context);
/* Wormnest: for now mostly following gimp_text_layer_new... */
layer =
GIMP_VECTOR_LAYER (gimp_drawable_new (GIMP_TYPE_VECTOR_LAYER,
image, NULL,
0, 0, 1, 1,
gimp_image_get_layer_format (image,
TRUE)));
gimp_layer_set_mode (GIMP_LAYER (layer),
gimp_image_get_default_new_layer_mode (image),
FALSE);
// FIXME: Add gimp_vector_layer_set_vector_options...
/*
layer = g_object_new (GIMP_TYPE_VECTOR_LAYER,
"vector-layer-options", options,
NULL);
*/
g_object_unref (options);
/*
gimp_drawable_configure (GIMP_DRAWABLE (layer), image,
0, 0, 1, 1,
gimp_image_base_type_with_alpha (image),
NULL);
*/
return layer;
}
/**
* gimp_vector_layer_refresh:
* @layer: a #GimpVectorLayer
*
* Updates the display of the vector layer. Sets the layer name to the name
* of the vectors and re renders the vector layer.
*/
void
gimp_vector_layer_refresh (GimpVectorLayer *layer)
{
if (layer->options)
{
gimp_vector_layer_refresh_name (layer);
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;
/* TODO: undo step here */
g_object_set (layer, "vector-layer-options", NULL, NULL);
}
/**
* gimp_item_is_vector_layer:
* @item: a #GimpItem
*
* Discards the vector information. This makes @layer behave like a
* normal layer.
*
* Returns: whether the item is a vector layer or not.
*/
gboolean
gimp_item_is_vector_layer (GimpItem *item)
{
return (GIMP_IS_VECTOR_LAYER (item) &&
GIMP_VECTOR_LAYER (item)->options);
// TODO: Text layer has:
// return gimp_item_id_is_text_layer (gimp_item_get_id (item));
}
/* private functions */
static gboolean
gimp_vector_layer_render (GimpVectorLayer *layer)
{
GimpDrawable *drawable = GIMP_DRAWABLE (layer);
GimpItem *item = GIMP_ITEM (layer);
GimpImage *image = gimp_item_get_image (item);
//gint width = gimp_image_get_width (image);
//gint height = gimp_image_get_height (image);
//GimpRGB blank;
g_return_val_if_fail (gimp_item_is_attached (GIMP_ITEM (drawable)), FALSE);
g_object_freeze_notify (G_OBJECT (drawable));
/* FIXME - Wormnest...
gimp_drawable_configure (GIMP_DRAWABLE (layer), image,
0, 0, width, height,
gimp_image_base_type_with_alpha (image),
NULL);
*/
/* make the layer background transparent */
//gimp_rgba_set (&blank, 1.0, 1.0, 1.0, 0.0);
// Wormnest: is user context here the right thing?
gimp_drawable_fill (GIMP_DRAWABLE (layer),
gimp_get_user_context (image->gimp),
GIMP_FILL_TRANSPARENT);
/* render vectors to the layer */
gimp_vector_layer_render_vectors (layer, layer->options->vectors);
g_object_thaw_notify (G_OBJECT (drawable));
return TRUE;
}
static void
gimp_vector_layer_render_vectors (GimpVectorLayer *layer,
GimpVectors *vectors)
{
GimpImage *image = gimp_item_get_image (GIMP_ITEM (layer));
GimpChannel *selection = gimp_image_get_mask (image);
GList *drawables = g_list_prepend (NULL, GIMP_DRAWABLE (layer));
/* don't mask these fill/stroke operations */
//gimp_selection_push_stroking (GIMP_SELECTION (selection));
// Wormnest I think the above is replaced by:
gimp_selection_suspend (GIMP_SELECTION (selection));
/* fill the vectors object onto the layer */
gimp_drawable_fill_vectors (GIMP_DRAWABLE (layer),
layer->options->fill_options,
vectors,
FALSE, /* undo */
NULL); /* error */
/* stroke the vectors object onto the layer */
gimp_item_stroke (GIMP_ITEM (vectors),
drawables,
gimp_get_user_context (image->gimp),
layer->options->stroke_options,
FALSE, FALSE,
NULL, NULL);
g_list_free (drawables);
//gimp_selection_pop_stroking (GIMP_SELECTION (selection));
gimp_selection_resume (GIMP_SELECTION (selection));
}
/* sets the layer's name to be the same as the vector's name */
static void
gimp_vector_layer_refresh_name (GimpVectorLayer *layer)
{
gimp_object_set_name_safe (GIMP_OBJECT (layer),
gimp_object_get_name (GIMP_OBJECT (layer->options->vectors)));
}
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->vectors)
{
gimp_vector_layer_discard (layer);
}
else if (gimp_item_is_attached (item))
{
gimp_vector_layer_refresh (layer);
}
}

View File

@@ -0,0 +1,63 @@
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* GimpVectorLayer
* Copyright (C) 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 2 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;
};
struct _GimpVectorLayerClass
{
GimpLayerClass parent_class;
};
GType gimp_vector_layer_get_type (void) G_GNUC_CONST;
GimpVectorLayer * gimp_vector_layer_new (GimpImage *image,
GimpVectors *vectors,
GimpContext *context);
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__ */

View File

@@ -0,0 +1,95 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* GimpVectorLayerOptions-parasite
* Copyright (C) 2003 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 2 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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#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 "vectors-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 (const 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, &parasite_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;
}

View File

@@ -0,0 +1,33 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* GimpVectorLayerOptions-parasite
* Copyright (C) 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 2 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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#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 (const GimpVectorLayerOptions *text);
GimpVectorLayerOptions * gimp_vector_layer_options_from_parasite (const GimpParasite *parasite,
GError **error,
Gimp *gimp);
#endif /* __GIMP_VECTOR_LAYER_OPTIONS_PARASITE_H__ */

View File

@@ -0,0 +1,367 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* GimpVectorLayerOptions
* Copyright (C) 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 2 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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "config.h"
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <gio/gio.h>
#include <cairo.h>
#include <gegl.h>
#include "libgimpbase/gimpbase.h"
#include "libgimpconfig/gimpconfig.h"
#include "libgimpcolor/gimpcolor.h"
#include "vectors-types.h"
#include "core/gimp.h"
#include "core/gimpimage.h"
#include "core/gimpstrokeoptions.h"
#include "gimpvectors.h"
#include "gimpvectorlayer.h"
#include "gimpvectorlayeroptions.h"
#include "gimp-intl.h"
enum
{
PROP_0,
PROP_GIMP,
PROP_VECTORS,
PROP_VECTORS_TATTOO,
PROP_FILL_OPTIONS,
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_vectors_changed
(GimpVectorLayerOptions *options);
static void gimp_vector_layer_options_vectors_removed
(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,
GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property (object_class, PROP_VECTORS,
g_param_spec_object ("vectors",
NULL, NULL,
GIMP_TYPE_VECTORS,
G_PARAM_CONSTRUCT |
GIMP_PARAM_READWRITE |
GIMP_PARAM_STATIC_STRINGS));
#if 0
g_object_class_install_property (object_class, PROP_VECTORS_TATTOO,
g_param_spec_uint ("vectors-tattoo",
NULL, NULL,
0, G_MAXUINT32, 0,
GIMP_PARAM_READABLE |
GIMP_CONFIG_PARAM_SERIALIZE |
GIMP_PARAM_STATIC_STRINGS));
#endif
GIMP_CONFIG_PROP_UINT (object_class, PROP_VECTORS_TATTOO,
"vectors-tattoo", NULL, NULL,
0, G_MAXUINT32, 0,
GIMP_PARAM_STATIC_STRINGS);
GIMP_CONFIG_PROP_OBJECT (object_class, PROP_FILL_OPTIONS,
"fill-options", NULL, NULL,
GIMP_TYPE_FILL_OPTIONS,
GIMP_PARAM_STATIC_STRINGS |
GIMP_CONFIG_PARAM_AGGREGATE);
GIMP_CONFIG_PROP_OBJECT (object_class, PROP_STROKE_OPTIONS,
"stroke-options", NULL, NULL,
GIMP_TYPE_STROKE_OPTIONS,
GIMP_PARAM_STATIC_STRINGS |
GIMP_CONFIG_PARAM_AGGREGATE);
}
static void
gimp_vector_layer_options_init (GimpVectorLayerOptions *options)
{
options->vectors = NULL;
options->vectors_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->vectors)
{
g_object_unref (options->vectors);
options->vectors = 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_VECTORS:
g_value_set_object (value, options->vectors);
break;
case PROP_VECTORS_TATTOO:
g_value_set_uint (value, options->vectors_tattoo);
break;
case PROP_FILL_OPTIONS:
g_value_set_object (value, options->fill_options);
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_VECTORS:
if (options->vectors)
{
g_signal_handlers_disconnect_by_func (options->vectors,
G_CALLBACK (gimp_vector_layer_options_vectors_changed),
options);
g_signal_handlers_disconnect_by_func (options->vectors,
G_CALLBACK (gimp_vector_layer_options_vectors_removed),
options);
g_object_unref (options->vectors);
}
options->vectors = g_value_dup_object (value);
if (options->vectors)
{
g_signal_connect_object (options->vectors, "invalidate-preview",
G_CALLBACK (gimp_vector_layer_options_vectors_changed),
options, G_CONNECT_SWAPPED);
g_signal_connect_object (options->vectors, "name-changed",
G_CALLBACK (gimp_vector_layer_options_vectors_changed),
options, G_CONNECT_SWAPPED);
g_signal_connect_object (options->vectors, "removed",
G_CALLBACK (gimp_vector_layer_options_vectors_removed),
options, G_CONNECT_SWAPPED);
/* update the tattoo */
options->vectors_tattoo = gimp_item_get_tattoo (GIMP_ITEM (options->vectors));
}
break;
case PROP_VECTORS_TATTOO:
options->vectors_tattoo = g_value_get_uint (value);
if (options->vectors &&
gimp_item_get_tattoo (GIMP_ITEM (options->vectors)) != options->vectors_tattoo)
{
GimpImage *image = gimp_item_get_image (GIMP_ITEM (options->vectors));
g_object_set (options,
"vectors", gimp_image_get_vectors_by_tattoo
(image, options->vectors_tattoo),
NULL);
}
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_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_vectors_changed (GimpVectorLayerOptions *options)
{
g_object_notify (G_OBJECT (options), "vectors");
}
static void
gimp_vector_layer_options_vectors_removed (GimpVectorLayerOptions *options)
{
g_object_set (options, "vectors", NULL, NULL);
}
/* public functions */
/**
* gimp_vector_layer_options_new:
* @image: the #GimpImage the layer belongs to
* @vectors: the #GimpVectors 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,
GimpVectors *vectors,
GimpContext *context)
{
GimpVectorLayerOptions *options;
GimpPattern *pattern;
GimpRGB stroke_color;
GimpRGB fill_color;
g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL);
g_return_val_if_fail (GIMP_IS_VECTORS (vectors), NULL);
g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL);
options = g_object_new (GIMP_TYPE_VECTOR_LAYER_OPTIONS,
"gimp", image->gimp,
NULL);
gimp_context_get_foreground (context, &stroke_color);
gimp_context_get_background (context, &fill_color);
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->stroke_options,
"width", 3.0,
NULL);
g_object_set (options,
"vectors", vectors,
NULL);
return options;
}

View File

@@ -0,0 +1,64 @@
/* The GIMP -- an image manipulation program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* GimpVectorLayerOptions
* Copyright (C) 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 2 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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#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 vectors_tattoo;
GimpVectors *vectors;
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,
GimpVectors *vectors,
GimpContext *context);
#endif /* __GIMP_VECTOR_LAYER_OPTIONS_H__ */

View File

@@ -3,6 +3,10 @@ libappvectors_sources = [
'gimpbezierstroke.c',
'gimpstroke-new.c',
'gimpstroke.c',
'gimpvectorlayer.c',
'gimpvectorlayer-xcf.c',
'gimpvectorlayeroptions.c',
'gimpvectorlayeroptions-parasite.c',
'gimpvectors-compat.c',
'gimpvectors-export.c',
'gimpvectors-import.c',

View File

@@ -27,7 +27,16 @@
#include "vectors/vectors-enums.h"
typedef struct _GimpAnchor GimpAnchor;
typedef struct _GimpAnchor GimpAnchor;
typedef struct _GimpVectors GimpVectors;
typedef struct _GimpVectorsUndo GimpVectorsUndo;
typedef struct _GimpVectorsModUndo GimpVectorsModUndo;
typedef struct _GimpVectorsPropUndo GimpVectorsPropUndo;
typedef struct _GimpStroke GimpStroke;
typedef struct _GimpBezierStroke GimpBezierStroke;
typedef struct _GimpVectorLayer GimpVectorLayer;
typedef struct _GimpVectorLayerOptions GimpVectorLayerOptions;
typedef struct _GimpVectors GimpVectors;
typedef struct _GimpStroke GimpStroke;

View File

@@ -69,6 +69,8 @@
#include "vectors/gimpbezierstroke.h"
#include "vectors/gimpvectors.h"
#include "vectors/gimpvectors-compat.h"
#include "vectors/gimpvectorlayer.h"
#include "vectors/gimpvectorlayer-xcf.h"
#include "xcf-private.h"
#include "xcf-load.h"
@@ -2204,7 +2206,7 @@ xcf_load_layer (XcfInfo *info,
xcf_progress_update (info);
/* call the evil text layer hack that might change our layer pointer */
/* call the evil text and vector layer hacks that might change our layer pointer */
selected = g_list_find (info->selected_layers, layer);
linked = g_list_find (info->linked_layers, layer);
floating = (info->floating_sel == layer);
@@ -2227,6 +2229,16 @@ xcf_load_layer (XcfInfo *info,
if (floating)
info->floating_sel = layer;
}
else if (gimp_vector_layer_xcf_load_hack (&layer))
{
if (selected)
{
info->selected_layers = g_list_delete_link (info->selected_layers, selected);
info->selected_layers = g_list_prepend (info->selected_layers, layer);
}
if (floating)
info->floating_sel = layer;
}
/* if this is not the floating selection, we can fix the layer's
* space already now, the function will do nothing if we already

View File

@@ -64,6 +64,8 @@
#include "vectors/gimpbezierstroke.h"
#include "vectors/gimpvectors.h"
#include "vectors/gimpvectors-compat.h"
#include "vectors/gimpvectorlayer.h"
#include "vectors/gimpvectorlayer-xcf.h"
#include "xcf-private.h"
#include "xcf-read.h"
@@ -599,6 +601,12 @@ xcf_save_layer_props (XcfInfo *info,
image, PROP_TEXT_LAYER_FLAGS, error,
flags));
}
else if (GIMP_IS_VECTOR_LAYER (layer) && GIMP_VECTOR_LAYER (layer)->options)
{
GimpVectorLayer *vector_layer = GIMP_VECTOR_LAYER (layer);
gimp_vector_layer_xcf_save_prepare (vector_layer);
}
if (gimp_viewable_get_children (GIMP_VIEWABLE (layer)))
{

View File

@@ -460,6 +460,10 @@
<menuitem action="layers-text-to-vectors" />
<menuitem action="layers-text-along-vectors" />
</placeholder>
<placeholder name="Vector">
<menuitem action="layers-vector-fill-stroke" />
<menuitem action="layers-vector-discard" />
</placeholder>
<separator />
<menu action="layers-stack-menu" name="Stack">
<placeholder name="Select">

View File

@@ -4,6 +4,8 @@
<ui>
<popup action="layers-popup">
<menuitem action="layers-edit-text" />
<menuitem action="layers-edit-vector" />
<menuitem action="layers-edit-attributes" />
<menu action="layers-blend-space-menu" name="Blend Space">
<menuitem action="layers-blend-space-auto" />
@@ -53,6 +55,9 @@
<menuitem action="layers-text-to-vectors" />
<menuitem action="layers-text-along-vectors" />
<separator />
<menuitem action="layers-vector-fill-stroke" />
<menuitem action="layers-vector-discard" />
<separator />
<menuitem action="layers-resize" />
<menuitem action="layers-resize-to-image" />
<menuitem action="layers-scale" />

View File

@@ -24,6 +24,7 @@
<menuitem action="vectors-delete" />
<menuitem action="vectors-merge-visible" />
<separator />
<menuitem action="vectors-to-vector-layer" />
<menuitem action="vectors-selection-replace" />
<menuitem action="vectors-selection-add" />
<menuitem action="vectors-selection-subtract" />