button: Convert to gadgets

This commit is contained in:
Matthias Clasen 2015-12-03 21:56:25 -05:00
parent a81267c28e
commit 37e9d92632
2 changed files with 133 additions and 213 deletions

View File

@ -72,9 +72,8 @@
#include "a11y/gtkbuttonaccessible.h"
#include "gtkapplicationprivate.h"
#include "gtkactionhelper.h"
static const GtkBorder default_default_border = { 0, 0, 0, 0 };
static const GtkBorder default_default_outside_border = { 0, 0, 0, 0 };
#include "gtkcsscustomgadgetprivate.h"
#include "gtkcontainerprivate.h"
/* Time out before giving up on getting a key release when animating
* the close button.
@ -195,7 +194,28 @@ static void gtk_button_get_preferred_height_and_baseline_for_width (GtkWidget *w
gint *natural_size,
gint *minimum_baseline,
gint *natural_baseline);
static void gtk_button_measure (GtkCssGadget *gadget,
GtkOrientation orientation,
int for_size,
int *minimum_size,
int *natural_size,
int *minimum_baseline,
int *natural_baseline,
gpointer data);
static void gtk_button_allocate (GtkCssGadget *gadget,
const GtkAllocation *allocation,
int baseline,
GtkAllocation *out_clip,
gpointer data);
static gboolean gtk_button_render (GtkCssGadget *gadget,
cairo_t *cr,
int x,
int y,
int width,
int height,
gpointer data);
static GParamSpec *props[LAST_PROP] = { NULL, };
static guint button_signals[LAST_SIGNAL] = { 0 };
@ -493,7 +513,8 @@ gtk_button_class_init (GtkButtonClass *klass)
* around a button that can become the default widget of its window.
* For more information about default widgets, see gtk_widget_grab_default().
*
* Deprecated: 3.14: use CSS margins and padding instead.
* Deprecated: 3.14: Use CSS margins and padding instead;
* the value of this style property is ignored.
*/
gtk_widget_class_install_style_property (widget_class,
@ -511,7 +532,8 @@ gtk_button_class_init (GtkButtonClass *klass)
* window. Extra outside space is always drawn outside the button border.
* For more information about default widgets, see gtk_widget_grab_default().
*
* Deprecated: 3.14: use CSS margins and padding instead.
* Deprecated: 3.14: Use CSS margins and padding instead;
* the value of this style property is ignored.
*/
gtk_widget_class_install_style_property (widget_class,
g_param_spec_boxed ("default-outside-border",
@ -720,6 +742,15 @@ gtk_button_init (GtkButton *button)
g_signal_connect (priv->gesture, "update", G_CALLBACK (multipress_gesture_update_cb), button);
g_signal_connect (priv->gesture, "cancel", G_CALLBACK (multipress_gesture_cancel_cb), button);
gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (priv->gesture), GTK_PHASE_BUBBLE);
priv->gadget = gtk_css_custom_gadget_new_for_node (gtk_widget_get_css_node (GTK_WIDGET (button)),
GTK_WIDGET (button),
gtk_button_measure,
gtk_button_allocate,
gtk_button_render,
NULL,
NULL);
}
static void
@ -729,8 +760,8 @@ gtk_button_destroy (GtkWidget *widget)
GtkButtonPrivate *priv = button->priv;
g_clear_pointer (&priv->label_text, g_free);
g_clear_object (&priv->gesture);
g_clear_object (&priv->gadget);
GTK_WIDGET_CLASS (gtk_button_parent_class)->destroy (widget);
}
@ -787,7 +818,7 @@ gtk_button_add (GtkContainer *container,
GTK_CONTAINER_CLASS (gtk_button_parent_class)->add (container, widget);
}
static void
static void
gtk_button_dispose (GObject *object)
{
GtkButton *button = GTK_BUTTON (object);
@ -1720,90 +1751,13 @@ gtk_button_style_updated (GtkWidget *widget)
gtk_button_update_image_spacing (GTK_BUTTON (widget), context);
}
static void
gtk_button_get_props (GtkButton *button,
GtkBorder *default_border,
GtkBorder *default_outside_border,
GtkBorder *padding,
GtkBorder *border)
{
GtkStyleContext *context;
GtkStateFlags state;
GtkBorder *tmp_border;
context = gtk_widget_get_style_context (GTK_WIDGET (button));
state = gtk_style_context_get_state (context);
if (default_border)
{
gtk_style_context_get_style (context,
"default-border", &tmp_border,
NULL);
if (tmp_border)
{
*default_border = *tmp_border;
gtk_border_free (tmp_border);
}
else
*default_border = default_default_border;
}
if (default_outside_border)
{
gtk_style_context_get_style (context,
"default-outside-border", &tmp_border,
NULL);
if (tmp_border)
{
*default_outside_border = *tmp_border;
gtk_border_free (tmp_border);
}
else
*default_outside_border = default_default_outside_border;
}
if (padding)
gtk_style_context_get_padding (context, state, padding);
if (border)
gtk_style_context_get_border (context, state, border);
}
/* Computes the size of the border around the button's child
* including all CSS and style properties so it can be used
* during size allocation and size request phases. */
static void
gtk_button_get_full_border (GtkButton *button,
GtkBorder *full_border)
{
GtkBorder default_border, padding, border;
gtk_button_get_props (button, &default_border, NULL,
&padding, &border);
full_border->left = padding.left + border.left;
full_border->right = padding.right + border.right;
full_border->top = padding.top + border.top;
full_border->bottom = padding.bottom + border.bottom;
if (gtk_widget_get_can_default (GTK_WIDGET (button)))
{
full_border->left += default_border.left;
full_border->right += default_border.right;
full_border->top += default_border.top;
full_border->bottom += default_border.bottom;
}
}
static void
gtk_button_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
GtkButton *button = GTK_BUTTON (widget);
GtkButtonPrivate *priv = button->priv;
GtkWidget *child;
GtkAllocation clip;
gtk_widget_set_allocation (widget, allocation);
@ -1814,91 +1768,58 @@ gtk_button_size_allocate (GtkWidget *widget,
allocation->width,
allocation->height);
child = gtk_bin_get_child (GTK_BIN (button));
gtk_css_gadget_allocate (priv->gadget,
allocation,
gtk_widget_get_allocated_baseline (widget),
&clip);
gtk_widget_set_clip (widget, &clip);
}
static void
gtk_button_allocate (GtkCssGadget *gadget,
const GtkAllocation *allocation,
int baseline,
GtkAllocation *out_clip,
gpointer unused)
{
GtkWidget *widget;
GtkWidget *child;
widget = gtk_css_gadget_get_owner (gadget);
child = gtk_bin_get_child (GTK_BIN (widget));
if (child && gtk_widget_get_visible (child))
{
GtkAllocation child_allocation;
GtkBorder border;
gint baseline;
gtk_widget_size_allocate_with_baseline (child, (GtkAllocation *)allocation, baseline);
gtk_button_get_full_border (button, &border);
child_allocation.x = allocation->x + border.left;
child_allocation.y = allocation->y + border.top;
child_allocation.width = allocation->width - border.left - border.right;
child_allocation.height = allocation->height - border.top - border.bottom;
baseline = gtk_widget_get_allocated_baseline (widget);
if (baseline != -1)
baseline -= border.top;
child_allocation.width = MAX (1, child_allocation.width);
child_allocation.height = MAX (1, child_allocation.height);
gtk_widget_size_allocate_with_baseline (child, &child_allocation, baseline);
}
_gtk_widget_set_simple_clip (widget, NULL);
gtk_container_get_children_clip (GTK_CONTAINER (widget), out_clip);
}
static gboolean
gtk_button_draw (GtkWidget *widget,
cairo_t *cr)
{
GtkButton *button = GTK_BUTTON (widget);
gint x, y;
gint width, height;
GtkBorder default_border;
GtkBorder default_outside_border;
GtkStyleContext *context;
GtkStateFlags state;
gtk_css_gadget_draw (GTK_BUTTON (widget)->priv->gadget, cr);
context = gtk_widget_get_style_context (widget);
state = gtk_style_context_get_state (context);
return FALSE;
}
gtk_button_get_props (button, &default_border, &default_outside_border, NULL, NULL);
static gboolean
gtk_button_render (GtkCssGadget *gadget,
cairo_t *cr,
int x,
int y,
int width,
int height,
gpointer data)
{
GtkWidget *widget;
x = 0;
y = 0;
width = gtk_widget_get_allocated_width (widget);
height = gtk_widget_get_allocated_height (widget);
if (gtk_widget_has_default (widget) &&
gtk_button_get_relief (button) == GTK_RELIEF_NORMAL)
{
x += default_border.left;
y += default_border.top;
width -= default_border.left + default_border.right;
height -= default_border.top + default_border.bottom;
}
else if (gtk_widget_get_can_default (widget))
{
x += default_outside_border.left;
y += default_outside_border.top;
width -= default_outside_border.left + default_outside_border.right;
height -= default_outside_border.top + default_outside_border.bottom;
}
gtk_render_background (context, cr, x, y, width, height);
gtk_render_frame (context, cr, x, y, width, height);
if (gtk_widget_has_visible_focus (widget))
{
GtkBorder border;
gtk_style_context_get_border (context, state, &border);
x += border.left;
y += border.top;
width -= border.left + border.right;
height -= border.top + border.bottom;
gtk_render_focus (context, cr, x, y, width, height);
}
widget = gtk_css_gadget_get_owner (gadget);
GTK_WIDGET_CLASS (gtk_button_parent_class)->draw (widget, cr);
return FALSE;
return gtk_widget_has_visible_focus (widget);
}
static void
@ -2127,106 +2048,103 @@ gtk_button_finish_activate (GtkButton *button,
static void
gtk_button_get_size (GtkWidget *widget,
GtkOrientation orientation,
gint for_size,
gint *minimum_size,
gint *natural_size,
gint *minimum_baseline,
gint *natural_baseline)
gtk_button_measure (GtkCssGadget *gadget,
GtkOrientation orientation,
int for_size,
int *minimum,
int *natural,
int *minimum_baseline,
int *natural_baseline,
gpointer data)
{
GtkButton *button = GTK_BUTTON (widget);
GtkWidget *widget;
GtkWidget *child;
GtkBorder border;
gint minimum, natural;
gtk_button_get_full_border (button, &border);
widget = gtk_css_gadget_get_owner (gadget);
child = gtk_bin_get_child (GTK_BIN (widget));
if (orientation == GTK_ORIENTATION_HORIZONTAL)
if (child && gtk_widget_get_visible (child))
{
minimum = border.left + border.right;
natural = minimum;
if (for_size >= 0)
for_size -= border.top + border.bottom;
_gtk_widget_get_preferred_size_for_size (child,
orientation,
for_size,
minimum, natural,
minimum_baseline, natural_baseline);
}
else
{
minimum = border.top + border.bottom;
natural = minimum;
if (for_size >= 0)
for_size -= border.left + border.right;
*minimum = 0;
*natural = 0;
if (minimum_baseline)
*minimum_baseline = 0;
if (natural_baseline)
*natural_baseline = 0;
}
if ((child = gtk_bin_get_child (GTK_BIN (button))) &&
gtk_widget_get_visible (child))
{
gint child_min, child_nat;
gint child_min_baseline = -1, child_nat_baseline = -1;
_gtk_widget_get_preferred_size_for_size (child,
orientation,
for_size,
&child_min, &child_nat,
&child_min_baseline, &child_nat_baseline);
if (minimum_baseline && child_min_baseline >= 0)
*minimum_baseline = child_min_baseline + border.top;
if (natural_baseline && child_nat_baseline >= 0)
*natural_baseline = child_nat_baseline + border.top;
minimum += child_min;
natural += child_nat;
}
*minimum_size = minimum;
*natural_size = natural;
}
static void
static void
gtk_button_get_preferred_width (GtkWidget *widget,
gint *minimum_size,
gint *natural_size)
{
gtk_button_get_size (widget, GTK_ORIENTATION_HORIZONTAL, -1, minimum_size, natural_size, NULL, NULL);
gtk_css_gadget_get_preferred_size (GTK_BUTTON (widget)->priv->gadget,
GTK_ORIENTATION_HORIZONTAL,
-1,
minimum_size, natural_size,
NULL, NULL);
}
static void
static void
gtk_button_get_preferred_height (GtkWidget *widget,
gint *minimum_size,
gint *natural_size)
{
gtk_button_get_size (widget, GTK_ORIENTATION_VERTICAL, -1, minimum_size, natural_size, NULL, NULL);
gtk_css_gadget_get_preferred_size (GTK_BUTTON (widget)->priv->gadget,
GTK_ORIENTATION_VERTICAL,
-1,
minimum_size, natural_size,
NULL, NULL);
}
static void
static void
gtk_button_get_preferred_width_for_height (GtkWidget *widget,
gint for_size,
gint *minimum_size,
gint *natural_size)
{
gtk_button_get_size (widget, GTK_ORIENTATION_HORIZONTAL, for_size, minimum_size, natural_size, NULL, NULL);
gtk_css_gadget_get_preferred_size (GTK_BUTTON (widget)->priv->gadget,
GTK_ORIENTATION_HORIZONTAL,
for_size,
minimum_size, natural_size,
NULL, NULL);
}
static void
static void
gtk_button_get_preferred_height_for_width (GtkWidget *widget,
gint for_size,
gint *minimum_size,
gint *natural_size)
{
gtk_button_get_size (widget, GTK_ORIENTATION_VERTICAL, for_size, minimum_size, natural_size, NULL, NULL);
gtk_css_gadget_get_preferred_size (GTK_BUTTON (widget)->priv->gadget,
GTK_ORIENTATION_VERTICAL,
for_size,
minimum_size, natural_size,
NULL, NULL);
}
static void
gtk_button_get_preferred_height_and_baseline_for_width (GtkWidget *widget,
gint width,
gint for_size,
gint *minimum_size,
gint *natural_size,
gint *minimum_baseline,
gint *natural_baseline)
{
gtk_button_get_size (widget, GTK_ORIENTATION_VERTICAL, width, minimum_size, natural_size, minimum_baseline, natural_baseline);
gtk_css_gadget_get_preferred_size (GTK_BUTTON (widget)->priv->gadget,
GTK_ORIENTATION_VERTICAL,
for_size,
minimum_size, natural_size,
minimum_baseline, natural_baseline);
}
/**

View File

@ -22,6 +22,7 @@
#include "gtkactionhelper.h"
#include "gtkgesturesingle.h"
#include "deprecated/gtkaction.h"
#include "gtkcssgadgetprivate.h"
G_BEGIN_DECLS
@ -31,6 +32,7 @@ struct _GtkButtonPrivate
GtkAction *action;
GtkWidget *image;
GtkActionHelper *action_helper;
GtkCssGadget *gadget;
GdkDevice *grab_keyboard;
GdkWindow *event_window;