[gimp] Add support for custom icons for tool presets
- From: Daniel Sabo <daniels src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] Add support for custom icons for tool presets
- Date: Fri, 8 Mar 2013 16:23:24 +0000 (UTC)
commit 2614404764d1697318892ddfe53af91578d6a247
Author: Daniel Sabo <DanielSabo gmail com>
Date: Tue Dec 11 20:50:45 2012 -0800
Add support for custom icons for tool presets
Adds an icon-pixbuf property to GimpViewable that is used for a default
implementation of new_pixbuf.
Extend gimp_icon_picker to allow the user to pick non-stock icons for tool
presets (or any other class derived from GimpViewable). Icons can come
from any file GdkPixbuf can load or from image data on the clipboard.
app/core/gimpviewable.c | 137 ++++++++++++-
app/widgets/gimpiconpicker.c | 387 +++++++++++++++++++++++++++++++++---
app/widgets/gimpiconpicker.h | 5 +
app/widgets/gimppropwidgets.c | 112 +++++++----
app/widgets/gimppropwidgets.h | 5 +-
app/widgets/gimptemplateeditor.c | 3 +-
app/widgets/gimptoolpreseteditor.c | 2 +-
po/POTFILES.in | 1 +
8 files changed, 569 insertions(+), 83 deletions(-)
---
diff --git a/app/core/gimpviewable.c b/app/core/gimpviewable.c
index 005a83b..883bde2 100644
--- a/app/core/gimpviewable.c
+++ b/app/core/gimpviewable.c
@@ -45,6 +45,7 @@ enum
{
PROP_0,
PROP_STOCK_ID,
+ PROP_ICON_PIXBUF,
PROP_FROZEN
};
@@ -61,6 +62,7 @@ typedef struct _GimpViewablePrivate GimpViewablePrivate;
struct _GimpViewablePrivate
{
gchar *stock_id;
+ GdkPixbuf *icon_pixbuf;
gint freeze_count;
GimpViewable *parent;
@@ -116,6 +118,12 @@ static gboolean gimp_viewable_serialize_property (GimpConfig *config,
GParamSpec *pspec,
GimpConfigWriter *writer);
+static gboolean gimp_viewable_deserialize_property (GimpConfig *config,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec,
+ GScanner *scanner,
+ GTokenType *expected);
G_DEFINE_TYPE_WITH_CODE (GimpViewable, gimp_viewable, GIMP_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (GIMP_TYPE_CONFIG,
@@ -178,6 +186,12 @@ gimp_viewable_class_init (GimpViewableClass *klass)
NULL, NULL,
GIMP_PARAM_STATIC_STRINGS);
+ GIMP_CONFIG_INSTALL_PROP_OBJECT (object_class, PROP_ICON_PIXBUF,
+ "icon-pixbuf", NULL,
+ GDK_TYPE_PIXBUF,
+ G_PARAM_CONSTRUCT |
+ GIMP_PARAM_STATIC_STRINGS);
+
g_object_class_install_property (object_class, PROP_FROZEN,
g_param_spec_boolean ("frozen",
NULL, NULL,
@@ -195,6 +209,7 @@ gimp_viewable_init (GimpViewable *viewable)
static void
gimp_viewable_config_iface_init (GimpConfigInterface *iface)
{
+ iface->deserialize_property = gimp_viewable_deserialize_property;
iface->serialize_property = gimp_viewable_serialize_property;
}
@@ -209,6 +224,12 @@ gimp_viewable_finalize (GObject *object)
private->stock_id = NULL;
}
+ if (private->icon_pixbuf)
+ {
+ g_object_unref (private->icon_pixbuf);
+ private->icon_pixbuf = NULL;
+ }
+
if (private->preview_temp_buf)
{
gimp_temp_buf_unref (private->preview_temp_buf);
@@ -230,13 +251,20 @@ gimp_viewable_set_property (GObject *object,
const GValue *value,
GParamSpec *pspec)
{
- GimpViewable *viewable = GIMP_VIEWABLE (object);
+ GimpViewable *viewable = GIMP_VIEWABLE (object);
+ GimpViewablePrivate *private = GET_PRIVATE (object);
switch (property_id)
{
case PROP_STOCK_ID:
gimp_viewable_set_stock_id (viewable, g_value_get_string (value));
break;
+ case PROP_ICON_PIXBUF:
+ if (private->icon_pixbuf)
+ g_object_unref (private->icon_pixbuf);
+ private->icon_pixbuf = g_value_dup_object (value);
+ gimp_viewable_invalidate_preview (viewable);
+ break;
case PROP_FROZEN:
/* read-only, fall through */
@@ -252,13 +280,17 @@ gimp_viewable_get_property (GObject *object,
GValue *value,
GParamSpec *pspec)
{
- GimpViewable *viewable = GIMP_VIEWABLE (object);
+ GimpViewable *viewable = GIMP_VIEWABLE (object);
+ GimpViewablePrivate *private = GET_PRIVATE (object);
switch (property_id)
{
case PROP_STOCK_ID:
g_value_set_string (value, gimp_viewable_get_stock_id (viewable));
break;
+ case PROP_ICON_PIXBUF:
+ g_value_set_object (value, private->icon_pixbuf);
+ break;
case PROP_FROZEN:
g_value_set_boolean (value, gimp_viewable_preview_is_frozen (viewable));
break;
@@ -348,8 +380,9 @@ gimp_viewable_real_get_new_pixbuf (GimpViewable *viewable,
gint width,
gint height)
{
- GimpTempBuf *temp_buf;
- GdkPixbuf *pixbuf = NULL;
+ GimpViewablePrivate *private = GET_PRIVATE (viewable);
+ GdkPixbuf *pixbuf = NULL;
+ GimpTempBuf *temp_buf;
temp_buf = gimp_viewable_get_preview (viewable, context, width, height);
@@ -372,6 +405,13 @@ gimp_viewable_real_get_new_pixbuf (GimpViewable *viewable,
g_object_unref (src_buffer);
g_object_unref (dest_buffer);
}
+ else if (private->icon_pixbuf)
+ {
+ pixbuf = gdk_pixbuf_scale_simple (private->icon_pixbuf,
+ width,
+ height,
+ GDK_INTERP_BILINEAR);
+ }
return pixbuf;
}
@@ -409,6 +449,35 @@ gimp_viewable_serialize_property (GimpConfig *config,
}
return TRUE;
+ case PROP_ICON_PIXBUF:
+ {
+ GdkPixbuf *icon_pixbuf = NULL;
+ gchar *pixbuffer = NULL;
+ gchar *pixbuffer_enc = NULL;
+ gsize pixbuffer_size = 0;
+ GError *error = NULL;
+
+ icon_pixbuf = g_value_get_object (value);
+ if (icon_pixbuf)
+ {
+ if (gdk_pixbuf_save_to_buffer (icon_pixbuf,
+ &pixbuffer,
+ &pixbuffer_size,
+ "png", &error, NULL))
+ {
+ pixbuffer_enc = g_base64_encode ((guchar *)pixbuffer,
+ pixbuffer_size);
+ gimp_config_writer_open (writer, "icon-pixbuf");
+ gimp_config_writer_string (writer, pixbuffer_enc);
+ gimp_config_writer_close (writer);
+
+ g_free (pixbuffer_enc);
+ g_free (pixbuffer);
+ }
+ }
+ }
+ return TRUE;
+
default:
break;
}
@@ -416,6 +485,64 @@ gimp_viewable_serialize_property (GimpConfig *config,
return FALSE;
}
+static gboolean
+gimp_viewable_deserialize_property (GimpConfig *config,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec,
+ GScanner *scanner,
+ GTokenType *expected)
+{
+ switch (property_id)
+ {
+ case PROP_ICON_PIXBUF:
+ {
+ gchar *encoded_image = NULL;
+ GdkPixbuf *icon_pixbuf = NULL;
+
+ if (! gimp_scanner_parse_string (scanner, &encoded_image))
+ {
+ *expected = G_TOKEN_STRING;
+ break;
+ }
+
+ if (encoded_image && strlen (encoded_image) > 0)
+ {
+ gsize out_len = 0;
+ guchar *decoded_image = g_base64_decode (encoded_image, &out_len);
+
+ if (decoded_image)
+ {
+ GInputStream *decoded_image_stream = NULL;
+ GdkPixbuf *pixbuf = NULL;
+
+ decoded_image_stream =
+ g_memory_input_stream_new_from_data (decoded_image,
+ out_len, NULL);
+ pixbuf = gdk_pixbuf_new_from_stream (decoded_image_stream,
+ NULL,
+ NULL);
+ if (pixbuf)
+ {
+ if (icon_pixbuf)
+ g_object_unref (icon_pixbuf);
+ icon_pixbuf = pixbuf;
+ }
+ g_free (decoded_image);
+ }
+ }
+
+ g_value_take_object (value, icon_pixbuf);
+ }
+ break;
+
+ default:
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
/**
* gimp_viewable_invalidate_preview:
* @viewable: a viewable object
@@ -1087,6 +1214,8 @@ gimp_viewable_set_stock_id (GimpViewable *viewable,
private->stock_id = g_strdup (stock_id);
}
+ gimp_viewable_invalidate_preview (viewable);
+
g_object_notify (G_OBJECT (viewable), "stock-id");
}
diff --git a/app/widgets/gimpiconpicker.c b/app/widgets/gimpiconpicker.c
index 97f930a..9801719 100644
--- a/app/widgets/gimpiconpicker.c
+++ b/app/widgets/gimpiconpicker.c
@@ -3,6 +3,7 @@
*
* gimpiconpicker.c
* Copyright (C) 2011 Michael Natterer <mitch gimp org>
+ * 2012 Daniel Sabo
*
* 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
@@ -31,18 +32,22 @@
#include "core/gimplist.h"
#include "core/gimpcontext.h"
#include "core/gimptemplate.h"
+#include "core/gimpviewable.h"
#include "gimpiconpicker.h"
#include "gimpviewablebutton.h"
+#include "gimpcontainerpopup.h"
#include "gimp-intl.h"
+#include "gimpview.h"
enum
{
PROP_0,
PROP_GIMP,
- PROP_STOCK_ID
+ PROP_STOCK_ID,
+ PROP_ICON_PIXBUF
};
@@ -53,9 +58,19 @@ struct _GimpIconPickerPrivate
Gimp *gimp;
gchar *stock_id;
+ GdkPixbuf *icon_pixbuf;
+
+ GimpViewable *preview;
GimpContainer *stock_id_container;
GimpContext *stock_id_context;
+ GimpObject *null_template_object;
+
+ GtkWidget *right_click_menu;
+ GtkWidget *menu_item_file_icon;
+ GtkWidget *menu_item_stock_icon;
+ GtkWidget *menu_item_copy;
+ GtkWidget *menu_item_paste;
};
#define GET_PRIVATE(picker) \
@@ -64,21 +79,42 @@ struct _GimpIconPickerPrivate
GimpIconPickerPrivate)
-static void gimp_icon_picker_constructed (GObject *object);
-static void gimp_icon_picker_finalize (GObject *object);
-static void gimp_icon_picker_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec);
-static void gimp_icon_picker_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec);
+static void gimp_icon_picker_constructed (GObject *object);
+static void gimp_icon_picker_finalize (GObject *object);
+
+static void gimp_icon_picker_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec);
+
+static void gimp_icon_picker_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec);
+
+static void gimp_icon_picker_icon_changed (GimpContext *context,
+ GimpTemplate *template,
+ GimpIconPicker *picker);
+
+static void gimp_icon_picker_clicked (GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer data);
+
+static void gimp_icon_picker_menu_from_file (GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer data);
+
+static void gimp_icon_picker_menu_from_stock (GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer data);
-static void gimp_icon_picker_icon_changed (GimpContext *context,
- GimpTemplate *template,
- GimpIconPicker *picker);
+static void gimp_icon_picker_menu_paste (GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer data);
+static void gimp_icon_picker_menu_copy (GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer data);
G_DEFINE_TYPE (GimpIconPicker, gimp_icon_picker, GTK_TYPE_BOX)
@@ -107,29 +143,44 @@ gimp_icon_picker_class_init (GimpIconPickerClass *klass)
GIMP_PARAM_READWRITE |
G_PARAM_CONSTRUCT));
+ g_object_class_install_property (object_class, PROP_ICON_PIXBUF,
+ g_param_spec_object ("icon-pixbuf", NULL, NULL,
+ GDK_TYPE_PIXBUF,
+ GIMP_PARAM_READWRITE));
+
g_type_class_add_private (object_class, sizeof (GimpIconPickerPrivate));
}
static void
gimp_icon_picker_init (GimpIconPicker *picker)
{
+ GimpIconPickerPrivate *private = GET_PRIVATE (picker);
+
gtk_orientable_set_orientation (GTK_ORIENTABLE (picker),
GTK_ORIENTATION_HORIZONTAL);
+
+ private->preview = g_object_new (GIMP_TYPE_VIEWABLE,
+ "stock-id", private->stock_id,
+ "icon-pixbuf", private->icon_pixbuf,
+ NULL);
+ private->icon_pixbuf = NULL;
}
static void
gimp_icon_picker_constructed (GObject *object)
{
- GimpIconPicker *picker = GIMP_ICON_PICKER (object);
- GimpIconPickerPrivate *private = GET_PRIVATE (object);
- GtkWidget *button;
- GSList *stock_list;
- GSList *list;
+ GimpIconPicker *picker = GIMP_ICON_PICKER (object);
+ GimpIconPickerPrivate *private = GET_PRIVATE (object);
+ GtkWidget *button;
+ GtkWidget *viewable_view;
+ GSList *stock_list;
+ GSList *list;
G_OBJECT_CLASS (parent_class)->constructed (object);
g_assert (GIMP_IS_GIMP (private->gimp));
+ /* Set up the stock icon picker */
private->stock_id_container = gimp_list_new (GIMP_TYPE_TEMPLATE, FALSE);
private->stock_id_context = gimp_context_new (private->gimp, "foo", NULL);
@@ -154,18 +205,75 @@ gimp_icon_picker_constructed (GObject *object)
GIMP_TEMPLATE (object));
}
+ /* An extra template object, use to make all stock icons clickable
+ * when a pixbuf icon is set.
+ */
+ private->null_template_object = g_object_new (GIMP_TYPE_TEMPLATE,
+ "name", "",
+ "stock-id", "",
+ NULL);
+
+ if (private->icon_pixbuf)
+ {
+ gimp_context_set_template (private->stock_id_context,
+ GIMP_TEMPLATE (private->null_template_object));
+ }
+
g_slist_free_full (stock_list, (GDestroyNotify) g_free);
- button = gimp_viewable_button_new (private->stock_id_container,
- private->stock_id_context,
- GIMP_VIEW_TYPE_LIST,
- GIMP_VIEW_SIZE_SMALL,
- GIMP_VIEW_SIZE_SMALL, 0,
- NULL, NULL, NULL, NULL);
- gimp_viewable_button_set_view_type (GIMP_VIEWABLE_BUTTON (button),
- GIMP_VIEW_TYPE_GRID);
+
+ /* Set up preview button */
+ viewable_view = gimp_view_new (private->stock_id_context,
+ private->preview,
+ GIMP_VIEW_SIZE_SMALL,
+ 0,
+ FALSE);
+
+ button = gtk_button_new ();
+
+ gtk_container_add (GTK_CONTAINER (button), GTK_WIDGET (viewable_view));
+
+ g_signal_connect (button, "button-press-event",
+ G_CALLBACK (gimp_icon_picker_clicked), object);
+
gtk_box_pack_start (GTK_BOX (picker), button, FALSE, FALSE, 0);
+
+ gtk_widget_show (viewable_view);
gtk_widget_show (button);
+
+ /* Set up right click menu */
+ private->right_click_menu = gtk_menu_new ();
+ gtk_menu_attach_to_widget (GTK_MENU (private->right_click_menu), button, NULL);
+
+ private->menu_item_file_icon = gtk_menu_item_new_with_label (_("From file..."));
+ g_signal_connect (private->menu_item_file_icon, "button-press-event",
+ G_CALLBACK (gimp_icon_picker_menu_from_file), object);
+
+ gtk_menu_shell_append (GTK_MENU_SHELL (private->right_click_menu),
+ GTK_WIDGET (private->menu_item_file_icon));
+
+ private->menu_item_stock_icon = gtk_menu_item_new_with_label (_("From stock icons..."));
+ g_signal_connect (private->menu_item_stock_icon, "button-press-event",
+ G_CALLBACK (gimp_icon_picker_menu_from_stock), object);
+
+ gtk_menu_shell_append (GTK_MENU_SHELL (private->right_click_menu),
+ GTK_WIDGET (private->menu_item_stock_icon));
+
+ private->menu_item_copy = gtk_menu_item_new_with_label (_("Copy icon"));
+ g_signal_connect (private->menu_item_copy, "button-press-event",
+ G_CALLBACK (gimp_icon_picker_menu_copy), object);
+
+ gtk_menu_shell_append (GTK_MENU_SHELL (private->right_click_menu),
+ GTK_WIDGET (private->menu_item_copy));
+
+ private->menu_item_paste = gtk_menu_item_new_with_label (_("Paste icon"));
+ g_signal_connect (private->menu_item_paste, "button-press-event",
+ G_CALLBACK (gimp_icon_picker_menu_paste), object);
+
+ gtk_menu_shell_append (GTK_MENU_SHELL (private->right_click_menu),
+ GTK_WIDGET (private->menu_item_paste));
+
+ gtk_widget_show_all (GTK_WIDGET (private->right_click_menu));
}
static void
@@ -191,6 +299,24 @@ gimp_icon_picker_finalize (GObject *object)
private->stock_id_context = NULL;
}
+ if (private->icon_pixbuf)
+ {
+ g_object_unref (private->icon_pixbuf);
+ private->icon_pixbuf = NULL;
+ }
+
+ if (private->preview)
+ {
+ g_object_unref (private->preview);
+ private->preview = NULL;
+ }
+
+ if (private->null_template_object)
+ {
+ g_object_unref (private->null_template_object);
+ private->null_template_object = NULL;
+ }
+
G_OBJECT_CLASS (parent_class)->finalize (object);
}
@@ -213,6 +339,11 @@ gimp_icon_picker_set_property (GObject *object,
g_value_get_string (value));
break;
+ case PROP_ICON_PIXBUF:
+ gimp_icon_picker_set_icon_pixbuf (GIMP_ICON_PICKER (object),
+ GDK_PIXBUF (g_value_get_object (value)));
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
@@ -220,10 +351,10 @@ gimp_icon_picker_set_property (GObject *object,
}
static void
-gimp_icon_picker_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
+gimp_icon_picker_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
{
GimpIconPickerPrivate *private = GET_PRIVATE (object);
@@ -237,6 +368,10 @@ gimp_icon_picker_get_property (GObject *object,
g_value_set_string (value, private->stock_id);
break;
+ case PROP_ICON_PIXBUF:
+ g_value_set_object (value, private->icon_pixbuf);
+ break;
+
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
@@ -287,9 +422,59 @@ gimp_icon_picker_set_stock_id (GimpIconPicker *picker,
GIMP_TEMPLATE (object));
}
+ g_object_set (private->preview, "stock-id", private->stock_id, NULL);
+
g_object_notify (G_OBJECT (picker), "stock-id");
}
+GdkPixbuf *
+gimp_icon_picker_get_icon_pixbuf (GimpIconPicker *picker)
+{
+ g_return_val_if_fail (GIMP_IS_ICON_PICKER (picker), NULL);
+
+ return GET_PRIVATE (picker)->icon_pixbuf;
+}
+
+void
+gimp_icon_picker_set_icon_pixbuf (GimpIconPicker *picker,
+ GdkPixbuf *value)
+{
+ GimpIconPickerPrivate *private;
+
+ g_return_if_fail (GIMP_IS_ICON_PICKER (picker));
+ g_return_if_fail (value == NULL || GDK_IS_PIXBUF (value));
+
+ private = GET_PRIVATE (picker);
+
+ if (private->icon_pixbuf)
+ g_object_unref (private->icon_pixbuf);
+
+ private->icon_pixbuf = value;
+
+ if (private->icon_pixbuf)
+ {
+ g_object_ref (private->icon_pixbuf);
+
+ gimp_context_set_template (private->stock_id_context,
+ GIMP_TEMPLATE (private->null_template_object));
+ }
+ else
+ {
+ GimpObject *object;
+
+ object = gimp_container_get_child_by_name (private->stock_id_container,
+ private->stock_id);
+
+ if (object)
+ gimp_context_set_template (private->stock_id_context,
+ GIMP_TEMPLATE (object));
+ }
+
+ g_object_set (private->preview, "icon-pixbuf", private->icon_pixbuf, NULL);
+
+ g_object_notify (G_OBJECT (picker), "icon-pixbuf");
+}
+
/* private functions */
@@ -298,5 +483,143 @@ gimp_icon_picker_icon_changed (GimpContext *context,
GimpTemplate *template,
GimpIconPicker *picker)
{
- gimp_icon_picker_set_stock_id (picker, gimp_object_get_name (template));
+ GimpIconPickerPrivate *private = GET_PRIVATE (picker);
+
+ if (GIMP_OBJECT (template) != private->null_template_object)
+ {
+ gimp_icon_picker_set_icon_pixbuf (picker, NULL);
+ gimp_icon_picker_set_stock_id (picker, gimp_object_get_name (template));
+ }
+}
+
+static void
+gimp_icon_picker_menu_from_file (GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer object)
+{
+ GimpIconPicker *picker = GIMP_ICON_PICKER (object);
+ GtkWidget *dialog;
+ GtkFileFilter *filter;
+
+ dialog = gtk_file_chooser_dialog_new (_("Load Icon Image"),
+ NULL,
+ GTK_FILE_CHOOSER_ACTION_OPEN,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
+ NULL);
+
+ filter = gtk_file_filter_new ();
+ gtk_file_filter_add_pixbuf_formats (filter);
+ gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
+
+ if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
+ {
+ gchar *filename;
+ GdkPixbuf *icon_pixbuf = NULL;
+
+ filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
+
+ icon_pixbuf = gdk_pixbuf_new_from_file (filename, NULL);
+
+ if (icon_pixbuf)
+ {
+ gimp_icon_picker_set_icon_pixbuf (picker, icon_pixbuf);
+ g_object_unref (icon_pixbuf);
+ }
+ g_free (filename);
+ }
+ gtk_widget_destroy (dialog);
+}
+
+static void
+gimp_icon_picker_menu_copy (GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer object)
+{
+ GimpIconPicker *picker = GIMP_ICON_PICKER (object);
+ GimpIconPickerPrivate *private = GET_PRIVATE (picker);
+ GtkClipboard *clipboard = NULL;
+
+ clipboard = gtk_clipboard_get_for_display (gtk_widget_get_display (widget),
+ GDK_SELECTION_CLIPBOARD);
+
+ if (private->icon_pixbuf)
+ {
+ gtk_clipboard_set_image (clipboard, private->icon_pixbuf);
+ }
+}
+
+static void
+gimp_icon_picker_menu_paste (GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer object)
+{
+ GimpIconPicker *picker = GIMP_ICON_PICKER (object);
+ GtkClipboard *clipboard = NULL;
+ GdkPixbuf *clipboard_pixbuf = NULL;
+
+ clipboard = gtk_clipboard_get_for_display (gtk_widget_get_display (widget),
+ GDK_SELECTION_CLIPBOARD);
+
+ clipboard_pixbuf = gtk_clipboard_wait_for_image (clipboard);
+
+ if (clipboard_pixbuf)
+ {
+ gimp_icon_picker_set_icon_pixbuf (picker, clipboard_pixbuf);
+ g_object_unref (clipboard_pixbuf);
+ }
+}
+
+static void
+gimp_icon_picker_clicked (GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer object)
+{
+ GimpIconPicker *picker = GIMP_ICON_PICKER (object);
+ GimpIconPickerPrivate *private = GET_PRIVATE (picker);
+ GtkClipboard *clipboard = NULL;
+
+ clipboard = gtk_clipboard_get_for_display (gtk_widget_get_display (widget),
+ GDK_SELECTION_CLIPBOARD);
+
+ if (gtk_clipboard_wait_is_image_available (clipboard))
+ gtk_widget_set_sensitive (private->menu_item_paste, TRUE);
+ else
+ gtk_widget_set_sensitive (private->menu_item_paste, FALSE);
+
+ if (private->icon_pixbuf)
+ gtk_widget_set_sensitive (private->menu_item_copy, TRUE);
+ else
+ gtk_widget_set_sensitive (private->menu_item_copy, FALSE);
+
+ gtk_menu_popup (GTK_MENU (private->right_click_menu),
+ NULL, NULL, NULL,
+ widget, event->button, event->time);
+}
+
+static void
+gimp_icon_picker_menu_from_stock (GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer object)
+{
+ GimpIconPicker *picker = GIMP_ICON_PICKER (object);
+ GimpIconPickerPrivate *private = GET_PRIVATE (picker);
+ GtkWidget *popup;
+
+ /* FIXME: Right clicking on this popup can cause a crash */
+ popup = gimp_container_popup_new (private->stock_id_container,
+ private->stock_id_context,
+ GIMP_VIEW_TYPE_LIST,
+ GIMP_VIEW_SIZE_SMALL,
+ GIMP_VIEW_SIZE_SMALL,
+ 0,
+ NULL,
+ NULL,
+ NULL,
+ NULL);
+
+ gimp_container_popup_set_view_type (GIMP_CONTAINER_POPUP (popup),
+ GIMP_VIEW_TYPE_GRID);
+
+ gimp_container_popup_show (GIMP_CONTAINER_POPUP (popup), GTK_WIDGET (picker));
}
diff --git a/app/widgets/gimpiconpicker.h b/app/widgets/gimpiconpicker.h
index c7b2519..eb6b7ad 100644
--- a/app/widgets/gimpiconpicker.h
+++ b/app/widgets/gimpiconpicker.h
@@ -3,6 +3,7 @@
*
* gimpiconpicker.h
* Copyright (C) 2011 Michael Natterer <mitch gimp org>
+ * 2012 Daniel Sabo
*
* 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
@@ -51,5 +52,9 @@ const gchar * gimp_icon_picker_get_stock_id (GimpIconPicker *picker);
void gimp_icon_picker_set_stock_id (GimpIconPicker *picker,
const gchar *stock_id);
+GdkPixbuf * gimp_icon_picker_get_icon_pixbuf (GimpIconPicker *picker);
+void gimp_icon_picker_set_icon_pixbuf (GimpIconPicker *picker,
+ GdkPixbuf *value);
+
#endif /* __GIMP_ICON_PICKER_H__ */
diff --git a/app/widgets/gimppropwidgets.c b/app/widgets/gimppropwidgets.c
index 4cc6bcf..179e722 100644
--- a/app/widgets/gimppropwidgets.c
+++ b/app/widgets/gimppropwidgets.c
@@ -1311,11 +1311,11 @@ gimp_prop_language_entry_notify (GObject *config,
g_free (value);
}
-
/*****************/
/* icon picker */
/*****************/
+
static void gimp_prop_icon_picker_callback (GtkWidget *picker,
GParamSpec *param_spec,
GObject *config);
@@ -1324,61 +1324,75 @@ static void gimp_prop_icon_picker_notify (GObject *config,
GtkWidget *picker);
GtkWidget *
-gimp_prop_icon_picker_new (GObject *config,
- const gchar *property_name,
- Gimp *gimp)
+gimp_prop_icon_picker_new (GimpViewable *viewable,
+ Gimp *gimp)
{
- GParamSpec *param_spec;
- GtkWidget *picker;
- gchar *value;
+ GObject *object = G_OBJECT (viewable);
+ GtkWidget *picker = NULL;
+ GdkPixbuf *pixbuf_value = NULL;
+ gchar *stock_id_value = NULL;
- param_spec = check_param_spec_w (config, property_name,
- G_TYPE_PARAM_STRING, G_STRFUNC);
- if (! param_spec)
- return NULL;
+ picker = gimp_icon_picker_new (gimp);
- g_object_get (config,
- property_name, &value,
+ g_object_get (object,
+ "stock-id", &stock_id_value,
+ "icon-pixbuf", &pixbuf_value,
NULL);
- picker = gimp_icon_picker_new (gimp);
- gimp_icon_picker_set_stock_id (GIMP_ICON_PICKER (picker), value);
- g_free (value);
+ gimp_icon_picker_set_stock_id (GIMP_ICON_PICKER (picker), stock_id_value);
+ gimp_icon_picker_set_icon_pixbuf (GIMP_ICON_PICKER (picker), pixbuf_value);
- set_param_spec (G_OBJECT (picker), picker, param_spec);
+ g_signal_connect (picker, "notify::icon-pixbuf",
+ G_CALLBACK (gimp_prop_icon_picker_callback),
+ object);
g_signal_connect (picker, "notify::stock-id",
G_CALLBACK (gimp_prop_icon_picker_callback),
- config);
+ object);
- connect_notify (config, property_name,
+ connect_notify (object, "stock-id",
G_CALLBACK (gimp_prop_icon_picker_notify),
picker);
+ connect_notify (object, "icon-pixbuf",
+ G_CALLBACK (gimp_prop_icon_picker_notify),
+ picker);
+
+ if (stock_id_value)
+ g_free (stock_id_value);
+ if (pixbuf_value)
+ g_object_unref (pixbuf_value);
+
return picker;
}
static void
gimp_prop_icon_picker_callback (GtkWidget *picker,
- GParamSpec *unuded_param_spec,
+ GParamSpec *param_spec,
GObject *config)
{
- GParamSpec *param_spec;
- const gchar *value;
-
- param_spec = get_param_spec (G_OBJECT (picker));
- if (! param_spec)
- return;
-
- value = gimp_icon_picker_get_stock_id (GIMP_ICON_PICKER (picker));
-
g_signal_handlers_block_by_func (config,
gimp_prop_icon_picker_notify,
picker);
- g_object_set (config,
- param_spec->name, value,
- NULL);
+ if (!strcmp (param_spec->name, "stock-id"))
+ {
+ const gchar *value = gimp_icon_picker_get_stock_id (GIMP_ICON_PICKER (picker));
+
+ g_object_set (config,
+ "stock-id", value,
+ NULL);
+
+ }
+ else if (!strcmp (param_spec->name, "icon-pixbuf"))
+ {
+ GdkPixbuf *value = gimp_icon_picker_get_icon_pixbuf (GIMP_ICON_PICKER (picker));
+
+ g_object_set (config,
+ "icon-pixbuf", value,
+ NULL);
+ }
+
g_signal_handlers_unblock_by_func (config,
gimp_prop_icon_picker_notify,
@@ -1390,26 +1404,42 @@ gimp_prop_icon_picker_notify (GObject *config,
GParamSpec *param_spec,
GtkWidget *picker)
{
- gchar *value;
-
- g_object_get (config,
- param_spec->name, &value,
- NULL);
-
g_signal_handlers_block_by_func (picker,
gimp_prop_icon_picker_callback,
config);
- gimp_icon_picker_set_stock_id (GIMP_ICON_PICKER (picker), value);
+ if (!strcmp (param_spec->name, "stock-id"))
+ {
+ gchar *value = NULL;
- g_free (value);
+ g_object_get (config,
+ "stock-id", &value,
+ NULL);
+
+ gimp_icon_picker_set_stock_id (GIMP_ICON_PICKER (picker), value);
+
+ if (value)
+ g_free (value);
+ }
+ else if (!strcmp (param_spec->name, "icon-pixbuf"))
+ {
+ GdkPixbuf *value = NULL;
+
+ g_object_get (config,
+ "icon-pixbuf", &value,
+ NULL);
+
+ gimp_icon_picker_set_icon_pixbuf (GIMP_ICON_PICKER (picker), value);
+
+ if (value)
+ g_object_unref (value);
+ }
g_signal_handlers_unblock_by_func (picker,
gimp_prop_icon_picker_callback,
config);
}
-
/***********/
/* table */
/***********/
diff --git a/app/widgets/gimppropwidgets.h b/app/widgets/gimppropwidgets.h
index bd1a3d8..2e18e72 100644
--- a/app/widgets/gimppropwidgets.h
+++ b/app/widgets/gimppropwidgets.h
@@ -95,9 +95,8 @@ GtkWidget * gimp_prop_language_combo_box_new (GObject *config,
GtkWidget * gimp_prop_language_entry_new (GObject *config,
const gchar *property_name);
-GtkWidget * gimp_prop_icon_picker_new (GObject *config,
- const gchar *property_name,
- Gimp *gimp);
+GtkWidget * gimp_prop_icon_picker_new (GimpViewable *viewable,
+ Gimp *gimp);
/* A view on all of an object's properties */
diff --git a/app/widgets/gimptemplateeditor.c b/app/widgets/gimptemplateeditor.c
index 95e38fb..a1c8f84 100644
--- a/app/widgets/gimptemplateeditor.c
+++ b/app/widgets/gimptemplateeditor.c
@@ -518,8 +518,7 @@ gimp_template_editor_new (GimpTemplate *template,
_("_Name:"), 1.0, 0.5,
entry, 1, FALSE);
- icon_picker = gimp_prop_icon_picker_new (G_OBJECT (private->template),
- "stock-id",
+ icon_picker = gimp_prop_icon_picker_new (GIMP_VIEWABLE (private->template),
gimp);
gimp_table_attach_aligned (GTK_TABLE (table), 0, 1,
_("_Icon:"), 1.0, 0.5,
diff --git a/app/widgets/gimptoolpreseteditor.c b/app/widgets/gimptoolpreseteditor.c
index b889370..c754b77 100644
--- a/app/widgets/gimptoolpreseteditor.c
+++ b/app/widgets/gimptoolpreseteditor.c
@@ -149,7 +149,7 @@ gimp_tool_preset_editor_constructed (GObject *object)
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
gtk_widget_show (label);
- button = gimp_prop_icon_picker_new (G_OBJECT (preset), "stock-id",
+ button = gimp_prop_icon_picker_new (GIMP_VIEWABLE (preset),
data_editor->context->gimp);
gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
gtk_widget_show (button);
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 4cbc260..a81e2f4 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -446,6 +446,7 @@ app/widgets/gimpgradienteditor.c
app/widgets/gimpgrideditor.c
app/widgets/gimphelp.c
app/widgets/gimphistogrameditor.c
+app/widgets/gimpiconpicker.c
app/widgets/gimpimagecommenteditor.c
app/widgets/gimpimageprofileview.c
app/widgets/gimpimagepropview.c
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]