This repository has been archived on 2024-07-15. You can view files and clone it, but cannot push or open issues or pull requests.
hedera/vn/field/vn-image.c

203 lines
5.1 KiB
C

/*
* 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 <http://www.gnu.org/licenses/>.
*/
#include "vn-image.h"
#include <db/db.h>
#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;
}