Compare commits
22 Commits
wip/pbor/c
...
picture
Author | SHA1 | Date | |
---|---|---|---|
|
1c44454854 | ||
|
fe3b6ffc7a | ||
|
1be6566272 | ||
|
403260b18b | ||
|
db3d517c22 | ||
|
d8d33bfa0c | ||
|
4c7c292a04 | ||
|
9223264b7a | ||
|
67e2fec6e1 | ||
|
3770c98f6e | ||
|
f9257fba91 | ||
|
b32c135abb | ||
|
9ef7ae541b | ||
|
0df9f21109 | ||
|
d6dcd5e51c | ||
|
5f230589bb | ||
|
1d927e872e | ||
|
252ccb129f | ||
|
9668dcba7d | ||
|
e56f013698 | ||
|
ad7ab0f781 | ||
|
edb1cb5569 |
@@ -79,7 +79,11 @@ gdk_public_h_sources = \
|
||||
gdkkeysyms-compat.h \
|
||||
gdkmain.h \
|
||||
gdkpango.h \
|
||||
gdkpicture.h \
|
||||
gdkpictureloader.h \
|
||||
gdkpixbuf.h \
|
||||
gdkpixbufpicture.h \
|
||||
gdkpixbufanimationpicture.h \
|
||||
gdkprivate.h \
|
||||
gdkproperty.h \
|
||||
gdkrectangle.h \
|
||||
@@ -128,7 +132,11 @@ gdk_c_sources = \
|
||||
gdkkeyuni.c \
|
||||
gdkoffscreenwindow.c \
|
||||
gdkpango.c \
|
||||
gdkpicture.c \
|
||||
gdkpictureloader.c \
|
||||
gdkpixbuf-drawable.c \
|
||||
gdkpixbufanimationpicture.c \
|
||||
gdkpixbufpicture.c \
|
||||
gdkrectangle.c \
|
||||
gdkrgba.c \
|
||||
gdkscreen.c \
|
||||
|
@@ -45,7 +45,11 @@
|
||||
#include <gdk/gdkkeysyms.h>
|
||||
#include <gdk/gdkmain.h>
|
||||
#include <gdk/gdkpango.h>
|
||||
#include <gdk/gdkpicture.h>
|
||||
#include <gdk/gdkpictureloader.h>
|
||||
#include <gdk/gdkpixbuf.h>
|
||||
#include <gdk/gdkpixbufpicture.h>
|
||||
#include <gdk/gdkpixbufanimationpicture.h>
|
||||
#include <gdk/gdkproperty.h>
|
||||
#include <gdk/gdkrectangle.h>
|
||||
#include <gdk/gdkrgba.h>
|
||||
|
@@ -231,6 +231,25 @@ gdk_pango_context_get_for_screen
|
||||
gdk_pango_layout_get_clip_region
|
||||
gdk_pango_layout_line_get_clip_region
|
||||
gdk_parse_args
|
||||
gdk_picture_changed
|
||||
gdk_picture_changed_rect
|
||||
gdk_picture_changed_region
|
||||
gdk_picture_draw
|
||||
gdk_picture_get_height
|
||||
gdk_picture_get_type
|
||||
gdk_picture_get_width
|
||||
gdk_picture_loader_get_error
|
||||
gdk_picture_loader_get_picture
|
||||
gdk_picture_loader_get_type G_GNUC_CONST
|
||||
gdk_picture_loader_load_from_stream
|
||||
gdk_picture_loader_load_from_stream_async
|
||||
gdk_picture_loader_load_from_file
|
||||
gdk_picture_loader_load_from_file_async
|
||||
gdk_picture_loader_load_from_filename
|
||||
gdk_picture_loader_load_from_filename_async
|
||||
gdk_picture_loader_new
|
||||
gdk_picture_ref_surface
|
||||
gdk_picture_resized
|
||||
gdk_pixbuf_get_from_surface
|
||||
gdk_pixbuf_get_from_window
|
||||
gdk_pointer_grab
|
||||
|
@@ -194,6 +194,16 @@ gdk_cairo_set_source_pixbuf (cairo_t *cr,
|
||||
const GdkPixbuf *pixbuf,
|
||||
gdouble pixbuf_x,
|
||||
gdouble pixbuf_y)
|
||||
{
|
||||
cairo_surface_t *surface;
|
||||
|
||||
surface = _gdk_cairo_create_surface_for_pixbuf (pixbuf);
|
||||
cairo_set_source_surface (cr, surface, pixbuf_x, pixbuf_y);
|
||||
cairo_surface_destroy (surface);
|
||||
}
|
||||
|
||||
cairo_surface_t *
|
||||
_gdk_cairo_create_surface_for_pixbuf (const GdkPixbuf *pixbuf)
|
||||
{
|
||||
gint width = gdk_pixbuf_get_width (pixbuf);
|
||||
gint height = gdk_pixbuf_get_height (pixbuf);
|
||||
@@ -277,8 +287,7 @@ gdk_cairo_set_source_pixbuf (cairo_t *cr,
|
||||
cairo_pixels += cairo_stride;
|
||||
}
|
||||
|
||||
cairo_set_source_surface (cr, surface, pixbuf_x, pixbuf_y);
|
||||
cairo_surface_destroy (surface);
|
||||
return surface;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -285,6 +285,8 @@ void gdk_synthesize_window_state (GdkWindow *window,
|
||||
gboolean _gdk_cairo_surface_extents (cairo_surface_t *surface,
|
||||
GdkRectangle *extents);
|
||||
|
||||
cairo_surface_t *_gdk_cairo_create_surface_for_pixbuf (const GdkPixbuf *pixbuf);
|
||||
|
||||
/*************************************
|
||||
* Interfaces used by windowing code *
|
||||
*************************************/
|
||||
|
371
gdk/gdkpicture.c
Normal file
371
gdk/gdkpicture.c
Normal file
@@ -0,0 +1,371 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2010 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gdkpicture.h"
|
||||
|
||||
#include <cairo-gobject.h>
|
||||
|
||||
#include "gdkintl.h"
|
||||
|
||||
struct _GdkPicturePrivate {
|
||||
int width;
|
||||
int height;
|
||||
};
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE (GdkPicture, gdk_picture, G_TYPE_OBJECT)
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_WIDTH,
|
||||
PROP_HEIGHT
|
||||
};
|
||||
|
||||
enum {
|
||||
RESIZED,
|
||||
CHANGED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static guint signals [LAST_SIGNAL] = { 0 };
|
||||
|
||||
/**
|
||||
* SECTION:gdkpicture
|
||||
* @Short_description: pixel areas to display
|
||||
* @Title: GdkPicture
|
||||
* @See_also: #GdkMotionPicture
|
||||
*
|
||||
* A #GdkPicture is used to represent a pixel area of a specific size.
|
||||
* Its main job is being the interface between applications that want
|
||||
* to display pictures without a lot of work and people that want to
|
||||
* provide pictures that can be rendered.
|
||||
*
|
||||
* Pictures can resize themselves and change their contents over time.
|
||||
* If you need to react to updates, you should connect to the
|
||||
* GdkPicture::resized and GdkPicture::changed signals.
|
||||
*
|
||||
* A lot of #GdkPicture subclasses require a running main loop, so if
|
||||
* you want to use #GdkPicture without a main loop, you need to make
|
||||
* sure that it actually works.
|
||||
*
|
||||
* #GdkPicture is meant to replace #GdkPixbuf.
|
||||
*/
|
||||
|
||||
static void
|
||||
gdk_picture_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GdkPicture *picture = GDK_PICTURE (object);
|
||||
GdkPicturePrivate *priv = picture->priv;
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_WIDTH:
|
||||
g_value_set_int (value, priv->width);
|
||||
break;
|
||||
case PROP_HEIGHT:
|
||||
g_value_set_int (value, priv->height);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static cairo_surface_t *
|
||||
gdk_picture_fallback_ref_surface (GdkPicture *picture)
|
||||
{
|
||||
GdkPicturePrivate *priv = picture->priv;
|
||||
cairo_surface_t *surface;
|
||||
cairo_t *cr;
|
||||
|
||||
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
|
||||
priv->width,
|
||||
priv->height);
|
||||
cr = cairo_create (surface);
|
||||
|
||||
gdk_picture_draw (picture, cr);
|
||||
|
||||
cairo_destroy (cr);
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_picture_fallback_draw (GdkPicture *picture,
|
||||
cairo_t *cr)
|
||||
{
|
||||
cairo_surface_t *surface;
|
||||
|
||||
surface = gdk_picture_ref_surface (picture);
|
||||
cairo_set_source_surface (cr, surface, 0, 0);
|
||||
cairo_surface_destroy (surface);
|
||||
|
||||
cairo_paint (cr);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_picture_class_init (GdkPictureClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
|
||||
object_class->get_property = gdk_picture_get_property;
|
||||
|
||||
klass->ref_surface = gdk_picture_fallback_ref_surface;
|
||||
klass->draw = gdk_picture_fallback_draw;
|
||||
|
||||
/**
|
||||
* GdkPicture:width:
|
||||
*
|
||||
* Number of pixels in the x direction.
|
||||
*
|
||||
* Since: 3.2
|
||||
*/
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_WIDTH,
|
||||
g_param_spec_int ("width",
|
||||
P_("width"),
|
||||
P_("Number of pixels in x direction"),
|
||||
0, G_MAXINT, 0,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
/**
|
||||
* GdkPicture:height:
|
||||
*
|
||||
* Number of pixels in the y direction.
|
||||
*
|
||||
* Since: 3.2
|
||||
*/
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_HEIGHT,
|
||||
g_param_spec_int ("height",
|
||||
P_("height"),
|
||||
P_("Number of pixels in y direction"),
|
||||
0, G_MAXINT, 0,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
/**
|
||||
* GdkPicture::changed:
|
||||
* @picture: the #GdkPicture that changed.
|
||||
* @region: the region that was changed
|
||||
*
|
||||
* The ::changed signal is emitted when the contents of a @picture
|
||||
* have changed and a redraw of parts of the @picture are necessary.
|
||||
* The given @region specifies the area that has changed.
|
||||
*/
|
||||
signals[CHANGED] =
|
||||
g_signal_new (g_intern_static_string ("changed"),
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0, NULL, NULL,
|
||||
g_cclosure_marshal_VOID__BOXED,
|
||||
G_TYPE_NONE, 1, CAIRO_GOBJECT_TYPE_REGION);
|
||||
|
||||
/**
|
||||
* GdkPicture::resized:
|
||||
* @picture: the #GdkPicture that changed size
|
||||
*
|
||||
* The ::resize signal is emitted when the width or height of a
|
||||
* @picture has changed. This and a redraw of parts of the
|
||||
* @picture are necessary.
|
||||
* After the emission of this signal, a #GdkPicture::changed
|
||||
* signal will be emitted, so it might not be necessary to connect
|
||||
* to both signals.
|
||||
*/
|
||||
signals[RESIZED] =
|
||||
g_signal_new (g_intern_static_string ("resized"),
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0, NULL, NULL,
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
g_type_class_add_private (klass, sizeof (GdkPicturePrivate));
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_picture_init (GdkPicture *picture)
|
||||
{
|
||||
picture->priv = G_TYPE_INSTANCE_GET_PRIVATE (picture,
|
||||
GDK_TYPE_PICTURE,
|
||||
GdkPicturePrivate);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_picture_get_width:
|
||||
* @picture: the picture
|
||||
*
|
||||
* Gets the width of the @picture. That is the number of pixels in the
|
||||
* X direction. Note that the width may be 0 in certain cases, like
|
||||
* when a picture hasn't finished loading from a file yet.
|
||||
*
|
||||
* Returns: The width of @picture
|
||||
**/
|
||||
int
|
||||
gdk_picture_get_width (GdkPicture *picture)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_PICTURE (picture), 0);
|
||||
|
||||
return picture->priv->width;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_picture_get_height:
|
||||
* @picture: the picture
|
||||
*
|
||||
* Gets the height of the @picture. That is the number of pixels in the
|
||||
* Y direction. Note that the width may be 0 in certain cases, like
|
||||
* when a picture hasn't finished loading from a file yet.
|
||||
*
|
||||
* Returns: The height of @picture
|
||||
**/
|
||||
int
|
||||
gdk_picture_get_height (GdkPicture *picture)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_PICTURE (picture), 0);
|
||||
|
||||
return picture->priv->height;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_picture_ref_surface:
|
||||
* @picture: the picture to get the surface from
|
||||
*
|
||||
* Gets a #cairo_surface_t representing the @picture. This function is
|
||||
* useful when you don't just want to draw @picture, but do more
|
||||
* sophisticated things, like use it in a cairo_mask() call. You must not
|
||||
* modify the returned surface.
|
||||
* If you just want to draw the @picture, calling gdk_picture_draw() is
|
||||
*
|
||||
* Returns: (transfer full): A surface representing @picture. The surface
|
||||
* remains a valid representation of @picture's contents until the next
|
||||
* time the GdkPicture::changed signal is emitted. Use
|
||||
* cairo_surface_destroy() to free the returned surface.
|
||||
**/
|
||||
cairo_surface_t *
|
||||
gdk_picture_ref_surface (GdkPicture *picture)
|
||||
{
|
||||
GdkPictureClass *picture_class;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_PICTURE (picture), NULL);
|
||||
|
||||
picture_class = GDK_PICTURE_GET_CLASS (picture);
|
||||
|
||||
return picture_class->ref_surface (picture);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_picture_draw:
|
||||
* @picture: the picture to draw
|
||||
* @cr: the cairo context to draw to
|
||||
*
|
||||
* Draws the given @picture to the given cairo context. The cairo context
|
||||
* should be set to default values for everything but the source and the
|
||||
* matrix. Otherwise the results are undefined.
|
||||
**/
|
||||
void
|
||||
gdk_picture_draw (GdkPicture *picture,
|
||||
cairo_t *cr)
|
||||
{
|
||||
GdkPictureClass *picture_class;
|
||||
|
||||
g_return_if_fail (GDK_IS_PICTURE (picture));
|
||||
|
||||
picture_class = GDK_PICTURE_GET_CLASS (picture);
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
picture_class->draw (picture, cr);
|
||||
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_picture_resized (GdkPicture *picture,
|
||||
int new_width,
|
||||
int new_height)
|
||||
{
|
||||
GObject *object;
|
||||
GdkPicturePrivate *priv;
|
||||
|
||||
g_return_if_fail (GDK_IS_PICTURE (picture));
|
||||
g_return_if_fail (new_width >= 0);
|
||||
g_return_if_fail (new_height >= 0);
|
||||
|
||||
object = G_OBJECT (picture);
|
||||
priv = picture->priv;
|
||||
|
||||
g_object_freeze_notify (object);
|
||||
|
||||
priv->width = new_width;
|
||||
g_object_notify (object, "width");
|
||||
priv->height = new_height;
|
||||
g_object_notify (object, "height");
|
||||
|
||||
g_object_thaw_notify (object);
|
||||
|
||||
g_signal_emit (picture, signals[RESIZED], 0);
|
||||
|
||||
gdk_picture_changed (picture);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_picture_changed (GdkPicture *picture)
|
||||
{
|
||||
GdkPicturePrivate *priv;
|
||||
cairo_rectangle_int_t rect;
|
||||
|
||||
g_return_if_fail (GDK_IS_PICTURE (picture));
|
||||
|
||||
priv = picture->priv;
|
||||
|
||||
rect.x = 0;
|
||||
rect.y = 0;
|
||||
rect.width = priv->width;
|
||||
rect.height = priv->height;
|
||||
|
||||
gdk_picture_changed_rect (picture, &rect);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_picture_changed_rect (GdkPicture *picture,
|
||||
const cairo_rectangle_int_t *rect)
|
||||
{
|
||||
cairo_region_t *region;
|
||||
|
||||
g_return_if_fail (GDK_IS_PICTURE (picture));
|
||||
|
||||
region = cairo_region_create_rectangle (rect);
|
||||
|
||||
gdk_picture_changed_region (picture, region);
|
||||
|
||||
cairo_region_destroy (region);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_picture_changed_region (GdkPicture *picture,
|
||||
const cairo_region_t *region)
|
||||
{
|
||||
g_return_if_fail (GDK_IS_PICTURE (picture));
|
||||
|
||||
g_signal_emit (picture, signals[CHANGED], 0, region);
|
||||
}
|
80
gdk/gdkpicture.h
Normal file
80
gdk/gdkpicture.h
Normal file
@@ -0,0 +1,80 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2010 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#if !defined (__GDK_H_INSIDE__) && !defined (GDK_COMPILATION)
|
||||
#error "Only <gdk/gdk.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __GDK_PICTURE_H__
|
||||
#define __GDK_PICTURE_H__
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <cairo.h>
|
||||
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GDK_TYPE_PICTURE (gdk_picture_get_type ())
|
||||
#define GDK_PICTURE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_PICTURE, GdkPicture))
|
||||
#define GDK_PICTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_PICTURE, GdkPictureClass))
|
||||
#define GDK_IS_PICTURE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_PICTURE))
|
||||
#define GDK_IS_PICTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_PICTURE))
|
||||
#define GDK_PICTURE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_PICTURE, GdkPictureClass))
|
||||
|
||||
typedef struct _GdkPicture GdkPicture;
|
||||
typedef struct _GdkPicturePrivate GdkPicturePrivate;
|
||||
typedef struct _GdkPictureClass GdkPictureClass;
|
||||
|
||||
struct _GdkPicture {
|
||||
GObject parent_object;
|
||||
|
||||
GdkPicturePrivate *priv;
|
||||
};
|
||||
|
||||
struct _GdkPictureClass {
|
||||
GObjectClass parent_class;
|
||||
|
||||
/* need to implement one of these */
|
||||
cairo_surface_t * (* ref_surface) (GdkPicture *picture);
|
||||
void (* draw) (GdkPicture *picture,
|
||||
cairo_t *cr);
|
||||
};
|
||||
|
||||
GType gdk_picture_get_type (void);
|
||||
|
||||
int gdk_picture_get_width (GdkPicture *picture);
|
||||
int gdk_picture_get_height (GdkPicture *picture);
|
||||
|
||||
cairo_surface_t * gdk_picture_ref_surface (GdkPicture *picture);
|
||||
void gdk_picture_draw (GdkPicture *picture,
|
||||
cairo_t *cr);
|
||||
|
||||
/* for implementing subclasses only */
|
||||
void gdk_picture_resized (GdkPicture *picture,
|
||||
int new_width,
|
||||
int new_height);
|
||||
void gdk_picture_changed (GdkPicture *picture);
|
||||
void gdk_picture_changed_rect (GdkPicture *picture,
|
||||
const cairo_rectangle_int_t *rect);
|
||||
void gdk_picture_changed_region (GdkPicture *picture,
|
||||
const cairo_region_t *region);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_PICTURE_H__ */
|
677
gdk/gdkpictureloader.c
Normal file
677
gdk/gdkpictureloader.c
Normal file
@@ -0,0 +1,677 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2010 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gdkpictureloader.h"
|
||||
|
||||
#include "gdkintl.h"
|
||||
#include "gdkinternals.h"
|
||||
#include "gdkpixbuf.h"
|
||||
|
||||
typedef struct _GdkPictureAsyncLoad GdkPictureAsyncLoad;
|
||||
|
||||
struct _GdkPictureLoaderPrivate {
|
||||
GdkPictureAsyncLoad *load;
|
||||
GdkPicture *picture;
|
||||
GError *error;
|
||||
};
|
||||
|
||||
struct _GdkPictureAsyncLoad {
|
||||
GdkPictureLoader *loader;
|
||||
GdkPixbufLoader *pixbuf_loader;
|
||||
guchar buffer[4096];
|
||||
|
||||
int io_priority;
|
||||
GCancellable *cancellable;
|
||||
GAsyncReadyCallback callback;
|
||||
gpointer user_data;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GdkPictureLoader, gdk_picture_loader, GDK_TYPE_PICTURE)
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_PICTURE,
|
||||
PROP_ERROR,
|
||||
};
|
||||
|
||||
/**
|
||||
* SECTION:gdkpictureloader
|
||||
* @Short_description: Loading images into Pictures
|
||||
* @Title: GdkPictureLoader
|
||||
* @See_also: #GdkPicture
|
||||
*
|
||||
* A #GdkPictureLoader is an implementation of #GdkPicture that can load
|
||||
* images from a stream. It takes care of figuring out the format,
|
||||
* decoding the image and error handling.
|
||||
*/
|
||||
|
||||
static void
|
||||
gdk_picture_loader_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GdkPictureLoader *loader = GDK_PICTURE_LOADER (object);
|
||||
GdkPictureLoaderPrivate *priv = loader->priv;
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_PICTURE:
|
||||
g_value_set_object (value, priv->picture);
|
||||
break;
|
||||
case PROP_ERROR:
|
||||
g_value_set_boxed (value, priv->error);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_picture_loader_draw (GdkPicture *picture,
|
||||
cairo_t *cr)
|
||||
{
|
||||
GdkPictureLoader *loader = GDK_PICTURE_LOADER (picture);
|
||||
GdkPictureLoaderPrivate *priv = loader->priv;
|
||||
|
||||
if (priv->error)
|
||||
{
|
||||
/* FIXME: Draw broken image icon */
|
||||
cairo_set_source_rgb (cr, 1, 0, 0);
|
||||
cairo_rectangle (cr, 0, 0,
|
||||
gdk_picture_get_width (picture),
|
||||
gdk_picture_get_height (picture));
|
||||
cairo_fill (cr);
|
||||
return;
|
||||
}
|
||||
|
||||
if (priv->picture)
|
||||
{
|
||||
gdk_picture_draw (priv->picture, cr);
|
||||
return;
|
||||
}
|
||||
|
||||
if (priv->load)
|
||||
{
|
||||
/* FIXME: Draw loading icon */
|
||||
cairo_set_source_rgb (cr, 0, 0, 1);
|
||||
cairo_rectangle (cr, 0, 0,
|
||||
gdk_picture_get_width (picture),
|
||||
gdk_picture_get_height (picture));
|
||||
cairo_fill (cr);
|
||||
return;
|
||||
}
|
||||
|
||||
/* no load happening, size should be empty */
|
||||
g_assert (gdk_picture_get_width (picture) == 0);
|
||||
g_assert (gdk_picture_get_height (picture) == 0);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_picture_loader_class_init (GdkPictureLoaderClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GdkPictureClass *picture_class = GDK_PICTURE_CLASS (klass);
|
||||
|
||||
object_class->get_property = gdk_picture_loader_get_property;
|
||||
|
||||
picture_class->draw = gdk_picture_loader_draw;
|
||||
|
||||
/**
|
||||
* GdkPictureLoader:picture:
|
||||
*
|
||||
* The picture that is loading or %NULL if loading hasn't processed
|
||||
* enough or no the loader is in an error.
|
||||
*
|
||||
* Since: 3.2
|
||||
*/
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_PICTURE,
|
||||
g_param_spec_object ("picture",
|
||||
P_("picture"),
|
||||
P_("the loading picture"),
|
||||
GDK_TYPE_PICTURE,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
/**
|
||||
* GdkPictureLoader:error:
|
||||
*
|
||||
* The error that happened during loading or %NULL if no error happened yet.
|
||||
*
|
||||
* Since: 3.2
|
||||
*/
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_ERROR,
|
||||
g_param_spec_boxed ("error",
|
||||
P_("error"),
|
||||
P_("error that happened during load"),
|
||||
G_TYPE_ERROR,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_type_class_add_private (klass, sizeof (GdkPictureLoaderPrivate));
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_picture_loader_init (GdkPictureLoader *loader)
|
||||
{
|
||||
loader->priv = G_TYPE_INSTANCE_GET_PRIVATE (loader,
|
||||
GDK_TYPE_PICTURE_LOADER,
|
||||
GdkPictureLoaderPrivate);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_picture_loader_new:
|
||||
*
|
||||
* Creates a new #GdkPictureLoader for loading images.
|
||||
*
|
||||
* Returns: a new picture
|
||||
**/
|
||||
GdkPicture *
|
||||
gdk_picture_loader_new (void)
|
||||
{
|
||||
return g_object_new (GDK_TYPE_PICTURE_LOADER, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_picture_loader_get_error:
|
||||
* @loader: the loader to check
|
||||
*
|
||||
* If there was an error while loading the image, it can be queried
|
||||
* with this function. Otherwise, %NULL is returned.
|
||||
*
|
||||
* Returns: The error that @loader is in or %NULL if none
|
||||
**/
|
||||
const GError *
|
||||
gdk_picture_loader_get_error (GdkPictureLoader *loader)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_PICTURE_LOADER (loader), NULL);
|
||||
|
||||
return loader->priv->error;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_picture_loader_get_picture:
|
||||
* @loader: the loader to get the picture from
|
||||
*
|
||||
* Gets the picture that is currently loading or has been loaded. If
|
||||
* there is an error or the load has not progressed enough
|
||||
*
|
||||
* Returns: (transfer none) (allow-none): a %GdkPicture or %NULL.
|
||||
**/
|
||||
GdkPicture *
|
||||
gdk_picture_loader_get_picture (GdkPictureLoader *loader)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_PICTURE_LOADER (loader), NULL);
|
||||
|
||||
return loader->priv->picture;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_picture_loader_reset (GdkPictureLoader *loader)
|
||||
{
|
||||
GdkPictureLoaderPrivate *priv = loader->priv;
|
||||
|
||||
if (priv->load) {
|
||||
if (priv->load->loader)
|
||||
g_object_unref (priv->load->loader);
|
||||
priv->load->loader = NULL;
|
||||
priv->load = NULL;
|
||||
}
|
||||
if (priv->error) {
|
||||
g_error_free (priv->error);
|
||||
priv->error = NULL;
|
||||
g_object_notify (G_OBJECT (loader), "error");
|
||||
}
|
||||
if (priv->picture) {
|
||||
g_object_unref (priv->picture);
|
||||
priv->picture = NULL;
|
||||
g_object_notify (G_OBJECT (loader), "picture");
|
||||
}
|
||||
|
||||
gdk_picture_resized (GDK_PICTURE (loader), 0, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_picture_loader_handle_error (GdkPictureLoader *loader,
|
||||
GError ** error)
|
||||
{
|
||||
GdkPictureLoaderPrivate *priv = loader->priv;
|
||||
|
||||
g_assert (priv->error);
|
||||
|
||||
if (error)
|
||||
*error = g_error_copy (priv->error);
|
||||
|
||||
g_object_notify (G_OBJECT (loader), "error");
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_picture_loader_size_prepared (GdkPixbufLoader *loader,
|
||||
int width,
|
||||
int height,
|
||||
GdkPictureLoader *picture)
|
||||
{
|
||||
gdk_picture_resized (GDK_PICTURE (picture), width, height);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_picture_loader_area_prepared (GdkPixbufLoader *loader,
|
||||
GdkPictureLoader *picture)
|
||||
{
|
||||
GdkPictureLoaderPrivate *priv = picture->priv;
|
||||
|
||||
priv->picture = gdk_pixbuf_picture_new (gdk_pixbuf_loader_get_pixbuf (loader));
|
||||
|
||||
g_assert (gdk_picture_get_width (priv->picture) == gdk_picture_get_width (GDK_PICTURE (picture)));
|
||||
g_assert (gdk_picture_get_height (priv->picture) == gdk_picture_get_height (GDK_PICTURE (picture)));
|
||||
|
||||
g_object_notify (G_OBJECT (picture), "picture");
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_picture_loader_area_updated (GdkPixbufLoader *loader,
|
||||
int x,
|
||||
int y,
|
||||
int width,
|
||||
int height,
|
||||
GdkPictureLoader *picture)
|
||||
{
|
||||
cairo_rectangle_int_t rect = { x, y, width, height };
|
||||
|
||||
gdk_picture_changed_rect (picture->priv->picture, &rect);
|
||||
gdk_picture_changed_rect (GDK_PICTURE (picture), &rect);
|
||||
}
|
||||
|
||||
static GdkPixbufLoader *
|
||||
gdk_picture_loader_create_loader (GdkPictureLoader *loader)
|
||||
{
|
||||
GdkPixbufLoader *pixbuf_loader;
|
||||
|
||||
pixbuf_loader = gdk_pixbuf_loader_new ();
|
||||
g_signal_connect (pixbuf_loader,
|
||||
"size-prepared",
|
||||
G_CALLBACK (gdk_picture_loader_size_prepared),
|
||||
loader);
|
||||
g_signal_connect (pixbuf_loader,
|
||||
"area-prepared",
|
||||
G_CALLBACK (gdk_picture_loader_area_prepared),
|
||||
loader);
|
||||
g_signal_connect (pixbuf_loader,
|
||||
"area-updated",
|
||||
G_CALLBACK (gdk_picture_loader_area_updated),
|
||||
loader);
|
||||
|
||||
return pixbuf_loader;
|
||||
}
|
||||
|
||||
void
|
||||
gdk_picture_loader_load_from_stream (GdkPictureLoader *loader,
|
||||
GInputStream * stream,
|
||||
GCancellable * cancellable,
|
||||
GError ** error)
|
||||
{
|
||||
GdkPictureLoaderPrivate *priv;
|
||||
GdkPixbufLoader *pixbuf_loader;
|
||||
guchar buffer[4096];
|
||||
gssize bytes_read;
|
||||
|
||||
g_return_if_fail (GDK_IS_PICTURE_LOADER (loader));
|
||||
g_return_if_fail (G_IS_INPUT_STREAM (stream));
|
||||
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
|
||||
|
||||
priv = loader->priv;
|
||||
pixbuf_loader = gdk_picture_loader_create_loader (loader);
|
||||
|
||||
do
|
||||
{
|
||||
bytes_read = g_input_stream_read (stream,
|
||||
buffer,
|
||||
sizeof (buffer),
|
||||
cancellable,
|
||||
&priv->error);
|
||||
|
||||
if (bytes_read > 0)
|
||||
{
|
||||
if (!gdk_pixbuf_loader_write (pixbuf_loader,
|
||||
buffer,
|
||||
bytes_read,
|
||||
&priv->error))
|
||||
bytes_read = -1;
|
||||
}
|
||||
else if (bytes_read == 0)
|
||||
{
|
||||
if (!gdk_pixbuf_loader_close (pixbuf_loader,
|
||||
&priv->error))
|
||||
bytes_read = -1;
|
||||
}
|
||||
|
||||
if (bytes_read < 0)
|
||||
gdk_picture_loader_handle_error (loader, error);
|
||||
}
|
||||
while (bytes_read > 0);
|
||||
|
||||
g_object_unref (pixbuf_loader);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_picture_loader_load_from_file (GdkPictureLoader *loader,
|
||||
GFile * file,
|
||||
GCancellable * cancellable,
|
||||
GError ** error)
|
||||
{
|
||||
GdkPictureLoaderPrivate *priv;
|
||||
GFileInputStream *stream;
|
||||
|
||||
g_return_if_fail (GDK_IS_PICTURE_LOADER (loader));
|
||||
g_return_if_fail (G_IS_FILE (file));
|
||||
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
|
||||
|
||||
priv = loader->priv;
|
||||
gdk_picture_loader_reset (loader);
|
||||
|
||||
stream = g_file_read (file, cancellable, &priv->error);
|
||||
if (stream == NULL)
|
||||
{
|
||||
gdk_picture_loader_handle_error (loader, error);
|
||||
return;
|
||||
}
|
||||
|
||||
gdk_picture_loader_load_from_stream (loader,
|
||||
G_INPUT_STREAM (stream),
|
||||
cancellable,
|
||||
error);
|
||||
g_object_unref (stream);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_picture_loader_load_from_filename (GdkPictureLoader *loader,
|
||||
const char * filename,
|
||||
GCancellable * cancellable,
|
||||
GError ** error)
|
||||
{
|
||||
GFile *file;
|
||||
|
||||
g_return_if_fail (GDK_IS_PICTURE_LOADER (loader));
|
||||
g_return_if_fail (filename != NULL);
|
||||
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
|
||||
|
||||
file = g_file_new_for_path (filename);
|
||||
gdk_picture_loader_load_from_file (loader, file, cancellable, error);
|
||||
g_object_unref (file);
|
||||
}
|
||||
|
||||
static GdkPictureAsyncLoad *
|
||||
gdk_picture_async_load_new (GdkPictureLoader * loader,
|
||||
int io_priority,
|
||||
GCancellable * cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GdkPictureAsyncLoad *data = g_slice_new0 (GdkPictureAsyncLoad);
|
||||
|
||||
data->loader = g_object_ref (loader);
|
||||
data->io_priority = io_priority;
|
||||
data->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
|
||||
data->callback = callback;
|
||||
data->user_data = user_data;
|
||||
data->pixbuf_loader = gdk_picture_loader_create_loader (loader);
|
||||
|
||||
loader->priv->load = data;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_picture_async_load_destroy (GdkPictureAsyncLoad *data)
|
||||
{
|
||||
if (data->loader && data->loader->priv->load == data)
|
||||
data->loader->priv->load = NULL;
|
||||
|
||||
if (data->callback)
|
||||
data->callback (G_OBJECT (data->loader), NULL, data->user_data);
|
||||
|
||||
g_object_unref (data->loader);
|
||||
if (data->cancellable)
|
||||
g_object_unref (data->cancellable);
|
||||
g_object_unref (data->pixbuf_loader);
|
||||
|
||||
g_slice_free (GdkPictureAsyncLoad, data);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_picture_async_load_handle_error (GdkPictureAsyncLoad *data)
|
||||
{
|
||||
gdk_picture_loader_handle_error (data->loader, NULL);
|
||||
gdk_picture_async_load_destroy (data);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_picture_load_check_active (GdkPictureAsyncLoad *data)
|
||||
{
|
||||
return data != NULL && data->loader != NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_picture_loader_close_callback (GObject * object,
|
||||
GAsyncResult *res,
|
||||
gpointer user_data)
|
||||
{
|
||||
GInputStream *stream = G_INPUT_STREAM (object);
|
||||
GdkPictureAsyncLoad *data = user_data;
|
||||
GdkPictureLoaderPrivate *priv;
|
||||
|
||||
/* Do we need to call this? */
|
||||
if (!gdk_picture_load_check_active (data))
|
||||
{
|
||||
g_input_stream_close_finish (stream, res, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
priv = data->loader->priv;
|
||||
|
||||
if (!g_input_stream_close_finish (stream, res, &priv->error))
|
||||
{
|
||||
gdk_picture_async_load_handle_error (data);
|
||||
return;
|
||||
}
|
||||
|
||||
gdk_picture_async_load_destroy (data);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_picture_loader_read_callback (GObject * object,
|
||||
GAsyncResult *res,
|
||||
gpointer user_data)
|
||||
{
|
||||
GdkPictureAsyncLoad *data = user_data;
|
||||
GInputStream *stream = G_INPUT_STREAM (object);
|
||||
|
||||
if (gdk_picture_load_check_active (data))
|
||||
{
|
||||
GdkPictureLoaderPrivate *priv = data->loader->priv;
|
||||
gssize bytes_read;
|
||||
|
||||
bytes_read = g_input_stream_read_finish (stream, res, &priv->error);
|
||||
|
||||
if (bytes_read > 0)
|
||||
{
|
||||
if (gdk_pixbuf_loader_write (data->pixbuf_loader,
|
||||
data->buffer,
|
||||
bytes_read,
|
||||
&priv->error))
|
||||
{
|
||||
g_input_stream_read_async (stream,
|
||||
data->buffer,
|
||||
sizeof (data->buffer),
|
||||
data->io_priority,
|
||||
data->cancellable,
|
||||
gdk_picture_loader_read_callback,
|
||||
data);
|
||||
return;
|
||||
}
|
||||
bytes_read = -1;
|
||||
}
|
||||
else if (bytes_read == 0)
|
||||
{
|
||||
if (!gdk_pixbuf_loader_close (data->pixbuf_loader,
|
||||
&priv->error))
|
||||
bytes_read = -1;
|
||||
}
|
||||
|
||||
if (bytes_read < 0)
|
||||
{
|
||||
g_input_stream_close_async (stream,
|
||||
data->io_priority,
|
||||
data->cancellable,
|
||||
gdk_picture_loader_close_callback,
|
||||
NULL);
|
||||
gdk_picture_async_load_handle_error (data);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
g_input_stream_close_async (stream,
|
||||
data->io_priority,
|
||||
data->cancellable,
|
||||
gdk_picture_loader_close_callback,
|
||||
data);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_picture_async_load_start (GdkPictureAsyncLoad *data,
|
||||
GInputStream *stream)
|
||||
{
|
||||
g_input_stream_read_async (stream,
|
||||
data->buffer,
|
||||
sizeof (data->buffer),
|
||||
data->io_priority,
|
||||
data->cancellable,
|
||||
gdk_picture_loader_read_callback,
|
||||
data);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_picture_loader_load_from_stream_async (GdkPictureLoader * loader,
|
||||
GInputStream * stream,
|
||||
int io_priority,
|
||||
GCancellable * cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GdkPictureAsyncLoad *data;
|
||||
GdkPictureLoaderPrivate *priv;
|
||||
|
||||
g_return_if_fail (GDK_IS_PICTURE_LOADER (loader));
|
||||
g_return_if_fail (G_IS_INPUT_STREAM (stream));
|
||||
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
|
||||
|
||||
priv = loader->priv;
|
||||
gdk_picture_loader_reset (loader);
|
||||
|
||||
data = gdk_picture_async_load_new (loader,
|
||||
io_priority,
|
||||
cancellable,
|
||||
callback,
|
||||
user_data);
|
||||
|
||||
gdk_picture_async_load_start (data, stream);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_picture_loader_file_read_callback (GObject * object,
|
||||
GAsyncResult *res,
|
||||
gpointer user_data)
|
||||
{
|
||||
GdkPictureAsyncLoad *data = user_data;
|
||||
GFile *file = G_FILE (object);
|
||||
GdkPictureLoaderPrivate *priv = data->loader->priv;
|
||||
GInputStream *stream;
|
||||
|
||||
stream = G_INPUT_STREAM (g_file_read_finish (file, res, &priv->error));
|
||||
if (stream == NULL)
|
||||
{
|
||||
gdk_picture_async_load_handle_error (data);
|
||||
return;
|
||||
}
|
||||
|
||||
if (gdk_picture_load_check_active (data))
|
||||
gdk_picture_async_load_start (data, stream);
|
||||
|
||||
g_object_unref (stream);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_picture_loader_load_from_file_async (GdkPictureLoader * loader,
|
||||
GFile * file,
|
||||
int io_priority,
|
||||
GCancellable * cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GdkPictureAsyncLoad *load;
|
||||
GdkPictureLoaderPrivate *priv;
|
||||
|
||||
g_return_if_fail (GDK_IS_PICTURE_LOADER (loader));
|
||||
g_return_if_fail (G_IS_FILE (file));
|
||||
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
|
||||
|
||||
priv = loader->priv;
|
||||
gdk_picture_loader_reset (loader);
|
||||
|
||||
load = gdk_picture_async_load_new (loader,
|
||||
io_priority,
|
||||
cancellable,
|
||||
callback,
|
||||
user_data);
|
||||
|
||||
g_file_read_async (file,
|
||||
io_priority,
|
||||
cancellable,
|
||||
gdk_picture_loader_file_read_callback,
|
||||
load);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_picture_loader_load_from_filename_async (GdkPictureLoader * loader,
|
||||
const char * filename,
|
||||
int io_priority,
|
||||
GCancellable * cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GFile *file;
|
||||
|
||||
g_return_if_fail (GDK_IS_PICTURE_LOADER (loader));
|
||||
g_return_if_fail (filename != NULL);
|
||||
g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));
|
||||
|
||||
file = g_file_new_for_path (filename);
|
||||
gdk_picture_loader_load_from_file_async (loader,
|
||||
file,
|
||||
io_priority,
|
||||
cancellable,
|
||||
callback,
|
||||
user_data);
|
||||
g_object_unref (file);
|
||||
}
|
96
gdk/gdkpictureloader.h
Normal file
96
gdk/gdkpictureloader.h
Normal file
@@ -0,0 +1,96 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2010 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#if !defined (__GDK_H_INSIDE__) && !defined (GDK_COMPILATION)
|
||||
#error "Only <gdk/gdk.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __GDK_PICTURE_LOADER_H__
|
||||
#define __GDK_PICTURE_LOADER_H__
|
||||
|
||||
#include <gdk/gdkpicture.h>
|
||||
|
||||
#include <gio/gio.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GDK_TYPE_PICTURE_LOADER (gdk_picture_loader_get_type ())
|
||||
#define GDK_PICTURE_LOADER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_PICTURE_LOADER, GdkPictureLoader))
|
||||
#define GDK_PICTURE_LOADER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_PICTURE_LOADER, GdkPictureLoaderClass))
|
||||
#define GDK_IS_PICTURE_LOADER(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_PICTURE_LOADER))
|
||||
#define GDK_IS_PICTURE_LOADER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_PICTURE_LOADER))
|
||||
#define GDK_PICTURE_LOADER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_PICTURE_LOADER, GdkPictureLoaderClass))
|
||||
|
||||
typedef struct _GdkPictureLoader GdkPictureLoader;
|
||||
typedef struct _GdkPictureLoaderPrivate GdkPictureLoaderPrivate;
|
||||
typedef struct _GdkPictureLoaderClass GdkPictureLoaderClass;
|
||||
|
||||
struct _GdkPictureLoader {
|
||||
GdkPicture parent_picture;
|
||||
|
||||
GdkPictureLoaderPrivate *priv;
|
||||
};
|
||||
|
||||
struct _GdkPictureLoaderClass {
|
||||
GdkPictureClass parent_class;
|
||||
};
|
||||
|
||||
GType gdk_picture_loader_get_type (void);
|
||||
|
||||
GdkPicture * gdk_picture_loader_new (void);
|
||||
|
||||
const GError * gdk_picture_loader_get_error (GdkPictureLoader * loader);
|
||||
GdkPicture * gdk_picture_loader_get_picture (GdkPictureLoader * loader);
|
||||
|
||||
void gdk_picture_loader_load_from_stream (GdkPictureLoader * loader,
|
||||
GInputStream * stream,
|
||||
GCancellable * cancellable,
|
||||
GError ** error);
|
||||
void gdk_picture_loader_load_from_file (GdkPictureLoader * loader,
|
||||
GFile * file,
|
||||
GCancellable * cancellable,
|
||||
GError ** error);
|
||||
void gdk_picture_loader_load_from_filename (GdkPictureLoader * loader,
|
||||
const char * filename,
|
||||
GCancellable * cancellable,
|
||||
GError ** error);
|
||||
|
||||
void gdk_picture_loader_load_from_stream_async(GdkPictureLoader * loader,
|
||||
GInputStream * stream,
|
||||
int io_priority,
|
||||
GCancellable * cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
void gdk_picture_loader_load_from_file_async (GdkPictureLoader * loader,
|
||||
GFile * file,
|
||||
int io_priority,
|
||||
GCancellable * cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
void gdk_picture_loader_load_from_filename_async (GdkPictureLoader *loader,
|
||||
const char * filename,
|
||||
int io_priority,
|
||||
GCancellable * cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_PICTURE_LOADER_H__ */
|
277
gdk/gdkpixbufanimationpicture.c
Normal file
277
gdk/gdkpixbufanimationpicture.c
Normal file
@@ -0,0 +1,277 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2010 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gdkpixbufanimationpicture.h"
|
||||
|
||||
#include <cairo-gobject.h>
|
||||
|
||||
#include "gdkintl.h"
|
||||
#include "gdkinternals.h"
|
||||
|
||||
struct _GdkPixbufAnimationPicturePrivate {
|
||||
GdkPixbufAnimation *animation;
|
||||
GdkPixbufAnimationIter *iter;
|
||||
guint timeout_id;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GdkPixbufAnimationPicture, gdk_pixbuf_animation_picture, GDK_TYPE_PICTURE)
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_ANIMATION,
|
||||
};
|
||||
|
||||
/**
|
||||
* SECTION:gdkpixbufanimationpicture
|
||||
* @Short_description: Pictures for pixbuf animations
|
||||
* @Title: GdkPixbufAnimationPicture
|
||||
* @See_also: #GdkPicture, #GdkPixbufAnimation
|
||||
*
|
||||
* A #GdkPixbufAnimationPicture is an implementation of #GdkPicture for a
|
||||
* #GdkPixbufAnimation. It is meant to help in the porting of applications
|
||||
* from #GdkPixbuf use to #GdkPicture use.
|
||||
*
|
||||
* You should try not to use it for newly written code.
|
||||
*/
|
||||
|
||||
static void
|
||||
gdk_pixbuf_animation_picture_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GdkPixbufAnimationPicture *picture = GDK_PIXBUF_ANIMATION_PICTURE (object);
|
||||
GdkPixbufAnimationPicturePrivate *priv = picture->priv;
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_ANIMATION:
|
||||
g_value_set_object (value, priv->animation);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_pixbuf_animation_picture_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GdkPixbufAnimationPicture *picture = GDK_PIXBUF_ANIMATION_PICTURE (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_ANIMATION:
|
||||
gdk_pixbuf_animation_picture_set_animation (picture, g_value_get_object (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_pixbuf_animation_picture_dispose (GObject *object)
|
||||
{
|
||||
GdkPixbufAnimationPicture *picture = GDK_PIXBUF_ANIMATION_PICTURE (object);
|
||||
|
||||
gdk_pixbuf_animation_picture_set_animation (picture, NULL);
|
||||
|
||||
G_OBJECT_CLASS (gdk_pixbuf_animation_picture_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static cairo_surface_t *
|
||||
gdk_pixbuf_animation_picture_ref_surface (GdkPicture *picture)
|
||||
{
|
||||
GdkPixbufAnimationPicture *animation = GDK_PIXBUF_ANIMATION_PICTURE (picture);
|
||||
GdkPixbufAnimationPicturePrivate *priv = animation->priv;
|
||||
|
||||
if (!priv->animation)
|
||||
return cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 0, 0);
|
||||
|
||||
if (!priv->iter)
|
||||
return _gdk_cairo_create_surface_for_pixbuf (gdk_pixbuf_animation_get_static_image (priv->animation));
|
||||
|
||||
return _gdk_cairo_create_surface_for_pixbuf (gdk_pixbuf_animation_iter_get_pixbuf (priv->iter));
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_pixbuf_animation_picture_class_init (GdkPixbufAnimationPictureClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GdkPictureClass *picture_class = GDK_PICTURE_CLASS (klass);
|
||||
|
||||
object_class->get_property = gdk_pixbuf_animation_picture_get_property;
|
||||
object_class->set_property = gdk_pixbuf_animation_picture_set_property;
|
||||
object_class->dispose = gdk_pixbuf_animation_picture_dispose;
|
||||
|
||||
picture_class->ref_surface = gdk_pixbuf_animation_picture_ref_surface;
|
||||
|
||||
/**
|
||||
* GdkPixbufAnimationPicture:animation:
|
||||
*
|
||||
* The animation to be drawn or %NULL if none was set.
|
||||
*
|
||||
* Since: 3.2
|
||||
*/
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_ANIMATION,
|
||||
g_param_spec_object ("animation",
|
||||
P_("Animation"),
|
||||
P_("the pixbuf animation to display"),
|
||||
GDK_TYPE_PIXBUF_ANIMATION,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_type_class_add_private (klass, sizeof (GdkPixbufAnimationPicturePrivate));
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_pixbuf_animation_picture_init (GdkPixbufAnimationPicture *picture)
|
||||
{
|
||||
GdkPixbufAnimationPicturePrivate *priv;
|
||||
|
||||
picture->priv = G_TYPE_INSTANCE_GET_PRIVATE (picture,
|
||||
GDK_TYPE_PIXBUF_ANIMATION_PICTURE,
|
||||
GdkPixbufAnimationPicturePrivate);
|
||||
priv = picture->priv;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_pixbuf_animation_picture_new:
|
||||
* @animation: the pixbuf animation to create the picture with or %NULL
|
||||
*
|
||||
* Creates a new #GdkPixbufAnimationPicture displaying the given @pixbuf_animation.
|
||||
*
|
||||
* Returns: a new picture
|
||||
**/
|
||||
GdkPicture *
|
||||
gdk_pixbuf_animation_picture_new (GdkPixbufAnimation *animation)
|
||||
{
|
||||
g_return_val_if_fail (animation == NULL || GDK_IS_PIXBUF_ANIMATION (animation), NULL);
|
||||
|
||||
return g_object_new (GDK_TYPE_PIXBUF_ANIMATION_PICTURE, "animation", animation, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_pixbuf_animation_iter_remove_timeout (GdkPixbufAnimationPicture *picture)
|
||||
{
|
||||
GdkPixbufAnimationPicturePrivate *priv = picture->priv;
|
||||
|
||||
if (priv->timeout_id == 0)
|
||||
return;
|
||||
|
||||
g_source_remove (priv->timeout_id);
|
||||
priv->timeout_id = 0;
|
||||
}
|
||||
|
||||
static gboolean gdk_pixbuf_animation_iter_timeout_callback (gpointer data);
|
||||
static void
|
||||
gdk_pixbuf_animation_iter_add_timeout (GdkPixbufAnimationPicture *picture)
|
||||
{
|
||||
GdkPixbufAnimationPicturePrivate *priv = picture->priv;
|
||||
guint delay;
|
||||
|
||||
g_assert (!priv->timeout_id);
|
||||
|
||||
delay = gdk_pixbuf_animation_iter_get_delay_time (priv->iter);
|
||||
|
||||
if (delay > 0)
|
||||
priv->timeout_id = gdk_threads_add_timeout (delay,
|
||||
gdk_pixbuf_animation_iter_timeout_callback,
|
||||
picture);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gdk_pixbuf_animation_iter_timeout_callback (gpointer data)
|
||||
{
|
||||
GdkPixbufAnimationPicture *picture = data;
|
||||
GdkPixbufAnimationPicturePrivate *priv = picture->priv;
|
||||
|
||||
priv->timeout_id = 0;
|
||||
|
||||
gdk_pixbuf_animation_iter_advance (priv->iter, NULL);
|
||||
|
||||
gdk_pixbuf_animation_iter_add_timeout (picture);
|
||||
|
||||
gdk_picture_changed (GDK_PICTURE (picture));
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
gdk_pixbuf_animation_picture_set_animation (GdkPixbufAnimationPicture *picture,
|
||||
GdkPixbufAnimation * animation)
|
||||
{
|
||||
GdkPixbufAnimationPicturePrivate *priv;
|
||||
|
||||
g_return_if_fail (GDK_IS_PIXBUF_ANIMATION_PICTURE (picture));
|
||||
g_return_if_fail (animation == NULL || GDK_IS_PIXBUF_ANIMATION (animation));
|
||||
|
||||
priv = picture->priv;
|
||||
|
||||
if (animation)
|
||||
g_object_ref (animation);
|
||||
|
||||
if (priv->iter)
|
||||
{
|
||||
gdk_pixbuf_animation_iter_remove_timeout (picture);
|
||||
g_object_unref (priv->iter);
|
||||
priv->iter = NULL;
|
||||
}
|
||||
if (priv->animation)
|
||||
{
|
||||
g_object_unref (priv->animation);
|
||||
priv->animation = NULL;
|
||||
}
|
||||
|
||||
priv->animation = animation;
|
||||
if (animation)
|
||||
{
|
||||
GdkPixbuf *pixbuf;
|
||||
|
||||
if (!gdk_pixbuf_animation_is_static_image (animation))
|
||||
{
|
||||
priv->iter = gdk_pixbuf_animation_get_iter (animation, NULL);
|
||||
gdk_pixbuf_animation_iter_add_timeout (picture);
|
||||
}
|
||||
|
||||
pixbuf = gdk_pixbuf_animation_get_static_image (animation);
|
||||
gdk_picture_resized (GDK_PICTURE (picture),
|
||||
gdk_pixbuf_get_width (pixbuf),
|
||||
gdk_pixbuf_get_height (pixbuf));
|
||||
}
|
||||
else
|
||||
gdk_picture_resized (GDK_PICTURE (picture), 0, 0);
|
||||
|
||||
g_object_notify (G_OBJECT (picture), "animation");
|
||||
}
|
||||
|
||||
GdkPixbufAnimation *
|
||||
gdk_pixbuf_animation_picture_get_animation (GdkPixbufAnimationPicture *picture)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_PIXBUF_ANIMATION_PICTURE (picture), NULL);
|
||||
|
||||
return picture->priv->animation;
|
||||
}
|
||||
|
66
gdk/gdkpixbufanimationpicture.h
Normal file
66
gdk/gdkpixbufanimationpicture.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2010 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#if !defined (__GDK_H_INSIDE__) && !defined (GDK_COMPILATION)
|
||||
#error "Only <gdk/gdk.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __GDK_PIXBUF_ANIMATION_PICTURE_H__
|
||||
#define __GDK_PIXBUF_ANIMATION_PICTURE_H__
|
||||
|
||||
#include <gdk/gdkpicture.h>
|
||||
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GDK_TYPE_PIXBUF_ANIMATION_PICTURE (gdk_pixbuf_animation_picture_get_type ())
|
||||
#define GDK_PIXBUF_ANIMATION_PICTURE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_PIXBUF_ANIMATION_PICTURE, GdkPixbufAnimationPicture))
|
||||
#define GDK_PIXBUF_ANIMATION_PICTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_PIXBUF_ANIMATION_PICTURE, GdkPixbufAnimationPictureClass))
|
||||
#define GDK_IS_PIXBUF_ANIMATION_PICTURE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_PIXBUF_ANIMATION_PICTURE))
|
||||
#define GDK_IS_PIXBUF_ANIMATION_PICTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_PIXBUF_ANIMATION_PICTURE))
|
||||
#define GDK_PIXBUF_ANIMATION_PICTURE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_PIXBUF_ANIMATION_PICTURE, GdkPixbufAnimationPictureClass))
|
||||
|
||||
typedef struct _GdkPixbufAnimationPicture GdkPixbufAnimationPicture;
|
||||
typedef struct _GdkPixbufAnimationPicturePrivate GdkPixbufAnimationPicturePrivate;
|
||||
typedef struct _GdkPixbufAnimationPictureClass GdkPixbufAnimationPictureClass;
|
||||
|
||||
struct _GdkPixbufAnimationPicture {
|
||||
GdkPicture parent_picture;
|
||||
|
||||
GdkPixbufAnimationPicturePrivate *priv;
|
||||
};
|
||||
|
||||
struct _GdkPixbufAnimationPictureClass {
|
||||
GdkPictureClass parent_class;
|
||||
};
|
||||
|
||||
GType gdk_pixbuf_animation_picture_get_type (void);
|
||||
|
||||
GdkPicture * gdk_pixbuf_animation_picture_new (GdkPixbufAnimation *animation);
|
||||
|
||||
void gdk_pixbuf_animation_picture_set_animation (GdkPixbufAnimationPicture *picture,
|
||||
GdkPixbufAnimation * animation);
|
||||
GdkPixbufAnimation *
|
||||
gdk_pixbuf_animation_picture_get_animation (GdkPixbufAnimationPicture *picture);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_PIXBUF_ANIMATION_PICTURE_H__ */
|
363
gdk/gdkpixbufpicture.c
Normal file
363
gdk/gdkpixbufpicture.c
Normal file
@@ -0,0 +1,363 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2010 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gdkpixbufpicture.h"
|
||||
|
||||
#include <cairo-gobject.h>
|
||||
|
||||
#include "gdkintl.h"
|
||||
#include "gdkinternals.h"
|
||||
|
||||
struct _GdkPixbufPicturePrivate {
|
||||
GdkPixbuf *pixbuf;
|
||||
cairo_surface_t *surface;
|
||||
guint keep_pixbuf : 1;
|
||||
guint keep_surface : 1;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GdkPixbufPicture, gdk_pixbuf_picture, GDK_TYPE_PICTURE)
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_PIXBUF,
|
||||
PROP_KEEP_PIXBUF,
|
||||
PROP_KEEP_SURFACE
|
||||
};
|
||||
|
||||
/**
|
||||
* SECTION:gdkpixbufpicture
|
||||
* @Short_description: Pictures for pixbufs
|
||||
* @Title: GdkPixbufPicture
|
||||
* @See_also: #GdkPicture
|
||||
*
|
||||
* A #GdkPixbufPicture is an implementation of #GdkPicture for a #GdkPixbuf.
|
||||
* It is meant to help in the porting of applications from #GdkPixbuf use
|
||||
* to #GdkPicture use.
|
||||
*
|
||||
* You should try not to use it for newly written code.
|
||||
*/
|
||||
|
||||
static void
|
||||
gdk_pixbuf_picture_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GdkPixbufPicture *picture = GDK_PIXBUF_PICTURE (object);
|
||||
GdkPixbufPicturePrivate *priv = picture->priv;
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_PIXBUF:
|
||||
g_value_set_object (value, gdk_pixbuf_picture_get_pixbuf (picture));
|
||||
break;
|
||||
case PROP_KEEP_PIXBUF:
|
||||
g_value_set_boolean (value, priv->keep_pixbuf);
|
||||
break;
|
||||
case PROP_KEEP_SURFACE:
|
||||
g_value_set_boolean (value, priv->keep_surface);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_pixbuf_picture_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GdkPixbufPicture *picture = GDK_PIXBUF_PICTURE (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_PIXBUF:
|
||||
gdk_pixbuf_picture_set_pixbuf (picture, g_value_get_object (value));
|
||||
break;
|
||||
case PROP_KEEP_PIXBUF:
|
||||
gdk_pixbuf_picture_set_keep_pixbuf (picture, g_value_get_boolean (value));
|
||||
break;
|
||||
case PROP_KEEP_SURFACE:
|
||||
gdk_pixbuf_picture_set_keep_surface (picture, g_value_get_boolean (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_pixbuf_picture_dispose (GObject *object)
|
||||
{
|
||||
GdkPixbufPicture *picture = GDK_PIXBUF_PICTURE (object);
|
||||
|
||||
gdk_pixbuf_picture_set_pixbuf (picture, NULL);
|
||||
|
||||
G_OBJECT_CLASS (gdk_pixbuf_picture_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static cairo_surface_t *
|
||||
gdk_pixbuf_picture_ref_surface (GdkPicture *picture)
|
||||
{
|
||||
GdkPixbufPicture *pixbuf_picture = GDK_PIXBUF_PICTURE (picture);
|
||||
GdkPixbufPicturePrivate *priv = pixbuf_picture->priv;
|
||||
cairo_surface_t *surface;
|
||||
|
||||
if (priv->surface)
|
||||
return cairo_surface_reference (priv->surface);
|
||||
|
||||
if (priv->pixbuf)
|
||||
surface = _gdk_cairo_create_surface_for_pixbuf (priv->pixbuf);
|
||||
else
|
||||
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 0, 0);
|
||||
|
||||
if (priv->keep_surface)
|
||||
priv->surface = cairo_surface_reference (surface);
|
||||
|
||||
return surface;
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_pixbuf_picture_class_init (GdkPixbufPictureClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GdkPictureClass *picture_class = GDK_PICTURE_CLASS (klass);
|
||||
|
||||
object_class->get_property = gdk_pixbuf_picture_get_property;
|
||||
object_class->set_property = gdk_pixbuf_picture_set_property;
|
||||
object_class->dispose = gdk_pixbuf_picture_dispose;
|
||||
|
||||
picture_class->ref_surface = gdk_pixbuf_picture_ref_surface;
|
||||
|
||||
/**
|
||||
* GdkPixbufPicture:pixbuf:
|
||||
*
|
||||
* The pixbuf to be drawn or %NULL if none was set or GdkPixbufPicture:keep-pixbuf
|
||||
* is %FALSE.
|
||||
*
|
||||
* Since: 3.2
|
||||
*/
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_PIXBUF,
|
||||
g_param_spec_object ("pixbuf",
|
||||
P_("pixbuf"),
|
||||
P_("the pixbuf to display"),
|
||||
GDK_TYPE_PIXBUF,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
/**
|
||||
* GdkPixbufPicture:keep-pixbuf:
|
||||
*
|
||||
* Whether to cache the pixbuf internally or to convert it into a #cairo_surface_t immediately.
|
||||
*
|
||||
* Since: 3.2
|
||||
*/
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_KEEP_PIXBUF,
|
||||
g_param_spec_boolean ("keep-pixbuf",
|
||||
P_("keep pixbuf"),
|
||||
P_("TRUE to keep the pixbuf around"),
|
||||
TRUE,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
/**
|
||||
* GdkPixbufPicture:keep-surface:
|
||||
*
|
||||
* Whether to keep the #cairo_surface_t internally that was created when drawing the picture.
|
||||
*
|
||||
* Since: 3.2
|
||||
*/
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_KEEP_SURFACE,
|
||||
g_param_spec_boolean ("keep-surface",
|
||||
P_("keep surface"),
|
||||
P_("TRUE to keep the surface around"),
|
||||
FALSE,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
g_type_class_add_private (klass, sizeof (GdkPixbufPicturePrivate));
|
||||
}
|
||||
|
||||
static void
|
||||
gdk_pixbuf_picture_init (GdkPixbufPicture *picture)
|
||||
{
|
||||
GdkPixbufPicturePrivate *priv;
|
||||
|
||||
picture->priv = G_TYPE_INSTANCE_GET_PRIVATE (picture,
|
||||
GDK_TYPE_PIXBUF_PICTURE,
|
||||
GdkPixbufPicturePrivate);
|
||||
priv = picture->priv;
|
||||
|
||||
priv->keep_pixbuf = TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gdk_pixbuf_picture_new:
|
||||
* @pixbuf: the pixbuf to create the picture with or %NULL
|
||||
*
|
||||
* Creates a new #GdkPixbufPicture displaying the given @pixbuf.
|
||||
*
|
||||
* Returns: a new picture
|
||||
**/
|
||||
GdkPicture *
|
||||
gdk_pixbuf_picture_new (GdkPixbuf *pixbuf)
|
||||
{
|
||||
g_return_val_if_fail (pixbuf == NULL || GDK_IS_PIXBUF (pixbuf), NULL);
|
||||
|
||||
return g_object_new (GDK_TYPE_PIXBUF_PICTURE, "pixbuf", pixbuf, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
gdk_pixbuf_picture_set_pixbuf (GdkPixbufPicture *picture,
|
||||
GdkPixbuf * pixbuf)
|
||||
{
|
||||
GdkPixbufPicturePrivate *priv;
|
||||
|
||||
g_return_if_fail (GDK_IS_PIXBUF_PICTURE (picture));
|
||||
g_return_if_fail (pixbuf == NULL || GDK_IS_PIXBUF (pixbuf));
|
||||
|
||||
priv = picture->priv;
|
||||
|
||||
if (pixbuf)
|
||||
g_object_ref (pixbuf);
|
||||
|
||||
if (priv->surface)
|
||||
{
|
||||
cairo_surface_destroy (priv->surface);
|
||||
priv->surface = NULL;
|
||||
}
|
||||
if (priv->pixbuf)
|
||||
{
|
||||
g_object_unref (priv->pixbuf);
|
||||
priv->pixbuf = NULL;
|
||||
}
|
||||
|
||||
if (priv->keep_pixbuf)
|
||||
{
|
||||
priv->pixbuf = pixbuf;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pixbuf)
|
||||
priv->surface = _gdk_cairo_create_surface_for_pixbuf (pixbuf);
|
||||
}
|
||||
|
||||
g_object_notify (G_OBJECT (picture), "pixbuf");
|
||||
|
||||
if (pixbuf)
|
||||
{
|
||||
gdk_picture_resized (GDK_PICTURE (picture),
|
||||
gdk_pixbuf_get_width (pixbuf),
|
||||
gdk_pixbuf_get_height (pixbuf));
|
||||
}
|
||||
else
|
||||
gdk_picture_resized (GDK_PICTURE (picture), 0, 0);
|
||||
}
|
||||
|
||||
GdkPixbuf *
|
||||
gdk_pixbuf_picture_get_pixbuf (GdkPixbufPicture *picture)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_PIXBUF_PICTURE (picture), NULL);
|
||||
|
||||
return picture->priv->pixbuf;
|
||||
}
|
||||
|
||||
void
|
||||
gdk_pixbuf_picture_set_keep_pixbuf (GdkPixbufPicture *picture,
|
||||
gboolean keep_pixbuf)
|
||||
{
|
||||
GdkPixbufPicturePrivate *priv;
|
||||
|
||||
g_return_if_fail (GDK_IS_PIXBUF_PICTURE (picture));
|
||||
|
||||
priv = picture->priv;
|
||||
|
||||
if (priv->keep_pixbuf == keep_pixbuf)
|
||||
return;
|
||||
|
||||
priv->keep_pixbuf = keep_pixbuf;
|
||||
if (keep_pixbuf)
|
||||
{
|
||||
/* This is equal to setting the pixbuf to NULL because
|
||||
* there's no pixbuf we could keep now. */
|
||||
gdk_pixbuf_picture_set_pixbuf (picture, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
gdk_pixbuf_picture_set_keep_surface (picture, TRUE);
|
||||
|
||||
if (priv->pixbuf)
|
||||
{
|
||||
priv->surface = _gdk_cairo_create_surface_for_pixbuf (priv->pixbuf);
|
||||
g_object_unref (priv->pixbuf);
|
||||
priv->pixbuf = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
g_object_notify (G_OBJECT (picture), "keep-pixbuf");
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_pixbuf_picture_get_keep_pixbuf (GdkPixbufPicture *picture)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_PIXBUF_PICTURE (picture), FALSE);
|
||||
|
||||
return picture->priv->keep_pixbuf;
|
||||
}
|
||||
|
||||
void
|
||||
gdk_pixbuf_picture_set_keep_surface (GdkPixbufPicture *picture,
|
||||
gboolean keep_surface)
|
||||
{
|
||||
GdkPixbufPicturePrivate *priv;
|
||||
|
||||
g_return_if_fail (GDK_IS_PIXBUF_PICTURE (picture));
|
||||
|
||||
priv = picture->priv;
|
||||
|
||||
if (priv->keep_surface == keep_surface)
|
||||
return;
|
||||
|
||||
priv->keep_surface = keep_surface;
|
||||
if (!keep_surface)
|
||||
{
|
||||
if (priv->surface)
|
||||
{
|
||||
cairo_surface_destroy (priv->surface);
|
||||
priv->surface = NULL;
|
||||
}
|
||||
|
||||
gdk_pixbuf_picture_set_keep_pixbuf (picture, TRUE);
|
||||
}
|
||||
|
||||
g_object_notify (G_OBJECT (picture), "keep-surface");
|
||||
}
|
||||
|
||||
gboolean
|
||||
gdk_pixbuf_picture_get_keep_surface (GdkPixbufPicture *picture)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_PIXBUF_PICTURE (picture), FALSE);
|
||||
|
||||
return picture->priv->keep_surface;
|
||||
}
|
||||
|
71
gdk/gdkpixbufpicture.h
Normal file
71
gdk/gdkpixbufpicture.h
Normal file
@@ -0,0 +1,71 @@
|
||||
/* GDK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2010 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#if !defined (__GDK_H_INSIDE__) && !defined (GDK_COMPILATION)
|
||||
#error "Only <gdk/gdk.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __GDK_PIXBUF_PICTURE_H__
|
||||
#define __GDK_PIXBUF_PICTURE_H__
|
||||
|
||||
#include <gdk/gdkpicture.h>
|
||||
|
||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GDK_TYPE_PIXBUF_PICTURE (gdk_pixbuf_picture_get_type ())
|
||||
#define GDK_PIXBUF_PICTURE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GDK_TYPE_PIXBUF_PICTURE, GdkPixbufPicture))
|
||||
#define GDK_PIXBUF_PICTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GDK_TYPE_PIXBUF_PICTURE, GdkPixbufPictureClass))
|
||||
#define GDK_IS_PIXBUF_PICTURE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GDK_TYPE_PIXBUF_PICTURE))
|
||||
#define GDK_IS_PIXBUF_PICTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GDK_TYPE_PIXBUF_PICTURE))
|
||||
#define GDK_PIXBUF_PICTURE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GDK_TYPE_PIXBUF_PICTURE, GdkPixbufPictureClass))
|
||||
|
||||
typedef struct _GdkPixbufPicture GdkPixbufPicture;
|
||||
typedef struct _GdkPixbufPicturePrivate GdkPixbufPicturePrivate;
|
||||
typedef struct _GdkPixbufPictureClass GdkPixbufPictureClass;
|
||||
|
||||
struct _GdkPixbufPicture {
|
||||
GdkPicture parent_picture;
|
||||
|
||||
GdkPixbufPicturePrivate *priv;
|
||||
};
|
||||
|
||||
struct _GdkPixbufPictureClass {
|
||||
GdkPictureClass parent_class;
|
||||
};
|
||||
|
||||
GType gdk_pixbuf_picture_get_type (void);
|
||||
|
||||
GdkPicture * gdk_pixbuf_picture_new (GdkPixbuf *pixbuf);
|
||||
|
||||
void gdk_pixbuf_picture_set_pixbuf (GdkPixbufPicture *picture,
|
||||
GdkPixbuf * pixbuf);
|
||||
GdkPixbuf * gdk_pixbuf_picture_get_pixbuf (GdkPixbufPicture *picture);
|
||||
void gdk_pixbuf_picture_set_keep_pixbuf (GdkPixbufPicture *picture,
|
||||
gboolean keep_pixbuf);
|
||||
gboolean gdk_pixbuf_picture_get_keep_pixbuf (GdkPixbufPicture *picture);
|
||||
void gdk_pixbuf_picture_set_keep_surface (GdkPixbufPicture *picture,
|
||||
gboolean keep_surface);
|
||||
gboolean gdk_pixbuf_picture_get_keep_surface (GdkPixbufPicture *picture);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GDK_PIXBUF_PICTURE_H__ */
|
@@ -227,7 +227,10 @@ gtk_public_h_sources = \
|
||||
gtkhseparator.h \
|
||||
gtkhsv.h \
|
||||
gtkiconfactory.h \
|
||||
gtkiconpicture.h \
|
||||
gtkiconsetpicture.h \
|
||||
gtkicontheme.h \
|
||||
gtkiconthemepicture.h \
|
||||
gtkiconview.h \
|
||||
gtkimage.h \
|
||||
gtkimagemenuitem.h \
|
||||
@@ -251,6 +254,7 @@ gtk_public_h_sources = \
|
||||
gtkmisc.h \
|
||||
gtkmodules.h \
|
||||
gtkmountoperation.h \
|
||||
gtknamedpicture.h \
|
||||
gtknotebook.h \
|
||||
gtknumerableicon.h \
|
||||
gtkoffscreenwindow.h \
|
||||
@@ -296,6 +300,8 @@ gtk_public_h_sources = \
|
||||
gtkstatusbar.h \
|
||||
gtkstatusicon.h \
|
||||
gtkstock.h \
|
||||
gtkstockpicture.h \
|
||||
gtkstylablepicture.h \
|
||||
gtkstylecontext.h \
|
||||
gtkstyleproperties.h \
|
||||
gtkstyleprovider.h \
|
||||
@@ -427,6 +433,7 @@ gtk_private_h_sources = \
|
||||
gtksizegroup-private.h \
|
||||
gtksocketprivate.h \
|
||||
gtkstylecontextprivate.h \
|
||||
gtkstyledpicture.h \
|
||||
gtktextbtree.h \
|
||||
gtktextbufferserialize.h \
|
||||
gtktextchildprivate.h \
|
||||
@@ -545,7 +552,10 @@ gtk_base_c_sources = \
|
||||
gtkiconcache.c \
|
||||
gtkiconcachevalidator.c \
|
||||
gtkiconfactory.c \
|
||||
gtkiconpicture.c \
|
||||
gtkiconsetpicture.c \
|
||||
gtkicontheme.c \
|
||||
gtkiconthemepicture.c \
|
||||
gtkiconview.c \
|
||||
gtkimage.c \
|
||||
gtkimagemenuitem.c \
|
||||
@@ -573,6 +583,7 @@ gtk_base_c_sources = \
|
||||
gtkmodifierstyle.c \
|
||||
gtkmodules.c \
|
||||
gtkmountoperation.c \
|
||||
gtknamedpicture.c \
|
||||
gtknotebook.c \
|
||||
gtknumerableicon.c \
|
||||
gtkoffscreenwindow.c \
|
||||
@@ -622,7 +633,10 @@ gtk_base_c_sources = \
|
||||
gtkstatusbar.c \
|
||||
gtkstatusicon.c \
|
||||
gtkstock.c \
|
||||
gtkstockpicture.c \
|
||||
gtkstylablepicture.c \
|
||||
gtkstylecontext.c \
|
||||
gtkstyledpicture.c \
|
||||
gtkstyleproperties.c \
|
||||
gtkstyleprovider.c \
|
||||
gtkstyle.c \
|
||||
|
@@ -113,7 +113,10 @@
|
||||
#include <gtk/gtkhseparator.h>
|
||||
#include <gtk/gtkhsv.h>
|
||||
#include <gtk/gtkiconfactory.h>
|
||||
#include <gtk/gtkiconpicture.h>
|
||||
#include <gtk/gtkiconsetpicture.h>
|
||||
#include <gtk/gtkicontheme.h>
|
||||
#include <gtk/gtkiconthemepicture.h>
|
||||
#include <gtk/gtkiconview.h>
|
||||
#include <gtk/gtkimage.h>
|
||||
#include <gtk/gtkimagemenuitem.h>
|
||||
@@ -136,6 +139,7 @@
|
||||
#include <gtk/gtkmisc.h>
|
||||
#include <gtk/gtkmodules.h>
|
||||
#include <gtk/gtkmountoperation.h>
|
||||
#include <gtk/gtknamedpicture.h>
|
||||
#include <gtk/gtknotebook.h>
|
||||
#include <gtk/gtknumerableicon.h>
|
||||
#include <gtk/gtkoffscreenwindow.h>
|
||||
@@ -179,6 +183,8 @@
|
||||
#include <gtk/gtkstatusbar.h>
|
||||
#include <gtk/gtkstatusicon.h>
|
||||
#include <gtk/gtkstock.h>
|
||||
#include <gtk/gtkstockpicture.h>
|
||||
#include <gtk/gtkstylablepicture.h>
|
||||
#include <gtk/gtkstylecontext.h>
|
||||
#include <gtk/gtkstyleproperties.h>
|
||||
#include <gtk/gtkstyleprovider.h>
|
||||
|
@@ -1135,12 +1135,24 @@ gtk_icon_info_load_symbolic_for_style
|
||||
gtk_icon_info_new_for_pixbuf
|
||||
gtk_icon_info_set_raw_coordinates
|
||||
gtk_icon_lookup_flags_get_type G_GNUC_CONST
|
||||
gtk_icon_picture_get_name
|
||||
gtk_icon_picture_get_size
|
||||
gtk_icon_picture_get_type G_GNUC_CONST
|
||||
gtk_icon_picture_new
|
||||
gtk_icon_picture_set_name
|
||||
gtk_icon_picture_set_size
|
||||
gtk_icon_set_add_source
|
||||
gtk_icon_set_copy
|
||||
gtk_icon_set_get_sizes
|
||||
gtk_icon_set_get_type G_GNUC_CONST
|
||||
gtk_icon_set_new
|
||||
gtk_icon_set_new_from_pixbuf
|
||||
gtk_icon_set_picture_get_icon_set
|
||||
gtk_icon_set_picture_get_size
|
||||
gtk_icon_set_picture_get_type G_GNUC_CONST
|
||||
gtk_icon_set_picture_new
|
||||
gtk_icon_set_picture_set_icon_set
|
||||
gtk_icon_set_picture_set_size
|
||||
gtk_icon_set_ref
|
||||
gtk_icon_set_render_icon
|
||||
gtk_icon_set_render_icon_pixbuf
|
||||
|
207
gtk/gtkiconpicture.c
Normal file
207
gtk/gtkiconpicture.c
Normal file
@@ -0,0 +1,207 @@
|
||||
/* GTK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2010 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gtkiconpicture.h"
|
||||
|
||||
#include "gtkintl.h"
|
||||
#include "gtkprivate.h"
|
||||
|
||||
struct _GtkIconPicturePrivate {
|
||||
GIcon *icon;
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_ICON
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GtkIconPicture, gtk_icon_picture, GTK_TYPE_ICON_THEME_PICTURE)
|
||||
|
||||
/**
|
||||
* SECTION:gtkiconsetpicture
|
||||
* @Short_description: Pictures for #GtkIcons
|
||||
* @Title: GtkIconPicture
|
||||
* @See_also: #GtkIcon
|
||||
*
|
||||
* A #GtkIconPicture is an implementation of #GdkPicture for icon sets.
|
||||
*/
|
||||
|
||||
static void
|
||||
gtk_icon_picture_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkIconPicture *picture = GTK_ICON_PICTURE (object);
|
||||
GtkIconPicturePrivate *priv = picture->priv;
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_ICON:
|
||||
g_value_set_object (value, priv->icon);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_icon_picture_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkIconPicture *picture = GTK_ICON_PICTURE (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_ICON:
|
||||
gtk_icon_picture_set_icon (picture, g_value_get_object (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_icon_picture_dispose (GObject *object)
|
||||
{
|
||||
GtkIconPicture *icon = GTK_ICON_PICTURE (object);
|
||||
GtkIconPicturePrivate *priv = icon->priv;
|
||||
|
||||
if (priv->icon) {
|
||||
g_object_unref (priv->icon);
|
||||
priv->icon = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (gtk_icon_picture_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
GtkIconInfo *
|
||||
gtk_icon_picture_lookup (GtkIconThemePicture * picture,
|
||||
GtkIconTheme * theme,
|
||||
int size,
|
||||
GtkIconLookupFlags flags)
|
||||
{
|
||||
GtkIconPicture *icon = GTK_ICON_PICTURE (picture);
|
||||
GtkIconPicturePrivate *priv = icon->priv;
|
||||
|
||||
if (priv->icon == NULL)
|
||||
return NULL;
|
||||
|
||||
return gtk_icon_theme_lookup_by_gicon (theme,
|
||||
priv->icon,
|
||||
size,
|
||||
flags);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_icon_picture_class_init (GtkIconPictureClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkIconThemePictureClass *icon_theme_picture_class = GTK_ICON_THEME_PICTURE_CLASS (klass);
|
||||
|
||||
object_class->get_property = gtk_icon_picture_get_property;
|
||||
object_class->set_property = gtk_icon_picture_set_property;
|
||||
object_class->dispose = gtk_icon_picture_dispose;
|
||||
|
||||
icon_theme_picture_class->lookup = gtk_icon_picture_lookup;
|
||||
|
||||
/**
|
||||
* GtkIconPicture:icon:
|
||||
*
|
||||
* The icon to display.
|
||||
*
|
||||
* Since: 3.2
|
||||
*/
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_ICON,
|
||||
g_param_spec_object ("icon",
|
||||
P_("Icon"),
|
||||
P_("Icon to display"),
|
||||
G_TYPE_ICON,
|
||||
GTK_PARAM_READWRITE));
|
||||
|
||||
g_type_class_add_private (klass, sizeof (GtkIconPicturePrivate));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_icon_picture_init (GtkIconPicture *picture)
|
||||
{
|
||||
picture->priv = G_TYPE_INSTANCE_GET_PRIVATE (picture,
|
||||
GTK_TYPE_ICON_PICTURE,
|
||||
GtkIconPicturePrivate);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_icon_picture_new:
|
||||
* @icon_name: the name of the icon to display
|
||||
* @size: The icon size to use or -1 for default
|
||||
*
|
||||
* Creates a new #GtkIconPicture displaying the given @icon.
|
||||
*
|
||||
* Returns: a new picture
|
||||
**/
|
||||
GdkPicture *
|
||||
gtk_icon_picture_new (GIcon * icon,
|
||||
GtkIconSize size)
|
||||
{
|
||||
return g_object_new (GTK_TYPE_ICON_PICTURE,
|
||||
"icon", icon,
|
||||
"size", size,
|
||||
NULL);
|
||||
}
|
||||
|
||||
GIcon *
|
||||
gtk_icon_picture_get_icon (GtkIconPicture * picture)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_ICON_PICTURE (picture), NULL);
|
||||
|
||||
return picture->priv->icon;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_icon_picture_set_icon (GtkIconPicture *picture,
|
||||
GIcon * icon)
|
||||
{
|
||||
GtkIconPicturePrivate *priv;
|
||||
|
||||
g_return_if_fail (GTK_IS_ICON_PICTURE (picture));
|
||||
|
||||
priv = picture->priv;
|
||||
|
||||
if (icon == priv->icon)
|
||||
return;
|
||||
|
||||
if (icon)
|
||||
g_object_ref (icon);
|
||||
|
||||
if (priv->icon)
|
||||
g_object_unref (priv->icon);
|
||||
|
||||
priv->icon = icon;
|
||||
|
||||
gtk_icon_theme_picture_update (GTK_ICON_THEME_PICTURE (picture));
|
||||
g_object_notify (G_OBJECT (picture), "icon");
|
||||
}
|
||||
|
64
gtk/gtkiconpicture.h
Normal file
64
gtk/gtkiconpicture.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/* GTK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2010 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
|
||||
#error "Only <gtk/gtk.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __GTK_ICON_PICTURE_H__
|
||||
#define __GTK_ICON_PICTURE_H__
|
||||
|
||||
#include <gtk/gtkiconthemepicture.h>
|
||||
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_ICON_PICTURE (gtk_icon_picture_get_type ())
|
||||
#define GTK_ICON_PICTURE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GTK_TYPE_ICON_PICTURE, GtkIconPicture))
|
||||
#define GTK_ICON_PICTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_ICON_PICTURE, GtkIconPictureClass))
|
||||
#define GTK_IS_ICON_PICTURE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GTK_TYPE_ICON_PICTURE))
|
||||
#define GTK_IS_ICON_PICTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_ICON_PICTURE))
|
||||
#define GTK_ICON_PICTURE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_ICON_PICTURE, GtkIconPictureClass))
|
||||
|
||||
typedef struct _GtkIconPicture GtkIconPicture;
|
||||
typedef struct _GtkIconPicturePrivate GtkIconPicturePrivate;
|
||||
typedef struct _GtkIconPictureClass GtkIconPictureClass;
|
||||
|
||||
struct _GtkIconPicture {
|
||||
GtkIconThemePicture parent_picture;
|
||||
|
||||
GtkIconPicturePrivate * priv;
|
||||
};
|
||||
|
||||
struct _GtkIconPictureClass {
|
||||
GtkIconThemePictureClass parent_class;
|
||||
};
|
||||
|
||||
GType gtk_icon_picture_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GdkPicture * gtk_icon_picture_new (GIcon * icon,
|
||||
GtkIconSize size);
|
||||
|
||||
GIcon * gtk_icon_picture_get_icon (GtkIconPicture * picture);
|
||||
void gtk_icon_picture_set_icon (GtkIconPicture * picture,
|
||||
GIcon * icon);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_ICON_PICTURE_H__ */
|
372
gtk/gtkiconsetpicture.c
Normal file
372
gtk/gtkiconsetpicture.c
Normal file
@@ -0,0 +1,372 @@
|
||||
/* GTK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2010 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gtkiconsetpicture.h"
|
||||
|
||||
#include <cairo-gobject.h>
|
||||
|
||||
#include "gtkintl.h"
|
||||
#include "gtkprivate.h"
|
||||
#include "gtkstyledpicture.h"
|
||||
|
||||
struct _GtkIconSetPicturePrivate {
|
||||
GdkPicture *picture;
|
||||
GtkIconSet *set;
|
||||
GtkIconSize size;
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_ICON_SET,
|
||||
PROP_SIZE
|
||||
};
|
||||
|
||||
static void
|
||||
gtk_icon_set_picture_update_picture (GtkIconSetPicture *picture)
|
||||
{
|
||||
GtkIconSetPicturePrivate *priv = picture->priv;
|
||||
GtkIconSet *icon_set;
|
||||
GtkStyleContext *style;
|
||||
GdkPixbuf *pixbuf;
|
||||
GtkWidgetPath *path;
|
||||
|
||||
path = gtk_widget_path_new ();
|
||||
style = gtk_style_context_new ();
|
||||
gtk_style_context_set_path (style, path);
|
||||
gtk_widget_path_free (path);
|
||||
|
||||
if (priv->set == NULL)
|
||||
{
|
||||
icon_set = gtk_style_context_lookup_icon_set (style, GTK_STOCK_MISSING_IMAGE);
|
||||
g_assert (icon_set);
|
||||
}
|
||||
else
|
||||
icon_set = priv->set;
|
||||
|
||||
pixbuf = gtk_icon_set_render_icon_pixbuf (icon_set, style, priv->size);
|
||||
gdk_pixbuf_picture_set_pixbuf (GDK_PIXBUF_PICTURE (priv->picture), pixbuf);
|
||||
g_object_unref (pixbuf);
|
||||
|
||||
g_object_unref (style);
|
||||
}
|
||||
|
||||
static GdkPicture *
|
||||
gtk_icon_set_picture_update_styled (GtkStyledPicture *styled,
|
||||
GdkPicture *pixbuf_picture)
|
||||
{
|
||||
GdkPicture *icon = gtk_picture_get_unstyled (GDK_PICTURE (styled));
|
||||
GtkWidget *widget = gtk_styled_picture_get_widget (styled);
|
||||
GtkIconSetPicturePrivate *priv = GTK_ICON_SET_PICTURE (icon)->priv;
|
||||
GtkIconSet *icon_set;
|
||||
GtkStyleContext *style;
|
||||
GdkPixbuf *pixbuf;
|
||||
|
||||
style = gtk_widget_get_style_context (widget);
|
||||
gtk_style_context_save (style);
|
||||
gtk_style_context_set_state (style, gtk_widget_get_state_flags (widget));
|
||||
|
||||
if (priv->set == NULL)
|
||||
{
|
||||
icon_set = gtk_style_context_lookup_icon_set (style, GTK_STOCK_MISSING_IMAGE);
|
||||
g_assert (icon_set);
|
||||
}
|
||||
else
|
||||
icon_set = priv->set;
|
||||
|
||||
pixbuf = gtk_icon_set_render_icon_pixbuf (icon_set, style, priv->size);
|
||||
gdk_pixbuf_picture_set_pixbuf (GDK_PIXBUF_PICTURE (pixbuf_picture), pixbuf);
|
||||
g_object_unref (pixbuf);
|
||||
|
||||
gtk_style_context_restore (style);
|
||||
|
||||
g_object_ref (pixbuf_picture);
|
||||
return pixbuf_picture;
|
||||
}
|
||||
|
||||
static GdkPicture *
|
||||
gtk_icon_set_picture_attach (GdkPicture *picture,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
GdkPicture *styled;
|
||||
GdkPicture *pixbuf_picture;
|
||||
|
||||
styled = gtk_styled_picture_new (picture, widget);
|
||||
pixbuf_picture = gdk_pixbuf_picture_new (NULL);
|
||||
g_signal_connect (styled, "update", G_CALLBACK (gtk_icon_set_picture_update_styled), pixbuf_picture);
|
||||
gtk_styled_picture_update (GTK_STYLED_PICTURE (styled));
|
||||
/* We can get rid of it here. styled will have a reference to it
|
||||
* and keep that reference until it goes away. */
|
||||
g_object_unref (pixbuf_picture);
|
||||
|
||||
return styled;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_icon_set_picture_stylable_picture_init (GtkStylablePictureInterface *iface)
|
||||
{
|
||||
iface->attach = gtk_icon_set_picture_attach;
|
||||
}
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (GtkIconSetPicture, gtk_icon_set_picture, GDK_TYPE_PICTURE,
|
||||
G_IMPLEMENT_INTERFACE (GTK_TYPE_STYLABLE_PICTURE,
|
||||
gtk_icon_set_picture_stylable_picture_init))
|
||||
|
||||
/**
|
||||
* SECTION:gtkiconsetpicture
|
||||
* @Short_description: Pictures for #GtkIconSets
|
||||
* @Title: GtkIconSetPicture
|
||||
* @See_also: #GtkIconSet
|
||||
*
|
||||
* A #GtkIconSetPicture is an implementation of #GdkPicture for icon sets.
|
||||
*/
|
||||
|
||||
static void
|
||||
gtk_icon_set_picture_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkIconSetPicture *picture = GTK_ICON_SET_PICTURE (object);
|
||||
GtkIconSetPicturePrivate *priv = picture->priv;
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_ICON_SET:
|
||||
g_value_set_boxed (value, priv->set);
|
||||
break;
|
||||
case PROP_SIZE:
|
||||
g_value_set_int (value, priv->size);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_icon_set_picture_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkIconSetPicture *picture = GTK_ICON_SET_PICTURE (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_ICON_SET:
|
||||
gtk_icon_set_picture_set_icon_set (picture, g_value_get_boxed (value));
|
||||
break;
|
||||
case PROP_SIZE:
|
||||
gtk_icon_set_picture_set_size (picture, g_value_get_int (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_icon_set_picture_dispose (GObject *object)
|
||||
{
|
||||
GtkIconSetPicture *icon_set = GTK_ICON_SET_PICTURE (object);
|
||||
GtkIconSetPicturePrivate *priv = icon_set->priv;
|
||||
|
||||
if (priv->set) {
|
||||
gtk_icon_set_unref (priv->set);
|
||||
priv->set = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (gtk_icon_set_picture_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static cairo_surface_t *
|
||||
gtk_icon_set_picture_ref_surface (GdkPicture *picture)
|
||||
{
|
||||
GtkIconSetPicture *icon_set = GTK_ICON_SET_PICTURE (picture);
|
||||
|
||||
return gdk_picture_ref_surface (icon_set->priv->picture);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_icon_set_picture_draw (GdkPicture *picture,
|
||||
cairo_t *cr)
|
||||
{
|
||||
GtkIconSetPicture *icon_set = GTK_ICON_SET_PICTURE (picture);
|
||||
|
||||
gdk_picture_draw (icon_set->priv->picture, cr);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_icon_set_picture_class_init (GtkIconSetPictureClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GdkPictureClass *picture_class = GDK_PICTURE_CLASS (klass);
|
||||
|
||||
object_class->get_property = gtk_icon_set_picture_get_property;
|
||||
object_class->set_property = gtk_icon_set_picture_set_property;
|
||||
object_class->dispose = gtk_icon_set_picture_dispose;
|
||||
|
||||
picture_class->ref_surface = gtk_icon_set_picture_ref_surface;
|
||||
picture_class->draw = gtk_icon_set_picture_draw;
|
||||
|
||||
/**
|
||||
* GtkIconSetPicture:size:
|
||||
*
|
||||
* The #GtkIconSize to use to determine the actual image size.
|
||||
*
|
||||
* Since: 3.2
|
||||
*/
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_SIZE,
|
||||
g_param_spec_int ("size",
|
||||
P_("Size"),
|
||||
P_("Symbolic size to use"),
|
||||
G_MININT, G_MAXINT,
|
||||
GTK_ICON_SIZE_BUTTON,
|
||||
GTK_PARAM_READWRITE));
|
||||
|
||||
/**
|
||||
* GtkIconSetPicture:icon-set:
|
||||
*
|
||||
* The icon set to display.
|
||||
*
|
||||
* Since: 3.2
|
||||
*/
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_ICON_SET,
|
||||
g_param_spec_boxed ("icon-set",
|
||||
P_("Icon set"),
|
||||
P_("Icon set to display"),
|
||||
GTK_TYPE_ICON_SET,
|
||||
GTK_PARAM_READWRITE));
|
||||
|
||||
g_type_class_add_private (klass, sizeof (GtkIconSetPicturePrivate));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_icon_set_picture_resized_callback (GdkPicture * pixbuf,
|
||||
GtkIconSetPicture *icon_set)
|
||||
{
|
||||
gdk_picture_resized (GDK_PICTURE (icon_set),
|
||||
gdk_picture_get_width (pixbuf),
|
||||
gdk_picture_get_height (pixbuf));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_icon_set_picture_init (GtkIconSetPicture *picture)
|
||||
{
|
||||
GtkIconSetPicturePrivate *priv;
|
||||
|
||||
picture->priv = G_TYPE_INSTANCE_GET_PRIVATE (picture,
|
||||
GTK_TYPE_ICON_SET_PICTURE,
|
||||
GtkIconSetPicturePrivate);
|
||||
|
||||
priv = picture->priv;
|
||||
priv->size = GTK_ICON_SIZE_BUTTON;
|
||||
priv->picture = gdk_pixbuf_picture_new (NULL);
|
||||
g_signal_connect_swapped (priv->picture,
|
||||
"changed",
|
||||
G_CALLBACK (gdk_picture_changed_region),
|
||||
picture);
|
||||
g_signal_connect (priv->picture,
|
||||
"resized",
|
||||
G_CALLBACK (gtk_icon_set_picture_resized_callback),
|
||||
picture);
|
||||
|
||||
gtk_icon_set_picture_update_picture (picture);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_icon_set_picture_new:
|
||||
* @icon_set_name: the name of the icon_set to display
|
||||
* @size: The icon_set size to use or -1 for default
|
||||
*
|
||||
* Creates a new #GtkIconSetPicture displaying the given @icon_set.
|
||||
*
|
||||
* Returns: a new picture
|
||||
**/
|
||||
GdkPicture *
|
||||
gtk_icon_set_picture_new (GtkIconSet *icon_set,
|
||||
GtkIconSize size)
|
||||
{
|
||||
return g_object_new (GTK_TYPE_ICON_SET_PICTURE,
|
||||
"icon-set", icon_set,
|
||||
"size", size,
|
||||
NULL);
|
||||
}
|
||||
|
||||
GtkIconSize
|
||||
gtk_icon_set_picture_get_size (GtkIconSetPicture *picture)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_ICON_SET_PICTURE (picture), -1);
|
||||
|
||||
return picture->priv->size;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_icon_set_picture_set_size (GtkIconSetPicture *picture,
|
||||
GtkIconSize size)
|
||||
{
|
||||
GtkIconSetPicturePrivate *priv;
|
||||
|
||||
g_return_if_fail (GTK_IS_ICON_SET_PICTURE (picture));
|
||||
|
||||
priv = picture->priv;
|
||||
|
||||
if (priv->size == size)
|
||||
return;
|
||||
|
||||
priv->size = size;
|
||||
|
||||
gtk_icon_set_picture_update_picture (picture);
|
||||
g_object_notify (G_OBJECT (picture), "size");
|
||||
}
|
||||
|
||||
GtkIconSet *
|
||||
gtk_icon_set_picture_get_icon_set (GtkIconSetPicture * picture)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_ICON_SET_PICTURE (picture), NULL);
|
||||
|
||||
return picture->priv->set;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_icon_set_picture_set_icon_set (GtkIconSetPicture *picture,
|
||||
GtkIconSet * icon_set)
|
||||
{
|
||||
GtkIconSetPicturePrivate *priv;
|
||||
|
||||
g_return_if_fail (GTK_IS_ICON_SET_PICTURE (picture));
|
||||
|
||||
priv = picture->priv;
|
||||
|
||||
if (icon_set)
|
||||
gtk_icon_set_ref (icon_set);
|
||||
|
||||
if (priv->set)
|
||||
gtk_icon_set_ref (priv->set);
|
||||
|
||||
priv->set = icon_set;
|
||||
|
||||
gtk_icon_set_picture_update_picture (picture);
|
||||
g_object_notify (G_OBJECT (picture), "icon-set");
|
||||
}
|
||||
|
67
gtk/gtkiconsetpicture.h
Normal file
67
gtk/gtkiconsetpicture.h
Normal file
@@ -0,0 +1,67 @@
|
||||
/* GTK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2010 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
|
||||
#error "Only <gtk/gtk.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __GTK_ICON_SET_PICTURE_H__
|
||||
#define __GTK_ICON_SET_PICTURE_H__
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_ICON_SET_PICTURE (gtk_icon_set_picture_get_type ())
|
||||
#define GTK_ICON_SET_PICTURE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GTK_TYPE_ICON_SET_PICTURE, GtkIconSetPicture))
|
||||
#define GTK_ICON_SET_PICTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_ICON_SET_PICTURE, GtkIconSetPictureClass))
|
||||
#define GTK_IS_ICON_SET_PICTURE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GTK_TYPE_ICON_SET_PICTURE))
|
||||
#define GTK_IS_ICON_SET_PICTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_ICON_SET_PICTURE))
|
||||
#define GTK_ICON_SET_PICTURE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_ICON_SET_PICTURE, GtkIconSetPictureClass))
|
||||
|
||||
typedef struct _GtkIconSetPicture GtkIconSetPicture;
|
||||
typedef struct _GtkIconSetPicturePrivate GtkIconSetPicturePrivate;
|
||||
typedef struct _GtkIconSetPictureClass GtkIconSetPictureClass;
|
||||
|
||||
struct _GtkIconSetPicture {
|
||||
GdkPicture parent_picture;
|
||||
|
||||
GtkIconSetPicturePrivate *priv;
|
||||
};
|
||||
|
||||
struct _GtkIconSetPictureClass {
|
||||
GdkPictureClass parent_class;
|
||||
};
|
||||
|
||||
GType gtk_icon_set_picture_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GdkPicture * gtk_icon_set_picture_new (GtkIconSet * icon_set,
|
||||
GtkIconSize size);
|
||||
|
||||
GtkIconSize gtk_icon_set_picture_get_size (GtkIconSetPicture * picture);
|
||||
void gtk_icon_set_picture_set_size (GtkIconSetPicture * picture,
|
||||
GtkIconSize size);
|
||||
GtkIconSet * gtk_icon_set_picture_get_icon_set (GtkIconSetPicture * picture);
|
||||
void gtk_icon_set_picture_set_icon_set (GtkIconSetPicture * picture,
|
||||
GtkIconSet * set);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_ICON_SET_PICTURE_H__ */
|
508
gtk/gtkiconthemepicture.c
Normal file
508
gtk/gtkiconthemepicture.c
Normal file
@@ -0,0 +1,508 @@
|
||||
/* GTK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2010 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gtkiconthemepicture.h"
|
||||
|
||||
#include <cairo-gobject.h>
|
||||
|
||||
#include "gtkintl.h"
|
||||
#include "gtkprivate.h"
|
||||
#include "gtkstyledpicture.h"
|
||||
|
||||
struct _GtkIconThemePicturePrivate {
|
||||
GdkPicture *picture;
|
||||
GtkIconTheme *theme;
|
||||
GtkIconSize size;
|
||||
int pixel_size;
|
||||
gboolean use_fallback;
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_ICON_THEME,
|
||||
PROP_SIZE,
|
||||
PROP_PIXEL_SIZE
|
||||
};
|
||||
|
||||
static int
|
||||
gtk_icon_theme_picture_lookup_size (GtkSettings *settings,
|
||||
GtkIconSize icon_size)
|
||||
{
|
||||
int width, height;
|
||||
|
||||
if (gtk_icon_size_lookup_for_settings (settings,
|
||||
icon_size,
|
||||
&width, &height))
|
||||
return MIN (width, height);
|
||||
|
||||
if (icon_size != -1)
|
||||
{
|
||||
g_warning ("Invalid icon size %d\n", icon_size);
|
||||
return 24;
|
||||
}
|
||||
|
||||
return 48;
|
||||
}
|
||||
|
||||
static GdkPixbuf *
|
||||
gtk_icon_theme_picture_get_pixbuf_for_widget (GtkIconThemePicture *picture,
|
||||
GtkWidget * widget)
|
||||
{
|
||||
GtkIconThemePicturePrivate *priv = picture->priv;
|
||||
GtkIconTheme *icon_theme;
|
||||
GdkScreen *screen;
|
||||
GtkSettings *settings;
|
||||
gint size;
|
||||
GtkIconInfo *info;
|
||||
GtkIconLookupFlags flags;
|
||||
GdkPixbuf *pixbuf;
|
||||
|
||||
screen = widget ? gtk_widget_get_screen (widget) : gdk_screen_get_default ();
|
||||
icon_theme = priv->theme ? priv->theme : gtk_icon_theme_get_for_screen (screen);
|
||||
settings = gtk_settings_get_for_screen (screen);
|
||||
|
||||
flags = GTK_ICON_LOOKUP_USE_BUILTIN;
|
||||
if (priv->use_fallback)
|
||||
flags |= GTK_ICON_LOOKUP_GENERIC_FALLBACK;
|
||||
|
||||
if (priv->pixel_size != -1)
|
||||
{
|
||||
size = priv->pixel_size;
|
||||
flags |= GTK_ICON_LOOKUP_FORCE_SIZE;
|
||||
}
|
||||
else
|
||||
size = gtk_icon_theme_picture_lookup_size (settings, priv->size);
|
||||
|
||||
info = GTK_ICON_THEME_PICTURE_GET_CLASS (picture)->lookup (picture,
|
||||
icon_theme,
|
||||
size,
|
||||
flags);
|
||||
|
||||
if (info)
|
||||
{
|
||||
if (widget)
|
||||
{
|
||||
GtkStyleContext *context;
|
||||
|
||||
context = gtk_widget_get_style_context (widget);
|
||||
gtk_style_context_save (context);
|
||||
gtk_style_context_set_state (context, gtk_widget_get_state_flags (widget));
|
||||
pixbuf = gtk_icon_info_load_symbolic_for_context (info,
|
||||
context,
|
||||
NULL, NULL);
|
||||
gtk_style_context_restore (context);
|
||||
}
|
||||
else
|
||||
{
|
||||
static const GdkRGBA foreground = { 0.0, 0.0, 0.0, 1.0 };
|
||||
static const GdkRGBA success_color = { 0.3, 0.6, 0.02, 1.0 };
|
||||
static const GdkRGBA warning_color = { 0.96, 0.47, 0.24, 1.0 };
|
||||
static const GdkRGBA error_color = { 0.8, 0.0, 0.0, 1.0 };
|
||||
|
||||
pixbuf = gtk_icon_info_load_symbolic (info,
|
||||
&foreground,
|
||||
&success_color,
|
||||
&warning_color,
|
||||
&error_color,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
gtk_icon_info_free (info);
|
||||
}
|
||||
else
|
||||
pixbuf = NULL;
|
||||
|
||||
if (pixbuf == NULL && widget != NULL)
|
||||
{
|
||||
pixbuf = gtk_widget_render_icon_pixbuf (widget,
|
||||
GTK_STOCK_MISSING_IMAGE,
|
||||
priv->size);
|
||||
}
|
||||
|
||||
return pixbuf;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_icon_theme_picture_update (GtkIconThemePicture *picture)
|
||||
{
|
||||
GtkIconThemePicturePrivate *priv = picture->priv;
|
||||
GdkPixbuf *pixbuf;
|
||||
|
||||
pixbuf = gtk_icon_theme_picture_get_pixbuf_for_widget (picture, NULL);
|
||||
gdk_pixbuf_picture_set_pixbuf (GDK_PIXBUF_PICTURE (priv->picture), pixbuf);
|
||||
if (pixbuf)
|
||||
g_object_unref (pixbuf);
|
||||
}
|
||||
|
||||
static GdkPicture *
|
||||
gtk_icon_theme_picture_update_styled (GtkStyledPicture *styled,
|
||||
GdkPicture *pixbuf_picture)
|
||||
{
|
||||
GdkPicture *icon = gtk_picture_get_unstyled (GDK_PICTURE (styled));
|
||||
GtkWidget *widget = gtk_styled_picture_get_widget (styled);
|
||||
GdkPixbuf *pixbuf;
|
||||
|
||||
pixbuf = gtk_icon_theme_picture_get_pixbuf_for_widget (GTK_ICON_THEME_PICTURE (icon),
|
||||
widget);
|
||||
gdk_pixbuf_picture_set_pixbuf (GDK_PIXBUF_PICTURE (pixbuf_picture), pixbuf);
|
||||
if (pixbuf)
|
||||
g_object_unref (pixbuf);
|
||||
|
||||
g_object_ref (pixbuf_picture);
|
||||
return pixbuf_picture;
|
||||
}
|
||||
|
||||
static GdkPicture *
|
||||
gtk_icon_theme_picture_attach (GdkPicture *picture,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
GdkPicture *styled;
|
||||
GdkPicture *pixbuf_picture;
|
||||
|
||||
styled = gtk_styled_picture_new (picture, widget);
|
||||
pixbuf_picture = gdk_pixbuf_picture_new (NULL);
|
||||
g_signal_connect (styled, "update", G_CALLBACK (gtk_icon_theme_picture_update_styled), pixbuf_picture);
|
||||
gtk_styled_picture_update (GTK_STYLED_PICTURE (styled));
|
||||
/* We can get rid of it here. styled will have a reference to it
|
||||
* and keep that reference until it goes away. */
|
||||
g_object_unref (pixbuf_picture);
|
||||
|
||||
return styled;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_icon_theme_picture_stylable_picture_init (GtkStylablePictureInterface *iface)
|
||||
{
|
||||
iface->attach = gtk_icon_theme_picture_attach;
|
||||
}
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GtkIconThemePicture, gtk_icon_theme_picture, GDK_TYPE_PICTURE,
|
||||
G_IMPLEMENT_INTERFACE (GTK_TYPE_STYLABLE_PICTURE,
|
||||
gtk_icon_theme_picture_stylable_picture_init))
|
||||
|
||||
/**
|
||||
* SECTION:gtkiconthemepicture
|
||||
* @Short_description: Pictures for a #GtkIconTheme
|
||||
* @Title: GtkIconThemePicture
|
||||
* @See_also: #GtkIconTheme
|
||||
*
|
||||
* A #GtkIconThemePicture is an implementation of #GdkPicture to display
|
||||
* icons from a #GtkIconTheme.
|
||||
*/
|
||||
|
||||
static void
|
||||
gtk_icon_theme_picture_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkIconThemePicture *picture = GTK_ICON_THEME_PICTURE (object);
|
||||
GtkIconThemePicturePrivate *priv = picture->priv;
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_ICON_THEME:
|
||||
g_value_set_object (value, priv->theme);
|
||||
break;
|
||||
case PROP_SIZE:
|
||||
g_value_set_int (value, priv->size);
|
||||
break;
|
||||
case PROP_PIXEL_SIZE:
|
||||
g_value_set_int (value, priv->pixel_size);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_icon_theme_picture_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkIconThemePicture *picture = GTK_ICON_THEME_PICTURE (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_ICON_THEME:
|
||||
gtk_icon_theme_picture_set_icon_theme (picture, g_value_get_object (value));
|
||||
break;
|
||||
case PROP_SIZE:
|
||||
gtk_icon_theme_picture_set_size (picture, g_value_get_int (value));
|
||||
break;
|
||||
case PROP_PIXEL_SIZE:
|
||||
gtk_icon_theme_picture_set_pixel_size (picture, g_value_get_int (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_icon_theme_picture_dispose (GObject *object)
|
||||
{
|
||||
GtkIconThemePicture *picture = GTK_ICON_THEME_PICTURE (object);
|
||||
|
||||
gtk_icon_theme_picture_set_icon_theme (picture, NULL);
|
||||
|
||||
G_OBJECT_CLASS (gtk_icon_theme_picture_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static cairo_surface_t *
|
||||
gtk_icon_theme_picture_ref_surface (GdkPicture *picture)
|
||||
{
|
||||
GtkIconThemePicture *icon_theme = GTK_ICON_THEME_PICTURE (picture);
|
||||
|
||||
return gdk_picture_ref_surface (icon_theme->priv->picture);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_icon_theme_picture_draw (GdkPicture *picture,
|
||||
cairo_t *cr)
|
||||
{
|
||||
GtkIconThemePicture *icon_theme = GTK_ICON_THEME_PICTURE (picture);
|
||||
|
||||
gdk_picture_draw (icon_theme->priv->picture, cr);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_icon_theme_picture_class_init (GtkIconThemePictureClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GdkPictureClass *picture_class = GDK_PICTURE_CLASS (klass);
|
||||
|
||||
object_class->get_property = gtk_icon_theme_picture_get_property;
|
||||
object_class->set_property = gtk_icon_theme_picture_set_property;
|
||||
object_class->dispose = gtk_icon_theme_picture_dispose;
|
||||
|
||||
picture_class->ref_surface = gtk_icon_theme_picture_ref_surface;
|
||||
picture_class->draw = gtk_icon_theme_picture_draw;
|
||||
|
||||
/**
|
||||
* GtkIconThemePicture:size:
|
||||
*
|
||||
* The #GtkIconSize to use to determine the actual image size.
|
||||
* This will only be used if #GtkIconThemePicture:pixel-size is
|
||||
* unset.
|
||||
*
|
||||
* Since: 3.2
|
||||
*/
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_SIZE,
|
||||
g_param_spec_int ("size",
|
||||
P_("Size"),
|
||||
P_("Symbolic size to use"),
|
||||
G_MININT, G_MAXINT,
|
||||
GTK_ICON_SIZE_BUTTON,
|
||||
GTK_PARAM_READWRITE));
|
||||
|
||||
/**
|
||||
* GtkIconThemePicture:pixel-size:
|
||||
*
|
||||
* The "pixel-size" property can be used to specify a fixed size
|
||||
* overriding the #GtkIconThemePicture:icon-size property.
|
||||
*
|
||||
* Since: 3.2
|
||||
*/
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_PIXEL_SIZE,
|
||||
g_param_spec_int ("pixel-size",
|
||||
P_("Pixel size"),
|
||||
P_("Pixel size to override size"),
|
||||
-1, G_MAXINT,
|
||||
-1,
|
||||
GTK_PARAM_READWRITE));
|
||||
|
||||
/**
|
||||
* GtkIconThemePicture:icon-theme:
|
||||
*
|
||||
* The icon theme to use or %NULL to use the default theme.
|
||||
*
|
||||
* Since: 3.2
|
||||
*/
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_ICON_THEME,
|
||||
g_param_spec_object ("icon-theme",
|
||||
P_("Icon theme"),
|
||||
P_("Icon theme to use"),
|
||||
GTK_TYPE_ICON_THEME,
|
||||
GTK_PARAM_READWRITE));
|
||||
|
||||
g_type_class_add_private (klass, sizeof (GtkIconThemePicturePrivate));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_icon_theme_picture_resized_callback (GdkPicture * pixbuf,
|
||||
GtkIconThemePicture *icon_theme)
|
||||
{
|
||||
gdk_picture_resized (GDK_PICTURE (icon_theme),
|
||||
gdk_picture_get_width (pixbuf),
|
||||
gdk_picture_get_height (pixbuf));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_icon_theme_picture_init (GtkIconThemePicture *picture)
|
||||
{
|
||||
GtkIconThemePicturePrivate *priv;
|
||||
|
||||
picture->priv = G_TYPE_INSTANCE_GET_PRIVATE (picture,
|
||||
GTK_TYPE_ICON_THEME_PICTURE,
|
||||
GtkIconThemePicturePrivate);
|
||||
|
||||
priv = picture->priv;
|
||||
priv->size = GTK_ICON_SIZE_BUTTON;
|
||||
priv->pixel_size = -1;
|
||||
priv->picture = gdk_pixbuf_picture_new (NULL);
|
||||
g_signal_connect_swapped (priv->picture,
|
||||
"changed",
|
||||
G_CALLBACK (gdk_picture_changed_region),
|
||||
picture);
|
||||
g_signal_connect (priv->picture,
|
||||
"resized",
|
||||
G_CALLBACK (gtk_icon_theme_picture_resized_callback),
|
||||
picture);
|
||||
}
|
||||
|
||||
GtkIconSize
|
||||
gtk_icon_theme_picture_get_size (GtkIconThemePicture *picture)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_ICON_THEME_PICTURE (picture), -1);
|
||||
|
||||
return picture->priv->size;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_icon_theme_picture_set_size (GtkIconThemePicture *picture,
|
||||
GtkIconSize size)
|
||||
{
|
||||
GtkIconThemePicturePrivate *priv;
|
||||
|
||||
g_return_if_fail (GTK_IS_ICON_THEME_PICTURE (picture));
|
||||
|
||||
priv = picture->priv;
|
||||
|
||||
if (priv->size == size)
|
||||
return;
|
||||
|
||||
priv->size = size;
|
||||
|
||||
gtk_icon_theme_picture_update (picture);
|
||||
g_object_notify (G_OBJECT (picture), "size");
|
||||
}
|
||||
|
||||
int
|
||||
gtk_icon_theme_picture_get_pixel_size (GtkIconThemePicture *picture)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_ICON_THEME_PICTURE (picture), -1);
|
||||
|
||||
return picture->priv->pixel_size;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_icon_theme_picture_set_pixel_size (GtkIconThemePicture *picture,
|
||||
int pixel_size)
|
||||
{
|
||||
GtkIconThemePicturePrivate *priv;
|
||||
|
||||
g_return_if_fail (GTK_IS_ICON_THEME_PICTURE (picture));
|
||||
|
||||
priv = picture->priv;
|
||||
|
||||
if (priv->pixel_size == pixel_size)
|
||||
return;
|
||||
|
||||
priv->pixel_size = pixel_size;
|
||||
|
||||
gtk_icon_theme_picture_update (picture);
|
||||
g_object_notify (G_OBJECT (picture), "pixel-size");
|
||||
}
|
||||
|
||||
GtkIconTheme *
|
||||
gtk_icon_theme_picture_get_icon_theme (GtkIconThemePicture * picture)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_ICON_THEME_PICTURE (picture), NULL);
|
||||
|
||||
return picture->priv->theme;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_icon_theme_picture_set_icon_theme (GtkIconThemePicture *picture,
|
||||
GtkIconTheme * icon_theme)
|
||||
{
|
||||
GtkIconThemePicturePrivate *priv;
|
||||
|
||||
g_return_if_fail (GTK_IS_ICON_THEME_PICTURE (picture));
|
||||
g_return_if_fail (icon_theme == NULL || GTK_IS_ICON_THEME (icon_theme));
|
||||
|
||||
priv = picture->priv;
|
||||
|
||||
if (icon_theme)
|
||||
{
|
||||
g_object_ref (icon_theme);
|
||||
g_signal_connect_swapped (icon_theme,
|
||||
"changed",
|
||||
G_CALLBACK (gtk_icon_theme_picture_update),
|
||||
picture);
|
||||
}
|
||||
|
||||
if (priv->theme)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (priv->theme,
|
||||
gtk_icon_theme_picture_update,
|
||||
picture);
|
||||
g_object_unref (priv->theme);
|
||||
}
|
||||
|
||||
priv->theme = icon_theme;
|
||||
|
||||
gtk_icon_theme_picture_update (picture);
|
||||
g_object_notify (G_OBJECT (picture), "icon-theme");
|
||||
}
|
||||
|
||||
gboolean
|
||||
gtk_icon_theme_picture_get_use_fallback (GtkIconThemePicture * picture)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_ICON_THEME_PICTURE (picture), FALSE);
|
||||
|
||||
return picture->priv->use_fallback;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_icon_theme_picture_set_use_fallback (GtkIconThemePicture *picture,
|
||||
gboolean use_fallback)
|
||||
{
|
||||
GtkIconThemePicturePrivate *priv;
|
||||
|
||||
g_return_if_fail (GTK_IS_ICON_THEME_PICTURE (picture));
|
||||
|
||||
priv = picture->priv;
|
||||
|
||||
if (priv->use_fallback == use_fallback)
|
||||
return;
|
||||
|
||||
priv->use_fallback = use_fallback;
|
||||
|
||||
gtk_icon_theme_picture_update (picture);
|
||||
g_object_notify (G_OBJECT (picture), "icon-theme");
|
||||
}
|
79
gtk/gtkiconthemepicture.h
Normal file
79
gtk/gtkiconthemepicture.h
Normal file
@@ -0,0 +1,79 @@
|
||||
/* GTK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2010 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
|
||||
#error "Only <gtk/gtk.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __GTK_ICON_THEME_PICTURE_H__
|
||||
#define __GTK_ICON_THEME_PICTURE_H__
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
#include <gtk/gtkicontheme.h>
|
||||
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_ICON_THEME_PICTURE (gtk_icon_theme_picture_get_type ())
|
||||
#define GTK_ICON_THEME_PICTURE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GTK_TYPE_ICON_THEME_PICTURE, GtkIconThemePicture))
|
||||
#define GTK_ICON_THEME_PICTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_ICON_THEME_PICTURE, GtkIconThemePictureClass))
|
||||
#define GTK_IS_ICON_THEME_PICTURE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GTK_TYPE_ICON_THEME_PICTURE))
|
||||
#define GTK_IS_ICON_THEME_PICTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_ICON_THEME_PICTURE))
|
||||
#define GTK_ICON_THEME_PICTURE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_ICON_THEME_PICTURE, GtkIconThemePictureClass))
|
||||
|
||||
typedef struct _GtkIconThemePicture GtkIconThemePicture;
|
||||
typedef struct _GtkIconThemePicturePrivate GtkIconThemePicturePrivate;
|
||||
typedef struct _GtkIconThemePictureClass GtkIconThemePictureClass;
|
||||
|
||||
struct _GtkIconThemePicture {
|
||||
GdkPicture parent_picture;
|
||||
|
||||
GtkIconThemePicturePrivate *priv;
|
||||
};
|
||||
|
||||
struct _GtkIconThemePictureClass {
|
||||
GdkPictureClass parent_class;
|
||||
|
||||
GtkIconInfo * (* lookup) (GtkIconThemePicture * picture,
|
||||
GtkIconTheme * theme,
|
||||
int size,
|
||||
GtkIconLookupFlags flags);
|
||||
};
|
||||
|
||||
GType gtk_icon_theme_picture_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GtkIconSize gtk_icon_theme_picture_get_size (GtkIconThemePicture * picture);
|
||||
void gtk_icon_theme_picture_set_size (GtkIconThemePicture * picture,
|
||||
GtkIconSize size);
|
||||
int gtk_icon_theme_picture_get_pixel_size (GtkIconThemePicture * picture);
|
||||
void gtk_icon_theme_picture_set_pixel_size (GtkIconThemePicture * picture,
|
||||
int pixel_size);
|
||||
GtkIconTheme * gtk_icon_theme_picture_get_icon_theme (GtkIconThemePicture * picture);
|
||||
void gtk_icon_theme_picture_set_icon_theme (GtkIconThemePicture * picture,
|
||||
GtkIconTheme * theme);
|
||||
gboolean gtk_icon_theme_picture_get_use_fallback (GtkIconThemePicture * picture);
|
||||
void gtk_icon_theme_picture_set_use_fallback (GtkIconThemePicture * picture,
|
||||
gboolean use_fallback);
|
||||
|
||||
/* for subclasses only */
|
||||
void gtk_icon_theme_picture_update (GtkIconThemePicture * picture);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_ICON_THEME_PICTURE_H__ */
|
1280
gtk/gtkimage.c
1280
gtk/gtkimage.c
File diff suppressed because it is too large
Load Diff
@@ -62,6 +62,8 @@ typedef struct _GtkImageClass GtkImageClass;
|
||||
* This image type was added in GTK+ 2.6
|
||||
* @GTK_IMAGE_GICON: the widget contains a #GIcon.
|
||||
* This image type was added in GTK+ 2.14
|
||||
* @GTK_IMAGE_PICTURE: the widget contains a #GdkPicture.
|
||||
* This image type was added in GTK+ 3.2
|
||||
*
|
||||
* Describes the image data representation used by a #GtkImage. If you
|
||||
* want to get the image from the widget, you can only get the
|
||||
@@ -79,7 +81,8 @@ typedef enum
|
||||
GTK_IMAGE_ICON_SET,
|
||||
GTK_IMAGE_ANIMATION,
|
||||
GTK_IMAGE_ICON_NAME,
|
||||
GTK_IMAGE_GICON
|
||||
GTK_IMAGE_GICON,
|
||||
GTK_IMAGE_PICTURE
|
||||
} GtkImageType;
|
||||
|
||||
/**
|
||||
@@ -111,6 +114,7 @@ GType gtk_image_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GtkWidget* gtk_image_new (void);
|
||||
GtkWidget* gtk_image_new_from_file (const gchar *filename);
|
||||
GtkWidget* gtk_image_new_from_picture (GdkPicture *picture);
|
||||
GtkWidget* gtk_image_new_from_pixbuf (GdkPixbuf *pixbuf);
|
||||
GtkWidget* gtk_image_new_from_stock (const gchar *stock_id,
|
||||
GtkIconSize size);
|
||||
@@ -125,6 +129,8 @@ GtkWidget* gtk_image_new_from_gicon (GIcon *icon,
|
||||
void gtk_image_clear (GtkImage *image);
|
||||
void gtk_image_set_from_file (GtkImage *image,
|
||||
const gchar *filename);
|
||||
void gtk_image_set_from_picture (GtkImage *image,
|
||||
GdkPicture *picture);
|
||||
void gtk_image_set_from_pixbuf (GtkImage *image,
|
||||
GdkPixbuf *pixbuf);
|
||||
void gtk_image_set_from_stock (GtkImage *image,
|
||||
@@ -147,6 +153,7 @@ void gtk_image_set_pixel_size (GtkImage *image,
|
||||
GtkImageType gtk_image_get_storage_type (GtkImage *image);
|
||||
|
||||
GdkPixbuf* gtk_image_get_pixbuf (GtkImage *image);
|
||||
GdkPicture*gtk_image_get_picture (GtkImage *image);
|
||||
void gtk_image_get_stock (GtkImage *image,
|
||||
gchar **stock_id,
|
||||
GtkIconSize *size);
|
||||
|
@@ -34,6 +34,7 @@
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _GtkImagePixbufData GtkImagePixbufData;
|
||||
typedef struct _GtkImagePictureData GtkImagePictureData;
|
||||
typedef struct _GtkImageStockData GtkImageStockData;
|
||||
typedef struct _GtkImageIconSetData GtkImageIconSetData;
|
||||
typedef struct _GtkImageAnimationData GtkImageAnimationData;
|
||||
@@ -45,6 +46,11 @@ struct _GtkImagePixbufData
|
||||
GdkPixbuf *pixbuf;
|
||||
};
|
||||
|
||||
struct _GtkImagePictureData
|
||||
{
|
||||
GdkPicture *picture;
|
||||
};
|
||||
|
||||
struct _GtkImageStockData
|
||||
{
|
||||
gchar *stock_id;
|
||||
|
200
gtk/gtknamedpicture.c
Normal file
200
gtk/gtknamedpicture.c
Normal file
@@ -0,0 +1,200 @@
|
||||
/* GTK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2010 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gtknamedpicture.h"
|
||||
|
||||
#include "gtkintl.h"
|
||||
#include "gtkprivate.h"
|
||||
|
||||
struct _GtkNamedPicturePrivate {
|
||||
char *name;
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_NAME
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GtkNamedPicture, gtk_named_picture, GTK_TYPE_ICON_THEME_PICTURE)
|
||||
|
||||
/**
|
||||
* SECTION:gtknamedpicture
|
||||
* @Short_description: Pictures for named icons
|
||||
* @Title: GtkNamedPicture
|
||||
* @See_also: #GtkIconTheme
|
||||
*
|
||||
* A #GtkNamedPicture is an implementation of #GdkPicture for named icons.
|
||||
*/
|
||||
|
||||
static void
|
||||
gtk_named_picture_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkNamedPicture *picture = GTK_NAMED_PICTURE (object);
|
||||
GtkNamedPicturePrivate *priv = picture->priv;
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_NAME:
|
||||
g_value_set_string (value, priv->name);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_named_picture_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkNamedPicture *picture = GTK_NAMED_PICTURE (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_NAME:
|
||||
gtk_named_picture_set_name (picture, g_value_get_string (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_named_picture_dispose (GObject *object)
|
||||
{
|
||||
GtkNamedPicture *named = GTK_NAMED_PICTURE (object);
|
||||
GtkNamedPicturePrivate *priv = named->priv;
|
||||
|
||||
g_free (priv->name);
|
||||
priv->name = NULL;
|
||||
|
||||
G_OBJECT_CLASS (gtk_named_picture_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
GtkIconInfo *
|
||||
gtk_named_picture_lookup (GtkIconThemePicture * picture,
|
||||
GtkIconTheme * theme,
|
||||
int size,
|
||||
GtkIconLookupFlags flags)
|
||||
{
|
||||
GtkNamedPicture *icon = GTK_NAMED_PICTURE (picture);
|
||||
GtkNamedPicturePrivate *priv = icon->priv;
|
||||
|
||||
if (priv->name == NULL)
|
||||
return NULL;
|
||||
|
||||
return gtk_icon_theme_lookup_icon (theme,
|
||||
priv->name,
|
||||
size,
|
||||
flags);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_named_picture_class_init (GtkNamedPictureClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GtkIconThemePictureClass *icon_theme_picture_class = GTK_ICON_THEME_PICTURE_CLASS (klass);
|
||||
|
||||
object_class->get_property = gtk_named_picture_get_property;
|
||||
object_class->set_property = gtk_named_picture_set_property;
|
||||
object_class->dispose = gtk_named_picture_dispose;
|
||||
|
||||
icon_theme_picture_class->lookup = gtk_named_picture_lookup;
|
||||
|
||||
/**
|
||||
* GtkNamedPicture:name:
|
||||
*
|
||||
* Name of the icon to display.
|
||||
*
|
||||
* Since: 3.2
|
||||
*/
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_NAME,
|
||||
g_param_spec_string ("name",
|
||||
P_("Name"),
|
||||
P_("Name of the icon to display"),
|
||||
NULL,
|
||||
GTK_PARAM_READWRITE));
|
||||
|
||||
g_type_class_add_private (klass, sizeof (GtkNamedPicturePrivate));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_named_picture_init (GtkNamedPicture *picture)
|
||||
{
|
||||
picture->priv = G_TYPE_INSTANCE_GET_PRIVATE (picture,
|
||||
GTK_TYPE_NAMED_PICTURE,
|
||||
GtkNamedPicturePrivate);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_named_picture_new:
|
||||
* @name: the name of the icon to display
|
||||
* @size: The icon size
|
||||
*
|
||||
* Creates a new #GtkNamedPicture displaying the icon for the
|
||||
* given @name.
|
||||
*
|
||||
* Returns: a new picture
|
||||
**/
|
||||
GdkPicture *
|
||||
gtk_named_picture_new (const char *name,
|
||||
GtkIconSize size)
|
||||
{
|
||||
g_return_val_if_fail (name != NULL, NULL);
|
||||
|
||||
return g_object_new (GTK_TYPE_NAMED_PICTURE,
|
||||
"name", name,
|
||||
"size", size,
|
||||
NULL);
|
||||
}
|
||||
|
||||
const char *
|
||||
gtk_named_picture_get_name (GtkNamedPicture * picture)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_NAMED_PICTURE (picture), NULL);
|
||||
|
||||
return picture->priv->name;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_named_picture_set_name (GtkNamedPicture *picture,
|
||||
const char * name)
|
||||
{
|
||||
GtkNamedPicturePrivate *priv;
|
||||
|
||||
g_return_if_fail (GTK_IS_NAMED_PICTURE (picture));
|
||||
|
||||
priv = picture->priv;
|
||||
|
||||
g_free (priv->name);
|
||||
priv->name = g_strdup (name);
|
||||
|
||||
gtk_icon_theme_picture_update (GTK_ICON_THEME_PICTURE (picture));
|
||||
g_object_notify (G_OBJECT (picture), "name");
|
||||
}
|
||||
|
64
gtk/gtknamedpicture.h
Normal file
64
gtk/gtknamedpicture.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/* GTK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2010 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
|
||||
#error "Only <gtk/gtk.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __GTK_NAMED_PICTURE_H__
|
||||
#define __GTK_NAMED_PICTURE_H__
|
||||
|
||||
#include <gtk/gtkiconthemepicture.h>
|
||||
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_NAMED_PICTURE (gtk_named_picture_get_type ())
|
||||
#define GTK_NAMED_PICTURE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GTK_TYPE_NAMED_PICTURE, GtkNamedPicture))
|
||||
#define GTK_NAMED_PICTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_NAMED_PICTURE, GtkNamedPictureClass))
|
||||
#define GTK_IS_NAMED_PICTURE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GTK_TYPE_NAMED_PICTURE))
|
||||
#define GTK_IS_NAMED_PICTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_NAMED_PICTURE))
|
||||
#define GTK_NAMED_PICTURE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_NAMED_PICTURE, GtkNamedPictureClass))
|
||||
|
||||
typedef struct _GtkNamedPicture GtkNamedPicture;
|
||||
typedef struct _GtkNamedPicturePrivate GtkNamedPicturePrivate;
|
||||
typedef struct _GtkNamedPictureClass GtkNamedPictureClass;
|
||||
|
||||
struct _GtkNamedPicture {
|
||||
GtkIconThemePicture parent_picture;
|
||||
|
||||
GtkNamedPicturePrivate * priv;
|
||||
};
|
||||
|
||||
struct _GtkNamedPictureClass {
|
||||
GtkIconThemePictureClass parent_class;
|
||||
};
|
||||
|
||||
GType gtk_named_picture_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GdkPicture * gtk_named_picture_new (const char * name,
|
||||
GtkIconSize size);
|
||||
|
||||
const char * gtk_named_picture_get_name (GtkNamedPicture * picture);
|
||||
void gtk_named_picture_set_name (GtkNamedPicture * picture,
|
||||
const char * name);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_NAMED_PICTURE_H__ */
|
371
gtk/gtkstockpicture.c
Normal file
371
gtk/gtkstockpicture.c
Normal file
@@ -0,0 +1,371 @@
|
||||
/* GTK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2010 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gtkstockpicture.h"
|
||||
|
||||
#include <cairo-gobject.h>
|
||||
|
||||
#include "gtkintl.h"
|
||||
#include "gtkprivate.h"
|
||||
#include "gtkstyledpicture.h"
|
||||
|
||||
struct _GtkStockPicturePrivate {
|
||||
GdkPicture *picture;
|
||||
char *stock_id;
|
||||
GtkIconSize size;
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_STOCK,
|
||||
PROP_SIZE
|
||||
};
|
||||
|
||||
static void
|
||||
gtk_stock_picture_update_picture (GtkStockPicture *picture)
|
||||
{
|
||||
GtkStockPicturePrivate *priv = picture->priv;
|
||||
GtkIconSet *icon_set;
|
||||
GtkStyleContext *style;
|
||||
GdkPixbuf *pixbuf;
|
||||
GtkWidgetPath *path;
|
||||
|
||||
path = gtk_widget_path_new ();
|
||||
style = gtk_style_context_new ();
|
||||
gtk_style_context_set_path (style, path);
|
||||
gtk_widget_path_free (path);
|
||||
|
||||
if (priv->stock_id)
|
||||
icon_set = gtk_style_context_lookup_icon_set (style, priv->stock_id);
|
||||
else
|
||||
icon_set = NULL;
|
||||
|
||||
if (icon_set == NULL)
|
||||
{
|
||||
icon_set = gtk_style_context_lookup_icon_set (style, GTK_STOCK_MISSING_IMAGE);
|
||||
g_assert (icon_set);
|
||||
}
|
||||
|
||||
pixbuf = gtk_icon_set_render_icon_pixbuf (icon_set, style, priv->size);
|
||||
gdk_pixbuf_picture_set_pixbuf (GDK_PIXBUF_PICTURE (priv->picture), pixbuf);
|
||||
g_object_unref (pixbuf);
|
||||
|
||||
g_object_unref (style);
|
||||
}
|
||||
|
||||
static GdkPicture *
|
||||
gtk_stock_picture_update_styled (GtkStyledPicture *styled,
|
||||
GdkPicture *pixbuf_picture)
|
||||
{
|
||||
GdkPicture *stock = gtk_picture_get_unstyled (GDK_PICTURE (styled));
|
||||
GtkWidget *widget = gtk_styled_picture_get_widget (styled);
|
||||
GtkStockPicturePrivate *priv = GTK_STOCK_PICTURE (stock)->priv;
|
||||
GdkPixbuf *pixbuf;
|
||||
|
||||
if (priv->stock_id)
|
||||
pixbuf = gtk_widget_render_icon_pixbuf (widget,
|
||||
priv->stock_id,
|
||||
priv->size);
|
||||
else
|
||||
pixbuf = NULL;
|
||||
|
||||
if (pixbuf == NULL)
|
||||
{
|
||||
pixbuf = gtk_widget_render_icon_pixbuf (widget,
|
||||
GTK_STOCK_MISSING_IMAGE,
|
||||
priv->size);
|
||||
g_assert (pixbuf != NULL);
|
||||
}
|
||||
|
||||
gdk_pixbuf_picture_set_pixbuf (GDK_PIXBUF_PICTURE (pixbuf_picture), pixbuf);
|
||||
g_object_unref (pixbuf);
|
||||
|
||||
g_object_ref (pixbuf_picture);
|
||||
return pixbuf_picture;
|
||||
}
|
||||
|
||||
static GdkPicture *
|
||||
gtk_stock_picture_attach (GdkPicture *picture,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
GdkPicture *styled;
|
||||
GdkPicture *pixbuf_picture;
|
||||
|
||||
styled = gtk_styled_picture_new (picture, widget);
|
||||
pixbuf_picture = gdk_pixbuf_picture_new (NULL);
|
||||
g_signal_connect (styled, "update", G_CALLBACK (gtk_stock_picture_update_styled), pixbuf_picture);
|
||||
gtk_styled_picture_update (GTK_STYLED_PICTURE (styled));
|
||||
/* We can get rid of it here. styled will have a reference to it
|
||||
* and keep that reference until it goes away. */
|
||||
g_object_unref (pixbuf_picture);
|
||||
|
||||
return styled;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_stock_picture_stylable_picture_init (GtkStylablePictureInterface *iface)
|
||||
{
|
||||
iface->attach = gtk_stock_picture_attach;
|
||||
}
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (GtkStockPicture, gtk_stock_picture, GDK_TYPE_PICTURE,
|
||||
G_IMPLEMENT_INTERFACE (GTK_TYPE_STYLABLE_PICTURE,
|
||||
gtk_stock_picture_stylable_picture_init))
|
||||
|
||||
/**
|
||||
* SECTION:gtkstockpicture
|
||||
* @Short_description: Pictures for stock icons
|
||||
* @Title: GtkStockPicture
|
||||
* @See_also: #GtkIconFactory
|
||||
*
|
||||
* A #GtkStockPicture is an implementation of #GdkPicture for stock icons.
|
||||
*/
|
||||
|
||||
static void
|
||||
gtk_stock_picture_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkStockPicture *picture = GTK_STOCK_PICTURE (object);
|
||||
GtkStockPicturePrivate *priv = picture->priv;
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_STOCK:
|
||||
g_value_set_string (value, priv->stock_id);
|
||||
break;
|
||||
case PROP_SIZE:
|
||||
g_value_set_int (value, priv->size);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_stock_picture_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkStockPicture *picture = GTK_STOCK_PICTURE (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_STOCK:
|
||||
gtk_stock_picture_set_stock_id (picture, g_value_get_string (value));
|
||||
break;
|
||||
case PROP_SIZE:
|
||||
gtk_stock_picture_set_size (picture, g_value_get_int (value));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_stock_picture_dispose (GObject *object)
|
||||
{
|
||||
GtkStockPicture *icon = GTK_STOCK_PICTURE (object);
|
||||
GtkStockPicturePrivate *priv = icon->priv;
|
||||
|
||||
if (priv->picture)
|
||||
{
|
||||
g_object_unref (priv->picture);
|
||||
priv->picture = NULL;
|
||||
}
|
||||
g_free (priv->stock_id);
|
||||
priv->stock_id = NULL;
|
||||
|
||||
G_OBJECT_CLASS (gtk_stock_picture_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static cairo_surface_t *
|
||||
gtk_stock_picture_ref_surface (GdkPicture *picture)
|
||||
{
|
||||
GtkStockPicture *icon = GTK_STOCK_PICTURE (picture);
|
||||
|
||||
return gdk_picture_ref_surface (icon->priv->picture);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_stock_picture_draw (GdkPicture *picture,
|
||||
cairo_t *cr)
|
||||
{
|
||||
GtkStockPicture *icon = GTK_STOCK_PICTURE (picture);
|
||||
|
||||
gdk_picture_draw (icon->priv->picture, cr);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_stock_picture_class_init (GtkStockPictureClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GdkPictureClass *picture_class = GDK_PICTURE_CLASS (klass);
|
||||
|
||||
object_class->get_property = gtk_stock_picture_get_property;
|
||||
object_class->set_property = gtk_stock_picture_set_property;
|
||||
object_class->dispose = gtk_stock_picture_dispose;
|
||||
|
||||
picture_class->ref_surface = gtk_stock_picture_ref_surface;
|
||||
picture_class->draw = gtk_stock_picture_draw;
|
||||
|
||||
/**
|
||||
* GtkStockPicture:size:
|
||||
*
|
||||
* The #GtkIconSize to use to determine the actual image size.
|
||||
*
|
||||
* Since: 3.2
|
||||
*/
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_SIZE,
|
||||
g_param_spec_int ("size",
|
||||
P_("Size"),
|
||||
P_("Symbolic size to use"),
|
||||
G_MININT, G_MAXINT,
|
||||
GTK_ICON_SIZE_BUTTON,
|
||||
GTK_PARAM_READWRITE));
|
||||
|
||||
/**
|
||||
* GtkStockPicture:stock:
|
||||
*
|
||||
* The stock id of the icon to display.
|
||||
*
|
||||
* Since: 3.2
|
||||
*/
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_STOCK,
|
||||
g_param_spec_string ("stock",
|
||||
P_("Name"),
|
||||
P_("The stock id of the icon from the icon theme"),
|
||||
NULL,
|
||||
GTK_PARAM_READWRITE));
|
||||
|
||||
g_type_class_add_private (klass, sizeof (GtkStockPicturePrivate));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_stock_picture_resized_callback (GdkPicture * pixbuf,
|
||||
GtkStockPicture *icon)
|
||||
{
|
||||
gdk_picture_resized (GDK_PICTURE (icon),
|
||||
gdk_picture_get_width (pixbuf),
|
||||
gdk_picture_get_height (pixbuf));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_stock_picture_init (GtkStockPicture *picture)
|
||||
{
|
||||
GtkStockPicturePrivate *priv;
|
||||
|
||||
picture->priv = G_TYPE_INSTANCE_GET_PRIVATE (picture,
|
||||
GTK_TYPE_STOCK_PICTURE,
|
||||
GtkStockPicturePrivate);
|
||||
|
||||
priv = picture->priv;
|
||||
priv->size = GTK_ICON_SIZE_BUTTON;
|
||||
priv->picture = gdk_pixbuf_picture_new (NULL);
|
||||
g_signal_connect_swapped (priv->picture,
|
||||
"changed",
|
||||
G_CALLBACK (gdk_picture_changed_region),
|
||||
picture);
|
||||
g_signal_connect (priv->picture,
|
||||
"resized",
|
||||
G_CALLBACK (gtk_stock_picture_resized_callback),
|
||||
picture);
|
||||
|
||||
gtk_stock_picture_update_picture (picture);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_stock_picture_new:
|
||||
* @stock_id: the stock_id of the icon to display
|
||||
* @size: The icon size to use or -1 for default
|
||||
*
|
||||
* Creates a new #GtkStockPicture displaying the given @icon.
|
||||
*
|
||||
* Returns: a new picture
|
||||
**/
|
||||
GdkPicture *
|
||||
gtk_stock_picture_new (const char *stock_id,
|
||||
GtkIconSize size)
|
||||
{
|
||||
return g_object_new (GTK_TYPE_STOCK_PICTURE,
|
||||
"stock", stock_id,
|
||||
"size", size,
|
||||
NULL);
|
||||
}
|
||||
|
||||
GtkIconSize
|
||||
gtk_stock_picture_get_size (GtkStockPicture *picture)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_STOCK_PICTURE (picture), -1);
|
||||
|
||||
return picture->priv->size;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_stock_picture_set_size (GtkStockPicture *picture,
|
||||
GtkIconSize size)
|
||||
{
|
||||
GtkStockPicturePrivate *priv;
|
||||
|
||||
g_return_if_fail (GTK_IS_STOCK_PICTURE (picture));
|
||||
|
||||
priv = picture->priv;
|
||||
|
||||
if (priv->size == size)
|
||||
return;
|
||||
|
||||
priv->size = size;
|
||||
|
||||
gtk_stock_picture_update_picture (picture);
|
||||
g_object_notify (G_OBJECT (picture), "size");
|
||||
}
|
||||
|
||||
const char *
|
||||
gtk_stock_picture_get_stock_id (GtkStockPicture * picture)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_STOCK_PICTURE (picture), NULL);
|
||||
|
||||
return picture->priv->stock_id;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_stock_picture_set_stock_id (GtkStockPicture *picture,
|
||||
const char * stock_id)
|
||||
{
|
||||
GtkStockPicturePrivate *priv;
|
||||
|
||||
g_return_if_fail (GTK_IS_STOCK_PICTURE (picture));
|
||||
|
||||
priv = picture->priv;
|
||||
|
||||
g_free (priv->stock_id);
|
||||
priv->stock_id = g_strdup (stock_id);
|
||||
|
||||
gtk_stock_picture_update_picture (picture);
|
||||
g_object_notify (G_OBJECT (picture), "stock");
|
||||
}
|
||||
|
67
gtk/gtkstockpicture.h
Normal file
67
gtk/gtkstockpicture.h
Normal file
@@ -0,0 +1,67 @@
|
||||
/* GTK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2010 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
|
||||
#error "Only <gtk/gtk.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __GTK_STOCK_PICTURE_H__
|
||||
#define __GTK_STOCK_PICTURE_H__
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_STOCK_PICTURE (gtk_stock_picture_get_type ())
|
||||
#define GTK_STOCK_PICTURE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GTK_TYPE_STOCK_PICTURE, GtkStockPicture))
|
||||
#define GTK_STOCK_PICTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_STOCK_PICTURE, GtkStockPictureClass))
|
||||
#define GTK_IS_STOCK_PICTURE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GTK_TYPE_STOCK_PICTURE))
|
||||
#define GTK_IS_STOCK_PICTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_STOCK_PICTURE))
|
||||
#define GTK_STOCK_PICTURE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_STOCK_PICTURE, GtkStockPictureClass))
|
||||
|
||||
typedef struct _GtkStockPicture GtkStockPicture;
|
||||
typedef struct _GtkStockPicturePrivate GtkStockPicturePrivate;
|
||||
typedef struct _GtkStockPictureClass GtkStockPictureClass;
|
||||
|
||||
struct _GtkStockPicture {
|
||||
GdkPicture parent_picture;
|
||||
|
||||
GtkStockPicturePrivate *priv;
|
||||
};
|
||||
|
||||
struct _GtkStockPictureClass {
|
||||
GdkPictureClass parent_class;
|
||||
};
|
||||
|
||||
GType gtk_stock_picture_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GdkPicture * gtk_stock_picture_new (const char * stock_id,
|
||||
GtkIconSize size);
|
||||
|
||||
GtkIconSize gtk_stock_picture_get_size (GtkStockPicture * picture);
|
||||
void gtk_stock_picture_set_size (GtkStockPicture * picture,
|
||||
GtkIconSize size);
|
||||
const char * gtk_stock_picture_get_stock_id (GtkStockPicture * picture);
|
||||
void gtk_stock_picture_set_stock_id (GtkStockPicture * picture,
|
||||
const char * stock_id);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_STOCK_PICTURE_H__ */
|
78
gtk/gtkstylablepicture.c
Normal file
78
gtk/gtkstylablepicture.c
Normal file
@@ -0,0 +1,78 @@
|
||||
/* gtktreesortable.c
|
||||
* Copyright (C) 2000 Red Hat, Inc., Jonathan Blandford <jrb@redhat.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gtkstylablepicture.h"
|
||||
#include "gtkintl.h"
|
||||
|
||||
|
||||
/**
|
||||
* SECTION:gtkstylablepicture
|
||||
* @Short_description: Pictures that can be styled when attached to widgets
|
||||
* @Title: GtkStylablePicture
|
||||
* @See_also:#GdkPicture, #GtkWidget
|
||||
*
|
||||
* #GtkStylablePicture is an interface to be implemented by pictures that can be
|
||||
* styled according to a #GtkWidget's #GtkStyleContext.
|
||||
*/
|
||||
|
||||
G_DEFINE_INTERFACE (GtkStylablePicture, gtk_stylable_picture, GDK_TYPE_PICTURE)
|
||||
|
||||
static void
|
||||
gtk_stylable_picture_default_init (GtkStylablePictureInterface *iface)
|
||||
{
|
||||
}
|
||||
|
||||
GdkPicture *
|
||||
gtk_widget_style_picture (GtkWidget *widget,
|
||||
GdkPicture *picture)
|
||||
{
|
||||
GtkStylablePictureInterface *iface;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
|
||||
g_return_val_if_fail (GDK_IS_PICTURE (picture), NULL);
|
||||
|
||||
if (!GTK_IS_STYLABLE_PICTURE (picture))
|
||||
return g_object_ref (picture);
|
||||
|
||||
iface = GTK_STYLABLE_PICTURE_GET_IFACE (picture);
|
||||
if (iface->attach == NULL)
|
||||
return g_object_ref (picture);
|
||||
|
||||
return (* iface->attach) (picture, widget);
|
||||
}
|
||||
|
||||
GdkPicture *
|
||||
gtk_picture_get_unstyled (GdkPicture *styled)
|
||||
{
|
||||
GtkStylablePictureInterface *iface;
|
||||
|
||||
g_return_val_if_fail (GDK_IS_PICTURE (styled), NULL);
|
||||
|
||||
if (!GTK_IS_STYLABLE_PICTURE (styled))
|
||||
return styled;
|
||||
|
||||
iface = GTK_STYLABLE_PICTURE_GET_IFACE (styled);
|
||||
if (iface->get_unstyled == NULL)
|
||||
return styled;
|
||||
|
||||
return iface->get_unstyled (styled);
|
||||
}
|
63
gtk/gtkstylablepicture.h
Normal file
63
gtk/gtkstylablepicture.h
Normal file
@@ -0,0 +1,63 @@
|
||||
/* gtktreesortable.h
|
||||
* Copyright (C) 2001 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
|
||||
#error "Only <gtk/gtk.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __GTK_STYLABLE_PICTURE_H__
|
||||
#define __GTK_STYLABLE_PICTURE_H__
|
||||
|
||||
|
||||
#include <gdk/gdk.h>
|
||||
#include <gtk/gtkwidget.h>
|
||||
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_STYLABLE_PICTURE (gtk_stylable_picture_get_type ())
|
||||
#define GTK_STYLABLE_PICTURE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_STYLABLE_PICTURE, GtkStylablePicture))
|
||||
#define GTK_STYLABLE_PICTURE_CLASS(obj) (G_TYPE_CHECK_CLASS_CAST ((obj), GTK_TYPE_STYLABLE_PICTURE, GtkStylablePictureInterface))
|
||||
#define GTK_IS_STYLABLE_PICTURE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_STYLABLE_PICTURE))
|
||||
#define GTK_STYLABLE_PICTURE_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GTK_TYPE_STYLABLE_PICTURE, GtkStylablePictureInterface))
|
||||
|
||||
typedef struct _GtkStylablePicture GtkStylablePicture; /* Dummy typedef */
|
||||
typedef struct _GtkStylablePictureInterface GtkStylablePictureInterface;
|
||||
|
||||
struct _GtkStylablePictureInterface
|
||||
{
|
||||
GTypeInterface g_iface;
|
||||
|
||||
/* virtual table */
|
||||
GdkPicture * (* attach) (GdkPicture *picture,
|
||||
GtkWidget *widget);
|
||||
GdkPicture * (* get_unstyled) (GdkPicture *picture);
|
||||
};
|
||||
|
||||
|
||||
GType gtk_stylable_picture_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GdkPicture * gtk_widget_style_picture (GtkWidget *widget,
|
||||
GdkPicture *picture);
|
||||
GdkPicture * gtk_picture_get_unstyled (GdkPicture *styled);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_STYLABLE_PICTURE_H__ */
|
287
gtk/gtkstyledpicture.c
Normal file
287
gtk/gtkstyledpicture.c
Normal file
@@ -0,0 +1,287 @@
|
||||
/* GTK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2010 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gtkstyledpicture.h"
|
||||
|
||||
#include <cairo-gobject.h>
|
||||
|
||||
#include "gtkintl.h"
|
||||
#include "gtkmarshalers.h"
|
||||
#include "gtkprivate.h"
|
||||
|
||||
struct _GtkStyledPicturePrivate {
|
||||
GdkPicture *styled;
|
||||
|
||||
GtkWidget *widget;
|
||||
GdkPicture *unstyled;
|
||||
};
|
||||
|
||||
enum {
|
||||
UPDATE,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static guint signals[LAST_SIGNAL] = { 0, };
|
||||
|
||||
static GdkPicture *
|
||||
gtk_styled_picture_attach (GdkPicture *picture,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
GtkStyledPicture *styled = GTK_STYLED_PICTURE (picture);
|
||||
GtkStyledPicturePrivate *priv = styled->priv;
|
||||
|
||||
g_warning ("styled pictures should not be exposed to the world, did somebody not call gtk_picture_get_unstyled()?");
|
||||
|
||||
return gtk_styled_picture_new (priv->unstyled,
|
||||
priv->widget);
|
||||
}
|
||||
|
||||
static GdkPicture *
|
||||
gtk_styled_picture_get_unstyled (GdkPicture *picture)
|
||||
{
|
||||
GtkStyledPicture *styled = GTK_STYLED_PICTURE (picture);
|
||||
|
||||
return styled->priv->unstyled;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_styled_picture_stylable_picture_init (GtkStylablePictureInterface *iface)
|
||||
{
|
||||
iface->attach = gtk_styled_picture_attach;
|
||||
iface->get_unstyled = gtk_styled_picture_get_unstyled;
|
||||
}
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (GtkStyledPicture, gtk_styled_picture, GDK_TYPE_PICTURE,
|
||||
G_IMPLEMENT_INTERFACE (GTK_TYPE_STYLABLE_PICTURE,
|
||||
gtk_styled_picture_stylable_picture_init))
|
||||
|
||||
static void
|
||||
gdk_styled_picture_resized_callback (GdkPicture *picture,
|
||||
GtkStyledPicture *styled)
|
||||
{
|
||||
gdk_picture_resized (GDK_PICTURE (styled),
|
||||
gdk_picture_get_width (picture),
|
||||
gdk_picture_get_height (picture));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_styled_picture_set_styled (GtkStyledPicture *styled,
|
||||
GdkPicture * picture)
|
||||
{
|
||||
GtkStyledPicturePrivate *priv = styled->priv;
|
||||
|
||||
if (priv->styled == picture)
|
||||
return;
|
||||
|
||||
if (picture)
|
||||
{
|
||||
g_object_ref (picture);
|
||||
g_signal_connect_swapped (picture,
|
||||
"changed",
|
||||
G_CALLBACK (gdk_picture_changed_region),
|
||||
styled);
|
||||
g_signal_connect (picture,
|
||||
"resized",
|
||||
G_CALLBACK (gdk_styled_picture_resized_callback),
|
||||
styled);
|
||||
}
|
||||
|
||||
if (priv->styled)
|
||||
{
|
||||
g_signal_handlers_disconnect_matched (priv->styled,
|
||||
G_SIGNAL_MATCH_DATA,
|
||||
0, 0, NULL, NULL, styled);
|
||||
g_object_unref (priv->styled);
|
||||
}
|
||||
|
||||
priv->styled = picture;
|
||||
|
||||
if (priv->styled)
|
||||
gdk_picture_resized (GDK_PICTURE (styled),
|
||||
gdk_picture_get_width (priv->styled),
|
||||
gdk_picture_get_height (priv->styled));
|
||||
else
|
||||
gdk_picture_resized (GDK_PICTURE (styled), 0, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_styled_picture_dispose (GObject *object)
|
||||
{
|
||||
GtkStyledPicture *styled = GTK_STYLED_PICTURE (object);
|
||||
GtkStyledPicturePrivate *priv = styled->priv;
|
||||
|
||||
gtk_styled_picture_set_styled (styled, NULL);
|
||||
|
||||
if (priv->unstyled)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (priv->unstyled,
|
||||
gtk_styled_picture_update,
|
||||
styled);
|
||||
g_object_unref (priv->unstyled);
|
||||
priv->unstyled = NULL;
|
||||
}
|
||||
if (priv->widget)
|
||||
{
|
||||
g_signal_handlers_disconnect_by_func (priv->widget,
|
||||
gtk_styled_picture_update,
|
||||
styled);
|
||||
g_object_remove_weak_pointer (G_OBJECT (priv->widget), (void **) &priv->widget);
|
||||
priv->widget = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (gtk_styled_picture_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static cairo_surface_t *
|
||||
gtk_styled_picture_ref_surface (GdkPicture *picture)
|
||||
{
|
||||
GtkStyledPicture *styled = GTK_STYLED_PICTURE (picture);
|
||||
|
||||
return gdk_picture_ref_surface (styled->priv->styled);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_styled_picture_draw (GdkPicture *picture,
|
||||
cairo_t *cr)
|
||||
{
|
||||
GtkStyledPicture *styled = GTK_STYLED_PICTURE (picture);
|
||||
|
||||
gdk_picture_draw (styled->priv->styled, cr);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_styled_picture_update_accumulator (GSignalInvocationHint *ihint,
|
||||
GValue *return_accu,
|
||||
const GValue *handler_return,
|
||||
gpointer unused)
|
||||
{
|
||||
gboolean continue_emission;
|
||||
GObject *object;
|
||||
|
||||
object = g_value_get_object (handler_return);
|
||||
g_value_set_object (return_accu, object);
|
||||
continue_emission = !object;
|
||||
|
||||
return continue_emission;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_styled_picture_class_init (GtkStyledPictureClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GdkPictureClass *picture_class = GDK_PICTURE_CLASS (klass);
|
||||
|
||||
object_class->dispose = gtk_styled_picture_dispose;
|
||||
|
||||
picture_class->ref_surface = gtk_styled_picture_ref_surface;
|
||||
picture_class->draw = gtk_styled_picture_draw;
|
||||
|
||||
signals[UPDATE] =
|
||||
g_signal_new (I_("update"),
|
||||
G_TYPE_FROM_CLASS (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GtkStyledPictureClass, update),
|
||||
gtk_styled_picture_update_accumulator, NULL,
|
||||
_gtk_marshal_OBJECT__VOID,
|
||||
GDK_TYPE_PICTURE, 0);
|
||||
|
||||
g_type_class_add_private (klass, sizeof (GtkStyledPicturePrivate));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_styled_picture_init (GtkStyledPicture *picture)
|
||||
{
|
||||
picture->priv = G_TYPE_INSTANCE_GET_PRIVATE (picture,
|
||||
GTK_TYPE_STYLED_PICTURE,
|
||||
GtkStyledPicturePrivate);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_styled_picture_new:
|
||||
* @unstyled: The unstyled picture
|
||||
* @widget: The widet to attach to
|
||||
*
|
||||
* Creates a new #GtkStyledPicture displaying the styled version of
|
||||
* an @unstyled #GdkPicture
|
||||
*
|
||||
* Returns: a new picture
|
||||
**/
|
||||
GdkPicture *
|
||||
gtk_styled_picture_new (GdkPicture *unstyled,
|
||||
GtkWidget *widget)
|
||||
{
|
||||
GtkStyledPicturePrivate *priv;
|
||||
GtkStyledPicture *styled;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
|
||||
g_return_val_if_fail (GDK_IS_PICTURE (unstyled), NULL);
|
||||
|
||||
styled = g_object_new (GTK_TYPE_STYLED_PICTURE, NULL);
|
||||
|
||||
priv = styled->priv;
|
||||
|
||||
priv->widget = widget;
|
||||
g_object_add_weak_pointer (G_OBJECT (widget), (void **) &priv->widget);
|
||||
g_signal_connect_swapped (widget,
|
||||
"style-updated",
|
||||
G_CALLBACK (gtk_styled_picture_update),
|
||||
styled);
|
||||
g_signal_connect_swapped (widget,
|
||||
"state-flags-changed",
|
||||
G_CALLBACK (gtk_styled_picture_update),
|
||||
styled);
|
||||
g_signal_connect_swapped (widget,
|
||||
"direction-changed",
|
||||
G_CALLBACK (gtk_styled_picture_update),
|
||||
styled);
|
||||
|
||||
styled->priv->unstyled = g_object_ref (unstyled);
|
||||
g_signal_connect_swapped (unstyled,
|
||||
"notify",
|
||||
G_CALLBACK (gtk_styled_picture_update),
|
||||
styled);
|
||||
|
||||
gtk_styled_picture_update (styled);
|
||||
|
||||
return GDK_PICTURE (styled);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_styled_picture_update (GtkStyledPicture *picture)
|
||||
{
|
||||
GdkPicture *new_picture = NULL;
|
||||
|
||||
g_signal_emit (picture, signals[UPDATE], 0, &new_picture);
|
||||
|
||||
gtk_styled_picture_set_styled (picture, new_picture);
|
||||
|
||||
if (new_picture)
|
||||
g_object_unref (new_picture);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
gtk_styled_picture_get_widget (GtkStyledPicture *picture)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_STYLED_PICTURE (picture), NULL);
|
||||
|
||||
return picture->priv->widget;
|
||||
}
|
||||
|
65
gtk/gtkstyledpicture.h
Normal file
65
gtk/gtkstyledpicture.h
Normal file
@@ -0,0 +1,65 @@
|
||||
/* GTK - The GIMP Drawing Kit
|
||||
* Copyright (C) 2010 Benjamin Otte <otte@gnome.org>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
|
||||
#error "Only <gtk/gtk.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#ifndef __GTK_STYLED_PICTURE_H__
|
||||
#define __GTK_STYLED_PICTURE_H__
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_STYLED_PICTURE (gtk_styled_picture_get_type ())
|
||||
#define GTK_STYLED_PICTURE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GTK_TYPE_STYLED_PICTURE, GtkStyledPicture))
|
||||
#define GTK_STYLED_PICTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_STYLED_PICTURE, GtkStyledPictureClass))
|
||||
#define GTK_IS_STYLED_PICTURE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), GTK_TYPE_STYLED_PICTURE))
|
||||
#define GTK_IS_STYLED_PICTURE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_STYLED_PICTURE))
|
||||
#define GTK_STYLED_PICTURE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_STYLED_PICTURE, GtkStyledPictureClass))
|
||||
|
||||
typedef struct _GtkStyledPicture GtkStyledPicture;
|
||||
typedef struct _GtkStyledPicturePrivate GtkStyledPicturePrivate;
|
||||
typedef struct _GtkStyledPictureClass GtkStyledPictureClass;
|
||||
|
||||
struct _GtkStyledPicture {
|
||||
GdkPicture parent_picture;
|
||||
|
||||
GtkStyledPicturePrivate *priv;
|
||||
};
|
||||
|
||||
struct _GtkStyledPictureClass {
|
||||
GdkPictureClass parent_class;
|
||||
|
||||
GdkPicture * ( *update) (GtkStyledPicture *picture);
|
||||
};
|
||||
|
||||
GType gtk_styled_picture_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GdkPicture * gtk_styled_picture_new (GdkPicture *unstyled,
|
||||
GtkWidget *widget);
|
||||
|
||||
void gtk_styled_picture_update (GtkStyledPicture *picture);
|
||||
GtkWidget * gtk_styled_picture_get_widget (GtkStyledPicture *picture);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_STYLED_PICTURE_H__ */
|
@@ -4464,8 +4464,8 @@ gtk_widget_unrealize (GtkWidget *widget)
|
||||
* Since: 3.0
|
||||
**/
|
||||
void
|
||||
gtk_widget_queue_draw_region (GtkWidget *widget,
|
||||
cairo_region_t *region)
|
||||
gtk_widget_queue_draw_region (GtkWidget *widget,
|
||||
const cairo_region_t *region)
|
||||
{
|
||||
GtkWidgetPrivate *priv;
|
||||
GtkWidget *w;
|
||||
|
@@ -477,7 +477,7 @@ void gtk_widget_queue_draw_area (GtkWidget *widget,
|
||||
gint width,
|
||||
gint height);
|
||||
void gtk_widget_queue_draw_region (GtkWidget *widget,
|
||||
cairo_region_t *region);
|
||||
const cairo_region_t*region);
|
||||
void gtk_widget_queue_resize (GtkWidget *widget);
|
||||
void gtk_widget_queue_resize_no_redraw (GtkWidget *widget);
|
||||
#ifndef GTK_DISABLE_DEPRECATED
|
||||
|
@@ -67,6 +67,7 @@ noinst_PROGRAMS = $(TEST_PROGS) \
|
||||
testoffscreen \
|
||||
testoffscreenwindow \
|
||||
testorientable \
|
||||
testpicture \
|
||||
testprint \
|
||||
testrecentchooser \
|
||||
testrecentchoosermenu \
|
||||
@@ -167,6 +168,7 @@ testoffscreenwindow_DEPENDENCIES = $(TEST_DEPS)
|
||||
testappchooser_DEPENDENCIES = $(TEST_DEPS)
|
||||
testappchooserbutton_DEPENDENCIES = $(TEST_DEPS)
|
||||
testorientable_DEPENDENCIES = $(TEST_DEPS)
|
||||
testpicture_DEPENDENCIES = $(TEST_DEPS)
|
||||
testprint_DEPENDENCIES = $(TEST_DEPS)
|
||||
testrecentchooser_DEPENDENCIES = $(TEST_DEPS)
|
||||
testrecentchoosermenu_DEPENDENCIES = $(TEST_DEPS)
|
||||
@@ -249,6 +251,7 @@ testoffscreenwindow_LDADD = $(LDADDS)
|
||||
testappchooser_LDADD = $(LDADDS)
|
||||
testappchooserbutton_LDADD = $(LDADDS)
|
||||
testorientable_LDADD = $(LDADDS)
|
||||
testpicture_LDADD = $(LDADDS)
|
||||
testprint_LDADD = $(LDADDS)
|
||||
testrecentchooser_LDADD = $(LDADDS)
|
||||
testrecentchoosermenu_LDADD = $(LDADDS)
|
||||
|
784
tests/testpicture.c
Normal file
784
tests/testpicture.c
Normal file
@@ -0,0 +1,784 @@
|
||||
#include <gtk/gtk.h>
|
||||
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
|
||||
#define IMAGE_TYPE_PICTURE (image_picture_get_type ())
|
||||
#define IMAGE_PICTURE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), IMAGE_TYPE_PICTURE, ImagePicture))
|
||||
#define IMAGE_PICTURE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), IMAGE_TYPE_PICTURE, ImagePictureClass))
|
||||
#define IMAGE_IS_PICTURE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), IMAGE_TYPE_PICTURE))
|
||||
#define IMAGE_IS_PICTURE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), IMAGE_TYPE_PICTURE))
|
||||
#define IMAGE_PICTURE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), IMAGE_TYPE_PICTURE, ImagePictureClass))
|
||||
|
||||
typedef struct _ImagePicture ImagePicture;
|
||||
typedef GdkPictureClass ImagePictureClass;
|
||||
struct _ImagePicture {
|
||||
GdkPicture picture;
|
||||
cairo_surface_t *surface;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (ImagePicture, image_picture, GDK_TYPE_PICTURE)
|
||||
|
||||
static void
|
||||
image_picture_finalize (GObject *object)
|
||||
{
|
||||
cairo_surface_destroy (IMAGE_PICTURE (object)->surface);
|
||||
|
||||
G_OBJECT_CLASS (image_picture_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static cairo_surface_t *
|
||||
image_picture_ref_surface (GdkPicture *picture)
|
||||
{
|
||||
return cairo_surface_reference (IMAGE_PICTURE (picture)->surface);
|
||||
}
|
||||
|
||||
static void
|
||||
image_picture_class_init (ImagePictureClass *klass)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
||||
GdkPictureClass *picture_class = GDK_PICTURE_CLASS (klass);
|
||||
|
||||
object_class->finalize = image_picture_finalize;
|
||||
|
||||
picture_class->ref_surface = image_picture_ref_surface;
|
||||
}
|
||||
|
||||
static void
|
||||
image_picture_init (ImagePicture *picture)
|
||||
{
|
||||
picture->surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 100, 100);
|
||||
gdk_picture_resized (GDK_PICTURE (picture), 100, 100);
|
||||
}
|
||||
|
||||
static GdkPicture *
|
||||
image_picture_new (void)
|
||||
{
|
||||
return g_object_new (IMAGE_TYPE_PICTURE, NULL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define SLOW_TYPE_INPUT_STREAM (slow_input_stream_get_type ())
|
||||
#define SLOW_INPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SLOW_TYPE_INPUT_STREAM, SlowInputStream))
|
||||
#define SLOW_INPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), SLOW_TYPE_INPUT_STREAM, SlowInputStreamClass))
|
||||
#define SLOW_IS_INPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), SLOW_TYPE_INPUT_STREAM))
|
||||
#define SLOW_IS_INPUT_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), SLOW_TYPE_INPUT_STREAM))
|
||||
#define SLOW_INPUT_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), SLOW_TYPE_INPUT_STREAM, SlowInputStreamClass))
|
||||
|
||||
typedef GFilterInputStream SlowInputStream;
|
||||
typedef GFilterInputStreamClass SlowInputStreamClass;
|
||||
G_DEFINE_TYPE (SlowInputStream, slow_input_stream, G_TYPE_FILTER_INPUT_STREAM)
|
||||
|
||||
static gssize
|
||||
slow_input_stream_read (GInputStream *stream,
|
||||
void *buffer,
|
||||
gsize count,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
gssize result;
|
||||
|
||||
count = MIN (count, 100);
|
||||
|
||||
result = g_input_stream_read (g_filter_input_stream_get_base_stream (G_FILTER_INPUT_STREAM (stream)),
|
||||
buffer,
|
||||
count,
|
||||
cancellable,
|
||||
error);
|
||||
|
||||
if (result > 0)
|
||||
g_usleep (result * G_USEC_PER_SEC / 500);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
slow_input_stream_close (GInputStream *stream,
|
||||
GCancellable *cancellable,
|
||||
GError **error)
|
||||
{
|
||||
g_usleep (5 * G_USEC_PER_SEC);
|
||||
|
||||
return g_input_stream_close (g_filter_input_stream_get_base_stream (G_FILTER_INPUT_STREAM (stream)),
|
||||
cancellable,
|
||||
error);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
slow_input_stream_class_init (SlowInputStreamClass *klass)
|
||||
{
|
||||
GInputStreamClass *input_stream_class = G_INPUT_STREAM_CLASS (klass);
|
||||
|
||||
input_stream_class->read_fn = slow_input_stream_read;
|
||||
input_stream_class->close_fn = slow_input_stream_close;
|
||||
}
|
||||
|
||||
static void
|
||||
slow_input_stream_init (SlowInputStream *klass)
|
||||
{
|
||||
}
|
||||
|
||||
static GInputStream *
|
||||
slow_input_stream_new (GInputStream *base_stream)
|
||||
{
|
||||
return g_object_new (slow_input_stream_get_type (), "base-stream", base_stream, NULL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
typedef struct _Demo Demo;
|
||||
struct _Demo
|
||||
{
|
||||
const char *name;
|
||||
void (* create) (Demo *demo);
|
||||
GtkWidget *widget;
|
||||
GdkPicture *picture;
|
||||
GdkPicture *attached_picture;
|
||||
};
|
||||
|
||||
static void
|
||||
file_is_loaded_callback (GObject *object,
|
||||
GAsyncResult *res,
|
||||
gpointer user_data)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
slowly_load_file (Demo *demo, GFile *file)
|
||||
{
|
||||
GInputStream *file_stream, *load_stream;
|
||||
|
||||
file_stream = G_INPUT_STREAM (g_file_read (file, NULL, NULL));
|
||||
if (file_stream == NULL)
|
||||
return;
|
||||
load_stream = slow_input_stream_new (file_stream);
|
||||
gdk_picture_loader_load_from_stream_async (GDK_PICTURE_LOADER (demo->picture),
|
||||
load_stream,
|
||||
G_PRIORITY_DEFAULT,
|
||||
NULL,
|
||||
file_is_loaded_callback,
|
||||
demo);
|
||||
g_object_unref (file_stream);
|
||||
g_object_unref (load_stream);
|
||||
}
|
||||
|
||||
static void
|
||||
file_set_callback (GtkFileChooser *button,
|
||||
Demo *demo)
|
||||
{
|
||||
GFile *file = gtk_file_chooser_get_file (button);
|
||||
|
||||
if (file)
|
||||
slowly_load_file (demo, file);
|
||||
}
|
||||
|
||||
static void
|
||||
create_slowly_loading_image (Demo *demo)
|
||||
{
|
||||
GtkWidget *button, *image;
|
||||
GtkFileFilter *filter;
|
||||
GFile *default_file;
|
||||
|
||||
demo->widget = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
demo->picture = gdk_picture_loader_new ();
|
||||
|
||||
button = gtk_file_chooser_button_new ("Select file to slowly load",
|
||||
GTK_FILE_CHOOSER_ACTION_OPEN);
|
||||
gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (button), FALSE);
|
||||
filter = gtk_file_filter_new ();
|
||||
gtk_file_filter_add_pixbuf_formats (filter);
|
||||
gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (button), filter);
|
||||
default_file = g_file_new_for_path ("apple-red.png");
|
||||
gtk_file_chooser_set_file (GTK_FILE_CHOOSER (button),
|
||||
default_file, NULL);
|
||||
slowly_load_file (demo, default_file);
|
||||
g_object_unref (default_file);
|
||||
g_signal_connect (button,
|
||||
"file-set",
|
||||
G_CALLBACK (file_set_callback),
|
||||
demo);
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (demo->widget), button, TRUE, TRUE, 0);
|
||||
|
||||
image = gtk_image_new_from_picture (demo->picture);
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (demo->widget), image, TRUE, TRUE, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
create_animation (Demo *demo)
|
||||
{
|
||||
GdkPixbufAnimation *animation = gdk_pixbuf_animation_new_from_file ("1234.gif", NULL);
|
||||
|
||||
demo->widget = gtk_label_new ("bla");
|
||||
demo->picture = gdk_pixbuf_animation_picture_new (animation);
|
||||
|
||||
g_object_unref (animation);
|
||||
}
|
||||
|
||||
static void
|
||||
create_stock_picture (Demo *demo)
|
||||
{
|
||||
demo->widget = gtk_image_new_from_stock (GTK_STOCK_GOTO_FIRST, GTK_ICON_SIZE_BUTTON);
|
||||
gtk_widget_set_direction (demo->widget, GTK_TEXT_DIR_RTL);
|
||||
demo->picture = gtk_stock_picture_new (GTK_STOCK_GOTO_FIRST, GTK_ICON_SIZE_BUTTON);
|
||||
}
|
||||
|
||||
static void
|
||||
create_icon_set_picture (Demo *demo)
|
||||
{
|
||||
struct {
|
||||
const char *icon_name;
|
||||
GtkStateType state;
|
||||
} states[] = {
|
||||
{ GTK_STOCK_HOME, GTK_STATE_NORMAL },
|
||||
{ GTK_STOCK_APPLY, GTK_STATE_ACTIVE },
|
||||
{ GTK_STOCK_YES, GTK_STATE_PRELIGHT },
|
||||
{ GTK_STOCK_SELECT_ALL, GTK_STATE_SELECTED },
|
||||
{ GTK_STOCK_HELP, GTK_STATE_INSENSITIVE },
|
||||
{ GTK_STOCK_ABOUT, GTK_STATE_INCONSISTENT },
|
||||
{ GTK_STOCK_OK, GTK_STATE_FOCUSED }
|
||||
};
|
||||
GtkIconSet *set;
|
||||
GtkIconSource *source;
|
||||
guint i;
|
||||
|
||||
set = gtk_icon_set_new ();
|
||||
for (i = 0; i < G_N_ELEMENTS (states); i++)
|
||||
{
|
||||
source = gtk_icon_source_new ();
|
||||
gtk_icon_source_set_state (source, states[i].state);
|
||||
gtk_icon_source_set_state_wildcarded (source, FALSE);
|
||||
gtk_icon_source_set_icon_name (source, states[i].icon_name);
|
||||
gtk_icon_set_add_source (set, source);
|
||||
gtk_icon_source_free (source);
|
||||
}
|
||||
|
||||
demo->widget = gtk_label_new ("Shows a manually constructed icon set.\n"
|
||||
"It displays random stock icons fordifferent states.");
|
||||
|
||||
demo->picture = gtk_icon_set_picture_new (set, GTK_ICON_SIZE_BUTTON);
|
||||
|
||||
gtk_icon_set_unref (set);
|
||||
}
|
||||
|
||||
static void
|
||||
change_icon_theme_callback (GtkWidget *combo, GtkIconThemePicture *picture)
|
||||
{
|
||||
const char *theme_name = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT (combo));
|
||||
|
||||
if (theme_name == NULL || g_str_equal (theme_name, "") || g_str_equal (theme_name, "(default)"))
|
||||
{
|
||||
gtk_icon_theme_picture_set_icon_theme (picture, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
GtkIconTheme *icon_theme = gtk_icon_theme_new ();
|
||||
gtk_icon_theme_set_custom_theme (icon_theme, theme_name);
|
||||
gtk_icon_theme_picture_set_icon_theme (picture, icon_theme);
|
||||
g_object_unref (icon_theme);
|
||||
}
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
theme_selector_new (GdkPicture *picture)
|
||||
{
|
||||
GtkWidget *combo;
|
||||
GList *names, *walk;
|
||||
GtkIconTheme *icon_theme;
|
||||
char **paths;
|
||||
guint i;
|
||||
|
||||
icon_theme = gtk_icon_theme_new ();
|
||||
gtk_icon_theme_get_search_path (icon_theme, &paths, NULL);
|
||||
|
||||
combo = gtk_combo_box_text_new_with_entry ();
|
||||
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "(default)");
|
||||
gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 0);
|
||||
g_signal_connect (combo, "changed", G_CALLBACK (change_icon_theme_callback), picture);
|
||||
|
||||
names = NULL;
|
||||
|
||||
for (i = 0; paths[i]; i++)
|
||||
{
|
||||
GDir *dir = g_dir_open (paths[i], 0, NULL);
|
||||
const char *name;
|
||||
|
||||
if (dir == NULL)
|
||||
continue;
|
||||
|
||||
while ((name = g_dir_read_name (dir)))
|
||||
{
|
||||
char *full = g_build_filename (paths[i], name, "index.theme", NULL);
|
||||
|
||||
if (g_file_test (full, G_FILE_TEST_EXISTS))
|
||||
names = g_list_prepend (names, g_strdup (name));
|
||||
|
||||
g_free (full);
|
||||
}
|
||||
|
||||
g_dir_close (dir);
|
||||
}
|
||||
|
||||
names = g_list_sort (names, (GCompareFunc) strcmp);
|
||||
|
||||
for (walk = names; walk; walk = walk->next)
|
||||
{
|
||||
/* skip identical names */
|
||||
while (walk->next && g_str_equal (walk->data, walk->next->data))
|
||||
walk = walk->next;
|
||||
|
||||
gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), walk->data);
|
||||
}
|
||||
|
||||
g_list_free_full (names, g_free);
|
||||
g_strfreev (paths);
|
||||
g_object_unref (icon_theme);
|
||||
|
||||
return combo;
|
||||
}
|
||||
|
||||
static void
|
||||
create_gicon_picture (Demo *demo)
|
||||
{
|
||||
GIcon *icon = g_themed_icon_new ("folder");
|
||||
|
||||
demo->widget = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
demo->picture = gtk_icon_picture_new (icon, GTK_ICON_SIZE_BUTTON);
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (demo->widget), gtk_label_new ("Theme:"), FALSE, TRUE, 0);
|
||||
gtk_box_pack_start (GTK_BOX (demo->widget), theme_selector_new (demo->picture), FALSE, TRUE, 0);
|
||||
|
||||
g_object_unref (icon);
|
||||
}
|
||||
|
||||
static void
|
||||
update_icon_names (GtkNamedPicture *picture, GParamSpec *pspec, GtkComboBoxText *combo)
|
||||
{
|
||||
GList *names, *walk;
|
||||
GtkIconTheme *icon_theme;
|
||||
char *current;
|
||||
guint i;
|
||||
|
||||
icon_theme = gtk_icon_theme_picture_get_icon_theme (GTK_ICON_THEME_PICTURE (picture));
|
||||
if (icon_theme == NULL)
|
||||
icon_theme = gtk_icon_theme_get_default ();
|
||||
|
||||
names = gtk_icon_theme_list_icons (icon_theme, NULL);
|
||||
names = g_list_sort (names, (GCompareFunc) strcmp);
|
||||
|
||||
current = g_strdup (gtk_named_picture_get_name (picture));
|
||||
|
||||
gtk_combo_box_text_remove_all (combo);
|
||||
for (walk = names, i = 0; walk; walk = walk->next, i++)
|
||||
{
|
||||
gtk_combo_box_text_append_text (combo, walk->data);
|
||||
if (current && g_str_equal (walk->data, current))
|
||||
gtk_combo_box_set_active (GTK_COMBO_BOX (combo), i);
|
||||
}
|
||||
|
||||
g_list_free_full (names, g_free);
|
||||
g_free (current);
|
||||
}
|
||||
|
||||
static void
|
||||
change_icon_name_callback (GtkComboBoxText *combo, GtkNamedPicture *picture)
|
||||
{
|
||||
gtk_named_picture_set_name (picture, gtk_combo_box_text_get_active_text (combo));
|
||||
}
|
||||
|
||||
static GtkWidget *
|
||||
icon_name_selector_new (GdkPicture *picture)
|
||||
{
|
||||
GtkWidget *combo;
|
||||
|
||||
combo = gtk_combo_box_text_new_with_entry ();
|
||||
g_signal_connect (combo, "changed", G_CALLBACK (change_icon_name_callback), picture);
|
||||
|
||||
g_signal_connect (picture, "notify::icon-theme", G_CALLBACK (update_icon_names), combo);
|
||||
update_icon_names (GTK_NAMED_PICTURE (picture), NULL, GTK_COMBO_BOX_TEXT (combo));
|
||||
|
||||
return combo;
|
||||
}
|
||||
|
||||
static void
|
||||
create_icon_name_picture (Demo *demo)
|
||||
{
|
||||
demo->widget = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
demo->picture = gtk_named_picture_new ("window-new", GTK_ICON_SIZE_BUTTON);
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (demo->widget), gtk_label_new ("Theme:"), FALSE, TRUE, 0);
|
||||
gtk_box_pack_start (GTK_BOX (demo->widget), theme_selector_new (demo->picture), FALSE, TRUE, 0);
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (demo->widget), gtk_label_new ("Icon:"), FALSE, TRUE, 0);
|
||||
gtk_box_pack_start (GTK_BOX (demo->widget), icon_name_selector_new (demo->picture), FALSE, TRUE, 0);
|
||||
}
|
||||
|
||||
static GdkRGBA scribble_colors[2] =
|
||||
{
|
||||
{ 0.0, 0.0, 0.0, 1.0 },
|
||||
{ 0.0, 0.0, 0.0, 0.0 }
|
||||
};
|
||||
|
||||
/* Draw a rectangle onto the picture */
|
||||
static void
|
||||
scribble (ImagePicture * picture,
|
||||
gdouble x,
|
||||
gdouble y,
|
||||
const GdkRGBA *color)
|
||||
{
|
||||
GdkRectangle update_rect;
|
||||
cairo_t *cr;
|
||||
|
||||
update_rect.x = x - 3;
|
||||
update_rect.y = y - 3;
|
||||
update_rect.width = 6;
|
||||
update_rect.height = 6;
|
||||
|
||||
/* Paint to the surface, where we store our state */
|
||||
cr = cairo_create (picture->surface);
|
||||
|
||||
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
|
||||
gdk_cairo_set_source_rgba (cr, color);
|
||||
gdk_cairo_rectangle (cr, &update_rect);
|
||||
cairo_fill (cr);
|
||||
|
||||
cairo_destroy (cr);
|
||||
|
||||
/* Now invalidate the affected region of the drawing area. */
|
||||
gdk_picture_changed_rect (GDK_PICTURE (picture), &update_rect);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
scribble_button_press_event (GtkWidget *widget,
|
||||
GdkEventButton *event,
|
||||
ImagePicture *picture)
|
||||
{
|
||||
if (event->button == 1)
|
||||
scribble (picture, event->x, event->y, &scribble_colors[0]);
|
||||
else if (event->button == 3)
|
||||
scribble (picture, event->x, event->y, &scribble_colors[1]);
|
||||
|
||||
/* We've handled the event, stop processing */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
scribble_motion_notify_event (GtkWidget *widget,
|
||||
GdkEventMotion *event,
|
||||
ImagePicture *picture)
|
||||
{
|
||||
int x, y;
|
||||
GdkModifierType state;
|
||||
|
||||
/* This call is very important; it requests the next motion event.
|
||||
* If you don't call gdk_window_get_pointer() you'll only get
|
||||
* a single motion event. The reason is that we specified
|
||||
* GDK_POINTER_MOTION_HINT_MASK to gtk_widget_set_events().
|
||||
* If we hadn't specified that, we could just use event->x, event->y
|
||||
* as the pointer location. But we'd also get deluged in events.
|
||||
* By requesting the next event as we handle the current one,
|
||||
* we avoid getting a huge number of events faster than we
|
||||
* can cope.
|
||||
*/
|
||||
|
||||
gdk_window_get_pointer (event->window, &x, &y, &state);
|
||||
|
||||
if (state & GDK_BUTTON1_MASK)
|
||||
scribble (picture, x, y, &scribble_colors[0]);
|
||||
if (state & GDK_BUTTON3_MASK)
|
||||
scribble (picture, x, y, &scribble_colors[1]);
|
||||
|
||||
/* We've handled it, stop processing */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
create_scribble_area (Demo *demo)
|
||||
{
|
||||
GtkWidget *frame, *image, *eventbox;
|
||||
|
||||
demo->picture = image_picture_new ();
|
||||
|
||||
demo->widget = gtk_alignment_new (0.5, 0.5, 0, 0);
|
||||
|
||||
frame = gtk_frame_new (NULL);
|
||||
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
|
||||
gtk_container_add (GTK_CONTAINER (demo->widget), frame);
|
||||
|
||||
eventbox = gtk_event_box_new ();
|
||||
gtk_container_add (GTK_CONTAINER (frame), eventbox);
|
||||
|
||||
/* Event signals */
|
||||
|
||||
g_signal_connect (eventbox, "motion-notify-event",
|
||||
G_CALLBACK (scribble_motion_notify_event), demo->picture);
|
||||
g_signal_connect (eventbox, "button-press-event",
|
||||
G_CALLBACK (scribble_button_press_event), demo->picture);
|
||||
|
||||
/* Ask to receive events the drawing area doesn't normally
|
||||
* subscribe to
|
||||
*/
|
||||
gtk_widget_add_events (eventbox,
|
||||
GDK_BUTTON_PRESS_MASK
|
||||
| GDK_POINTER_MOTION_MASK
|
||||
| GDK_POINTER_MOTION_HINT_MASK);
|
||||
|
||||
image = gtk_image_new_from_picture (demo->picture);
|
||||
gtk_container_add (GTK_CONTAINER (eventbox), image);
|
||||
}
|
||||
|
||||
Demo demos[] = {
|
||||
{ "Slowly loading image", create_slowly_loading_image, NULL, NULL },
|
||||
{ "Animation", create_animation, NULL, NULL },
|
||||
{ "Named theme icons", create_stock_picture, NULL, NULL },
|
||||
{ "Icon Set", create_icon_set_picture, NULL, NULL },
|
||||
{ "GIcon", create_gicon_picture, NULL, NULL },
|
||||
{ "Named Icon", create_icon_name_picture, NULL, NULL },
|
||||
{ "Scribble Area", create_scribble_area, NULL, NULL }
|
||||
};
|
||||
|
||||
static guint rotation = 0;
|
||||
static guint rotation_source = 0;
|
||||
|
||||
static void
|
||||
get_picture_offset (GtkWidget *widget,
|
||||
guint i,
|
||||
double *offset_x,
|
||||
double *offset_y)
|
||||
{
|
||||
double rx, ry;
|
||||
|
||||
rx = (gtk_widget_get_allocated_width (widget) - gdk_picture_get_width (demos[i].attached_picture)) / 2.0;
|
||||
ry = (gtk_widget_get_allocated_height (widget) - gdk_picture_get_height (demos[i].attached_picture)) / 2.0;
|
||||
|
||||
*offset_x = gtk_widget_get_allocated_width (widget) / 2.0
|
||||
+ rx * sin (2 * G_PI * i / G_N_ELEMENTS (demos) + (2 * G_PI * rotation / 360))
|
||||
- gdk_picture_get_width (demos[i].attached_picture) / 2.0;
|
||||
*offset_y = gtk_widget_get_allocated_height (widget) / 2.0
|
||||
+ ry * cos (2 * G_PI * i / G_N_ELEMENTS (demos) + (2 * G_PI * rotation / 360))
|
||||
- gdk_picture_get_height (demos[i].attached_picture) / 2.0;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
draw_callback (GtkWidget *area,
|
||||
cairo_t *cr,
|
||||
gpointer unused)
|
||||
{
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (demos); i++)
|
||||
{
|
||||
double x, y;
|
||||
|
||||
get_picture_offset (area, i, &x, &y);
|
||||
|
||||
cairo_save (cr);
|
||||
|
||||
cairo_translate (cr, x, y);
|
||||
gdk_picture_draw (demos[i].attached_picture, cr);
|
||||
|
||||
cairo_restore (cr);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#define ROTATE_FPS 30
|
||||
#define ROTATE_SECONDS 6
|
||||
|
||||
static void
|
||||
area_invalidate_picture (GtkWidget *area, guint i, const cairo_region_t *region)
|
||||
{
|
||||
cairo_region_t *copy;
|
||||
double x, y;
|
||||
int dx, dy;
|
||||
|
||||
get_picture_offset (area, i, &x, &y);
|
||||
if (region)
|
||||
copy = cairo_region_copy (region);
|
||||
else
|
||||
{
|
||||
cairo_rectangle_int_t rect = { 0, 0,
|
||||
gdk_picture_get_width (demos[i].attached_picture),
|
||||
gdk_picture_get_height (demos[i].attached_picture) };
|
||||
copy = cairo_region_create_rectangle (&rect);
|
||||
}
|
||||
cairo_region_translate (copy, floor (x), floor (y));
|
||||
gtk_widget_queue_draw_region (area, copy);
|
||||
dx = (floor (x) != ceil (x)) ? 1 : 0;
|
||||
dy = (floor (y) != ceil (y)) ? 1 : 0;
|
||||
if (dx || dy)
|
||||
{
|
||||
cairo_region_translate (copy, dx, dy);
|
||||
gtk_widget_queue_draw_region (area, copy);
|
||||
}
|
||||
cairo_region_destroy (copy);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
rotate_area (gpointer area)
|
||||
{
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (demos); i++)
|
||||
area_invalidate_picture (area, i, NULL);
|
||||
|
||||
rotation += 360 / ROTATE_SECONDS / ROTATE_FPS;
|
||||
rotation %= 360;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (demos); i++)
|
||||
area_invalidate_picture (area, i, NULL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
rotation_toggled (GtkButton *button, GtkWidget *area)
|
||||
{
|
||||
if (rotation_source)
|
||||
{
|
||||
g_source_remove (rotation_source);
|
||||
rotation_source = 0;
|
||||
gtk_button_set_label (button, GTK_STOCK_MEDIA_PLAY);
|
||||
}
|
||||
else
|
||||
{
|
||||
rotation_source = gdk_threads_add_timeout (1000 / ROTATE_FPS, rotate_area, area);
|
||||
gtk_button_set_label (button, GTK_STOCK_MEDIA_PAUSE);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
picture_changed (GdkPicture *picture, const cairo_region_t *region, GtkWidget *area)
|
||||
{
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (demos); i++)
|
||||
{
|
||||
if (demos[i].attached_picture == picture)
|
||||
break;
|
||||
}
|
||||
g_assert (i < G_N_ELEMENTS (demos));
|
||||
|
||||
area_invalidate_picture (area, i, region);
|
||||
}
|
||||
|
||||
static void
|
||||
toggled_flag (GtkWidget *check, gpointer area)
|
||||
{
|
||||
int flag = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (check), "flags"));
|
||||
|
||||
if (flag)
|
||||
{
|
||||
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (check)))
|
||||
gtk_widget_set_state_flags (area, flag, FALSE);
|
||||
else
|
||||
gtk_widget_unset_state_flags (area, flag);
|
||||
}
|
||||
else
|
||||
gtk_widget_set_direction (area,
|
||||
gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (check)) ? GTK_TEXT_DIR_RTL :
|
||||
GTK_TEXT_DIR_LTR);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
create_optionsview (GtkWidget *area)
|
||||
{
|
||||
struct {
|
||||
GtkStateFlags flags;
|
||||
const char * text;
|
||||
} options[] = {
|
||||
{ 0, "right-to-left" },
|
||||
{ GTK_STATE_FLAG_ACTIVE, "active" },
|
||||
{ GTK_STATE_FLAG_PRELIGHT, "prelight" },
|
||||
{ GTK_STATE_FLAG_SELECTED, "selected" },
|
||||
{ GTK_STATE_FLAG_INSENSITIVE, "insensitive" },
|
||||
{ GTK_STATE_FLAG_INCONSISTENT, "inconsistent" },
|
||||
{ GTK_STATE_FLAG_FOCUSED, "focused" }
|
||||
};
|
||||
GtkWidget *box, *check;
|
||||
guint i;
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
for (i = 0; i < G_N_ELEMENTS (options); i++)
|
||||
{
|
||||
check = gtk_check_button_new_with_label (options[i].text);
|
||||
if (options[i].flags)
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check),
|
||||
gtk_widget_get_state_flags (area) & options[i].flags);
|
||||
else
|
||||
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check),
|
||||
gtk_widget_get_direction (area) == GTK_TEXT_DIR_RTL);
|
||||
g_object_set_data (G_OBJECT (check), "flags", GINT_TO_POINTER (options[i].flags));
|
||||
g_signal_connect (check, "toggled", G_CALLBACK (toggled_flag), area);
|
||||
gtk_box_pack_start (GTK_BOX (box), check, TRUE, TRUE, 0);
|
||||
}
|
||||
|
||||
return box;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
GtkWidget *window, *vbox, *hbox, *area, *widget;
|
||||
guint i;
|
||||
|
||||
gtk_init (&argc, &argv);
|
||||
|
||||
//gdk_window_set_debug_updates (TRUE);
|
||||
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_title (GTK_WINDOW (window), "Pictures");
|
||||
|
||||
g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
|
||||
|
||||
hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 8);
|
||||
gtk_container_add (GTK_CONTAINER (window), hbox);
|
||||
|
||||
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
|
||||
|
||||
area = gtk_drawing_area_new ();
|
||||
gtk_widget_set_size_request (area, 400, 400);
|
||||
g_signal_connect (area, "draw", G_CALLBACK (draw_callback), NULL);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), area, TRUE, TRUE, 0);
|
||||
|
||||
widget = gtk_button_new_from_stock (GTK_STOCK_MEDIA_PAUSE);
|
||||
g_signal_connect (widget, "clicked", G_CALLBACK (rotation_toggled), area);
|
||||
rotation_toggled (GTK_BUTTON (widget), area);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), widget, FALSE, TRUE, 0);
|
||||
|
||||
vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), vbox, FALSE, TRUE, 0);
|
||||
|
||||
widget = create_optionsview (area);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), widget, FALSE, TRUE, 0);
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (demos); i++)
|
||||
{
|
||||
GtkWidget *expander;
|
||||
|
||||
demos[i].create (&demos[i]);
|
||||
|
||||
demos[i].attached_picture = gtk_widget_style_picture (area, demos[i].picture);
|
||||
g_signal_connect (demos[i].attached_picture, "changed", G_CALLBACK (picture_changed), area);
|
||||
|
||||
expander = gtk_expander_new (demos[i].name);
|
||||
gtk_container_add (GTK_CONTAINER (expander), demos[i].widget);
|
||||
|
||||
gtk_box_pack_start (GTK_BOX (vbox), expander, FALSE, TRUE, 0);
|
||||
}
|
||||
|
||||
gtk_widget_show_all (window);
|
||||
|
||||
gtk_main ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user