[gtk+/buttons: 2/5] More GtkButton cleanup
- From: Ryan Lortie <ryanl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/buttons: 2/5] More GtkButton cleanup
- Date: Wed, 1 Dec 2010 07:52:17 +0000 (UTC)
commit 1a423ac7666c6bb43c4616fa0349453dc561a204
Author: Ryan Lortie <desrt desrt ca>
Date: Wed Dec 1 01:10:41 2010 -0500
More GtkButton cleanup
Patch from Matthias in bug #636101 to merge drawing code up and turn the
subclasses into empty shells.
gtk/gtkbutton.c | 58 +++++
gtk/gtkbutton.h | 4 +
gtk/gtkbuttonprivate.h | 1 +
gtk/gtkcheckbutton.c | 405 +----------------------------------
gtk/gtkcheckbutton.h | 15 +--
gtk/gtkenums.h | 9 +
gtk/gtkradiobutton.c | 91 +--------
gtk/gtkradiotoolbutton.c | 3 +-
gtk/gtktogglebutton.c | 542 +++++++++++++++++++++++++++++++++++-----------
gtk/gtktogglebutton.h | 40 ++--
10 files changed, 516 insertions(+), 652 deletions(-)
---
diff --git a/gtk/gtkbutton.c b/gtk/gtkbutton.c
index 5337887..9faabcf 100644
--- a/gtk/gtkbutton.c
+++ b/gtk/gtkbutton.c
@@ -92,6 +92,7 @@ enum {
PROP_IMAGE_POSITION,
PROP_IS_TOGGLE,
PROP_ACTION,
+ PROP_INDICATOR_STYLE,
/* activatable properties */
PROP_ACTIVATABLE_RELATED_ACTION,
@@ -364,6 +365,14 @@ gtk_button_class_init (GtkButtonClass *klass)
G_TYPE_ACTION,
GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+ g_object_class_install_property (gobject_class, PROP_INDICATOR_STYLE,
+ g_param_spec_enum ("indicator-style",
+ P_("Indicator style"),
+ P_("Whether the button looks like a plain button, check or radio button"),
+ GTK_TYPE_INDICATOR_STYLE,
+ GTK_INDICATOR_STYLE_PLAIN,
+ GTK_PARAM_READWRITE));
+
g_object_class_override_property (gobject_class, PROP_ACTIVATABLE_RELATED_ACTION, "related-action");
g_object_class_override_property (gobject_class, PROP_ACTIVATABLE_USE_ACTION_APPEARANCE, "use-action-appearance");
@@ -560,6 +569,20 @@ gtk_button_class_init (GtkButtonClass *klass)
2,
GTK_PARAM_READABLE));
+ gtk_widget_class_install_style_property (widget_class,
+ g_param_spec_int ("indicator-size",
+ P_("Indicator Size"),
+ P_("Size of check or radio indicator"),
+ 0, G_MAXINT, 13,
+ GTK_PARAM_READABLE));
+
+ gtk_widget_class_install_style_property (widget_class,
+ g_param_spec_int ("indicator-spacing",
+ P_("Indicator Spacing"),
+ P_("Spacing around check or radio indicator"),
+ 0, G_MAXINT, 2,
+ GTK_PARAM_READABLE));
+
g_type_class_add_private (gobject_class, sizeof (GtkButtonPrivate));
}
@@ -595,6 +618,7 @@ gtk_button_init (GtkButton *button)
priv->image_is_stock = TRUE;
priv->image_position = GTK_POS_LEFT;
priv->use_action_appearance = TRUE;
+ priv->indicator_style = GTK_INDICATOR_STYLE_PLAIN;
}
static void
@@ -853,6 +877,9 @@ gtk_button_set_property (GObject *object,
if (g_value_get_object (value) != NULL)
gtk_button_set_action (button, g_value_get_object (value));
break;
+ case PROP_INDICATOR_STYLE:
+ gtk_button_set_indicator_style (button, g_value_get_enum (value));
+ break;
case PROP_ACTIVATABLE_RELATED_ACTION:
gtk_button_set_related_action (button, g_value_get_object (value));
break;
@@ -906,6 +933,9 @@ gtk_button_get_property (GObject *object,
case PROP_ACTION:
g_value_set_object (value, priv->g_action);
break;
+ case PROP_INDICATOR_STYLE:
+ g_value_set_enum (value, priv->indicator_style);
+ break;
case PROP_ACTIVATABLE_RELATED_ACTION:
g_value_set_object (value, priv->action);
break;
@@ -2690,3 +2720,31 @@ gtk_button_get_event_window (GtkButton *button)
return button->priv->event_window;
}
+
+void
+gtk_button_set_indicator_style (GtkButton *button,
+ GtkIndicatorStyle style)
+{
+ GtkButtonPrivate *priv;
+
+ g_return_if_fail (GTK_IS_BUTTON (button));
+
+ priv = button->priv;
+
+ if (priv->indicator_style != style)
+ {
+ priv->indicator_style = style;
+
+ gtk_widget_queue_resize (GTK_WIDGET (button));
+
+ g_object_notify (G_OBJECT (button), "indicator-style");
+ }
+}
+
+GtkIndicatorStyle
+gtk_button_get_indicator_style (GtkButton *button)
+{
+ g_return_val_if_fail (GTK_IS_BUTTON (button), GTK_INDICATOR_STYLE_PLAIN);
+
+ return button->priv->indicator_style;
+}
diff --git a/gtk/gtkbutton.h b/gtk/gtkbutton.h
index 3e2fee8..1e5b514 100644
--- a/gtk/gtkbutton.h
+++ b/gtk/gtkbutton.h
@@ -34,6 +34,7 @@
#include <gtk/gtkbin.h>
#include <gtk/gtkimage.h>
+#include <gtk/gtkenums.h>
G_BEGIN_DECLS
@@ -125,6 +126,9 @@ void gtk_button_set_action (GtkButton *button,
GAction *action);
GAction * gtk_button_get_action (GtkButton *button);
+void gtk_button_set_indicator_style (GtkButton *button,
+ GtkIndicatorStyle style);
+GtkIndicatorStyle gtk_button_get_indicator_style (GtkButton *button);
void _gtk_button_set_depressed (GtkButton *button,
gboolean depressed);
void _gtk_button_paint (GtkButton *button,
diff --git a/gtk/gtkbuttonprivate.h b/gtk/gtkbuttonprivate.h
index da5f56b..edcdcf5 100644
--- a/gtk/gtkbuttonprivate.h
+++ b/gtk/gtkbuttonprivate.h
@@ -55,6 +55,7 @@ struct _GtkButtonPrivate
guint use_stock : 1;
guint use_underline : 1;
guint is_toggle : 1;
+ guint indicator_style : 2;
};
#endif /* __GTK_BUTTON_PRIVATE_H__ */
diff --git a/gtk/gtkcheckbutton.c b/gtk/gtkcheckbutton.c
index f9087b5..3ee43cd 100644
--- a/gtk/gtkcheckbutton.c
+++ b/gtk/gtkcheckbutton.c
@@ -34,68 +34,17 @@
#include "gtkprivate.h"
#include "gtkintl.h"
-
-#define INDICATOR_SIZE 13
-#define INDICATOR_SPACING 2
-
-
-static void gtk_check_button_get_preferred_width (GtkWidget *widget,
- gint *minimum,
- gint *natural);
-static void gtk_check_button_get_preferred_height (GtkWidget *widget,
- gint *minimum,
- gint *natural);
-static void gtk_check_button_size_allocate (GtkWidget *widget,
- GtkAllocation *allocation);
-static gboolean gtk_check_button_draw (GtkWidget *widget,
- cairo_t *cr);
-static void gtk_check_button_paint (GtkWidget *widget,
- cairo_t *cr);
-static void gtk_check_button_draw_indicator (GtkCheckButton *check_button,
- cairo_t *cr);
-static void gtk_real_check_button_draw_indicator (GtkCheckButton *check_button,
- cairo_t *cr);
-
G_DEFINE_TYPE (GtkCheckButton, gtk_check_button, GTK_TYPE_TOGGLE_BUTTON)
static void
gtk_check_button_class_init (GtkCheckButtonClass *class)
{
- GtkWidgetClass *widget_class;
-
- widget_class = (GtkWidgetClass*) class;
-
- widget_class->get_preferred_width = gtk_check_button_get_preferred_width;
- widget_class->get_preferred_height = gtk_check_button_get_preferred_height;
- widget_class->size_allocate = gtk_check_button_size_allocate;
- widget_class->draw = gtk_check_button_draw;
-
- class->draw_indicator = gtk_real_check_button_draw_indicator;
-
- gtk_widget_class_install_style_property (widget_class,
- g_param_spec_int ("indicator-size",
- P_("Indicator Size"),
- P_("Size of check or radio indicator"),
- 0,
- G_MAXINT,
- INDICATOR_SIZE,
- GTK_PARAM_READABLE));
- gtk_widget_class_install_style_property (widget_class,
- g_param_spec_int ("indicator-spacing",
- P_("Indicator Spacing"),
- P_("Spacing around check or radio indicator"),
- 0,
- G_MAXINT,
- INDICATOR_SPACING,
- GTK_PARAM_READABLE));
}
static void
-gtk_check_button_init (GtkCheckButton *check_button)
+gtk_check_button_init (GtkCheckButton *button)
{
- gtk_widget_set_has_window (GTK_WIDGET (check_button), FALSE);
- gtk_widget_set_receives_default (GTK_WIDGET (check_button), FALSE);
- gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (check_button), TRUE);
+ gtk_button_set_indicator_style (GTK_BUTTON (button), GTK_INDICATOR_STYLE_CHECK);
}
GtkWidget*
@@ -135,353 +84,3 @@ gtk_check_button_new_with_mnemonic (const gchar *label)
}
-/* This should only be called when toggle_button->draw_indicator
- * is true.
- */
-static void
-gtk_check_button_paint (GtkWidget *widget,
- cairo_t *cr)
-{
- GtkCheckButton *check_button = GTK_CHECK_BUTTON (widget);
- gint border_width;
- gint interior_focus;
- gint focus_width;
- gint focus_pad;
-
- gtk_widget_style_get (widget,
- "interior-focus", &interior_focus,
- "focus-line-width", &focus_width,
- "focus-padding", &focus_pad,
- NULL);
-
- gtk_check_button_draw_indicator (check_button, cr);
-
- border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
- if (gtk_widget_has_focus (widget))
- {
- GtkStateType state = gtk_widget_get_state (widget);
- GtkStyle *style = gtk_widget_get_style (widget);
- GtkWidget *child = gtk_bin_get_child (GTK_BIN (widget));
- GtkAllocation allocation;
-
- gtk_widget_get_allocation (widget, &allocation);
-
- if (interior_focus && child && gtk_widget_get_visible (child))
- {
- GtkAllocation child_allocation;
-
- gtk_widget_get_allocation (child, &child_allocation);
- gtk_paint_focus (style, cr, state,
- widget, "checkbutton",
- child_allocation.x - allocation.x - focus_width - focus_pad,
- child_allocation.y - allocation.y - focus_width - focus_pad,
- child_allocation.width + 2 * (focus_width + focus_pad),
- child_allocation.height + 2 * (focus_width + focus_pad));
- }
- else
- {
- gtk_paint_focus (style, cr, state,
- widget, "checkbutton",
- border_width,
- border_width,
- allocation.width - 2 * border_width,
- allocation.height - 2 * border_width);
- }
- }
-}
-
-void
-_gtk_check_button_get_props (GtkCheckButton *check_button,
- gint *indicator_size,
- gint *indicator_spacing)
-{
- GtkWidget *widget = GTK_WIDGET (check_button);
-
- if (indicator_size)
- gtk_widget_style_get (widget, "indicator-size", indicator_size, NULL);
-
- if (indicator_spacing)
- gtk_widget_style_get (widget, "indicator-spacing", indicator_spacing, NULL);
-}
-
-static void
-gtk_check_button_get_preferred_width (GtkWidget *widget,
- gint *minimum,
- gint *natural)
-{
- GtkToggleButton *toggle_button = GTK_TOGGLE_BUTTON (widget);
-
- if (gtk_toggle_button_get_mode (toggle_button))
- {
- GtkWidget *child;
- gint indicator_size;
- gint indicator_spacing;
- gint focus_width;
- gint focus_pad;
- guint border_width;
-
- border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
-
- gtk_widget_style_get (GTK_WIDGET (widget),
- "focus-line-width", &focus_width,
- "focus-padding", &focus_pad,
- NULL);
- *minimum = 2 * border_width;
- *natural = 2 * border_width;
-
- _gtk_check_button_get_props (GTK_CHECK_BUTTON (widget),
- &indicator_size, &indicator_spacing);
-
- child = gtk_bin_get_child (GTK_BIN (widget));
- if (child && gtk_widget_get_visible (child))
- {
- gint child_min, child_nat;
-
- gtk_widget_get_preferred_width (child, &child_min, &child_nat);
-
- *minimum += child_min + indicator_spacing;
- *natural += child_nat + indicator_spacing;
- }
-
- *minimum += (indicator_size + indicator_spacing * 2 + 2 * (focus_width + focus_pad));
- *natural += (indicator_size + indicator_spacing * 2 + 2 * (focus_width + focus_pad));
- }
- else
- GTK_WIDGET_CLASS (gtk_check_button_parent_class)->get_preferred_width (widget, minimum, natural);
-}
-
-static void
-gtk_check_button_get_preferred_height (GtkWidget *widget,
- gint *minimum,
- gint *natural)
-{
- GtkToggleButton *toggle_button = GTK_TOGGLE_BUTTON (widget);
-
- if (gtk_toggle_button_get_mode (toggle_button))
- {
- GtkWidget *child;
- gint temp;
- gint indicator_size;
- gint indicator_spacing;
- gint focus_width;
- gint focus_pad;
- guint border_width;
-
- border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
-
- gtk_widget_style_get (GTK_WIDGET (widget),
- "focus-line-width", &focus_width,
- "focus-padding", &focus_pad,
- NULL);
-
- *minimum = border_width * 2;
- *natural = border_width * 2;
-
- _gtk_check_button_get_props (GTK_CHECK_BUTTON (widget),
- &indicator_size, &indicator_spacing);
-
- child = gtk_bin_get_child (GTK_BIN (widget));
- if (child && gtk_widget_get_visible (child))
- {
- gint child_min, child_nat;
-
- gtk_widget_get_preferred_height (child, &child_min, &child_nat);
-
- *minimum += child_min;
- *natural += child_nat;
- }
-
- temp = indicator_size + indicator_spacing * 2;
- *minimum = MAX (*minimum, temp) + 2 * (focus_width + focus_pad);
- *natural = MAX (*natural, temp) + 2 * (focus_width + focus_pad);
- }
- else
- GTK_WIDGET_CLASS (gtk_check_button_parent_class)->get_preferred_height (widget, minimum, natural);
-}
-
-static void
-gtk_check_button_size_allocate (GtkWidget *widget,
- GtkAllocation *allocation)
-{
- GtkCheckButton *check_button;
- GtkToggleButton *toggle_button;
- GtkButton *button;
- GtkAllocation child_allocation;
-
- button = GTK_BUTTON (widget);
- check_button = GTK_CHECK_BUTTON (widget);
- toggle_button = GTK_TOGGLE_BUTTON (widget);
-
- if (gtk_toggle_button_get_mode (toggle_button))
- {
- GtkWidget *child;
- gint indicator_size;
- gint indicator_spacing;
- gint focus_width;
- gint focus_pad;
-
- _gtk_check_button_get_props (check_button, &indicator_size, &indicator_spacing);
- gtk_widget_style_get (widget,
- "focus-line-width", &focus_width,
- "focus-padding", &focus_pad,
- NULL);
-
- gtk_widget_set_allocation (widget, allocation);
-
- if (gtk_widget_get_realized (widget))
- gdk_window_move_resize (gtk_button_get_event_window (button),
- allocation->x, allocation->y,
- allocation->width, allocation->height);
-
- child = gtk_bin_get_child (GTK_BIN (button));
- if (child && gtk_widget_get_visible (child))
- {
- GtkRequisition child_requisition;
- guint border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
-
- gtk_widget_get_preferred_size (child, &child_requisition, NULL);
-
- child_allocation.width = MIN (child_requisition.width,
- allocation->width -
- ((border_width + focus_width + focus_pad) * 2
- + indicator_size + indicator_spacing * 3));
- child_allocation.width = MAX (child_allocation.width, 1);
-
- child_allocation.height = MIN (child_requisition.height,
- allocation->height - (border_width + focus_width + focus_pad) * 2);
- child_allocation.height = MAX (child_allocation.height, 1);
-
- child_allocation.x = (border_width + indicator_size + indicator_spacing * 3 +
- allocation->x + focus_width + focus_pad);
- child_allocation.y = allocation->y + (allocation->height - child_allocation.height) / 2;
-
- if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
- child_allocation.x = allocation->x + allocation->width
- - (child_allocation.x - allocation->x + child_allocation.width);
-
- gtk_widget_size_allocate (child, &child_allocation);
- }
- }
- else
- GTK_WIDGET_CLASS (gtk_check_button_parent_class)->size_allocate (widget, allocation);
-}
-
-static gint
-gtk_check_button_draw (GtkWidget *widget,
- cairo_t *cr)
-{
- GtkToggleButton *toggle_button;
- GtkBin *bin;
- GtkWidget *child;
-
- toggle_button = GTK_TOGGLE_BUTTON (widget);
- bin = GTK_BIN (widget);
-
- if (gtk_toggle_button_get_mode (toggle_button))
- {
- gtk_check_button_paint (widget, cr);
-
- child = gtk_bin_get_child (bin);
- if (child)
- gtk_container_propagate_draw (GTK_CONTAINER (widget),
- child,
- cr);
- }
- else if (GTK_WIDGET_CLASS (gtk_check_button_parent_class)->draw)
- GTK_WIDGET_CLASS (gtk_check_button_parent_class)->draw (widget, cr);
-
- return FALSE;
-}
-
-
-static void
-gtk_check_button_draw_indicator (GtkCheckButton *check_button,
- cairo_t *cr)
-{
- GtkCheckButtonClass *class = GTK_CHECK_BUTTON_GET_CLASS (check_button);
-
- if (class->draw_indicator)
- class->draw_indicator (check_button, cr);
-}
-
-static void
-gtk_real_check_button_draw_indicator (GtkCheckButton *check_button,
- cairo_t *cr)
-{
- GtkWidget *widget;
- GtkWidget *child;
- GtkButton *button;
- GtkToggleButton *toggle_button;
- GtkStateType state_type;
- GtkShadowType shadow_type;
- gint x, y;
- gint indicator_size;
- gint indicator_spacing;
- gint focus_width;
- gint focus_pad;
- guint border_width;
- gboolean interior_focus;
- GtkAllocation allocation;
- GtkStyle *style;
- GdkWindow *window;
-
- widget = GTK_WIDGET (check_button);
- button = GTK_BUTTON (check_button);
- toggle_button = GTK_TOGGLE_BUTTON (check_button);
-
- gtk_widget_get_allocation (widget, &allocation);
- style = gtk_widget_get_style (widget);
- window = gtk_widget_get_window (widget);
-
- gtk_widget_style_get (widget,
- "interior-focus", &interior_focus,
- "focus-line-width", &focus_width,
- "focus-padding", &focus_pad,
- NULL);
-
- _gtk_check_button_get_props (check_button, &indicator_size, &indicator_spacing);
-
- border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
-
- x = indicator_spacing + border_width;
- y = (allocation.height - indicator_size) / 2;
-
- child = gtk_bin_get_child (GTK_BIN (check_button));
- if (!interior_focus || !(child && gtk_widget_get_visible (child)))
- x += focus_width + focus_pad;
-
- if (gtk_toggle_button_get_inconsistent (toggle_button))
- shadow_type = GTK_SHADOW_ETCHED_IN;
- else if (gtk_toggle_button_get_active (toggle_button))
- shadow_type = GTK_SHADOW_IN;
- else
- shadow_type = GTK_SHADOW_OUT;
-
- if (button->priv->activate_timeout || (button->priv->button_down && button->priv->in_button))
- state_type = GTK_STATE_ACTIVE;
- else if (button->priv->in_button)
- state_type = GTK_STATE_PRELIGHT;
- else if (!gtk_widget_is_sensitive (widget))
- state_type = GTK_STATE_INSENSITIVE;
- else
- state_type = GTK_STATE_NORMAL;
-
- if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
- x = allocation.width - (indicator_size + x);
-
- if (gtk_widget_get_state (widget) == GTK_STATE_PRELIGHT)
- {
-
- gtk_paint_flat_box (style, cr, GTK_STATE_PRELIGHT,
- GTK_SHADOW_ETCHED_OUT,
- widget, "checkbutton",
- border_width, border_width,
- allocation.width - (2 * border_width),
- allocation.height - (2 * border_width));
- }
-
- gtk_paint_check (style, cr,
- state_type, shadow_type,
- widget, "checkbutton",
- x, y, indicator_size, indicator_size);
-}
diff --git a/gtk/gtkcheckbutton.h b/gtk/gtkcheckbutton.h
index 1ea6e31..887b356 100644
--- a/gtk/gtkcheckbutton.h
+++ b/gtk/gtkcheckbutton.h
@@ -56,27 +56,14 @@ struct _GtkCheckButton
struct _GtkCheckButtonClass
{
GtkToggleButtonClass parent_class;
-
- void (* draw_indicator) (GtkCheckButton *check_button,
- cairo_t *cr);
-
- /* Padding for future expansion */
- void (*_gtk_reserved1) (void);
- void (*_gtk_reserved2) (void);
- void (*_gtk_reserved3) (void);
- void (*_gtk_reserved4) (void);
};
-GType gtk_check_button_get_type (void) G_GNUC_CONST;
+GType gtk_check_button_get_type (void) G_GNUC_CONST;
GtkWidget* gtk_check_button_new (void);
GtkWidget* gtk_check_button_new_with_label (const gchar *label);
GtkWidget* gtk_check_button_new_with_mnemonic (const gchar *label);
-void _gtk_check_button_get_props (GtkCheckButton *check_button,
- gint *indicator_size,
- gint *indicator_spacing);
-
G_END_DECLS
#endif /* __GTK_CHECK_BUTTON_H__ */
diff --git a/gtk/gtkenums.h b/gtk/gtkenums.h
index 9dbab6d..6abd2bf 100644
--- a/gtk/gtkenums.h
+++ b/gtk/gtkenums.h
@@ -558,6 +558,15 @@ typedef enum
} GtkScrollablePolicy;
+
+typedef enum
+{
+ GTK_INDICATOR_STYLE_PLAIN,
+ GTK_INDICATOR_STYLE_CHECK,
+ GTK_INDICATOR_STYLE_RADIO
+} GtkIndicatorStyle;
+
+
G_END_DECLS
diff --git a/gtk/gtkradiobutton.c b/gtk/gtkradiobutton.c
index 085f9ee..95b89b2 100644
--- a/gtk/gtkradiobutton.c
+++ b/gtk/gtkradiobutton.c
@@ -121,8 +121,6 @@ static void gtk_radio_button_destroy (GtkWidget *widget);
static gboolean gtk_radio_button_focus (GtkWidget *widget,
GtkDirectionType direction);
static void gtk_radio_button_clicked (GtkButton *button);
-static void gtk_radio_button_draw_indicator (GtkCheckButton *check_button,
- cairo_t *cr);
static void gtk_radio_button_set_property (GObject *object,
guint prop_id,
const GValue *value,
@@ -169,8 +167,6 @@ gtk_radio_button_class_init (GtkRadioButtonClass *class)
button_class->clicked = gtk_radio_button_clicked;
- check_button_class->draw_indicator = gtk_radio_button_draw_indicator;
-
class->group_changed = NULL;
/**
@@ -209,8 +205,9 @@ gtk_radio_button_init (GtkRadioButton *radio_button)
gtk_widget_set_has_window (GTK_WIDGET (radio_button), FALSE);
gtk_widget_set_receives_default (GTK_WIDGET (radio_button), FALSE);
-
_gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio_button), TRUE);
+ gtk_button_set_indicator_style (GTK_BUTTON (radio_button),
+ GTK_INDICATOR_STYLE_RADIO);
GTK_BUTTON (radio_button)->priv->depress_on_activate = FALSE;
@@ -660,7 +657,7 @@ gtk_radio_button_focus (GtkWidget *widget,
/* Radio buttons with draw_indicator unset focus "normally", since
* they look like buttons to the user.
*/
- if (!gtk_toggle_button_get_mode (GTK_TOGGLE_BUTTON (widget)))
+ if (gtk_button_get_indicator_style (GTK_BUTTON (widget)) == GTK_INDICATOR_STYLE_PLAIN)
return GTK_WIDGET_CLASS (gtk_radio_button_parent_class)->focus (widget, direction);
if (gtk_widget_is_focus (widget))
@@ -877,85 +874,3 @@ gtk_radio_button_clicked (GtkButton *button)
g_object_unref (button);
}
-
-static void
-gtk_radio_button_draw_indicator (GtkCheckButton *check_button,
- cairo_t *cr)
-{
- GtkAllocation allocation;
- GtkWidget *widget;
- GtkWidget *child;
- GtkButton *button;
- GtkToggleButton *toggle_button;
- GtkStateType state_type;
- GtkShadowType shadow_type;
- GtkStyle *style;
- GdkWindow *window;
- gint x, y;
- gint indicator_size, indicator_spacing;
- gint focus_width;
- gint focus_pad;
- guint border_width;
- gboolean interior_focus;
-
- widget = GTK_WIDGET (check_button);
- button = GTK_BUTTON (check_button);
- toggle_button = GTK_TOGGLE_BUTTON (check_button);
-
- border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
-
- style = gtk_widget_get_style (widget);
- gtk_widget_style_get (widget,
- "interior-focus", &interior_focus,
- "focus-line-width", &focus_width,
- "focus-padding", &focus_pad,
- NULL);
-
- window = gtk_widget_get_window (widget);
-
- _gtk_check_button_get_props (check_button, &indicator_size, &indicator_spacing);
-
- gtk_widget_get_allocation (widget, &allocation);
-
- x = indicator_spacing + border_width;
- y = (allocation.height - indicator_size) / 2;
-
- child = gtk_bin_get_child (GTK_BIN (check_button));
- if (!interior_focus || !(child && gtk_widget_get_visible (child)))
- x += focus_width + focus_pad;
-
- if (gtk_toggle_button_get_inconsistent (toggle_button))
- shadow_type = GTK_SHADOW_ETCHED_IN;
- else if (gtk_toggle_button_get_active (toggle_button))
- shadow_type = GTK_SHADOW_IN;
- else
- shadow_type = GTK_SHADOW_OUT;
-
- if (button->priv->activate_timeout || (button->priv->button_down && button->priv->in_button))
- state_type = GTK_STATE_ACTIVE;
- else if (button->priv->in_button)
- state_type = GTK_STATE_PRELIGHT;
- else if (!gtk_widget_is_sensitive (widget))
- state_type = GTK_STATE_INSENSITIVE;
- else
- state_type = GTK_STATE_NORMAL;
-
- if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
- x = allocation.width - (indicator_size + x);
-
- if (gtk_widget_get_state (widget) == GTK_STATE_PRELIGHT)
- {
- gtk_paint_flat_box (style, cr,
- GTK_STATE_PRELIGHT,
- GTK_SHADOW_ETCHED_OUT,
- widget, "checkbutton",
- border_width, border_width,
- allocation.width - (2 * border_width),
- allocation.height - (2 * border_width));
- }
-
- gtk_paint_option (style, cr,
- state_type, shadow_type,
- widget, "radiobutton",
- x, y, indicator_size, indicator_size);
-}
diff --git a/gtk/gtkradiotoolbutton.c b/gtk/gtkradiotoolbutton.c
index 9a37c18..b04f86a 100644
--- a/gtk/gtkradiotoolbutton.c
+++ b/gtk/gtkradiotoolbutton.c
@@ -73,7 +73,8 @@ static void
gtk_radio_tool_button_init (GtkRadioToolButton *button)
{
GtkToolButton *tool_button = GTK_TOOL_BUTTON (button);
- gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (_gtk_tool_button_get_button (tool_button)), FALSE);
+ gtk_button_set_indicator_style (GTK_BUTTON (_gtk_tool_button_get_button (tool_button)),
+ GTK_INDICATOR_STYLE_PLAIN);
}
static void
diff --git a/gtk/gtktogglebutton.c b/gtk/gtktogglebutton.c
index eda7ab3..ecddc5a 100644
--- a/gtk/gtktogglebutton.c
+++ b/gtk/gtktogglebutton.c
@@ -38,15 +38,10 @@
#include "gtkintl.h"
-#define DEFAULT_LEFT_POS 4
-#define DEFAULT_TOP_POS 4
-#define DEFAULT_SPACING 7
-
struct _GtkToggleButtonPrivate
{
- guint active : 1;
- guint draw_indicator : 1;
- guint inconsistent : 1;
+ guint active : 1;
+ guint inconsistent : 1;
};
enum {
@@ -61,40 +56,46 @@ enum {
PROP_DRAW_INDICATOR
};
-
-static gint gtk_toggle_button_draw (GtkWidget *widget,
- cairo_t *cr);
-static gboolean gtk_toggle_button_mnemonic_activate (GtkWidget *widget,
- gboolean group_cycling);
+static void gtk_toggle_button_get_preferred_width (GtkWidget *widget,
+ gint *minimum,
+ gint *natural);
+static void gtk_toggle_button_get_preferred_height (GtkWidget *widget,
+ gint *minimum,
+ gint *natural);
+static void gtk_toggle_button_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation);
+static gint gtk_toggle_button_draw (GtkWidget *widget,
+ cairo_t *cr);
+static gboolean gtk_toggle_button_mnemonic_activate (GtkWidget *widget,
+ gboolean group_cycling);
static void gtk_toggle_button_pressed (GtkButton *button);
static void gtk_toggle_button_released (GtkButton *button);
static void gtk_toggle_button_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec);
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec);
static void gtk_toggle_button_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec);
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
static void gtk_toggle_button_update_state (GtkButton *button);
static void gtk_toggle_button_action_state_changed (GtkButton *button,
GVariant *state);
-
static void gtk_toggle_button_activatable_interface_init (GtkActivatableIface *iface);
-static void gtk_toggle_button_update (GtkActivatable *activatable,
- GtkAction *action,
- const gchar *property_name);
+static void gtk_toggle_button_update (GtkActivatable *activatable,
+ GtkAction *action,
+ const gchar *property_name);
static void gtk_toggle_button_sync_action_properties (GtkActivatable *activatable,
- GtkAction *action);
+ GtkAction *action);
static GtkActivatableIface *parent_activatable_iface;
static guint toggle_button_signals[LAST_SIGNAL] = { 0 };
G_DEFINE_TYPE_WITH_CODE (GtkToggleButton, gtk_toggle_button, GTK_TYPE_BUTTON,
- G_IMPLEMENT_INTERFACE (GTK_TYPE_ACTIVATABLE,
- gtk_toggle_button_activatable_interface_init))
+ G_IMPLEMENT_INTERFACE (GTK_TYPE_ACTIVATABLE,
+ gtk_toggle_button_activatable_interface_init))
static void
gtk_toggle_button_class_init (GtkToggleButtonClass *class)
@@ -110,6 +111,9 @@ gtk_toggle_button_class_init (GtkToggleButtonClass *class)
gobject_class->set_property = gtk_toggle_button_set_property;
gobject_class->get_property = gtk_toggle_button_get_property;
+ widget_class->get_preferred_width = gtk_toggle_button_get_preferred_width;
+ widget_class->get_preferred_height = gtk_toggle_button_get_preferred_height;
+ widget_class->size_allocate = gtk_toggle_button_size_allocate;
widget_class->draw = gtk_toggle_button_draw;
widget_class->mnemonic_activate = gtk_toggle_button_mnemonic_activate;
@@ -124,35 +128,49 @@ gtk_toggle_button_class_init (GtkToggleButtonClass *class)
g_object_class_install_property (gobject_class,
PROP_ACTIVE,
g_param_spec_boolean ("active",
- P_("Active"),
- P_("If the toggle button should be pressed in"),
- FALSE,
- GTK_PARAM_READWRITE));
+ P_("Active"),
+ P_("If the toggle button should be pressed in"),
+ FALSE,
+ GTK_PARAM_READWRITE));
g_object_class_install_property (gobject_class,
PROP_INCONSISTENT,
g_param_spec_boolean ("inconsistent",
- P_("Inconsistent"),
- P_("If the toggle button is in an \"in between\" state"),
- FALSE,
- GTK_PARAM_READWRITE));
+ P_("Inconsistent"),
+ P_("If the toggle button is in an \"in between\" state"),
+ FALSE,
+ GTK_PARAM_READWRITE));
g_object_class_install_property (gobject_class,
PROP_DRAW_INDICATOR,
g_param_spec_boolean ("draw-indicator",
- P_("Draw Indicator"),
- P_("If the toggle part of the button is displayed"),
- FALSE,
- GTK_PARAM_READWRITE));
+ P_("Draw Indicator"),
+ P_("If the toggle part of the button is displayed"),
+ FALSE,
+ GTK_PARAM_READWRITE|G_PARAM_DEPRECATED));
toggle_button_signals[TOGGLED] =
g_signal_new (I_("toggled"),
- G_OBJECT_CLASS_TYPE (gobject_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (GtkToggleButtonClass, toggled),
- NULL, NULL,
- _gtk_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
+ G_OBJECT_CLASS_TYPE (gobject_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (GtkToggleButtonClass, toggled),
+ NULL, NULL,
+ _gtk_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ gtk_widget_class_install_style_property (widget_class,
+ g_param_spec_int ("indicator-size",
+ P_("Indicator Size"),
+ P_("Size of check or radio indicator"),
+ 0, G_MAXINT, 13,
+ GTK_PARAM_READABLE));
+
+ gtk_widget_class_install_style_property (widget_class,
+ g_param_spec_int ("indicator-spacing",
+ P_("Indicator Spacing"),
+ P_("Spacing around check or radio indicator"),
+ 0, G_MAXINT, 2,
+ GTK_PARAM_READABLE));
g_type_class_add_private (class, sizeof (GtkToggleButtonPrivate));
}
@@ -167,7 +185,6 @@ gtk_toggle_button_init (GtkToggleButton *toggle_button)
GtkToggleButtonPrivate);
priv = toggle_button->priv;
- priv->draw_indicator = FALSE;
GTK_BUTTON (toggle_button)->priv->depress_on_activate = TRUE;
}
@@ -181,8 +198,8 @@ gtk_toggle_button_activatable_interface_init (GtkActivatableIface *iface)
static void
gtk_toggle_button_update (GtkActivatable *activatable,
- GtkAction *action,
- const gchar *property_name)
+ GtkAction *action,
+ const gchar *property_name)
{
GtkToggleButton *button;
@@ -201,7 +218,7 @@ gtk_toggle_button_update (GtkActivatable *activatable,
static void
gtk_toggle_button_sync_action_properties (GtkActivatable *activatable,
- GtkAction *action)
+ GtkAction *action)
{
GtkToggleButton *button;
@@ -272,7 +289,10 @@ gtk_toggle_button_set_property (GObject *object,
gtk_toggle_button_set_inconsistent (tb, g_value_get_boolean (value));
break;
case PROP_DRAW_INDICATOR:
- gtk_toggle_button_set_mode (tb, g_value_get_boolean (value));
+ gtk_button_set_indicator_style (GTK_BUTTON (tb),
+ g_value_get_boolean (value)
+ ? GTK_INDICATOR_STYLE_CHECK
+ : GTK_INDICATOR_STYLE_PLAIN);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -282,9 +302,9 @@ gtk_toggle_button_set_property (GObject *object,
static void
gtk_toggle_button_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
{
GtkToggleButton *tb = GTK_TOGGLE_BUTTON (object);
GtkToggleButtonPrivate *priv = tb->priv;
@@ -298,7 +318,7 @@ gtk_toggle_button_get_property (GObject *object,
g_value_set_boolean (value, priv->inconsistent);
break;
case PROP_DRAW_INDICATOR:
- g_value_set_boolean (value, priv->draw_indicator);
+ g_value_set_boolean (value, gtk_button_get_indicator_style (GTK_BUTTON (object)) != GTK_INDICATOR_STYLE_PLAIN);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -308,7 +328,7 @@ gtk_toggle_button_get_property (GObject *object,
/**
* gtk_toggle_button_set_mode:
- * @toggle_button: a #GtkToggleButton
+ * @button: a #GtkToggleButton
* @draw_indicator: if %TRUE, draw the button as a separate indicator
* and label; if %FALSE, draw the button like a normal button
*
@@ -319,94 +339,86 @@ gtk_toggle_button_get_property (GObject *object,
* This function only affects instances of classes like #GtkCheckButton
* and #GtkRadioButton that derive from #GtkToggleButton,
* not instances of #GtkToggleButton itself.
+ *
+ * Deprecated:3.0: Use gtk_button_set_indicator_style() instead
*/
void
-gtk_toggle_button_set_mode (GtkToggleButton *toggle_button,
- gboolean draw_indicator)
+gtk_toggle_button_set_mode (GtkToggleButton *button,
+ gboolean draw_indicator)
{
- GtkToggleButtonPrivate *priv;
-
- g_return_if_fail (GTK_IS_TOGGLE_BUTTON (toggle_button));
+ g_return_if_fail (GTK_IS_TOGGLE_BUTTON (button));
- priv = toggle_button->priv;
-
- draw_indicator = draw_indicator ? TRUE : FALSE;
-
- if (priv->draw_indicator != draw_indicator)
- {
- priv->draw_indicator = draw_indicator;
- GTK_BUTTON (toggle_button)->priv->depress_on_activate = !draw_indicator;
-
- if (gtk_widget_get_visible (GTK_WIDGET (toggle_button)))
- gtk_widget_queue_resize (GTK_WIDGET (toggle_button));
-
- g_object_notify (G_OBJECT (toggle_button), "draw-indicator");
- }
+ gtk_button_set_indicator_style (GTK_BUTTON (button),
+ draw_indicator ? GTK_INDICATOR_STYLE_CHECK
+ : GTK_INDICATOR_STYLE_PLAIN);
+ g_object_notify (G_OBJECT (button), "draw-indicator");
}
/**
* gtk_toggle_button_get_mode:
- * @toggle_button: a #GtkToggleButton
+ * @button: a #GtkToggleButton
*
* Retrieves whether the button is displayed as a separate indicator
* and label. See gtk_toggle_button_set_mode().
*
* Return value: %TRUE if the togglebutton is drawn as a separate indicator
* and label.
+ *
+ * Deprecated:3.0: Use gtk_button_get_indicator_style() instead
**/
gboolean
-gtk_toggle_button_get_mode (GtkToggleButton *toggle_button)
+gtk_toggle_button_get_mode (GtkToggleButton *button)
{
- g_return_val_if_fail (GTK_IS_TOGGLE_BUTTON (toggle_button), FALSE);
+ g_return_val_if_fail (GTK_IS_TOGGLE_BUTTON (button), FALSE);
- return toggle_button->priv->draw_indicator;
+ return gtk_button_get_indicator_style (GTK_BUTTON (button)) != GTK_INDICATOR_STYLE_PLAIN;
}
void
-gtk_toggle_button_set_active (GtkToggleButton *toggle_button,
+gtk_toggle_button_set_active (GtkToggleButton *button,
gboolean is_active)
{
GtkToggleButtonPrivate *priv;
- g_return_if_fail (GTK_IS_TOGGLE_BUTTON (toggle_button));
+ g_return_if_fail (GTK_IS_TOGGLE_BUTTON (button));
- priv = toggle_button->priv;
+ priv = button->priv;
is_active = is_active != FALSE;
if (priv->active != is_active)
- gtk_button_clicked (GTK_BUTTON (toggle_button));
+ gtk_button_clicked (GTK_BUTTON (button));
}
void
-_gtk_toggle_button_set_active (GtkToggleButton *toggle_button,
+_gtk_toggle_button_set_active (GtkToggleButton *button,
gboolean is_active)
{
g_warning ("this is broken...");
- toggle_button->priv->active = is_active;
+ button->priv->active = is_active;
}
gboolean
-gtk_toggle_button_get_active (GtkToggleButton *toggle_button)
+gtk_toggle_button_get_active (GtkToggleButton *button)
{
- g_return_val_if_fail (GTK_IS_TOGGLE_BUTTON (toggle_button), FALSE);
+ g_return_val_if_fail (GTK_IS_TOGGLE_BUTTON (button), FALSE);
- return toggle_button->priv->active;
+ return button->priv->active;
}
void
-gtk_toggle_button_toggled (GtkToggleButton *toggle_button)
+gtk_toggle_button_toggled (GtkToggleButton *button)
{
- g_return_if_fail (GTK_IS_TOGGLE_BUTTON (toggle_button));
+ g_return_if_fail (GTK_IS_TOGGLE_BUTTON (button));
- g_signal_emit (toggle_button, toggle_button_signals[TOGGLED], 0);
+ g_signal_emit (button, toggle_button_signals[TOGGLED], 0);
}
/**
* gtk_toggle_button_set_inconsistent:
- * @toggle_button: a #GtkToggleButton
- * @setting: %TRUE if state is inconsistent
+ * @button: a #GtkToggleButton
+ * @is_inconsistent: %TRUE if state is inconsistent
*
* If the user has selected a range of elements (such as some text or
* spreadsheet cells) that are affected by a toggle button, and the
@@ -416,75 +428,350 @@ gtk_toggle_button_toggled (GtkToggleButton *toggle_button)
* state again if the user toggles the toggle button. This has to be
* done manually, gtk_toggle_button_set_inconsistent() only affects
* visual appearance, it doesn't affect the semantics of the button.
- *
**/
void
-gtk_toggle_button_set_inconsistent (GtkToggleButton *toggle_button,
- gboolean setting)
+gtk_toggle_button_set_inconsistent (GtkToggleButton *button,
+ gboolean is_inconsistent)
{
GtkToggleButtonPrivate *priv;
- g_return_if_fail (GTK_IS_TOGGLE_BUTTON (toggle_button));
+ g_return_if_fail (GTK_IS_TOGGLE_BUTTON (button));
- priv = toggle_button->priv;
+ priv = button->priv;
- setting = setting != FALSE;
+ is_inconsistent = is_inconsistent != FALSE;
- if (setting != priv->inconsistent)
+ if (priv->inconsistent != is_inconsistent)
{
- priv->inconsistent = setting;
+ priv->inconsistent = is_inconsistent;
- gtk_toggle_button_update_state (GTK_BUTTON (toggle_button));
- gtk_widget_queue_draw (GTK_WIDGET (toggle_button));
+ gtk_toggle_button_update_state (GTK_BUTTON (button));
+ gtk_widget_queue_draw (GTK_WIDGET (button));
- g_object_notify (G_OBJECT (toggle_button), "inconsistent");
+ g_object_notify (G_OBJECT (button), "inconsistent");
}
}
/**
* gtk_toggle_button_get_inconsistent:
- * @toggle_button: a #GtkToggleButton
+ * @button: a #GtkToggleButton
*
* Gets the value set by gtk_toggle_button_set_inconsistent().
*
- * Return value: %TRUE if the button is displayed as inconsistent, %FALSE otherwise
+ * Return value: %TRUE if the button is displayed as inconsistent,
+ * %FALSE otherwise
**/
gboolean
-gtk_toggle_button_get_inconsistent (GtkToggleButton *toggle_button)
+gtk_toggle_button_get_inconsistent (GtkToggleButton *button)
{
- g_return_val_if_fail (GTK_IS_TOGGLE_BUTTON (toggle_button), FALSE);
+ g_return_val_if_fail (GTK_IS_TOGGLE_BUTTON (button), FALSE);
- return toggle_button->priv->inconsistent;
+ return button->priv->inconsistent;
+}
+
+static void
+gtk_toggle_button_get_preferred_width (GtkWidget *widget,
+ gint *minimum,
+ gint *natural)
+{
+ GtkToggleButton *button = GTK_TOGGLE_BUTTON (widget);
+ GtkToggleButtonPrivate *priv = button->priv;
+
+ if (gtk_button_get_indicator_style (GTK_BUTTON (widget)) != GTK_INDICATOR_STYLE_PLAIN)
+ {
+ GtkWidget *child;
+ gint indicator_size;
+ gint indicator_spacing;
+ gint focus_width;
+ gint focus_pad;
+ guint border_width;
+
+ border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
+
+ gtk_widget_style_get (GTK_WIDGET (widget),
+ "focus-line-width", &focus_width,
+ "focus-padding", &focus_pad,
+ "indicator-size", &indicator_size,
+ "indicator-spacing", &indicator_spacing,
+ NULL);
+ *minimum = 2 * border_width;
+ *natural = 2 * border_width;
+
+ child = gtk_bin_get_child (GTK_BIN (widget));
+ if (child && gtk_widget_get_visible (child))
+ {
+ gint child_min, child_nat;
+
+ gtk_widget_get_preferred_width (child, &child_min, &child_nat);
+
+ *minimum += child_min + indicator_spacing;
+ *natural += child_nat + indicator_spacing;
+ }
+
+ *minimum += (indicator_size + indicator_spacing * 2 + 2 * (focus_width + focus_pad));
+ *natural += (indicator_size + indicator_spacing * 2 + 2 * (focus_width + focus_pad));
+ }
+ else
+ GTK_WIDGET_CLASS (gtk_toggle_button_parent_class)->get_preferred_width (widget, minimum, natural);
+}
+
+static void
+gtk_toggle_button_get_preferred_height (GtkWidget *widget,
+ gint *minimum,
+ gint *natural)
+{
+ GtkToggleButton *button = GTK_TOGGLE_BUTTON (widget);
+ GtkToggleButtonPrivate *priv = button->priv;
+
+ if (gtk_button_get_indicator_style (GTK_BUTTON (widget)) != GTK_INDICATOR_STYLE_PLAIN)
+ {
+ GtkWidget *child;
+ gint temp;
+ gint indicator_size;
+ gint indicator_spacing;
+ gint focus_width;
+ gint focus_pad;
+ guint border_width;
+
+ border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
+
+ gtk_widget_style_get (GTK_WIDGET (widget),
+ "focus-line-width", &focus_width,
+ "focus-padding", &focus_pad,
+ "indicator-size", &indicator_size,
+ "indicator-spacing", &indicator_spacing,
+ NULL);
+
+ *minimum = border_width * 2;
+ *natural = border_width * 2;
+
+ child = gtk_bin_get_child (GTK_BIN (widget));
+ if (child && gtk_widget_get_visible (child))
+ {
+ gint child_min, child_nat;
+
+ gtk_widget_get_preferred_height (child, &child_min, &child_nat);
+
+ *minimum += child_min;
+ *natural += child_nat;
+ }
+
+ temp = indicator_size + indicator_spacing * 2;
+ *minimum = MAX (*minimum, temp) + 2 * (focus_width + focus_pad);
+ *natural = MAX (*natural, temp) + 2 * (focus_width + focus_pad);
+ }
+ else
+ GTK_WIDGET_CLASS (gtk_toggle_button_parent_class)->get_preferred_height (widget, minimum, natural);
+}
+
+static void
+gtk_toggle_button_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation)
+{
+ GtkToggleButton *button = GTK_TOGGLE_BUTTON (widget);
+ GtkToggleButtonPrivate *priv = button->priv;
+ GtkAllocation child_allocation;
+
+ if (gtk_button_get_indicator_style (GTK_BUTTON (widget)) != GTK_INDICATOR_STYLE_PLAIN)
+ {
+ GtkWidget *child;
+ gint indicator_size;
+ gint indicator_spacing;
+ gint focus_width;
+ gint focus_pad;
+
+ gtk_widget_style_get (widget,
+ "focus-line-width", &focus_width,
+ "focus-padding", &focus_pad,
+ "indicator-size", &indicator_size,
+ "indicator-spacing", &indicator_spacing,
+ NULL);
+
+ gtk_widget_set_allocation (widget, allocation);
+
+ if (gtk_widget_get_realized (widget))
+ gdk_window_move_resize (gtk_button_get_event_window (GTK_BUTTON (widget)),
+ allocation->x, allocation->y,
+ allocation->width, allocation->height);
+
+ child = gtk_bin_get_child (GTK_BIN (widget));
+ if (child && gtk_widget_get_visible (child))
+ {
+ GtkRequisition child_requisition;
+ guint border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
+
+ gtk_widget_get_preferred_size (child, &child_requisition, NULL);
+ child_allocation.width = MIN (child_requisition.width,
+ allocation->width -
+ ((border_width + focus_width + focus_pad) * 2
+ + indicator_size + indicator_spacing * 3));
+ child_allocation.width = MAX (child_allocation.width, 1);
+
+ child_allocation.height = MIN (child_requisition.height,
+ allocation->height - (border_width + focus_width + focus_pad) * 2);
+ child_allocation.height = MAX (child_allocation.height, 1);
+
+ child_allocation.x = (border_width + indicator_size + indicator_spacing * 3 +
+ allocation->x + focus_width + focus_pad);
+ child_allocation.y = allocation->y + (allocation->height - child_allocation.height) / 2;
+
+ if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
+ child_allocation.x = allocation->x + allocation->width
+ - (child_allocation.x - allocation->x + child_allocation.width);
+
+ gtk_widget_size_allocate (child, &child_allocation);
+ }
+ }
+ else
+ GTK_WIDGET_CLASS (gtk_toggle_button_parent_class)->size_allocate (widget, allocation);
+}
+
+static void
+gtk_toggle_button_draw_indicator (GtkToggleButton *button,
+ cairo_t *cr)
+{
+ GtkWidget *widget = GTK_WIDGET (button);
+ GtkWidget *child;
+ GtkStateType state_type;
+ GtkShadowType shadow_type;
+ gint x, y;
+ gint indicator_size;
+ gint indicator_spacing;
+ gint focus_width;
+ gint focus_pad;
+ guint border_width;
+ gboolean interior_focus;
+
+ gtk_widget_style_get (widget,
+ "interior-focus", &interior_focus,
+ "focus-line-width", &focus_width,
+ "focus-padding", &focus_pad,
+ "indicator-size", &indicator_size,
+ "indicator-spacing", &indicator_spacing,
+ NULL);
+
+ border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
+
+ x = indicator_spacing + border_width;
+ y = (gtk_widget_get_allocated_height (widget) - indicator_size) / 2;
+
+ child = gtk_bin_get_child (GTK_BIN (widget));
+ if (!interior_focus || !(child && gtk_widget_get_visible (child)))
+ x += focus_width + focus_pad;
+
+ if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
+ x = gtk_widget_get_allocated_width (widget) - (indicator_size + x);
+
+ if (gtk_toggle_button_get_inconsistent (button))
+ shadow_type = GTK_SHADOW_ETCHED_IN;
+ else if (gtk_toggle_button_get_active (button))
+ shadow_type = GTK_SHADOW_IN;
+ else
+ shadow_type = GTK_SHADOW_OUT;
+
+ if (GTK_BUTTON (widget)->priv->activate_timeout ||
+ (GTK_BUTTON (widget)->priv->button_down && GTK_BUTTON (widget)->priv->in_button))
+ state_type = GTK_STATE_ACTIVE;
+ else if (GTK_BUTTON (widget)->priv->in_button)
+ state_type = GTK_STATE_PRELIGHT;
+ else if (!gtk_widget_is_sensitive (widget))
+ state_type = GTK_STATE_INSENSITIVE;
+ else
+ state_type = GTK_STATE_NORMAL;
+
+ if (gtk_widget_get_state (widget) == GTK_STATE_PRELIGHT)
+ gtk_paint_flat_box (gtk_widget_get_style (widget), cr, GTK_STATE_PRELIGHT,
+ GTK_SHADOW_ETCHED_OUT,
+ widget, "checkbutton",
+ border_width, border_width,
+ gtk_widget_get_allocated_width (widget) - (2 * border_width),
+ gtk_widget_get_allocated_height (widget) - (2 * border_width));
+
+ if (gtk_button_get_indicator_style (GTK_BUTTON (widget)) == GTK_INDICATOR_STYLE_CHECK)
+ gtk_paint_check (gtk_widget_get_style (widget), cr,
+ state_type, shadow_type,
+ widget, "checkbutton",
+ x, y, indicator_size, indicator_size);
+ else
+ gtk_paint_option (gtk_widget_get_style (widget), cr,
+ state_type, shadow_type,
+ widget, "radiobutton",
+ x, y, indicator_size, indicator_size);
}
static gint
gtk_toggle_button_draw (GtkWidget *widget,
- cairo_t *cr)
+ cairo_t *cr)
{
- GtkToggleButton *toggle_button = GTK_TOGGLE_BUTTON (widget);
- GtkToggleButtonPrivate *priv = toggle_button->priv;
- GtkWidget *child = gtk_bin_get_child (GTK_BIN (widget));
- GtkButton *button = GTK_BUTTON (widget);
- GtkStateType state_type;
+ GtkToggleButton *button = GTK_TOGGLE_BUTTON (widget);
+ GtkToggleButtonPrivate *priv = button->priv;
+ GtkStateType state;
GtkShadowType shadow_type;
+ GtkWidget *child;
+ gint interior_focus;
+ gint focus_width;
+ gint focus_pad;
+ gint border_width;
+ GtkAllocation allocation;
- state_type = gtk_widget_get_state (widget);
+ gtk_widget_get_allocation (widget, &allocation);
+ state = gtk_widget_get_state (widget);
- if (priv->inconsistent)
+ if (gtk_button_get_indicator_style (GTK_BUTTON (widget)) != GTK_INDICATOR_STYLE_PLAIN)
{
- if (state_type == GTK_STATE_ACTIVE)
- state_type = GTK_STATE_NORMAL;
- shadow_type = GTK_SHADOW_ETCHED_IN;
+ gtk_toggle_button_draw_indicator (button, cr);
+
+ if (gtk_widget_has_focus (widget))
+ {
+ border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
+ gtk_widget_style_get (widget,
+ "interior-focus", &interior_focus,
+ "focus-line-width", &focus_width,
+ "focus-padding", &focus_pad,
+ NULL);
+
+ child = gtk_bin_get_child (GTK_BIN (widget));
+ if (interior_focus && child && gtk_widget_get_visible (child))
+ {
+ GtkAllocation child_allocation;
+
+ gtk_widget_get_allocation (child, &child_allocation);
+ gtk_paint_focus (gtk_widget_get_style (widget), cr, state,
+ widget, "checkbutton",
+ child_allocation.x - allocation.x - focus_width - focus_pad,
+ child_allocation.y - allocation.y - focus_width - focus_pad,
+ child_allocation.width + 2 * (focus_width + focus_pad),
+ child_allocation.height + 2 * (focus_width + focus_pad));
+ }
+ else
+ {
+ gtk_paint_focus (gtk_widget_get_style (widget), cr, state,
+ widget, "checkbutton",
+ border_width,
+ border_width,
+ allocation.width - 2 * border_width,
+ allocation.height - 2 * border_width);
+ }
+ }
}
else
- shadow_type = button->priv->depressed ? GTK_SHADOW_IN : GTK_SHADOW_OUT;
-
- _gtk_button_paint (button, cr,
- gtk_widget_get_allocated_width (widget),
- gtk_widget_get_allocated_height (widget),
- state_type, shadow_type,
- "togglebutton", "togglebuttondefault");
+ {
+ if (priv->inconsistent)
+ {
+ if (state == GTK_STATE_ACTIVE)
+ state = GTK_STATE_NORMAL;
+ shadow_type = GTK_SHADOW_ETCHED_IN;
+ }
+ else
+ shadow_type = GTK_BUTTON (widget)->priv->depressed ? GTK_SHADOW_IN : GTK_SHADOW_OUT;
+
+ _gtk_button_paint (GTK_BUTTON (widget), cr,
+ allocation.width, allocation.height,
+ state, shadow_type,
+ "togglebutton", "togglebuttondefault");
+ }
+ child = gtk_bin_get_child (GTK_BIN (widget));
if (child)
gtk_container_propagate_draw (GTK_CONTAINER (widget), child, cr);
@@ -526,7 +813,7 @@ gtk_toggle_button_released (GtkButton *button)
button->priv->button_down = FALSE;
if (button->priv->in_button)
- gtk_button_clicked (button);
+ gtk_button_clicked (button);
gtk_toggle_button_update_state (button);
gtk_widget_queue_draw (GTK_WIDGET (button));
@@ -570,11 +857,12 @@ gtk_toggle_button_update_state (GtkButton *button)
else
depressed = priv->active;
- if (!touchscreen && button->priv->in_button && (!button->priv->button_down || priv->draw_indicator))
+ if (!touchscreen && button->priv->in_button &&
+ (!button->priv->button_down || button->priv->indicator_style != GTK_INDICATOR_STYLE_PLAIN))
new_state = GTK_STATE_PRELIGHT;
else
new_state = depressed ? GTK_STATE_ACTIVE : GTK_STATE_NORMAL;
- _gtk_button_set_depressed (button, depressed);
+ _gtk_button_set_depressed (button, depressed);
gtk_widget_set_state (GTK_WIDGET (toggle_button), new_state);
}
diff --git a/gtk/gtktogglebutton.h b/gtk/gtktogglebutton.h
index 48b477c..0ff9280 100644
--- a/gtk/gtktogglebutton.h
+++ b/gtk/gtktogglebutton.h
@@ -60,7 +60,7 @@ struct _GtkToggleButtonClass
{
GtkButtonClass parent_class;
- void (* toggled) (GtkToggleButton *toggle_button);
+ void (* toggled) (GtkToggleButton *toggle_button);
/* Padding for future expansion */
void (*_gtk_reserved1) (void);
@@ -70,24 +70,26 @@ struct _GtkToggleButtonClass
};
-GType gtk_toggle_button_get_type (void) G_GNUC_CONST;
-
-GtkWidget* gtk_toggle_button_new (void);
-GtkWidget* gtk_toggle_button_new_with_label (const gchar *label);
-GtkWidget* gtk_toggle_button_new_with_mnemonic (const gchar *label);
-void gtk_toggle_button_set_mode (GtkToggleButton *toggle_button,
- gboolean draw_indicator);
-gboolean gtk_toggle_button_get_mode (GtkToggleButton *toggle_button);
-void gtk_toggle_button_set_active (GtkToggleButton *toggle_button,
- gboolean is_active);
-gboolean gtk_toggle_button_get_active (GtkToggleButton *toggle_button);
-void gtk_toggle_button_toggled (GtkToggleButton *toggle_button);
-void gtk_toggle_button_set_inconsistent (GtkToggleButton *toggle_button,
- gboolean setting);
-gboolean gtk_toggle_button_get_inconsistent (GtkToggleButton *toggle_button);
-
-void _gtk_toggle_button_set_active (GtkToggleButton *toggle_button,
- gboolean is_active);
+GType gtk_toggle_button_get_type (void) G_GNUC_CONST;
+
+GtkWidget* gtk_toggle_button_new (void);
+GtkWidget* gtk_toggle_button_new_with_label (const gchar *label);
+GtkWidget* gtk_toggle_button_new_with_mnemonic (const gchar *label);
+#ifndef GTK_DISABLE_DEPRECATED
+void gtk_toggle_button_set_mode (GtkToggleButton *button,
+ gboolean mode);
+gboolean gtk_toggle_button_get_mode (GtkToggleButton *button);
+#endif
+void gtk_toggle_button_set_active (GtkToggleButton *button,
+ gboolean is_active);
+gboolean gtk_toggle_button_get_active (GtkToggleButton *button);
+void gtk_toggle_button_set_inconsistent (GtkToggleButton *button,
+ gboolean is_inconsistent);
+gboolean gtk_toggle_button_get_inconsistent (GtkToggleButton *button);
+void gtk_toggle_button_toggled (GtkToggleButton *button);
+
+void _gtk_toggle_button_set_active (GtkToggleButton *button,
+ gboolean is_active);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]