diff options
author | Benjamin Otte <otte@redhat.com> | 2011-02-09 19:42:55 +0100 |
---|---|---|
committer | Benjamin Otte <otte@redhat.com> | 2011-02-14 19:33:03 +0100 |
commit | 5f230589bbe1651db86727348fbd50f9deaef6a4 (patch) | |
tree | e1ac5258f606725931550ca9416926f535cf1a9f | |
parent | 1d927e872eb194da2a5ad9c65dfa47d0b63eb495 (diff) | |
download | gtk+-5f230589bbe1651db86727348fbd50f9deaef6a4.tar.gz |
gtk: Add a private GtkStyledPicture
It's supposed to handle our use cases for styling. And it's better to
write this code only once after all.
-rw-r--r-- | gtk/Makefile.am | 2 | ||||
-rw-r--r-- | gtk/gtkstyledpicture.c | 287 | ||||
-rw-r--r-- | gtk/gtkstyledpicture.h | 65 |
3 files changed, 354 insertions, 0 deletions
diff --git a/gtk/Makefile.am b/gtk/Makefile.am index 299bc5782b..588ef48bfa 100644 --- a/gtk/Makefile.am +++ b/gtk/Makefile.am @@ -428,6 +428,7 @@ gtk_private_h_sources = \ gtksizegroup-private.h \ gtksocketprivate.h \ gtkstylecontextprivate.h \ + gtkstyledpicture.h \ gtktextbtree.h \ gtktextbufferserialize.h \ gtktextchildprivate.h \ @@ -625,6 +626,7 @@ gtk_base_c_sources = \ gtkstock.c \ gtkstylablepicture.c \ gtkstylecontext.c \ + gtkstyledpicture.c \ gtkstyleproperties.c \ gtkstyleprovider.c \ gtkstyle.c \ diff --git a/gtk/gtkstyledpicture.c b/gtk/gtkstyledpicture.c new file mode 100644 index 0000000000..c7c8976ae3 --- /dev/null +++ b/gtk/gtkstyledpicture.c @@ -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; +} + diff --git a/gtk/gtkstyledpicture.h b/gtk/gtkstyledpicture.h new file mode 100644 index 0000000000..0fa2e6ced5 --- /dev/null +++ b/gtk/gtkstyledpicture.h @@ -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__ */ |