Skip to content

Instantly share code, notes, and snippets.

@feliwir
Created March 29, 2022 14:56
Show Gist options
  • Save feliwir/364f9590e633c8b4edb3c2b30d40ff77 to your computer and use it in GitHub Desktop.
Save feliwir/364f9590e633c8b4edb3c2b30d40ff77 to your computer and use it in GitHub Desktop.
#include "voyager-image.h"
#include <gexiv2/gexiv2.h>
#include <graphene.h>
#include <gtk/gtk.h>
struct _VoyagerImage
{
GObject parent_instance;
GdkTexture *texture;
GExiv2Metadata *metadata;
};
static void
voyager_image_snapshot (GdkPaintable *paintable, GdkSnapshot *snapshot, double width, double height)
{
VoyagerImage *image = VOYAGER_IMAGE (paintable);
// TODO: use rotation
gtk_snapshot_append_texture (snapshot, image->texture,
&GRAPHENE_RECT_INIT (0, 0, width, height));
}
static GdkPaintableFlags
voyager_image_get_flags (GdkPaintable *paintable)
{
return GDK_PAINTABLE_STATIC_CONTENTS | GDK_PAINTABLE_STATIC_SIZE;
}
static int
voyager_image_get_intrinsic_width (GdkPaintable *paintable)
{
VoyagerImage *image = VOYAGER_IMAGE (paintable);
// TODO: use rotation
return gdk_texture_get_width (image->texture);
}
static int
voyager_image_get_intrinsic_height (GdkPaintable *paintable)
{
VoyagerImage *image = VOYAGER_IMAGE (paintable);
// TODO: use rotation
return gdk_texture_get_height (image->texture);
}
static void
voyager_image_paintable_init (GdkPaintableInterface *iface)
{
iface->snapshot = voyager_image_snapshot;
iface->get_flags = voyager_image_get_flags;
iface->get_intrinsic_width = voyager_image_get_intrinsic_width;
iface->get_intrinsic_height = voyager_image_get_intrinsic_height;
}
/* When defining the GType, we need to implement the GdkPaintable interface */
G_DEFINE_TYPE_WITH_CODE (VoyagerImage,
voyager_image,
G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (GDK_TYPE_PAINTABLE, voyager_image_paintable_init))
static void
voyager_image_class_init (VoyagerImageClass *klass)
{
}
static void
voyager_image_init (VoyagerImage *image)
{
image->metadata = gexiv2_metadata_new ();
}
VoyagerImage *
voyager_image_new_from_file (GFile *file)
{
VoyagerImage *image;
image = g_object_new (VOYAGER_TYPE_IMAGE, NULL);
voyager_image_set_from_file (image, file);
return image;
}
void
voyager_image_set_from_file (VoyagerImage *image, GFile *file)
{
g_return_if_fail (VOYAGER_IS_IMAGE (image));
g_object_freeze_notify (G_OBJECT (image));
if (file == NULL)
{
g_object_thaw_notify (G_OBJECT (image));
return;
}
GError *error = NULL;
gchar *filepath = g_file_get_path (file);
if (! gexiv2_metadata_open_path (image->metadata, filepath, &error))
{
g_object_thaw_notify (G_OBJECT (image));
return;
}
GdkTexture *texture = gdk_texture_new_from_file (file, &error);
if (texture == NULL)
{
g_object_thaw_notify (G_OBJECT (texture));
return;
}
voyager_image_set_from_texture (image, texture);
g_object_unref (texture);
g_object_thaw_notify (G_OBJECT (image));
}
void
voyager_image_set_from_texture (VoyagerImage *image, GdkTexture *texture)
{
g_return_if_fail (VOYAGER_IS_IMAGE (image));
g_return_if_fail (texture == NULL || GDK_IS_TEXTURE (texture));
g_object_freeze_notify (G_OBJECT (image));
if (texture)
g_object_ref (texture);
if (texture)
{
image->texture = texture;
}
g_object_thaw_notify (G_OBJECT (image));
}
#pragma once
#include <gdk/gdk.h>
G_BEGIN_DECLS
#define VOYAGER_TYPE_IMAGE (voyager_image_get_type ())
G_DECLARE_FINAL_TYPE (VoyagerImage, voyager_image, VOYAGER, IMAGE, GObject)
VoyagerImage *voyager_image_new_from_file (GFile *file);
void voyager_image_set_from_file (VoyagerImage *image, GFile *file);
void voyager_image_set_from_texture (VoyagerImage *image, GdkTexture *texture);
G_END_DECLS
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment