Compare commits
5 Commits
reverse-li
...
buttons
Author | SHA1 | Date | |
---|---|---|---|
|
8713d6bff6 | ||
|
9a01b164e3 | ||
|
7c7a10c7c1 | ||
|
1a423ac766 | ||
|
da39db7b2f |
364
gtk/gtkbutton.c
364
gtk/gtkbutton.c
@@ -76,6 +76,7 @@ enum {
|
||||
ENTER,
|
||||
LEAVE,
|
||||
ACTIVATE,
|
||||
TOGGLED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
@@ -90,6 +91,10 @@ enum {
|
||||
PROP_XALIGN,
|
||||
PROP_YALIGN,
|
||||
PROP_IMAGE_POSITION,
|
||||
PROP_ACTION,
|
||||
PROP_INDICATOR_STYLE,
|
||||
PROP_ACTIVE,
|
||||
PROP_INCONSISTENT,
|
||||
|
||||
/* activatable properties */
|
||||
PROP_ACTIVATABLE_RELATED_ACTION,
|
||||
@@ -99,6 +104,7 @@ enum {
|
||||
|
||||
static void gtk_button_destroy (GtkWidget *widget);
|
||||
static void gtk_button_dispose (GObject *object);
|
||||
static void gtk_button_finalize (GObject *object);
|
||||
static void gtk_button_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
const GValue *value,
|
||||
@@ -188,6 +194,7 @@ gtk_button_class_init (GtkButtonClass *klass)
|
||||
gobject_class->dispose = gtk_button_dispose;
|
||||
gobject_class->set_property = gtk_button_set_property;
|
||||
gobject_class->get_property = gtk_button_get_property;
|
||||
gobject_class->finalize = gtk_button_finalize;
|
||||
|
||||
widget_class->get_preferred_width = gtk_button_get_preferred_width;
|
||||
widget_class->get_preferred_height = gtk_button_get_preferred_height;
|
||||
@@ -330,6 +337,46 @@ gtk_button_class_init (GtkButtonClass *klass)
|
||||
GTK_POS_LEFT,
|
||||
GTK_PARAM_READWRITE));
|
||||
|
||||
/**
|
||||
* GtkButton:action:
|
||||
*
|
||||
* The #GAction that the button activates.
|
||||
*
|
||||
* Since: 3.0
|
||||
*/
|
||||
g_object_class_install_property (gobject_class,
|
||||
PROP_ACTION,
|
||||
g_param_spec_object ("action",
|
||||
P_("Action"),
|
||||
P_("The GAction that the button activates."),
|
||||
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_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));
|
||||
|
||||
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));
|
||||
|
||||
|
||||
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");
|
||||
|
||||
@@ -435,6 +482,15 @@ gtk_button_class_init (GtkButtonClass *klass)
|
||||
G_TYPE_NONE, 0);
|
||||
widget_class->activate_signal = button_signals[ACTIVATE];
|
||||
|
||||
button_signals[TOGGLED] =
|
||||
g_signal_new (I_("toggled"),
|
||||
G_OBJECT_CLASS_TYPE (gobject_class),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET (GtkButtonClass, toggled),
|
||||
NULL, NULL,
|
||||
_gtk_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
/**
|
||||
* GtkButton:default-border:
|
||||
*
|
||||
@@ -526,6 +582,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));
|
||||
}
|
||||
|
||||
@@ -561,6 +631,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
|
||||
@@ -578,6 +649,77 @@ gtk_button_destroy (GtkWidget *widget)
|
||||
GTK_WIDGET_CLASS (gtk_button_parent_class)->destroy (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_button_action_state_changed (GAction *action,
|
||||
GParamSpec *pspec,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkButton *button = GTK_BUTTON (user_data);
|
||||
GVariant *state;
|
||||
gboolean active;
|
||||
|
||||
state = g_action_get_state (action);
|
||||
|
||||
active = g_variant_is_of_type (state, G_VARIANT_TYPE_BOOLEAN) &&
|
||||
g_variant_get_boolean (state);
|
||||
|
||||
if (active != button->priv->active)
|
||||
{
|
||||
button->priv->active = active;
|
||||
|
||||
gtk_button_toggled (button);
|
||||
gtk_button_update_state (button);
|
||||
g_object_notify (G_OBJECT (button), "active");
|
||||
}
|
||||
|
||||
g_variant_unref (state);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_button_release_action (GtkButton *button)
|
||||
{
|
||||
if (button->priv->state_id)
|
||||
g_signal_handler_disconnect (button->priv->g_action,
|
||||
button->priv->state_id);
|
||||
|
||||
if (button->priv->g_action)
|
||||
g_object_unref (button->priv->g_action);
|
||||
|
||||
button->priv->state_id = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_button_setup_action (GtkButton *button)
|
||||
{
|
||||
GVariant *state;
|
||||
gboolean active;
|
||||
|
||||
state = g_action_get_state (button->priv->g_action);
|
||||
|
||||
if (state != NULL)
|
||||
{
|
||||
button->priv->state_id =
|
||||
g_signal_connect (button->priv->g_action, "notify::state",
|
||||
G_CALLBACK (gtk_button_action_state_changed), button);
|
||||
|
||||
active = g_variant_is_of_type (state, G_VARIANT_TYPE_BOOLEAN) &&
|
||||
g_variant_get_boolean (state);
|
||||
|
||||
g_variant_unref (state);
|
||||
}
|
||||
else
|
||||
active = FALSE;
|
||||
|
||||
if (active != button->priv->active)
|
||||
{
|
||||
button->priv->active = active;
|
||||
|
||||
gtk_button_toggled (button);
|
||||
gtk_button_update_state (button);
|
||||
g_object_notify (G_OBJECT (button), "active");
|
||||
}
|
||||
}
|
||||
|
||||
static GObject*
|
||||
gtk_button_constructor (GType type,
|
||||
guint n_construct_properties,
|
||||
@@ -596,9 +738,22 @@ gtk_button_constructor (GType type,
|
||||
|
||||
priv->constructed = TRUE;
|
||||
|
||||
if (priv->g_action == NULL)
|
||||
{
|
||||
priv->g_action = G_ACTION (g_simple_action_new ("anonymous", NULL));
|
||||
gtk_button_setup_action (button);
|
||||
}
|
||||
|
||||
if (priv->label_text != NULL)
|
||||
gtk_button_construct_child (button);
|
||||
|
||||
|
||||
/* This should be a default handler, but for compatibility reasons
|
||||
* we need to support derived classes that don't chain up their
|
||||
* clicked handler.
|
||||
*/
|
||||
g_signal_connect_after (button, "clicked",
|
||||
G_CALLBACK (gtk_real_button_clicked), NULL);
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
@@ -662,9 +817,21 @@ gtk_button_dispose (GObject *object)
|
||||
gtk_activatable_do_set_related_action (GTK_ACTIVATABLE (button), NULL);
|
||||
priv->action = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (gtk_button_parent_class)->dispose (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_button_finalize (GObject *object)
|
||||
{
|
||||
GtkButton *button = GTK_BUTTON (object);
|
||||
|
||||
gtk_button_release_action (button);
|
||||
|
||||
G_OBJECT_CLASS (gtk_button_parent_class)
|
||||
->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_button_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
@@ -703,6 +870,19 @@ gtk_button_set_property (GObject *object,
|
||||
case PROP_IMAGE_POSITION:
|
||||
gtk_button_set_image_position (button, g_value_get_enum (value));
|
||||
break;
|
||||
case PROP_ACTION:
|
||||
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_ACTIVE:
|
||||
gtk_button_set_active (button, g_value_get_boolean (value));
|
||||
break;
|
||||
case PROP_INCONSISTENT:
|
||||
gtk_button_set_inconsistent (button, g_value_get_boolean (value));
|
||||
break;
|
||||
case PROP_ACTIVATABLE_RELATED_ACTION:
|
||||
gtk_button_set_related_action (button, g_value_get_object (value));
|
||||
break;
|
||||
@@ -753,6 +933,18 @@ gtk_button_get_property (GObject *object,
|
||||
case PROP_IMAGE_POSITION:
|
||||
g_value_set_enum (value, priv->image_position);
|
||||
break;
|
||||
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_ACTIVE:
|
||||
g_value_set_boolean (value, priv->active);
|
||||
break;
|
||||
case PROP_INCONSISTENT:
|
||||
g_value_set_boolean (value, priv->inconsistent);
|
||||
break;
|
||||
case PROP_ACTIVATABLE_RELATED_ACTION:
|
||||
g_value_set_object (value, priv->action);
|
||||
break;
|
||||
@@ -893,6 +1085,32 @@ gtk_button_sync_action_properties (GtkActivatable *activatable,
|
||||
}
|
||||
}
|
||||
|
||||
GAction *
|
||||
gtk_button_get_action (GtkButton *button)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_BUTTON (button), NULL);
|
||||
|
||||
return button->priv->g_action;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_button_set_action (GtkButton *button,
|
||||
GAction *action)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_BUTTON (button));
|
||||
g_return_if_fail (G_IS_ACTION (action));
|
||||
|
||||
if (button->priv->g_action != action)
|
||||
{
|
||||
g_object_freeze_notify (G_OBJECT (button));
|
||||
gtk_button_release_action (button);
|
||||
button->priv->g_action = g_object_ref (action);
|
||||
gtk_button_setup_action (button);
|
||||
g_object_notify (G_OBJECT (button), "action");
|
||||
g_object_thaw_notify (G_OBJECT (button));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_button_set_related_action (GtkButton *button,
|
||||
GtkAction *action)
|
||||
@@ -902,15 +1120,6 @@ gtk_button_set_related_action (GtkButton *button,
|
||||
if (priv->action == action)
|
||||
return;
|
||||
|
||||
/* This should be a default handler, but for compatibility reasons
|
||||
* we need to support derived classes that don't chain up their
|
||||
* clicked handler.
|
||||
*/
|
||||
g_signal_handlers_disconnect_by_func (button, gtk_real_button_clicked, NULL);
|
||||
if (action)
|
||||
g_signal_connect_after (button, "clicked",
|
||||
G_CALLBACK (gtk_real_button_clicked), NULL);
|
||||
|
||||
gtk_activatable_do_set_related_action (GTK_ACTIVATABLE (button), action);
|
||||
|
||||
priv->action = action;
|
||||
@@ -1779,6 +1988,7 @@ gtk_real_button_pressed (GtkButton *button)
|
||||
|
||||
priv->button_down = TRUE;
|
||||
gtk_button_update_state (button);
|
||||
gtk_widget_queue_draw (GTK_WIDGET (button));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1797,6 +2007,7 @@ gtk_real_button_released (GtkButton *button)
|
||||
gtk_button_clicked (button);
|
||||
|
||||
gtk_button_update_state (button);
|
||||
gtk_widget_queue_draw (GTK_WIDGET (button));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1807,6 +2018,9 @@ gtk_real_button_clicked (GtkButton *button)
|
||||
|
||||
if (priv->action)
|
||||
gtk_action_activate (priv->action);
|
||||
|
||||
if (priv->g_action)
|
||||
g_action_activate (priv->g_action, NULL);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -2255,15 +2469,22 @@ static void
|
||||
gtk_button_update_state (GtkButton *button)
|
||||
{
|
||||
GtkButtonPrivate *priv = button->priv;
|
||||
gboolean depressed, touchscreen;
|
||||
GtkStateType new_state;
|
||||
gboolean depressed;
|
||||
|
||||
g_object_get (gtk_widget_get_settings (GTK_WIDGET (button)),
|
||||
"gtk-touchscreen-mode", &touchscreen,
|
||||
NULL);
|
||||
|
||||
if (priv->activate_timeout)
|
||||
depressed = priv->depress_on_activate;
|
||||
else if (priv->in_button && priv->button_down)
|
||||
depressed = TRUE;
|
||||
else
|
||||
depressed = priv->in_button && priv->button_down;
|
||||
depressed = button->priv->active;
|
||||
|
||||
if (priv->in_button && (!priv->button_down || !depressed))
|
||||
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;
|
||||
@@ -2517,3 +2738,120 @@ 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;
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_button_set_active (GtkButton *button,
|
||||
gboolean active)
|
||||
{
|
||||
g_warning ("this is broken...");
|
||||
button->priv->active = active;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_button_set_active (GtkButton *button,
|
||||
gboolean active)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_BUTTON (button));
|
||||
|
||||
active = active != FALSE;
|
||||
|
||||
if (button->priv->active != active)
|
||||
gtk_button_clicked (button);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gtk_button_get_active (GtkButton *button)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_BUTTON (button), FALSE);
|
||||
|
||||
return button->priv->active;
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_button_set_inconsistent:
|
||||
* @button: a #GtkButton
|
||||
* @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
|
||||
* current values in that range are inconsistent, you may want to
|
||||
* display the toggle in an "in between" state. This function turns on
|
||||
* "in between" display. Normally you would turn off the inconsistent
|
||||
* 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_button_set_inconsistent (GtkButton *button,
|
||||
gboolean inconsistent)
|
||||
{
|
||||
GtkButtonPrivate *priv;
|
||||
|
||||
g_return_if_fail (GTK_IS_BUTTON (button));
|
||||
|
||||
priv = button->priv;
|
||||
|
||||
inconsistent = inconsistent != FALSE;
|
||||
|
||||
if (priv->inconsistent != inconsistent)
|
||||
{
|
||||
priv->inconsistent = inconsistent;
|
||||
|
||||
gtk_button_update_state (GTK_BUTTON (button));
|
||||
gtk_widget_queue_draw (GTK_WIDGET (button));
|
||||
|
||||
g_object_notify (G_OBJECT (button), "inconsistent");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_button_get_inconsistent:
|
||||
* @button: a #GtkButton
|
||||
*
|
||||
* Gets the value set by gtk_button_set_inconsistent().
|
||||
*
|
||||
* Return value: %TRUE if the button is displayed as inconsistent,
|
||||
* %FALSE otherwise
|
||||
**/
|
||||
gboolean
|
||||
gtk_button_get_inconsistent (GtkButton *button)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_BUTTON (button), FALSE);
|
||||
|
||||
return button->priv->inconsistent;
|
||||
}
|
||||
|
||||
void
|
||||
gtk_button_toggled (GtkButton *button)
|
||||
{
|
||||
g_signal_emit (button, button_signals[TOGGLED], 0);
|
||||
}
|
||||
|
@@ -34,6 +34,7 @@
|
||||
|
||||
#include <gtk/gtkbin.h>
|
||||
#include <gtk/gtkimage.h>
|
||||
#include <gtk/gtkenums.h>
|
||||
|
||||
|
||||
G_BEGIN_DECLS
|
||||
@@ -67,6 +68,7 @@ struct _GtkButtonClass
|
||||
void (* enter) (GtkButton *button);
|
||||
void (* leave) (GtkButton *button);
|
||||
void (* activate) (GtkButton *button);
|
||||
void (* toggled) (GtkButton *button);
|
||||
|
||||
/* Padding for future expansion */
|
||||
void (*_gtk_reserved1) (void);
|
||||
@@ -120,7 +122,20 @@ void gtk_button_set_image_position (GtkButton *button,
|
||||
GtkPositionType gtk_button_get_image_position (GtkButton *button);
|
||||
|
||||
GdkWindow* gtk_button_get_event_window (GtkButton *button);
|
||||
void gtk_button_set_action (GtkButton *button,
|
||||
GAction *action);
|
||||
GAction * gtk_button_get_action (GtkButton *button);
|
||||
gboolean gtk_button_get_active (GtkButton *button);
|
||||
void gtk_button_set_active (GtkButton *button,
|
||||
gboolean active);
|
||||
gboolean gtk_button_get_inconsistent (GtkButton *button);
|
||||
void gtk_button_set_inconsistent (GtkButton *button,
|
||||
gboolean active);
|
||||
|
||||
|
||||
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,
|
||||
@@ -131,6 +146,8 @@ void _gtk_button_paint (GtkButton *button,
|
||||
GtkShadowType shadow_type,
|
||||
const gchar *main_detail,
|
||||
const gchar *default_detail);
|
||||
void _gtk_button_set_active (GtkButton *, gboolean);
|
||||
void gtk_button_toggled (GtkButton *);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
@@ -24,6 +24,10 @@
|
||||
struct _GtkButtonPrivate
|
||||
{
|
||||
GtkAction *action;
|
||||
GAction *g_action;
|
||||
guint state_id;
|
||||
GVariant *state;
|
||||
|
||||
GtkPositionType image_position;
|
||||
GtkWidget *image;
|
||||
|
||||
@@ -38,6 +42,8 @@ struct _GtkButtonPrivate
|
||||
guint activate_timeout;
|
||||
guint32 grab_time;
|
||||
|
||||
guint active : 1;
|
||||
guint inconsistent : 1;
|
||||
guint align_set : 1;
|
||||
guint button_down : 1;
|
||||
guint constructed : 1;
|
||||
@@ -50,6 +56,7 @@ struct _GtkButtonPrivate
|
||||
guint use_action_appearance : 1;
|
||||
guint use_stock : 1;
|
||||
guint use_underline : 1;
|
||||
guint indicator_style : 2;
|
||||
};
|
||||
|
||||
#endif /* __GTK_BUTTON_PRIVATE_H__ */
|
||||
|
@@ -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*
|
||||
@@ -108,7 +57,9 @@ gtk_check_button_new (void)
|
||||
GtkWidget*
|
||||
gtk_check_button_new_with_label (const gchar *label)
|
||||
{
|
||||
return g_object_new (GTK_TYPE_CHECK_BUTTON, "label", label, NULL);
|
||||
return g_object_new (GTK_TYPE_CHECK_BUTTON,
|
||||
"label", label,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -131,353 +82,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);
|
||||
}
|
||||
|
@@ -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__ */
|
||||
|
@@ -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
|
||||
|
||||
|
||||
|
@@ -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_active (GTK_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;
|
||||
|
||||
@@ -440,7 +437,9 @@ gtk_radio_button_new_with_label (GSList *group,
|
||||
{
|
||||
GtkWidget *radio_button;
|
||||
|
||||
radio_button = g_object_new (GTK_TYPE_RADIO_BUTTON, "label", label, NULL) ;
|
||||
radio_button = g_object_new (GTK_TYPE_RADIO_BUTTON,
|
||||
"label", label,
|
||||
NULL);
|
||||
|
||||
if (group)
|
||||
gtk_radio_button_set_group (GTK_RADIO_BUTTON (radio_button), group);
|
||||
@@ -656,7 +655,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))
|
||||
@@ -789,7 +788,7 @@ gtk_radio_button_clicked (GtkButton *button)
|
||||
GtkRadioButton *radio_button = GTK_RADIO_BUTTON (button);
|
||||
GtkRadioButtonPrivate *priv = radio_button->priv;
|
||||
GtkToggleButton *toggle_button = GTK_TOGGLE_BUTTON (button);
|
||||
GtkToggleButton *tmp_button;
|
||||
GtkButton *tmp_button;
|
||||
GtkStateType new_state;
|
||||
GSList *tmp_list;
|
||||
gint toggled;
|
||||
@@ -799,7 +798,7 @@ gtk_radio_button_clicked (GtkButton *button)
|
||||
|
||||
g_object_ref (GTK_WIDGET (button));
|
||||
|
||||
if (gtk_toggle_button_get_active (toggle_button))
|
||||
if (gtk_button_get_active (button))
|
||||
{
|
||||
tmp_button = NULL;
|
||||
tmp_list = priv->group;
|
||||
@@ -809,8 +808,8 @@ gtk_radio_button_clicked (GtkButton *button)
|
||||
tmp_button = tmp_list->data;
|
||||
tmp_list = tmp_list->next;
|
||||
|
||||
if (tmp_button != toggle_button &&
|
||||
gtk_toggle_button_get_active (tmp_button))
|
||||
if (tmp_button != button &&
|
||||
gtk_button_get_active (tmp_button))
|
||||
break;
|
||||
|
||||
tmp_button = NULL;
|
||||
@@ -823,16 +822,14 @@ gtk_radio_button_clicked (GtkButton *button)
|
||||
else
|
||||
{
|
||||
toggled = TRUE;
|
||||
_gtk_toggle_button_set_active (toggle_button,
|
||||
!gtk_toggle_button_get_active (toggle_button));
|
||||
_gtk_button_set_active (button, !gtk_button_get_active (button));
|
||||
new_state = (button->priv->in_button ? GTK_STATE_PRELIGHT : GTK_STATE_NORMAL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
toggled = TRUE;
|
||||
_gtk_toggle_button_set_active (toggle_button,
|
||||
!gtk_toggle_button_get_active (toggle_button));
|
||||
_gtk_button_set_active (button, !gtk_button_get_active (button));
|
||||
|
||||
tmp_list = priv->group;
|
||||
while (tmp_list)
|
||||
@@ -840,7 +837,7 @@ gtk_radio_button_clicked (GtkButton *button)
|
||||
tmp_button = tmp_list->data;
|
||||
tmp_list = tmp_list->next;
|
||||
|
||||
if (gtk_toggle_button_get_active (tmp_button) && (tmp_button != toggle_button))
|
||||
if (gtk_button_get_active (tmp_button) && (tmp_button != button))
|
||||
{
|
||||
gtk_button_clicked (GTK_BUTTON (tmp_button));
|
||||
break;
|
||||
@@ -873,85 +870,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);
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -38,61 +38,44 @@
|
||||
#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;
|
||||
};
|
||||
|
||||
enum {
|
||||
TOGGLED,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
enum {
|
||||
PROP_0,
|
||||
PROP_ACTIVE,
|
||||
PROP_INCONSISTENT,
|
||||
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_pressed (GtkButton *button);
|
||||
static void gtk_toggle_button_released (GtkButton *button);
|
||||
static void gtk_toggle_button_clicked (GtkButton *button);
|
||||
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_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);
|
||||
static void gtk_toggle_button_update_state (GtkButton *button);
|
||||
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec);
|
||||
|
||||
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)
|
||||
@@ -108,65 +91,53 @@ 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;
|
||||
|
||||
button_class->pressed = gtk_toggle_button_pressed;
|
||||
button_class->released = gtk_toggle_button_released;
|
||||
button_class->clicked = gtk_toggle_button_clicked;
|
||||
button_class->enter = gtk_toggle_button_update_state;
|
||||
button_class->leave = gtk_toggle_button_update_state;
|
||||
|
||||
class->toggled = NULL;
|
||||
|
||||
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));
|
||||
|
||||
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));
|
||||
|
||||
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);
|
||||
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));
|
||||
|
||||
g_type_class_add_private (class, sizeof (GtkToggleButtonPrivate));
|
||||
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));
|
||||
}
|
||||
|
||||
static void
|
||||
invert (GAction *action,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_action_set_state (action, g_variant_new_boolean (!g_variant_get_boolean (g_action_get_state (action))));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_toggle_button_init (GtkToggleButton *toggle_button)
|
||||
{
|
||||
GtkToggleButtonPrivate *priv;
|
||||
GSimpleAction *action;
|
||||
|
||||
toggle_button->priv = G_TYPE_INSTANCE_GET_PRIVATE (toggle_button,
|
||||
GTK_TYPE_TOGGLE_BUTTON,
|
||||
GtkToggleButtonPrivate);
|
||||
priv = toggle_button->priv;
|
||||
action = g_simple_action_new_stateful ("anonymous", NULL,
|
||||
g_variant_new_boolean (FALSE));
|
||||
g_signal_connect (action, "activate", G_CALLBACK (invert), NULL);
|
||||
gtk_button_set_action (GTK_BUTTON (toggle_button), G_ACTION (action));
|
||||
g_object_unref (action);
|
||||
|
||||
priv->active = FALSE;
|
||||
priv->draw_indicator = FALSE;
|
||||
GTK_BUTTON (toggle_button)->priv->depress_on_activate = TRUE;
|
||||
}
|
||||
|
||||
@@ -180,8 +151,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;
|
||||
|
||||
@@ -200,7 +171,7 @@ gtk_toggle_button_update (GtkActivatable *activatable,
|
||||
|
||||
static void
|
||||
gtk_toggle_button_sync_action_properties (GtkActivatable *activatable,
|
||||
GtkAction *action)
|
||||
GtkAction *action)
|
||||
{
|
||||
GtkToggleButton *button;
|
||||
|
||||
@@ -226,7 +197,9 @@ gtk_toggle_button_new (void)
|
||||
GtkWidget*
|
||||
gtk_toggle_button_new_with_label (const gchar *label)
|
||||
{
|
||||
return g_object_new (GTK_TYPE_TOGGLE_BUTTON, "label", label, NULL);
|
||||
return g_object_new (GTK_TYPE_TOGGLE_BUTTON,
|
||||
"label", label,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -260,14 +233,11 @@ gtk_toggle_button_set_property (GObject *object,
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_ACTIVE:
|
||||
gtk_toggle_button_set_active (tb, g_value_get_boolean (value));
|
||||
break;
|
||||
case PROP_INCONSISTENT:
|
||||
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);
|
||||
@@ -277,23 +247,14 @@ 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;
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_ACTIVE:
|
||||
g_value_set_boolean (value, priv->active);
|
||||
break;
|
||||
case PROP_INCONSISTENT:
|
||||
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);
|
||||
@@ -303,7 +264,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
|
||||
*
|
||||
@@ -314,93 +275,71 @@ 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 (button));
|
||||
|
||||
g_return_if_fail (GTK_IS_TOGGLE_BUTTON (toggle_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 (button));
|
||||
|
||||
g_return_if_fail (GTK_IS_TOGGLE_BUTTON (toggle_button));
|
||||
|
||||
priv = toggle_button->priv;
|
||||
|
||||
is_active = is_active != FALSE;
|
||||
|
||||
if (priv->active != is_active)
|
||||
gtk_button_clicked (GTK_BUTTON (toggle_button));
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_toggle_button_set_active (GtkToggleButton *toggle_button,
|
||||
gboolean is_active)
|
||||
{
|
||||
toggle_button->priv->active = is_active;
|
||||
gtk_button_set_active (GTK_BUTTON (button), 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 gtk_button_get_active (GTK_BUTTON (button));
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
gtk_button_toggled (GTK_BUTTON (button));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
@@ -410,75 +349,328 @@ 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 (button));
|
||||
|
||||
g_return_if_fail (GTK_IS_TOGGLE_BUTTON (toggle_button));
|
||||
|
||||
priv = toggle_button->priv;
|
||||
|
||||
setting = setting != FALSE;
|
||||
|
||||
if (setting != priv->inconsistent)
|
||||
{
|
||||
priv->inconsistent = setting;
|
||||
|
||||
gtk_toggle_button_update_state (GTK_BUTTON (toggle_button));
|
||||
gtk_widget_queue_draw (GTK_WIDGET (toggle_button));
|
||||
|
||||
g_object_notify (G_OBJECT (toggle_button), "inconsistent");
|
||||
}
|
||||
gtk_button_set_inconsistent (GTK_BUTTON (button), is_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 gtk_button_get_inconsistent (GTK_BUTTON (button));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_toggle_button_get_preferred_width (GtkWidget *widget,
|
||||
gint *minimum,
|
||||
gint *natural)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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 (GtkButton *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_button_get_inconsistent (button))
|
||||
shadow_type = GTK_SHADOW_ETCHED_IN;
|
||||
else if (gtk_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;
|
||||
GtkButtonPrivate *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;
|
||||
{
|
||||
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 (button, cr,
|
||||
gtk_widget_get_allocated_width (widget),
|
||||
gtk_widget_get_allocated_height (widget),
|
||||
state_type, shadow_type,
|
||||
"togglebutton", "togglebuttondefault");
|
||||
_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);
|
||||
|
||||
@@ -502,73 +694,3 @@ gtk_toggle_button_mnemonic_activate (GtkWidget *widget,
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_toggle_button_pressed (GtkButton *button)
|
||||
{
|
||||
button->priv->button_down = TRUE;
|
||||
|
||||
gtk_toggle_button_update_state (button);
|
||||
gtk_widget_queue_draw (GTK_WIDGET (button));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_toggle_button_released (GtkButton *button)
|
||||
{
|
||||
if (button->priv->button_down)
|
||||
{
|
||||
button->priv->button_down = FALSE;
|
||||
|
||||
if (button->priv->in_button)
|
||||
gtk_button_clicked (button);
|
||||
|
||||
gtk_toggle_button_update_state (button);
|
||||
gtk_widget_queue_draw (GTK_WIDGET (button));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_toggle_button_clicked (GtkButton *button)
|
||||
{
|
||||
GtkToggleButton *toggle_button = GTK_TOGGLE_BUTTON (button);
|
||||
GtkToggleButtonPrivate *priv = toggle_button->priv;
|
||||
|
||||
priv->active = !priv->active;
|
||||
|
||||
gtk_toggle_button_toggled (toggle_button);
|
||||
|
||||
gtk_toggle_button_update_state (button);
|
||||
|
||||
g_object_notify (G_OBJECT (toggle_button), "active");
|
||||
|
||||
if (GTK_BUTTON_CLASS (gtk_toggle_button_parent_class)->clicked)
|
||||
GTK_BUTTON_CLASS (gtk_toggle_button_parent_class)->clicked (button);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_toggle_button_update_state (GtkButton *button)
|
||||
{
|
||||
GtkToggleButton *toggle_button = GTK_TOGGLE_BUTTON (button);
|
||||
GtkToggleButtonPrivate *priv = toggle_button->priv;
|
||||
gboolean depressed, touchscreen;
|
||||
GtkStateType new_state;
|
||||
|
||||
g_object_get (gtk_widget_get_settings (GTK_WIDGET (button)),
|
||||
"gtk-touchscreen-mode", &touchscreen,
|
||||
NULL);
|
||||
|
||||
if (priv->inconsistent)
|
||||
depressed = FALSE;
|
||||
else if (button->priv->in_button && button->priv->button_down)
|
||||
depressed = TRUE;
|
||||
else
|
||||
depressed = priv->active;
|
||||
|
||||
if (!touchscreen && button->priv->in_button && (!button->priv->button_down || priv->draw_indicator))
|
||||
new_state = GTK_STATE_PRELIGHT;
|
||||
else
|
||||
new_state = depressed ? GTK_STATE_ACTIVE : GTK_STATE_NORMAL;
|
||||
|
||||
_gtk_button_set_depressed (button, depressed);
|
||||
gtk_widget_set_state (GTK_WIDGET (toggle_button), new_state);
|
||||
}
|
||||
|
@@ -45,23 +45,18 @@ G_BEGIN_DECLS
|
||||
#define GTK_TOGGLE_BUTTON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_TOGGLE_BUTTON, GtkToggleButtonClass))
|
||||
|
||||
typedef struct _GtkToggleButton GtkToggleButton;
|
||||
typedef struct _GtkToggleButtonPrivate GtkToggleButtonPrivate;
|
||||
typedef struct _GtkToggleButtonClass GtkToggleButtonClass;
|
||||
|
||||
struct _GtkToggleButton
|
||||
{
|
||||
/*< private >*/
|
||||
GtkButton button;
|
||||
|
||||
GtkToggleButtonPrivate *priv;
|
||||
};
|
||||
|
||||
struct _GtkToggleButtonClass
|
||||
{
|
||||
GtkButtonClass parent_class;
|
||||
|
||||
void (* toggled) (GtkToggleButton *toggle_button);
|
||||
|
||||
/* Padding for future expansion */
|
||||
void (*_gtk_reserved1) (void);
|
||||
void (*_gtk_reserved2) (void);
|
||||
@@ -70,24 +65,23 @@ struct _GtkToggleButtonClass
|
||||
};
|
||||
|
||||
|
||||
GType gtk_toggle_button_get_type (void) G_GNUC_CONST;
|
||||
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);
|
||||
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);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
Reference in New Issue
Block a user