187 lines
5.0 KiB
C
187 lines
5.0 KiB
C
|
/* Paintable/Emblems
|
|||
|
*
|
|||
|
* This demo shows how GdkPaintable can be used to
|
|||
|
* overlay an emblem on top of an icon. The emblem
|
|||
|
* can either be another icon, or an arbitrary
|
|||
|
* paintable.
|
|||
|
*/
|
|||
|
|
|||
|
#include <gtk/gtk.h>
|
|||
|
|
|||
|
#include "paintable.h"
|
|||
|
|
|||
|
static GtkWidget *window = NULL;
|
|||
|
|
|||
|
#define DEMO_TYPE_ICON (demo_icon_get_type ())
|
|||
|
G_DECLARE_FINAL_TYPE (DemoIcon, demo_icon, DEMO, ICON, GObject)
|
|||
|
|
|||
|
struct _DemoIcon
|
|||
|
{
|
|||
|
GObject parent_instance;
|
|||
|
|
|||
|
GdkPaintable *icon;
|
|||
|
GdkPaintable *emblem;
|
|||
|
GdkPaintableFlags flags;
|
|||
|
};
|
|||
|
|
|||
|
struct _DemoIconClass
|
|||
|
{
|
|||
|
GObjectClass parent_class;
|
|||
|
};
|
|||
|
|
|||
|
void
|
|||
|
demo_icon_snapshot (GdkPaintable *paintable,
|
|||
|
GtkSnapshot *snapshot,
|
|||
|
double width,
|
|||
|
double height)
|
|||
|
{
|
|||
|
DemoIcon *self = DEMO_ICON (paintable);
|
|||
|
|
|||
|
gdk_paintable_snapshot (self->icon, snapshot, width, height);
|
|||
|
gtk_snapshot_save (snapshot);
|
|||
|
gtk_snapshot_translate (snapshot, &GRAPHENE_POINT_INIT (0.5 * width, 0));
|
|||
|
gdk_paintable_snapshot (self->emblem, snapshot, 0.5 * width, 0.5 * height);
|
|||
|
gtk_snapshot_restore (snapshot);
|
|||
|
}
|
|||
|
|
|||
|
static GdkPaintableFlags
|
|||
|
demo_icon_get_flags (GdkPaintable *paintable)
|
|||
|
{
|
|||
|
DemoIcon *self = DEMO_ICON (paintable);
|
|||
|
|
|||
|
return self->flags;
|
|||
|
}
|
|||
|
|
|||
|
static void
|
|||
|
demo_icon_paintable_init (GdkPaintableInterface *iface)
|
|||
|
{
|
|||
|
iface->snapshot = demo_icon_snapshot;
|
|||
|
iface->get_flags = demo_icon_get_flags;
|
|||
|
}
|
|||
|
|
|||
|
G_DEFINE_TYPE_WITH_CODE (DemoIcon, demo_icon, G_TYPE_OBJECT,
|
|||
|
G_IMPLEMENT_INTERFACE (GDK_TYPE_PAINTABLE,
|
|||
|
demo_icon_paintable_init))
|
|||
|
|
|||
|
static void
|
|||
|
demo_icon_dispose (GObject *object)
|
|||
|
{
|
|||
|
DemoIcon *self = DEMO_ICON (object);
|
|||
|
|
|||
|
g_signal_handlers_disconnect_by_func (self->emblem,
|
|||
|
gdk_paintable_invalidate_contents,
|
|||
|
self);
|
|||
|
|
|||
|
g_clear_object (&self->icon);
|
|||
|
g_clear_object (&self->emblem);
|
|||
|
|
|||
|
G_OBJECT_CLASS (demo_icon_parent_class)->dispose (object);
|
|||
|
}
|
|||
|
|
|||
|
static void
|
|||
|
demo_icon_class_init (DemoIconClass *klass)
|
|||
|
{
|
|||
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|||
|
|
|||
|
object_class->dispose = demo_icon_dispose;
|
|||
|
}
|
|||
|
|
|||
|
static void
|
|||
|
demo_icon_init (DemoIcon *self)
|
|||
|
{
|
|||
|
self->flags = GDK_PAINTABLE_STATIC_SIZE | GDK_PAINTABLE_STATIC_CONTENTS;
|
|||
|
}
|
|||
|
|
|||
|
GdkPaintable *
|
|||
|
demo_icon_new_with_paintable (const char *icon_name,
|
|||
|
GdkPaintable *emblem)
|
|||
|
{
|
|||
|
GtkIconTheme *theme;
|
|||
|
GtkIconPaintable *icon;
|
|||
|
DemoIcon *self;
|
|||
|
|
|||
|
theme = gtk_icon_theme_get_for_display (gdk_display_get_default ());
|
|||
|
|
|||
|
icon = gtk_icon_theme_lookup_icon (theme,
|
|||
|
icon_name, NULL,
|
|||
|
128, 1,
|
|||
|
GTK_TEXT_DIR_LTR, 0);
|
|||
|
|
|||
|
self = g_object_new (DEMO_TYPE_ICON, NULL);
|
|||
|
|
|||
|
self->icon = GDK_PAINTABLE (icon);
|
|||
|
self->emblem = emblem;
|
|||
|
|
|||
|
if ((gdk_paintable_get_flags (emblem) & GDK_PAINTABLE_STATIC_CONTENTS) == 0)
|
|||
|
{
|
|||
|
self->flags &= ~GDK_PAINTABLE_STATIC_CONTENTS;
|
|||
|
|
|||
|
g_signal_connect_swapped (emblem, "invalidate-contents",
|
|||
|
G_CALLBACK (gdk_paintable_invalidate_contents), self);
|
|||
|
}
|
|||
|
|
|||
|
return GDK_PAINTABLE (self);
|
|||
|
}
|
|||
|
|
|||
|
GdkPaintable *
|
|||
|
demo_icon_new (const char *icon_name,
|
|||
|
const char *emblem_name)
|
|||
|
{
|
|||
|
GtkIconTheme *theme;
|
|||
|
GtkIconPaintable *emblem;
|
|||
|
|
|||
|
theme = gtk_icon_theme_get_for_display (gdk_display_get_default ());
|
|||
|
|
|||
|
emblem = gtk_icon_theme_lookup_icon (theme,
|
|||
|
emblem_name, NULL,
|
|||
|
128, 1,
|
|||
|
GTK_TEXT_DIR_LTR, 0);
|
|||
|
|
|||
|
return GDK_PAINTABLE (demo_icon_new_with_paintable (icon_name,
|
|||
|
GDK_PAINTABLE (emblem)));
|
|||
|
}
|
|||
|
|
|||
|
GtkWidget *
|
|||
|
do_paintable_emblem (GtkWidget *do_widget)
|
|||
|
{
|
|||
|
GdkPaintable *icon;
|
|||
|
GtkWidget *grid;
|
|||
|
GtkWidget *image;
|
|||
|
|
|||
|
if (!window)
|
|||
|
{
|
|||
|
window = gtk_window_new ();
|
|||
|
gtk_window_set_display (GTK_WINDOW (window),
|
|||
|
gtk_widget_get_display (do_widget));
|
|||
|
gtk_window_set_title (GTK_WINDOW (window), "Paintable — Emblems");
|
|||
|
gtk_window_set_default_size (GTK_WINDOW (window), 300, 200);
|
|||
|
g_object_add_weak_pointer (G_OBJECT (window), (gpointer *)&window);
|
|||
|
|
|||
|
grid = gtk_grid_new ();
|
|||
|
|
|||
|
icon = demo_icon_new ("folder", "starred");
|
|||
|
image = gtk_image_new_from_paintable (icon);
|
|||
|
gtk_widget_set_hexpand (image, TRUE);
|
|||
|
gtk_widget_set_vexpand (image, TRUE);
|
|||
|
gtk_grid_attach (GTK_GRID (grid), image, 0, 0, 1, 1);
|
|||
|
|
|||
|
icon = demo_icon_new_with_paintable ("drive-multidisk",
|
|||
|
gtk_nuclear_animation_new (FALSE));
|
|||
|
image = gtk_image_new_from_paintable (icon);
|
|||
|
gtk_widget_set_hexpand (image, TRUE);
|
|||
|
gtk_widget_set_vexpand (image, TRUE);
|
|||
|
gtk_grid_attach (GTK_GRID (grid), image, 1, 0, 1, 1);
|
|||
|
|
|||
|
gtk_window_set_child (GTK_WINDOW (window), grid);
|
|||
|
g_object_unref (icon);
|
|||
|
}
|
|||
|
|
|||
|
if (!gtk_widget_get_visible (window))
|
|||
|
gtk_widget_set_visible (window, TRUE);
|
|||
|
else
|
|||
|
gtk_window_destroy (GTK_WINDOW (window));
|
|||
|
|
|||
|
return window;
|
|||
|
}
|
|||
|
|