checkbutton: Use a builtin icon

Also, add support to uiltin icons to look up the default size from a
style property.
This commit is contained in:
Benjamin Otte 2015-12-16 18:44:58 +01:00
parent abbd6b11f6
commit 36653bea41
3 changed files with 90 additions and 92 deletions

View File

@ -29,6 +29,7 @@ typedef struct _GtkBuiltinIconPrivate GtkBuiltinIconPrivate;
struct _GtkBuiltinIconPrivate { struct _GtkBuiltinIconPrivate {
GtkCssImageBuiltinType image_type; GtkCssImageBuiltinType image_type;
int default_size; int default_size;
char * default_size_property;
}; };
G_DEFINE_TYPE_WITH_CODE (GtkBuiltinIcon, gtk_builtin_icon, GTK_TYPE_CSS_GADGET, 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; 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; *minimum = priv->default_size;
*natural = priv->default_size; *natural = priv->default_size;
} }
@ -81,11 +97,11 @@ gtk_builtin_icon_allocate (GtkCssGadget *gadget,
static gboolean static gboolean
gtk_builtin_icon_draw (GtkCssGadget *gadget, gtk_builtin_icon_draw (GtkCssGadget *gadget,
cairo_t *cr, cairo_t *cr,
int x, int x,
int y, int y,
int width, int width,
int height) int height)
{ {
GtkBuiltinIconPrivate *priv = gtk_builtin_icon_get_instance_private (GTK_BUILTIN_ICON (gadget)); GtkBuiltinIconPrivate *priv = gtk_builtin_icon_get_instance_private (GTK_BUILTIN_ICON (gadget));
@ -101,7 +117,9 @@ gtk_builtin_icon_draw (GtkCssGadget *gadget,
static void static void
gtk_builtin_icon_finalize (GObject *object) 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); 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; 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;
}

View File

@ -59,6 +59,9 @@ GtkCssImageBuiltinType gtk_builtin_icon_get_image (GtkBuiltinIcon
void gtk_builtin_icon_set_default_size (GtkBuiltinIcon *icon, void gtk_builtin_icon_set_default_size (GtkBuiltinIcon *icon,
int default_size); int default_size);
int gtk_builtin_icon_get_default_size (GtkBuiltinIcon *icon); 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 G_END_DECLS

View File

@ -33,6 +33,7 @@
#include "gtkprivate.h" #include "gtkprivate.h"
#include "gtkrender.h" #include "gtkrender.h"
#include "gtkwidgetprivate.h" #include "gtkwidgetprivate.h"
#include "gtkbuiltiniconprivate.h"
#include "gtkcssnodeprivate.h" #include "gtkcssnodeprivate.h"
#include "gtkcsscustomgadgetprivate.h" #include "gtkcsscustomgadgetprivate.h"
#include "gtkcontainerprivate.h" #include "gtkcontainerprivate.h"
@ -128,21 +129,6 @@ static gboolean gtk_check_button_render (GtkCssGadget *gadget,
int width, int width,
int height, int height,
gpointer data); 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 { typedef struct {
GtkCssGadget *gadget; GtkCssGadget *gadget;
@ -156,8 +142,22 @@ gtk_check_button_state_flags_changed (GtkWidget *widget,
GtkStateFlags previous_state_flags) GtkStateFlags previous_state_flags)
{ {
GtkCheckButtonPrivate *priv = gtk_check_button_get_instance_private (GTK_CHECK_BUTTON (widget)); 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); 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,
NULL); NULL);
priv->indicator_gadget = gtk_css_custom_gadget_new ("check", priv->indicator_gadget = gtk_builtin_icon_new ("check",
GTK_WIDGET (check_button), GTK_WIDGET (check_button),
priv->gadget, priv->gadget,
NULL, NULL);
gtk_check_button_measure_check, gtk_builtin_icon_set_default_size_property (GTK_BUILTIN_ICON (priv->indicator_gadget), "indicator-size");
NULL,
gtk_check_button_render_check,
NULL,
NULL);
} }
/** /**
@ -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 static void
gtk_check_button_get_preferred_width_for_height (GtkWidget *widget, gtk_check_button_get_preferred_width_for_height (GtkWidget *widget,
gint height, gint height,
@ -799,37 +765,6 @@ gtk_check_button_draw_indicator (GtkCheckButton *check_button,
gtk_css_gadget_draw (priv->indicator_gadget, cr); 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 * GtkCssNode *
gtk_check_button_get_indicator_node (GtkCheckButton *check_button) gtk_check_button_get_indicator_node (GtkCheckButton *check_button)
{ {