From 9b7473b633833bb90603ed34464351d2ba3de385 Mon Sep 17 00:00:00 2001 From: Cosimo Cecchi Date: Mon, 21 Dec 2015 14:46:44 -0800 Subject: [PATCH] Introduce GtkIcon private class This is an utility widget that wraps a GtkBuiltinIcon for situations where using a real widget is more convenient than a gadget. --- gtk/Makefile.am | 2 + gtk/gtkicon.c | 223 +++++++++++++++++++++++++++++++++++++++++++ gtk/gtkiconprivate.h | 56 +++++++++++ 3 files changed, 281 insertions(+) create mode 100644 gtk/gtkicon.c create mode 100644 gtk/gtkiconprivate.h diff --git a/gtk/Makefile.am b/gtk/Makefile.am index 77f645d371..33eb9ccc7f 100644 --- a/gtk/Makefile.am +++ b/gtk/Makefile.am @@ -468,6 +468,7 @@ gtk_private_h_sources = \ gtkhslaprivate.h \ gtkiconcache.h \ gtkiconhelperprivate.h \ + gtkiconprivate.h \ gtkiconthemeprivate.h \ gtkiconviewprivate.h \ gtkimagedefinitionprivate.h \ @@ -741,6 +742,7 @@ gtk_base_c_sources = \ gtkgrid.c \ gtkheaderbar.c \ gtkhsla.c \ + gtkicon.c \ gtkiconcache.c \ gtkiconcachevalidator.c \ gtkiconhelper.c \ diff --git a/gtk/gtkicon.c b/gtk/gtkicon.c new file mode 100644 index 0000000000..06c19dc69f --- /dev/null +++ b/gtk/gtkicon.c @@ -0,0 +1,223 @@ + +/* + * Copyright © 2015 Endless Mobile, Inc. + * + * 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.1 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, see . + * + * Authors: Cosimo Cecchi + */ + +#include "config.h" + +#include "gtkbuiltiniconprivate.h" +#include "gtkcssnodeprivate.h" +#include "gtkiconprivate.h" +#include "gtkwidgetprivate.h" + +enum { + PROP_0, + PROP_CSS_NAME, + NUM_PROPERTIES +}; + +static GParamSpec *icon_props[NUM_PROPERTIES] = { NULL, }; + +typedef struct _GtkIconPrivate GtkIconPrivate; +struct _GtkIconPrivate { + GtkCssGadget *gadget; +}; + +G_DEFINE_TYPE_WITH_PRIVATE (GtkIcon, gtk_icon, GTK_TYPE_WIDGET) + +static void +gtk_icon_finalize (GObject *object) +{ + GtkIcon *self = GTK_ICON (object); + GtkIconPrivate *priv = gtk_icon_get_instance_private (self); + + g_clear_object (&priv->gadget); + + G_OBJECT_CLASS (gtk_icon_parent_class)->finalize (object); +} + +static void +gtk_icon_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + GtkIcon *self = GTK_ICON (object); + + switch (property_id) + { + case PROP_CSS_NAME: + g_value_set_string (value, gtk_icon_get_css_name (self)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +gtk_icon_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + GtkIcon *self = GTK_ICON (object); + + switch (property_id) + { + case PROP_CSS_NAME: + gtk_icon_set_css_name (self, g_value_get_string (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +gtk_icon_get_preferred_height_and_baseline_for_width (GtkWidget *widget, + gint for_width, + gint *minimum, + gint *natural, + gint *minimum_baseline, + gint *natural_baseline) +{ + GtkIcon *self = GTK_ICON (widget); + GtkIconPrivate *priv = gtk_icon_get_instance_private (self); + + gtk_css_gadget_get_preferred_size (priv->gadget, + GTK_ORIENTATION_VERTICAL, + for_width, + minimum, natural, + minimum_baseline, natural_baseline); +} + +static void +gtk_icon_get_preferred_height (GtkWidget *widget, + gint *minimum, + gint *natural) +{ + gtk_icon_get_preferred_height_and_baseline_for_width (widget, -1, + minimum, natural, + NULL, NULL); +} + +static void +gtk_icon_get_preferred_width (GtkWidget *widget, + gint *minimum, + gint *natural) +{ + GtkIcon *self = GTK_ICON (widget); + GtkIconPrivate *priv = gtk_icon_get_instance_private (self); + + gtk_css_gadget_get_preferred_size (priv->gadget, + GTK_ORIENTATION_HORIZONTAL, + -1, + minimum, natural, + NULL, NULL); +} + +static void +gtk_icon_size_allocate (GtkWidget *widget, + GtkAllocation *allocation) +{ + GtkIcon *self = GTK_ICON (widget); + GtkIconPrivate *priv = gtk_icon_get_instance_private (self); + GtkAllocation clip; + + gtk_widget_set_allocation (widget, allocation); + gtk_css_gadget_allocate (priv->gadget, allocation, + gtk_widget_get_allocated_baseline (widget), + &clip); + + gtk_widget_set_clip (widget, &clip); +} + +static gboolean +gtk_icon_draw (GtkWidget *widget, + cairo_t *cr) +{ + GtkIcon *self = GTK_ICON (widget); + GtkIconPrivate *priv = gtk_icon_get_instance_private (self); + + gtk_css_gadget_draw (priv->gadget, cr); + + return FALSE; +} + +static void +gtk_icon_class_init (GtkIconClass *klass) +{ + GObjectClass *oclass = G_OBJECT_CLASS (klass); + GtkWidgetClass *wclass = GTK_WIDGET_CLASS (klass); + + oclass->get_property = gtk_icon_get_property; + oclass->set_property = gtk_icon_set_property; + oclass->finalize = gtk_icon_finalize; + + wclass->size_allocate = gtk_icon_size_allocate; + wclass->get_preferred_width = gtk_icon_get_preferred_width; + wclass->get_preferred_height = gtk_icon_get_preferred_height; + wclass->get_preferred_height_and_baseline_for_width = gtk_icon_get_preferred_height_and_baseline_for_width; + wclass->draw = gtk_icon_draw; + + icon_props[PROP_CSS_NAME] = + g_param_spec_string ("css-name", "CSS name", + "CSS name", + NULL, + G_PARAM_READWRITE | + G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (oclass, NUM_PROPERTIES, icon_props); +} + +static void +gtk_icon_init (GtkIcon *self) +{ + GtkWidget *widget = GTK_WIDGET (self); + GtkIconPrivate *priv = gtk_icon_get_instance_private (self); + GtkCssNode *widget_node; + + gtk_widget_set_has_window (widget, FALSE); + + widget_node = gtk_widget_get_css_node (widget); + priv->gadget = gtk_builtin_icon_new_for_node (widget_node, widget); +} + +GtkWidget * +gtk_icon_new (const char *css_name) +{ + return g_object_new (GTK_TYPE_ICON, + "css-name", css_name, + NULL); +} + +const char * +gtk_icon_get_css_name (GtkIcon *self) +{ + GtkCssNode *widget_node = gtk_widget_get_css_node (GTK_WIDGET (self)); + return gtk_css_node_get_name (widget_node); +} + +void +gtk_icon_set_css_name (GtkIcon *self, + const char *css_name) +{ + GtkCssNode *widget_node = gtk_widget_get_css_node (GTK_WIDGET (self)); + gtk_css_node_set_name (widget_node, g_intern_string (css_name)); +} diff --git a/gtk/gtkiconprivate.h b/gtk/gtkiconprivate.h new file mode 100644 index 0000000000..08f8b0f33b --- /dev/null +++ b/gtk/gtkiconprivate.h @@ -0,0 +1,56 @@ +/* + * Copyright © 2015 Endless Mobile, Inc. + * + * 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.1 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, see . + * + * Authors: Cosimo Cecchi + */ + +#ifndef __GTK_ICON_PRIVATE_H__ +#define __GTK_ICON_PRIVATE_H__ + +#include "gtk/gtkwidget.h" + +G_BEGIN_DECLS + +#define GTK_TYPE_ICON (gtk_icon_get_type ()) +#define GTK_ICON(obj) (G_TYPE_CHECK_INSTANCE_CAST (obj, GTK_TYPE_ICON, GtkIcon)) +#define GTK_ICON_CLASS(cls) (G_TYPE_CHECK_CLASS_CAST (cls, GTK_TYPE_ICON, GtkIconClass)) +#define GTK_IS_ICON(obj) (G_TYPE_CHECK_INSTANCE_TYPE (obj, GTK_TYPE_ICON)) +#define GTK_IS_ICON_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE (obj, GTK_TYPE_ICON)) +#define GTK_ICON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_ICON, GtkIconClass)) + +typedef struct _GtkIcon GtkIcon; +typedef struct _GtkIconClass GtkIconClass; + +struct _GtkIcon +{ + GtkWidget parent; +}; + +struct _GtkIconClass +{ + GtkWidgetClass parent_class; +}; + +GType gtk_icon_get_type (void) G_GNUC_CONST; + +GtkWidget * gtk_icon_new (const char *css_name); +const char * gtk_icon_get_css_name (GtkIcon *icon); +void gtk_icon_set_css_name (GtkIcon *icon, + const char *css_name); + +G_END_DECLS + +#endif /* __GTK_ICON_PRIVATE_H__ */