forked from AuroraMiddleware/gtk
checkbutton: Use a box gadget
Now that builtin icons have a baseline, we can just use a box gadget with baseline alignment for the indicator and the label.
This commit is contained in:
parent
da30858ee4
commit
7859f8ee91
@ -35,7 +35,7 @@
|
|||||||
#include "gtkwidgetprivate.h"
|
#include "gtkwidgetprivate.h"
|
||||||
#include "gtkbuiltiniconprivate.h"
|
#include "gtkbuiltiniconprivate.h"
|
||||||
#include "gtkcssnodeprivate.h"
|
#include "gtkcssnodeprivate.h"
|
||||||
#include "gtkcsscustomgadgetprivate.h"
|
#include "gtkboxgadgetprivate.h"
|
||||||
#include "gtkcontainerprivate.h"
|
#include "gtkcontainerprivate.h"
|
||||||
#include "gtkstylecontextprivate.h"
|
#include "gtkstylecontextprivate.h"
|
||||||
#include "gtkcssnumbervalueprivate.h"
|
#include "gtkcssnumbervalueprivate.h"
|
||||||
@ -106,29 +106,6 @@ static void gtk_check_button_size_allocate (GtkWidget *widget,
|
|||||||
GtkAllocation *allocation);
|
GtkAllocation *allocation);
|
||||||
static gboolean gtk_check_button_draw (GtkWidget *widget,
|
static gboolean gtk_check_button_draw (GtkWidget *widget,
|
||||||
cairo_t *cr);
|
cairo_t *cr);
|
||||||
static void gtk_check_button_draw_indicator (GtkCheckButton *check_button,
|
|
||||||
cairo_t *cr);
|
|
||||||
|
|
||||||
static void gtk_check_button_measure (GtkCssGadget *gadget,
|
|
||||||
GtkOrientation orientation,
|
|
||||||
int for_size,
|
|
||||||
int *minimum,
|
|
||||||
int *natural,
|
|
||||||
int *minimum_baseline,
|
|
||||||
int *natural_baseline,
|
|
||||||
gpointer unused);
|
|
||||||
static void gtk_check_button_allocate (GtkCssGadget *gadget,
|
|
||||||
const GtkAllocation *allocation,
|
|
||||||
int baseline,
|
|
||||||
GtkAllocation *out_clip,
|
|
||||||
gpointer unused);
|
|
||||||
static gboolean gtk_check_button_render (GtkCssGadget *gadget,
|
|
||||||
cairo_t *cr,
|
|
||||||
int x,
|
|
||||||
int y,
|
|
||||||
int width,
|
|
||||||
int height,
|
|
||||||
gpointer data);
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
GtkCssGadget *gadget;
|
GtkCssGadget *gadget;
|
||||||
@ -206,11 +183,34 @@ gtk_check_button_finalize (GObject *object)
|
|||||||
G_OBJECT_CLASS (gtk_check_button_parent_class)->finalize (object);
|
G_OBJECT_CLASS (gtk_check_button_parent_class)->finalize (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gtk_check_button_add (GtkContainer *container,
|
||||||
|
GtkWidget *widget)
|
||||||
|
{
|
||||||
|
GtkCheckButtonPrivate *priv = gtk_check_button_get_instance_private (GTK_CHECK_BUTTON (container));
|
||||||
|
|
||||||
|
GTK_CONTAINER_CLASS (gtk_check_button_parent_class)->add (container, widget);
|
||||||
|
|
||||||
|
gtk_box_gadget_insert_widget (GTK_BOX_GADGET (priv->gadget), 1, widget);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gtk_check_button_remove (GtkContainer *container,
|
||||||
|
GtkWidget *widget)
|
||||||
|
{
|
||||||
|
GtkCheckButtonPrivate *priv = gtk_check_button_get_instance_private (GTK_CHECK_BUTTON (container));
|
||||||
|
|
||||||
|
gtk_box_gadget_remove_widget (GTK_BOX_GADGET (priv->gadget), widget);
|
||||||
|
|
||||||
|
GTK_CONTAINER_CLASS (gtk_check_button_parent_class)->remove (container, widget);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gtk_check_button_class_init (GtkCheckButtonClass *class)
|
gtk_check_button_class_init (GtkCheckButtonClass *class)
|
||||||
{
|
{
|
||||||
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
||||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
|
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
|
||||||
|
GtkContainerClass *container_class = GTK_CONTAINER_CLASS (class);
|
||||||
|
|
||||||
object_class->finalize = gtk_check_button_finalize;
|
object_class->finalize = gtk_check_button_finalize;
|
||||||
|
|
||||||
@ -224,6 +224,9 @@ gtk_check_button_class_init (GtkCheckButtonClass *class)
|
|||||||
widget_class->state_flags_changed = gtk_check_button_state_flags_changed;
|
widget_class->state_flags_changed = gtk_check_button_state_flags_changed;
|
||||||
widget_class->direction_changed = gtk_check_button_direction_changed;
|
widget_class->direction_changed = gtk_check_button_direction_changed;
|
||||||
|
|
||||||
|
container_class->add = gtk_check_button_add;
|
||||||
|
container_class->remove = gtk_check_button_remove;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GtkCheckButton:indicator-size:
|
* GtkCheckButton:indicator-size:
|
||||||
*
|
*
|
||||||
@ -321,19 +324,14 @@ gtk_check_button_init (GtkCheckButton *check_button)
|
|||||||
gtk_style_context_remove_class (gtk_widget_get_style_context (GTK_WIDGET (check_button)), "toggle");
|
gtk_style_context_remove_class (gtk_widget_get_style_context (GTK_WIDGET (check_button)), "toggle");
|
||||||
|
|
||||||
widget_node = gtk_widget_get_css_node (GTK_WIDGET (check_button));
|
widget_node = gtk_widget_get_css_node (GTK_WIDGET (check_button));
|
||||||
priv->gadget = gtk_css_custom_gadget_new_for_node (widget_node,
|
priv->gadget = gtk_box_gadget_new_for_node (widget_node, GTK_WIDGET (check_button));
|
||||||
GTK_WIDGET (check_button),
|
gtk_box_gadget_set_orientation (GTK_BOX_GADGET (priv->gadget), GTK_ORIENTATION_HORIZONTAL);
|
||||||
gtk_check_button_measure,
|
|
||||||
gtk_check_button_allocate,
|
|
||||||
gtk_check_button_render,
|
|
||||||
NULL,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
priv->indicator_gadget = gtk_builtin_icon_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_builtin_icon_set_default_size_property (GTK_BUILTIN_ICON (priv->indicator_gadget), "indicator-size");
|
gtk_builtin_icon_set_default_size_property (GTK_BUILTIN_ICON (priv->indicator_gadget), "indicator-size");
|
||||||
|
gtk_box_gadget_insert_gadget (GTK_BOX_GADGET (priv->gadget), 0, priv->indicator_gadget, FALSE, FALSE, GTK_ALIGN_BASELINE);
|
||||||
|
|
||||||
gtk_check_button_update_node_state (GTK_WIDGET (check_button));
|
gtk_check_button_update_node_state (GTK_WIDGET (check_button));
|
||||||
}
|
}
|
||||||
@ -386,145 +384,6 @@ gtk_check_button_new_with_mnemonic (const gchar *label)
|
|||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
|
||||||
gtk_check_button_render (GtkCssGadget *gadget,
|
|
||||||
cairo_t *cr,
|
|
||||||
int x,
|
|
||||||
int y,
|
|
||||||
int width,
|
|
||||||
int height,
|
|
||||||
gpointer data)
|
|
||||||
{
|
|
||||||
GtkWidget *widget;
|
|
||||||
GtkWidget *child;
|
|
||||||
|
|
||||||
widget = gtk_css_gadget_get_owner (gadget);
|
|
||||||
|
|
||||||
gtk_check_button_draw_indicator (GTK_CHECK_BUTTON (widget), cr);
|
|
||||||
|
|
||||||
child = gtk_bin_get_child (GTK_BIN (widget));
|
|
||||||
if (child)
|
|
||||||
gtk_container_propagate_draw (GTK_CONTAINER (widget), child, cr);
|
|
||||||
|
|
||||||
if (gtk_widget_has_visible_focus (widget))
|
|
||||||
{
|
|
||||||
GtkWidget *child = gtk_bin_get_child (GTK_BIN (widget));
|
|
||||||
GtkStyleContext *context;
|
|
||||||
GtkAllocation allocation;
|
|
||||||
|
|
||||||
gtk_widget_get_allocation (widget, &allocation);
|
|
||||||
context = gtk_widget_get_style_context (widget);
|
|
||||||
|
|
||||||
if (child && gtk_widget_get_visible (child))
|
|
||||||
{
|
|
||||||
GtkAllocation child_allocation;
|
|
||||||
|
|
||||||
gtk_widget_get_allocation (child, &child_allocation);
|
|
||||||
gtk_render_focus (context, cr,
|
|
||||||
child_allocation.x - allocation.x,
|
|
||||||
child_allocation.y - allocation.y,
|
|
||||||
child_allocation.width,
|
|
||||||
child_allocation.height);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
gtk_render_focus (context, cr, x, y, width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gtk_check_button_measure (GtkCssGadget *gadget,
|
|
||||||
GtkOrientation orientation,
|
|
||||||
int for_size,
|
|
||||||
int *minimum,
|
|
||||||
int *natural,
|
|
||||||
int *minimum_baseline,
|
|
||||||
int *natural_baseline,
|
|
||||||
gpointer unused)
|
|
||||||
{
|
|
||||||
GtkWidget *widget;
|
|
||||||
GtkCheckButtonPrivate *priv;
|
|
||||||
|
|
||||||
widget = gtk_css_gadget_get_owner (gadget);
|
|
||||||
priv = gtk_check_button_get_instance_private (GTK_CHECK_BUTTON (widget));
|
|
||||||
|
|
||||||
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
|
||||||
{
|
|
||||||
GtkWidget *child;
|
|
||||||
gint check_min, check_nat;
|
|
||||||
|
|
||||||
gtk_css_gadget_get_preferred_size (priv->indicator_gadget,
|
|
||||||
GTK_ORIENTATION_HORIZONTAL,
|
|
||||||
for_size,
|
|
||||||
&check_min, &check_nat,
|
|
||||||
NULL, NULL);
|
|
||||||
|
|
||||||
child = gtk_bin_get_child (GTK_BIN (widget));
|
|
||||||
if (child && gtk_widget_get_visible (child))
|
|
||||||
{
|
|
||||||
gint child_min, child_nat;
|
|
||||||
|
|
||||||
_gtk_widget_get_preferred_size_for_size (child,
|
|
||||||
GTK_ORIENTATION_HORIZONTAL,
|
|
||||||
for_size,
|
|
||||||
&child_min, &child_nat,
|
|
||||||
NULL, NULL);
|
|
||||||
*minimum = check_min + child_min;
|
|
||||||
*natural = check_nat + child_nat;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*minimum = check_min;
|
|
||||||
*natural = check_nat;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
GtkWidget *child;
|
|
||||||
gint check_min, check_nat;
|
|
||||||
gint check_min_width, check_nat_width;
|
|
||||||
|
|
||||||
gtk_css_gadget_get_preferred_size (priv->indicator_gadget,
|
|
||||||
GTK_ORIENTATION_HORIZONTAL,
|
|
||||||
-1,
|
|
||||||
&check_min_width, &check_nat_width,
|
|
||||||
NULL, NULL);
|
|
||||||
gtk_css_gadget_get_preferred_size (priv->indicator_gadget,
|
|
||||||
GTK_ORIENTATION_VERTICAL,
|
|
||||||
-1,
|
|
||||||
&check_min, &check_nat,
|
|
||||||
NULL, NULL);
|
|
||||||
|
|
||||||
child = gtk_bin_get_child (GTK_BIN (widget));
|
|
||||||
if (child && gtk_widget_get_visible (child))
|
|
||||||
{
|
|
||||||
gint child_min, child_nat;
|
|
||||||
gint child_min_baseline = -1, child_nat_baseline = -1;
|
|
||||||
|
|
||||||
if (for_size > -1)
|
|
||||||
for_size -= check_nat_width;
|
|
||||||
|
|
||||||
gtk_widget_get_preferred_height_and_baseline_for_width (child, for_size,
|
|
||||||
&child_min, &child_nat,
|
|
||||||
&child_min_baseline, &child_nat_baseline);
|
|
||||||
|
|
||||||
*minimum = MAX (check_min, child_min);
|
|
||||||
*natural = MAX (check_nat, child_nat);
|
|
||||||
|
|
||||||
if (minimum_baseline && child_min_baseline >= 0)
|
|
||||||
*minimum_baseline = child_min_baseline + (*minimum - child_min) / 2;
|
|
||||||
if (natural_baseline && child_nat_baseline >= 0)
|
|
||||||
*natural_baseline = child_nat_baseline + (*natural - child_nat) / 2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*minimum = check_min;
|
|
||||||
*natural = check_nat;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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,
|
||||||
@ -635,13 +494,16 @@ gtk_check_button_size_allocate (GtkWidget *widget,
|
|||||||
GtkAllocation *allocation)
|
GtkAllocation *allocation)
|
||||||
{
|
{
|
||||||
GtkCheckButtonPrivate *priv = gtk_check_button_get_instance_private (GTK_CHECK_BUTTON (widget));
|
GtkCheckButtonPrivate *priv = gtk_check_button_get_instance_private (GTK_CHECK_BUTTON (widget));
|
||||||
|
GtkButton *button = GTK_BUTTON (widget);
|
||||||
GtkCssGadget *gadget;
|
GtkCssGadget *gadget;
|
||||||
GdkRectangle clip;
|
GdkRectangle clip;
|
||||||
|
PangoContext *pango_context;
|
||||||
|
PangoFontMetrics *metrics;
|
||||||
|
|
||||||
if (gtk_toggle_button_get_mode (GTK_TOGGLE_BUTTON (widget)))
|
if (gtk_toggle_button_get_mode (GTK_TOGGLE_BUTTON (widget)))
|
||||||
gadget = priv->gadget;
|
gadget = priv->gadget;
|
||||||
else
|
else
|
||||||
gadget = GTK_BUTTON (widget)->priv->gadget;
|
gadget = button->priv->gadget;
|
||||||
|
|
||||||
gtk_widget_set_allocation (widget, allocation);
|
gtk_widget_set_allocation (widget, allocation);
|
||||||
gtk_css_gadget_allocate (gadget,
|
gtk_css_gadget_allocate (gadget,
|
||||||
@ -650,71 +512,6 @@ gtk_check_button_size_allocate (GtkWidget *widget,
|
|||||||
&clip);
|
&clip);
|
||||||
|
|
||||||
gtk_widget_set_clip (widget, &clip);
|
gtk_widget_set_clip (widget, &clip);
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
gtk_check_button_allocate (GtkCssGadget *gadget,
|
|
||||||
const GtkAllocation *allocation,
|
|
||||||
int baseline,
|
|
||||||
GtkAllocation *out_clip,
|
|
||||||
gpointer unused)
|
|
||||||
{
|
|
||||||
GtkCheckButtonPrivate *priv;
|
|
||||||
GtkWidget *widget;
|
|
||||||
PangoContext *pango_context;
|
|
||||||
PangoFontMetrics *metrics;
|
|
||||||
GtkCheckButton *check_button;
|
|
||||||
GtkButton *button;
|
|
||||||
GtkAllocation child_allocation;
|
|
||||||
GtkWidget *child;
|
|
||||||
gint check_width, check_height;
|
|
||||||
GdkRectangle check_clip;
|
|
||||||
|
|
||||||
widget = gtk_css_gadget_get_owner (gadget);
|
|
||||||
button = GTK_BUTTON (widget);
|
|
||||||
check_button = GTK_CHECK_BUTTON (widget);
|
|
||||||
priv = gtk_check_button_get_instance_private (check_button);
|
|
||||||
|
|
||||||
g_assert (gtk_toggle_button_get_mode (GTK_TOGGLE_BUTTON (widget)));
|
|
||||||
|
|
||||||
gtk_css_gadget_get_preferred_size (priv->indicator_gadget,
|
|
||||||
GTK_ORIENTATION_HORIZONTAL,
|
|
||||||
-1,
|
|
||||||
NULL, &check_width,
|
|
||||||
NULL, NULL);
|
|
||||||
gtk_css_gadget_get_preferred_size (priv->indicator_gadget,
|
|
||||||
GTK_ORIENTATION_VERTICAL,
|
|
||||||
-1,
|
|
||||||
NULL, &check_height,
|
|
||||||
NULL, NULL);
|
|
||||||
|
|
||||||
child = gtk_bin_get_child (GTK_BIN (button));
|
|
||||||
|
|
||||||
if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
|
|
||||||
child_allocation.x = allocation->x;
|
|
||||||
else
|
|
||||||
child_allocation.x = allocation->x + allocation->width - check_width;
|
|
||||||
child_allocation.y = allocation->y + (allocation->height - check_height) / 2;
|
|
||||||
child_allocation.width = check_width;
|
|
||||||
child_allocation.height = check_height;
|
|
||||||
|
|
||||||
gtk_css_gadget_allocate (priv->indicator_gadget,
|
|
||||||
&child_allocation,
|
|
||||||
baseline,
|
|
||||||
&check_clip);
|
|
||||||
|
|
||||||
if (child && gtk_widget_get_visible (child))
|
|
||||||
{
|
|
||||||
if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
|
|
||||||
child_allocation.x = allocation->x + check_width;
|
|
||||||
else
|
|
||||||
child_allocation.x = allocation->x;
|
|
||||||
child_allocation.y = allocation->y;
|
|
||||||
child_allocation.width = allocation->width - check_width;
|
|
||||||
child_allocation.height = allocation->height;
|
|
||||||
|
|
||||||
gtk_widget_size_allocate_with_baseline (child, &child_allocation, baseline);
|
|
||||||
}
|
|
||||||
|
|
||||||
pango_context = gtk_widget_get_pango_context (widget);
|
pango_context = gtk_widget_get_pango_context (widget);
|
||||||
metrics = pango_context_get_metrics (pango_context,
|
metrics = pango_context_get_metrics (pango_context,
|
||||||
@ -735,9 +532,6 @@ gtk_check_button_allocate (GtkCssGadget *gadget,
|
|||||||
border_allocation.width,
|
border_allocation.width,
|
||||||
border_allocation.height);
|
border_allocation.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
gtk_container_get_children_clip (GTK_CONTAINER (widget), out_clip);
|
|
||||||
gdk_rectangle_union (out_clip, &check_clip, out_clip);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static gint
|
static gint
|
||||||
@ -757,19 +551,6 @@ gtk_check_button_draw (GtkWidget *widget,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
gtk_check_button_draw_indicator (GtkCheckButton *check_button,
|
|
||||||
cairo_t *cr)
|
|
||||||
{
|
|
||||||
GtkCheckButtonClass *class = GTK_CHECK_BUTTON_GET_CLASS (check_button);
|
|
||||||
GtkCheckButtonPrivate *priv = gtk_check_button_get_instance_private (check_button);
|
|
||||||
|
|
||||||
if (class->draw_indicator)
|
|
||||||
class->draw_indicator (check_button, cr);
|
|
||||||
else
|
|
||||||
gtk_css_gadget_draw (priv->indicator_gadget, cr);
|
|
||||||
}
|
|
||||||
|
|
||||||
GtkCssNode *
|
GtkCssNode *
|
||||||
gtk_check_button_get_indicator_node (GtkCheckButton *check_button)
|
gtk_check_button_get_indicator_node (GtkCheckButton *check_button)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user