/* * Copyright (C) 2012 - Juan Ferrer Toribio * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "vn-image.h" #include #define set_default_image(self) g_object_set (self->image, \ "icon-name", "dialog-question", "icon-size", GTK_ICON_SIZE_DIALOG, NULL) /** * SECTION:vn-image * @Short_description: an image widget * @Title: VnImage * @See_also: #VnField * @Image: image.png * * An image widget that allows to set a new image with a double click. */ G_DEFINE_TYPE (VnImage, vn_image, VN_TYPE_FIELD); /** * vn_image_new: * * Creates a new #VnImage * * Return value: a #VnImage **/ VnField * vn_image_new () { return g_object_new (VN_TYPE_IMAGE, NULL); } //+++++++++++++++++++++++++++++++++++++++++++++++++++ Private static void vn_image_set_value (VnImage * self, const GValue * value) { GBytes * bytes = NULL; if (!gvn_value_is_null (value) && G_VALUE_TYPE (value) == G_TYPE_BYTES) bytes = g_value_get_boxed (value); if (bytes) { gsize size; const guchar * data; GError * err = NULL; GdkPixbufLoader * loader; loader = gdk_pixbuf_loader_new (); data = g_bytes_get_data (bytes, &size); if (gdk_pixbuf_loader_write (loader, data, size, &err) && gdk_pixbuf_loader_close (loader, &err)) { GdkPixbuf * pixbuf = gdk_pixbuf_loader_get_pixbuf (loader); gtk_image_set_from_pixbuf (self->image, pixbuf); } else { g_warning ("%s",err->message); g_error_free (err); set_default_image (self); } g_object_unref (loader); } else set_default_image (self); } static void vn_image_on_update_preview (GtkFileChooser * chooser, GtkImage * image) { char *filename; GdkPixbuf *pixbuf; filename = gtk_file_chooser_get_preview_filename (chooser); if (filename) { pixbuf = gdk_pixbuf_new_from_file_at_size (filename, 128, 128, NULL); g_free (filename); if (pixbuf) { gtk_image_set_from_pixbuf (image, pixbuf); g_object_unref (pixbuf); } } else pixbuf = NULL; gtk_file_chooser_set_preview_widget_active (chooser, pixbuf != NULL); } static gboolean vn_image_on_event (VnField * field, GdkEvent * event, VnImage * self) { if (event->type != GDK_2BUTTON_PRESS) return FALSE; GtkWidget * image; GtkWidget * toplevel; GtkFileChooser * chooser; GtkFileFilter * filter; filter = gtk_file_filter_new (); gtk_file_filter_add_mime_type (filter, "image/png"); gtk_file_filter_add_mime_type (filter, "image/jpeg"); gtk_file_filter_add_mime_type (filter, "image/gif"); gtk_file_filter_add_mime_type (filter, "image/bmp"); gtk_file_filter_add_mime_type (filter, "image/svg+xml"); toplevel = gtk_widget_get_toplevel (GTK_WIDGET (self)); if (!gtk_widget_is_toplevel (toplevel)) toplevel = NULL; chooser = GTK_FILE_CHOOSER (gtk_file_chooser_dialog_new ( _("Select the image") ,GTK_WINDOW (toplevel) ,GTK_FILE_CHOOSER_ACTION_OPEN ,"Cancel", GTK_RESPONSE_CANCEL ,"Open", GTK_RESPONSE_ACCEPT ,NULL )); gtk_file_chooser_set_filter (chooser, filter); image = gtk_image_new (); gtk_file_chooser_set_preview_widget (chooser, image); g_signal_connect (chooser, "update-preview", G_CALLBACK (vn_image_on_update_preview), image); if (gtk_dialog_run (GTK_DIALOG (chooser)) == GTK_RESPONSE_ACCEPT) { gsize len; gchar * data; gchar * filename; GError * err = NULL; filename = gtk_file_chooser_get_filename (chooser); if (g_file_get_contents (filename, &data, &len, &err)) { GValue value = G_VALUE_INIT; g_value_init (&value, G_TYPE_BYTES); g_value_take_boxed (&value, g_bytes_new_take (data, len)); VN_FIELD_GET_CLASS (self)->value_changed (VN_FIELD (self), &value); vn_image_set_value (self, &value); g_value_unset (&value); } else { g_warning ("%s", err->message); g_error_free (err); } g_free (filename); } gtk_widget_destroy (GTK_WIDGET (chooser)); return FALSE; } //+++++++++++++++++++++++++++++++++++++++++++++++++++ Class static void vn_image_init (VnImage * self) { self->image = GTK_IMAGE (gtk_image_new ()); g_signal_connect (self, "event", G_CALLBACK (vn_image_on_event), self); set_default_image (self); gtk_container_add (GTK_CONTAINER (self), GTK_WIDGET (self->image)); VN_FIELD_GET_CLASS (self)->set_widget (VN_FIELD (self), GTK_WIDGET (self->image)); } static void vn_image_finalize (VnImage * self) { G_OBJECT_CLASS (vn_image_parent_class)->finalize (G_OBJECT (self)); } static void vn_image_class_init (VnImageClass * klass) { G_OBJECT_CLASS (klass)->finalize = (GObjectFinalizeFunc) vn_image_finalize; VN_FIELD_CLASS (klass)->set_value = (VnFieldSetValueFunc) vn_image_set_value; }