From 36653bea4189221c1b3d391890793f50fde3c758 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Wed, 16 Dec 2015 18:44:58 +0100 Subject: [PATCH] checkbutton: Use a builtin icon Also, add support to uiltin icons to look up the default size from a style property. --- gtk/gtkbuiltinicon.c | 72 ++++++++++++++++++++++-- gtk/gtkbuiltiniconprivate.h | 3 + gtk/gtkcheckbutton.c | 107 +++++++----------------------------- 3 files changed, 90 insertions(+), 92 deletions(-) diff --git a/gtk/gtkbuiltinicon.c b/gtk/gtkbuiltinicon.c index 9c497c4d1d..71a44f6c26 100644 --- a/gtk/gtkbuiltinicon.c +++ b/gtk/gtkbuiltinicon.c @@ -29,6 +29,7 @@ typedef struct _GtkBuiltinIconPrivate GtkBuiltinIconPrivate; struct _GtkBuiltinIconPrivate { GtkCssImageBuiltinType image_type; int default_size; + char * default_size_property; }; G_DEFINE_TYPE_WITH_CODE (GtkBuiltinIcon, gtk_builtin_icon, GTK_TYPE_CSS_GADGET, @@ -58,6 +59,21 @@ gtk_builtin_icon_get_preferred_size (GtkCssGadget *gadget, return; } + if (priv->default_size_property) + { + GValue value = G_VALUE_INIT; + + /* Do it a bit more complicated here so we get warnings when + * somebody sets a non-int proerty. */ + g_value_init (&value, G_TYPE_INT); + gtk_widget_style_get_property (gtk_css_gadget_get_owner (gadget), + priv->default_size_property, + &value); + *minimum = *natural = g_value_get_int (&value); + g_value_unset (&value); + return; + } + *minimum = priv->default_size; *natural = priv->default_size; } @@ -81,11 +97,11 @@ gtk_builtin_icon_allocate (GtkCssGadget *gadget, static gboolean gtk_builtin_icon_draw (GtkCssGadget *gadget, - cairo_t *cr, - int x, - int y, - int width, - int height) + cairo_t *cr, + int x, + int y, + int width, + int height) { GtkBuiltinIconPrivate *priv = gtk_builtin_icon_get_instance_private (GTK_BUILTIN_ICON (gadget)); @@ -101,7 +117,9 @@ gtk_builtin_icon_draw (GtkCssGadget *gadget, static void gtk_builtin_icon_finalize (GObject *object) { - //GtkBuiltinIconPrivate *priv = gtk_builtin_icon_get_instance_private (GTK_BUILTIN_ICON (object)); + GtkBuiltinIconPrivate *priv = gtk_builtin_icon_get_instance_private (GTK_BUILTIN_ICON (object)); + + g_free (priv->default_size_property); G_OBJECT_CLASS (gtk_builtin_icon_parent_class)->finalize (object); } @@ -215,3 +233,45 @@ gtk_builtin_icon_get_default_size (GtkBuiltinIcon *icon) return priv->default_size; } +/** + * gtk_builtin_icon_set_default_size_property: + * @icon: icon to set the property for + * @property_name: Name of the style property + * + * Sets the name of a widget style property to use to compute the default size + * of the icon. If it is set to no %NULL, it will be used instead of the value + * set via gtk_builtin_icon_set_default_size() to set the default size of the + * icon. + * + * @property_name must refer to a style property that is of integer type. + * + * This function is intended strictly for backwards compatibility reasons. + */ +void +gtk_builtin_icon_set_default_size_property (GtkBuiltinIcon *icon, + const char *property_name) +{ + GtkBuiltinIconPrivate *priv; + + g_return_if_fail (GTK_IS_BUILTIN_ICON (icon)); + + priv = gtk_builtin_icon_get_instance_private (icon); + + if (g_strcmp0 (priv->default_size_property, property_name)) + { + priv->default_size_property = g_strdup (property_name); + gtk_widget_queue_resize (gtk_css_gadget_get_owner (GTK_CSS_GADGET (icon))); + } +} + +const char * +gtk_builtin_icon_get_default_size_property (GtkBuiltinIcon *icon) +{ + GtkBuiltinIconPrivate *priv; + + g_return_val_if_fail (GTK_IS_BUILTIN_ICON (icon), GTK_CSS_IMAGE_BUILTIN_NONE); + + priv = gtk_builtin_icon_get_instance_private (icon); + + return priv->default_size_property; +} diff --git a/gtk/gtkbuiltiniconprivate.h b/gtk/gtkbuiltiniconprivate.h index 5da73ef50e..7aa7e35b9b 100644 --- a/gtk/gtkbuiltiniconprivate.h +++ b/gtk/gtkbuiltiniconprivate.h @@ -59,6 +59,9 @@ GtkCssImageBuiltinType gtk_builtin_icon_get_image (GtkBuiltinIcon void gtk_builtin_icon_set_default_size (GtkBuiltinIcon *icon, int default_size); int gtk_builtin_icon_get_default_size (GtkBuiltinIcon *icon); +void gtk_builtin_icon_set_default_size_property (GtkBuiltinIcon *icon, + const char *property_name); +const char * gtk_builtin_icon_get_default_size_property (GtkBuiltinIcon *icon); G_END_DECLS diff --git a/gtk/gtkcheckbutton.c b/gtk/gtkcheckbutton.c index 95a58629b1..0dec2ad16c 100644 --- a/gtk/gtkcheckbutton.c +++ b/gtk/gtkcheckbutton.c @@ -33,6 +33,7 @@ #include "gtkprivate.h" #include "gtkrender.h" #include "gtkwidgetprivate.h" +#include "gtkbuiltiniconprivate.h" #include "gtkcssnodeprivate.h" #include "gtkcsscustomgadgetprivate.h" #include "gtkcontainerprivate.h" @@ -128,21 +129,6 @@ static gboolean gtk_check_button_render (GtkCssGadget *gadget, int width, int height, gpointer data); -static void gtk_check_button_measure_check (GtkCssGadget *gadget, - GtkOrientation orientation, - int for_size, - int *minimum, - int *natural, - int *minimum_baseline, - int *natural_baseline, - gpointer unused); -static gboolean gtk_check_button_render_check (GtkCssGadget *gadget, - cairo_t *cr, - int x, - int y, - int width, - int height, - gpointer data); typedef struct { GtkCssGadget *gadget; @@ -156,8 +142,22 @@ gtk_check_button_state_flags_changed (GtkWidget *widget, GtkStateFlags previous_state_flags) { GtkCheckButtonPrivate *priv = gtk_check_button_get_instance_private (GTK_CHECK_BUTTON (widget)); + GtkCssImageBuiltinType image_type; + GtkStateFlags state; - gtk_css_node_set_state (gtk_css_gadget_get_node (priv->indicator_gadget), gtk_widget_get_state_flags (widget)); + state = gtk_widget_get_state_flags (widget); + + /* XXX: This is soimewhat awkward here, but there's no better + * way to update the icon */ + if (state & GTK_STATE_FLAG_CHECKED) + image_type = GTK_IS_RADIO_BUTTON (widget) ? GTK_CSS_IMAGE_BUILTIN_OPTION_CHECKED : GTK_CSS_IMAGE_BUILTIN_CHECK_CHECKED; + else if (state & GTK_STATE_FLAG_INCONSISTENT) + image_type = GTK_IS_RADIO_BUTTON (widget) ? GTK_CSS_IMAGE_BUILTIN_OPTION_INCONSISTENT : GTK_CSS_IMAGE_BUILTIN_CHECK_INCONSISTENT; + else + image_type = GTK_IS_RADIO_BUTTON (widget) ? GTK_CSS_IMAGE_BUILTIN_OPTION : GTK_CSS_IMAGE_BUILTIN_CHECK; + gtk_builtin_icon_set_image (GTK_BUILTIN_ICON (priv->indicator_gadget), image_type); + + gtk_css_node_set_state (gtk_css_gadget_get_node (priv->indicator_gadget), state); GTK_WIDGET_CLASS (gtk_check_button_parent_class)->state_flags_changed (widget, previous_state_flags); } @@ -321,15 +321,11 @@ gtk_check_button_init (GtkCheckButton *check_button) NULL, NULL); - priv->indicator_gadget = gtk_css_custom_gadget_new ("check", - GTK_WIDGET (check_button), - priv->gadget, - NULL, - gtk_check_button_measure_check, - NULL, - gtk_check_button_render_check, - NULL, - NULL); + priv->indicator_gadget = gtk_builtin_icon_new ("check", + GTK_WIDGET (check_button), + priv->gadget, + NULL); + gtk_builtin_icon_set_default_size_property (GTK_BUILTIN_ICON (priv->indicator_gadget), "indicator-size"); } /** @@ -519,36 +515,6 @@ gtk_check_button_measure (GtkCssGadget *gadget, } } -static void -gtk_check_button_measure_check (GtkCssGadget *gadget, - GtkOrientation orientation, - int for_size, - int *minimum, - int *natural, - int *minimum_baseline, - int *natural_baseline, - gpointer unused) -{ - gdouble min_size; - guint property; - - if (orientation == GTK_ORIENTATION_HORIZONTAL) - property = GTK_CSS_PROPERTY_MIN_WIDTH; - else - property = GTK_CSS_PROPERTY_MIN_HEIGHT; - - min_size = _gtk_css_number_value_get (gtk_css_style_get_value (gtk_css_gadget_get_style (gadget), property), 100); - if (min_size > 0.0) - *minimum = *natural = 0; - else - { - gtk_widget_style_get (gtk_css_gadget_get_owner (gadget), - "indicator-size", minimum, - NULL); - *natural = *minimum; - } -} - static void gtk_check_button_get_preferred_width_for_height (GtkWidget *widget, gint height, @@ -799,37 +765,6 @@ gtk_check_button_draw_indicator (GtkCheckButton *check_button, gtk_css_gadget_draw (priv->indicator_gadget, cr); } -static gboolean -gtk_check_button_render_check (GtkCssGadget *gadget, - cairo_t *cr, - int x, - int y, - int width, - int height, - gpointer data) -{ - GtkWidget *widget; - GtkStyleContext *context; - GtkCheckButtonPrivate *priv; - GtkCssNode *css_node; - - widget = gtk_css_gadget_get_owner (gadget); - priv = gtk_check_button_get_instance_private (GTK_CHECK_BUTTON (widget)); - context = gtk_widget_get_style_context (widget); - - css_node = gtk_css_gadget_get_node (priv->indicator_gadget); - gtk_style_context_save_to_node (context, css_node); - - if (strcmp (gtk_css_node_get_name (css_node), "check") == 0) - gtk_render_check (context, cr, x, y, width, height); - else - gtk_render_option (context, cr, x, y, width, height); - - gtk_style_context_restore (context); - - return FALSE; -} - GtkCssNode * gtk_check_button_get_indicator_node (GtkCheckButton *check_button) {