summaryrefslogtreecommitdiff
path: root/gtk
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2020-08-31 16:30:21 +0000
committerMatthias Clasen <mclasen@redhat.com>2020-08-31 16:30:21 +0000
commitccb447da02e641d21cbde3329168dd0bfc9b4e24 (patch)
treea2dddb413e882d5028abe1e255071d7e1be224b8 /gtk
parent4580e71250e42ea53bdceb6b14b4f63c39ae8842 (diff)
parent76b5ff6a0030d2d72614b7268354c6a745bc3504 (diff)
downloadgtk+-ccb447da02e641d21cbde3329168dd0bfc9b4e24.tar.gz
Merge branch 'wip/baedert/for-master' into 'master'
Wip/baedert/for master Closes #2777 See merge request GNOME/gtk!2503
Diffstat (limited to 'gtk')
-rw-r--r--gtk/gtk-autocleanups.h1
-rw-r--r--gtk/gtk.h1
-rw-r--r--gtk/gtkbutton.c57
-rw-r--r--gtk/gtkcheckbutton.c847
-rw-r--r--gtk/gtkcheckbutton.h41
-rw-r--r--gtk/gtkcheckbuttonprivate.h40
-rw-r--r--gtk/gtkexpression.c2
-rw-r--r--gtk/gtkfilechooserwidget.c8
-rw-r--r--gtk/gtkfontchooserwidget.c81
-rw-r--r--gtk/gtkmodelbutton.c2
-rw-r--r--gtk/gtkmountoperation.c51
-rw-r--r--gtk/gtkpagesetupunixdialog.c17
-rw-r--r--gtk/gtkprintbackend.c5
-rw-r--r--gtk/gtkprinteroptionwidget.c59
-rw-r--r--gtk/gtkprintunixdialog.c45
-rw-r--r--gtk/gtkradiobutton.c780
-rw-r--r--gtk/gtkradiobutton.h74
-rw-r--r--gtk/gtkrender.c2
-rw-r--r--gtk/gtkspinbutton.c6
-rw-r--r--gtk/gtkstackswitcher.c2
-rw-r--r--gtk/gtktogglebutton.c129
-rw-r--r--gtk/gtktogglebutton.h4
-rw-r--r--gtk/gtkwindow.c2
-rw-r--r--gtk/inspector/logs.c4
-rw-r--r--gtk/inspector/prop-editor.c22
-rw-r--r--gtk/meson.build2
-rw-r--r--gtk/theme/Adwaita/_common.scss3
-rw-r--r--gtk/tools/gtk-builder-tool-simplify.c56
-rw-r--r--gtk/ui/gtkpagesetupunixdialog.ui74
-rw-r--r--gtk/ui/gtkprintunixdialog.ui16
30 files changed, 1059 insertions, 1374 deletions
diff --git a/gtk/gtk-autocleanups.h b/gtk/gtk-autocleanups.h
index b5689b9075..eb4fb1b874 100644
--- a/gtk/gtk-autocleanups.h
+++ b/gtk/gtk-autocleanups.h
@@ -120,7 +120,6 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkPrintOperation, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkPrintOperationPreview, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkPrintSettings, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkProgressBar, g_object_unref)
-G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkRadioButton, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkRange, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkRecentManager, g_object_unref)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkRevealer, g_object_unref)
diff --git a/gtk/gtk.h b/gtk/gtk.h
index 4819d51756..be942b218b 100644
--- a/gtk/gtk.h
+++ b/gtk/gtk.h
@@ -201,7 +201,6 @@
#include <gtk/gtkprintoperationpreview.h>
#include <gtk/gtkprintsettings.h>
#include <gtk/gtkprogressbar.h>
-#include <gtk/gtkradiobutton.h>
#include <gtk/gtkrange.h>
#include <gtk/gtkrecentmanager.h>
#include <gtk/gtkrender.h>
diff --git a/gtk/gtkbutton.c b/gtk/gtkbutton.c
index 007bd41ba1..1bacdc797b 100644
--- a/gtk/gtkbutton.c
+++ b/gtk/gtkbutton.c
@@ -74,6 +74,7 @@
#include "gtkstylecontext.h"
#include "gtktypebuiltins.h"
#include "gtkwidgetprivate.h"
+#include "gtkshortcuttrigger.h"
#include <string.h>
@@ -138,7 +139,7 @@ static void gtk_button_unrealize (GtkWidget * widget);
static void gtk_real_button_clicked (GtkButton * button);
static void gtk_real_button_activate (GtkButton *button);
static void gtk_button_finish_activate (GtkButton *button,
- gboolean do_it);
+ gboolean do_it);
static void gtk_button_state_flags_changed (GtkWidget *widget,
GtkStateFlags previous_state);
@@ -200,8 +201,11 @@ gtk_button_get_request_mode (GtkWidget *widget)
static void
gtk_button_class_init (GtkButtonClass *klass)
{
+ const guint activate_keyvals[] = { GDK_KEY_space, GDK_KEY_KP_Space, GDK_KEY_Return,
+ GDK_KEY_ISO_Enter, GDK_KEY_KP_Enter };
GObjectClass *gobject_class;
GtkWidgetClass *widget_class;
+ GtkShortcutAction *activate_action;
gobject_class = G_OBJECT_CLASS (klass);
widget_class = (GtkWidgetClass*) klass;
@@ -267,12 +271,12 @@ gtk_button_class_init (GtkButtonClass *klass)
*/
button_signals[CLICKED] =
g_signal_new (I_("clicked"),
- G_OBJECT_CLASS_TYPE (gobject_class),
- G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
- G_STRUCT_OFFSET (GtkButtonClass, clicked),
- NULL, NULL,
- NULL,
- G_TYPE_NONE, 0);
+ G_OBJECT_CLASS_TYPE (gobject_class),
+ G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (GtkButtonClass, clicked),
+ NULL, NULL,
+ NULL,
+ G_TYPE_NONE, 0);
/**
* GtkButton::activate:
@@ -285,29 +289,28 @@ gtk_button_class_init (GtkButtonClass *klass)
*/
button_signals[ACTIVATE] =
g_signal_new (I_("activate"),
- G_OBJECT_CLASS_TYPE (gobject_class),
- G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
- G_STRUCT_OFFSET (GtkButtonClass, activate),
- NULL, NULL,
- NULL,
- G_TYPE_NONE, 0);
+ G_OBJECT_CLASS_TYPE (gobject_class),
+ G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (GtkButtonClass, activate),
+ NULL, NULL,
+ NULL,
+ G_TYPE_NONE, 0);
widget_class->activate_signal = button_signals[ACTIVATE];
+ activate_action = gtk_signal_action_new ("activate");
- gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
- gtk_widget_class_set_css_name (widget_class, I_("button"));
+ for (guint i = 0; i < G_N_ELEMENTS (activate_keyvals); i++)
+ {
+ GtkShortcut *activate_shortcut = gtk_shortcut_new (gtk_keyval_trigger_new (activate_keyvals[i], 0),
+ g_object_ref (activate_action));
- gtk_widget_class_add_binding_signal (widget_class, GDK_KEY_space, 0,
- "activate", NULL);
- gtk_widget_class_add_binding_signal (widget_class, GDK_KEY_KP_Space, 0,
- "activate", NULL);
- gtk_widget_class_add_binding_signal (widget_class, GDK_KEY_Return, 0,
- "activate", NULL);
- gtk_widget_class_add_binding_signal (widget_class, GDK_KEY_ISO_Enter, 0,
- "activate", NULL);
- gtk_widget_class_add_binding_signal (widget_class, GDK_KEY_KP_Enter, 0,
- "activate", NULL);
+ gtk_widget_class_add_shortcut (widget_class, activate_shortcut);
+ g_object_unref (activate_shortcut);
+ }
+ g_object_unref (activate_action);
gtk_widget_class_set_accessible_role (widget_class, GTK_ACCESSIBLE_ROLE_BUTTON);
+ gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
+ gtk_widget_class_set_css_name (widget_class, I_("button"));
}
static void
@@ -766,7 +769,7 @@ gtk_button_do_release (GtkButton *button,
priv->button_down = FALSE;
if (priv->activate_timeout)
- return;
+ return;
if (emit_clicked)
g_signal_emit (button, button_signals[CLICKED], 0);
@@ -806,7 +809,7 @@ gtk_real_button_activate (GtkButton *button)
static void
gtk_button_finish_activate (GtkButton *button,
- gboolean do_it)
+ gboolean do_it)
{
GtkButtonPrivate *priv = gtk_button_get_instance_private (button);
diff --git a/gtk/gtkcheckbutton.c b/gtk/gtkcheckbutton.c
index c6db13518f..13aa7fb6cd 100644
--- a/gtk/gtkcheckbutton.c
+++ b/gtk/gtkcheckbutton.c
@@ -19,60 +19,45 @@
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
- * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#include "config.h"
-#include "gtkcheckbuttonprivate.h"
-
-#include "gtkbuttonprivate.h"
-#include "gtklabel.h"
+#include "gtkcheckbutton.h"
+#include "gtkactionhelperprivate.h"
+#include "gtkboxlayout.h"
+#include "gtkbuiltiniconprivate.h"
+#include "gtkcssnodeprivate.h"
+#include "gtkcssnumbervalueprivate.h"
+#include "gtkgestureclick.h"
#include "gtkintl.h"
+#include "gtklabel.h"
#include "gtkprivate.h"
-#include "gtkwidgetprivate.h"
-#include "gtkcssnodeprivate.h"
#include "gtkstylecontextprivate.h"
-#include "gtkcssnumbervalueprivate.h"
-#include "gtkradiobutton.h"
-#include "gtkbuiltiniconprivate.h"
-#include "gtkboxlayout.h"
-
+#include "gtkwidgetprivate.h"
/**
* SECTION:gtkcheckbutton
* @Short_description: Create widgets with a discrete toggle button
* @Title: GtkCheckButton
- * @See_also: #GtkButton, #GtkToggleButton, #GtkRadioButton
- *
- * A #GtkCheckButton places a discrete #GtkToggleButton next to a widget,
- * (usually a #GtkLabel). See the section on #GtkToggleButton widgets for
- * more information about toggle/check buttons.
+ * @See_also: #GtkButton, #GtkToggleButton
*
- * The important signal ( #GtkToggleButton::toggled ) is also inherited from
- * #GtkToggleButton.
+ * A #GtkCheckButton places a label next to an indicator.
*
* # CSS nodes
*
* |[<!-- language="plain" -->
- * checkbutton
- * ├── check
- * ╰── <child>
- * ]|
- *
- * A GtkCheckButton with indicator (see gtk_check_button_set_draw_indicator()) has a
- * main CSS node with name checkbutton and a subnode with name check.
- *
- * |[<!-- language="plain" -->
- * button.check
+ * checkbutton[.text-button]
* ├── check
- * ╰── <child>
+ * ╰── [label]
* ]|
*
- * A GtkCheckButton without indicator changes the name of its main node
- * to button and adds a .check style class to it. The subnode is invisible
- * in this case.
+ * A #GtkCheckButton has a main node with name checkbutton. If the
+ * #GtkCheckButton:label property is set, it contains a label child.
+ * The indicator node is named check when no group is set, and radio
+ * if the checkbutton is grouped together with other checkbuttons.
*
* # Accessibility
*
@@ -81,55 +66,83 @@
typedef struct {
GtkWidget *indicator_widget;
+ GtkWidget *label_widget;
- guint draw_indicator : 1;
- guint inconsistent : 1;
+ guint inconsistent: 1;
+ guint active: 1;
+ guint use_underline: 1;
+
+ GtkCheckButton *group_next;
+ GtkCheckButton *group_prev;
+
+ GtkActionHelper *action_helper;
} GtkCheckButtonPrivate;
enum {
PROP_0,
- PROP_DRAW_INDICATOR,
+ PROP_ACTIVE,
+ PROP_GROUP,
+ PROP_LABEL,
PROP_INCONSISTENT,
- NUM_PROPERTIES
+ PROP_USE_UNDERLINE,
+
+ /* actionable properties */
+ PROP_ACTION_NAME,
+ PROP_ACTION_TARGET,
+ LAST_PROP = PROP_ACTION_NAME
+};
+
+enum {
+ TOGGLED,
+ LAST_SIGNAL
};
-static GParamSpec *props[NUM_PROPERTIES] = { NULL, };
+static void gtk_check_button_actionable_iface_init (GtkActionableInterface *iface);
-G_DEFINE_TYPE_WITH_PRIVATE (GtkCheckButton, gtk_check_button, GTK_TYPE_TOGGLE_BUTTON)
+static guint signals[LAST_SIGNAL] = { 0 };
+static GParamSpec *props[LAST_PROP] = { NULL, };
+G_DEFINE_TYPE_WITH_CODE (GtkCheckButton, gtk_check_button, GTK_TYPE_WIDGET,
+ G_ADD_PRIVATE (GtkCheckButton)
+ G_IMPLEMENT_INTERFACE (GTK_TYPE_ACTIONABLE, gtk_check_button_actionable_iface_init))
static void
-gtk_check_button_update_node_state (GtkWidget *widget)
+gtk_check_button_dispose (GObject *object)
{
- GtkCheckButtonPrivate *priv = gtk_check_button_get_instance_private (GTK_CHECK_BUTTON (widget));
- GtkStateFlags state;
+ GtkCheckButtonPrivate *priv = gtk_check_button_get_instance_private (GTK_CHECK_BUTTON (object));
- if (!priv->indicator_widget)
- return;
+ g_clear_pointer (&priv->indicator_widget, gtk_widget_unparent);
+ g_clear_pointer (&priv->label_widget, gtk_widget_unparent);
- state = gtk_widget_get_state_flags (widget);
+ gtk_check_button_set_group (GTK_CHECK_BUTTON (object), NULL);
- gtk_widget_set_state_flags (priv->indicator_widget, state, TRUE);
+ G_OBJECT_CLASS (gtk_check_button_parent_class)->dispose (object);
}
-
static void
-gtk_check_button_state_flags_changed (GtkWidget *widget,
- GtkStateFlags previous_state_flags)
+gtk_check_button_set_action_name (GtkActionable *actionable,
+ const char *action_name)
{
- gtk_check_button_update_node_state (widget);
+ GtkCheckButton *self = GTK_CHECK_BUTTON (actionable);
+ GtkCheckButtonPrivate *priv = gtk_check_button_get_instance_private (self);
- GTK_WIDGET_CLASS (gtk_check_button_parent_class)->state_flags_changed (widget, previous_state_flags);
+ if (!priv->action_helper)
+ priv->action_helper = gtk_action_helper_new (actionable);
+
+ gtk_action_helper_set_action_name (priv->action_helper, action_name);
}
static void
-gtk_check_button_finalize (GObject *object)
+gtk_check_button_set_action_target_value (GtkActionable *actionable,
+ GVariant *action_target)
{
- GtkCheckButtonPrivate *priv = gtk_check_button_get_instance_private (GTK_CHECK_BUTTON (object));
+ GtkCheckButton *self = GTK_CHECK_BUTTON (actionable);
+ GtkCheckButtonPrivate *priv = gtk_check_button_get_instance_private (self);
- g_clear_pointer (&priv->indicator_widget, gtk_widget_unparent);
+ if (!priv->action_helper)
+ priv->action_helper = gtk_action_helper_new (actionable);
- G_OBJECT_CLASS (gtk_check_button_parent_class)->finalize (object);
+ gtk_action_helper_set_action_target_value (priv->action_helper, action_target);
}
static void
@@ -140,41 +153,126 @@ gtk_check_button_set_property (GObject *object,
{
switch (prop_id)
{
- case PROP_DRAW_INDICATOR:
- gtk_check_button_set_draw_indicator (GTK_CHECK_BUTTON (object),
- g_value_get_boolean (value));
-
+ case PROP_ACTIVE:
+ gtk_check_button_set_active (GTK_CHECK_BUTTON (object), g_value_get_boolean (value));
+ break;
+ case PROP_GROUP:
+ gtk_check_button_set_group (GTK_CHECK_BUTTON (object), g_value_get_object (value));
+ break;
+ case PROP_LABEL:
+ gtk_check_button_set_label (GTK_CHECK_BUTTON (object), g_value_get_string (value));
+ break;
+ case PROP_INCONSISTENT:
+ gtk_check_button_set_inconsistent (GTK_CHECK_BUTTON (object), g_value_get_boolean (value));
+ break;
+ case PROP_USE_UNDERLINE:
+ gtk_check_button_set_use_underline (GTK_CHECK_BUTTON (object), g_value_get_boolean (value));
+ break;
+ case PROP_ACTION_NAME:
+ gtk_check_button_set_action_name (GTK_ACTIONABLE (object), g_value_get_string (value));
break;
- case PROP_INCONSISTENT:
- gtk_check_button_set_inconsistent (GTK_CHECK_BUTTON (object),
- g_value_get_boolean (value));
+ case PROP_ACTION_TARGET:
+ gtk_check_button_set_action_target_value (GTK_ACTIONABLE (object), g_value_get_variant (value));
break;
- default:
+ default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
-gtk_check_button_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
+gtk_check_button_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
{
+ GtkCheckButtonPrivate *priv = gtk_check_button_get_instance_private (GTK_CHECK_BUTTON (object));
+
switch (prop_id)
{
- case PROP_DRAW_INDICATOR:
- g_value_set_boolean (value, gtk_check_button_get_draw_indicator (GTK_CHECK_BUTTON (object)));
+ case PROP_ACTIVE:
+ g_value_set_boolean (value, gtk_check_button_get_active (GTK_CHECK_BUTTON (object)));
+ break;
+ case PROP_LABEL:
+ g_value_set_string (value, gtk_check_button_get_label (GTK_CHECK_BUTTON (object)));
break;
- case PROP_INCONSISTENT:
- g_value_set_boolean (value, gtk_check_button_get_inconsistent (GTK_CHECK_BUTTON (object)));
+ case PROP_INCONSISTENT:
+ g_value_set_boolean (value, gtk_check_button_get_inconsistent (GTK_CHECK_BUTTON (object)));
break;
- default:
+ case PROP_USE_UNDERLINE:
+ g_value_set_boolean (value, gtk_check_button_get_use_underline (GTK_CHECK_BUTTON (object)));
+ break;
+ case PROP_ACTION_NAME:
+ g_value_set_string (value, gtk_action_helper_get_action_name (priv->action_helper));
+ break;
+ case PROP_ACTION_TARGET:
+ g_value_set_variant (value, gtk_action_helper_get_action_target_value (priv->action_helper));
+ break;
+ default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
+static const char *
+gtk_check_button_get_action_name (GtkActionable *actionable)
+{
+ GtkCheckButton *self = GTK_CHECK_BUTTON (actionable);
+ GtkCheckButtonPrivate *priv = gtk_check_button_get_instance_private (self);
+
+ return gtk_action_helper_get_action_name (priv->action_helper);
+}
+
+static GVariant *
+gtk_check_button_get_action_target_value (GtkActionable *actionable)
+{
+ GtkCheckButton *self = GTK_CHECK_BUTTON (actionable);
+ GtkCheckButtonPrivate *priv = gtk_check_button_get_instance_private (self);
+
+ return gtk_action_helper_get_action_target_value (priv->action_helper);
+}
+
+static void
+gtk_check_button_actionable_iface_init (GtkActionableInterface *iface)
+{
+ iface->get_action_name = gtk_check_button_get_action_name;
+ iface->set_action_name = gtk_check_button_set_action_name;
+ iface->get_action_target_value = gtk_check_button_get_action_target_value;
+ iface->set_action_target_value = gtk_check_button_set_action_target_value;
+}
+
+static void
+click_pressed_cb (GtkGestureClick *gesture,
+ guint n_press,
+ double x,
+ double y,
+ GtkWidget *widget)
+{
+ if (gtk_widget_get_focus_on_click (widget) && !gtk_widget_has_focus (widget))
+ gtk_widget_grab_focus (widget);
+
+ gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_CLAIMED);
+}
+
+static void
+click_released_cb (GtkGestureClick *gesture,
+ guint n_press,
+ double x,
+ double y,
+ GtkWidget *widget)
+{
+ GtkCheckButton *self = GTK_CHECK_BUTTON (widget);
+ GtkCheckButtonPrivate *priv = gtk_check_button_get_instance_private (self);
+
+ if (priv->active && (priv->group_prev || priv->group_next))
+ return;
+
+ gtk_check_button_set_active (self, !priv->active);
+
+ if (priv->action_helper)
+ gtk_action_helper_activate (priv->action_helper);
+}
+
static void
update_accessible_state (GtkCheckButton *check_button)
{
@@ -184,7 +282,7 @@ update_accessible_state (GtkCheckButton *check_button)
if (priv->inconsistent)
checked_state = GTK_ACCESSIBLE_TRISTATE_MIXED;
- else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (check_button)))
+ else if (priv->active)
checked_state = GTK_ACCESSIBLE_TRISTATE_TRUE;
else
checked_state = GTK_ACCESSIBLE_TRISTATE_FALSE;
@@ -194,106 +292,224 @@ update_accessible_state (GtkCheckButton *check_button)
-1);
}
-static void
-gtk_check_button_notify (GObject *object,
- GParamSpec *pspec)
+
+static GtkCheckButton *
+get_group_next (GtkCheckButton *self)
{
- if (pspec->name == I_("active"))
- update_accessible_state (GTK_CHECK_BUTTON (object));
+ return ((GtkCheckButtonPrivate *)gtk_check_button_get_instance_private (self))->group_next;
+}
- if (G_OBJECT_CLASS (gtk_check_button_parent_class)->notify)
- G_OBJECT_CLASS (gtk_check_button_parent_class)->notify (object, pspec);
+static GtkCheckButton *
+get_group_prev (GtkCheckButton *self)
+{
+ return ((GtkCheckButtonPrivate *)gtk_check_button_get_instance_private (self))->group_prev;
}
-static void
-gtk_check_button_class_init (GtkCheckButtonClass *class)
+static GtkCheckButton *
+get_group_first (GtkCheckButton *self)
{
- GObjectClass *object_class = G_OBJECT_CLASS (class);
- GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
+ GtkCheckButton *group_first = NULL;
+ GtkCheckButton *iter;
- object_class->notify = gtk_check_button_notify;
- object_class->finalize = gtk_check_button_finalize;
- object_class->set_property = gtk_check_button_set_property;
- object_class->get_property = gtk_check_button_get_property;
+ /* Find first in group */
+ iter = self;
+ while (iter)
+ {
+ group_first = iter;
- widget_class->state_flags_changed = gtk_check_button_state_flags_changed;
+ iter = get_group_prev (iter);
+ if (!iter)
+ break;
+ }
- props[PROP_DRAW_INDICATOR] =
- g_param_spec_boolean ("draw-indicator",
- P_("Draw Indicator"),
- P_("If the indicator part of the button is displayed"),
- TRUE,
- GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
+ g_assert (group_first);
- props[PROP_INCONSISTENT] =
- g_param_spec_boolean ("inconsistent",
- P_("Inconsistent"),
- P_("If the check button is in an “in between” state"),
- FALSE,
- GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
+ return group_first;
+}
- g_object_class_install_properties (object_class, NUM_PROPERTIES, props);
+static GtkCheckButton *
+get_group_active_button (GtkCheckButton *self)
+{
+ GtkCheckButton *iter;
- gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BOX_LAYOUT);
- gtk_widget_class_set_css_name (widget_class, I_("checkbutton"));
- gtk_widget_class_set_accessible_role (widget_class, GTK_ACCESSIBLE_ROLE_CHECKBOX);
+ for (iter = get_group_first (self); iter; iter = get_group_next (iter))
+ {
+ if (gtk_check_button_get_active (iter))
+ return iter;
+ }
+
+ return NULL;
}
-static void
-draw_indicator_changed (GtkCheckButton *check_button)
+static gboolean
+gtk_check_button_focus (GtkWidget *widget,
+ GtkDirectionType direction)
{
- GtkCheckButtonPrivate *priv = gtk_check_button_get_instance_private (check_button);
- GtkCssNode *widget_node;
+ GtkCheckButton *self = GTK_CHECK_BUTTON (widget);
+ GtkCheckButton *active_button;
- widget_node = gtk_widget_get_css_node (GTK_WIDGET (check_button));
+ active_button = get_group_active_button (self);
- if (priv->draw_indicator)
+ if (gtk_widget_is_focus (widget))
{
- priv->indicator_widget = gtk_builtin_icon_new ("check");
- gtk_widget_set_halign (priv->indicator_widget, GTK_ALIGN_CENTER);
- gtk_widget_set_valign (priv->indicator_widget, GTK_ALIGN_CENTER);
- gtk_widget_set_parent (priv->indicator_widget, GTK_WIDGET (check_button));
- if (GTK_IS_RADIO_BUTTON (check_button))
+ GtkCheckButton *iter;
+ GPtrArray *child_array;
+ GtkWidget *new_focus = NULL;
+ guint index;
+ gboolean found;
+ guint i;
+
+ if (direction == GTK_DIR_TAB_FORWARD ||
+ direction == GTK_DIR_TAB_BACKWARD)
+ return FALSE;
+
+ child_array = g_ptr_array_new ();
+ for (iter = get_group_first (self); iter; iter = get_group_next (iter))
+ g_ptr_array_add (child_array, iter);
+
+ gtk_widget_focus_sort (widget, direction, child_array);
+ found = g_ptr_array_find (child_array, widget, &index);
+
+ if (found)
{
- gtk_css_node_remove_class (widget_node, g_quark_from_static_string ("radio"));
- gtk_css_node_set_name (widget_node, g_quark_from_static_string ("radiobutton"));
+ /* Start at the *next* widget in the list */
+ if (index < child_array->len - 1)
+ index ++;
}
- else if (GTK_IS_CHECK_BUTTON (check_button))
+ else
{
- gtk_css_node_remove_class (widget_node, g_quark_from_static_string ("check"));
- gtk_css_node_set_name (widget_node, g_quark_from_static_string ("checkbutton"));
+ /* Search from the start of the list */
+ index = 0;
}
- }
- else
- {
- gtk_widget_unparent (priv->indicator_widget);
- priv->indicator_widget = NULL;
- if (GTK_IS_RADIO_BUTTON (check_button))
+
+ for (i = index; i < child_array->len; i ++)
{
- gtk_css_node_add_class (widget_node, g_quark_from_static_string ("radio"));
- gtk_css_node_set_name (widget_node, g_quark_from_static_string ("button"));
+ GtkWidget *child = g_ptr_array_index (child_array, i);
+
+ if (gtk_widget_get_mapped (child) && gtk_widget_is_sensitive (child))
+ {
+ new_focus = child;
+ break;
+ }
}
- else if (GTK_IS_CHECK_BUTTON (check_button))
+
+
+ if (new_focus)
{
- gtk_css_node_add_class (widget_node, g_quark_from_static_string ("check"));
- gtk_css_node_set_name (widget_node, g_quark_from_static_string ("button"));
+ gtk_widget_grab_focus (new_focus);
+ gtk_check_button_set_active (GTK_CHECK_BUTTON (new_focus), TRUE);
+ if (active_button && active_button != (GtkCheckButton *)new_focus)
+ gtk_check_button_set_active (GTK_CHECK_BUTTON (active_button), FALSE);
}
+
+ g_ptr_array_free (child_array, TRUE);
+
+ return TRUE;
+ }
+ else
+ {
+ if (active_button && active_button != self)
+ return FALSE;
+
+ gtk_widget_grab_focus (widget);
+ return TRUE;
}
}
static void
-gtk_check_button_init (GtkCheckButton *check_button)
+gtk_check_button_class_init (GtkCheckButtonClass *class)
{
- GtkCheckButtonPrivate *priv = gtk_check_button_get_instance_private (check_button);
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
+
+ object_class->dispose = gtk_check_button_dispose;
+ object_class->set_property = gtk_check_button_set_property;
+ object_class->get_property = gtk_check_button_get_property;
+
+ widget_class->focus = gtk_check_button_focus;
+
+ props[PROP_ACTIVE] =
+ g_param_spec_boolean ("active",
+ P_("Active"),
+ P_("If the toggle button should be pressed in"),
+ FALSE,
+ GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
+ props[PROP_GROUP] =
+ g_param_spec_object ("group",
+ P_("Group"),
+ P_("The check button whose group this widget belongs to."),
+ GTK_TYPE_CHECK_BUTTON,
+ GTK_PARAM_WRITABLE);
+ props[PROP_LABEL] =
+ g_param_spec_string ("label",
+ P_("Label"),
+ P_("Text of the label widget inside the button, if the button contains a label widget"),
+ NULL,
+ GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
+
+ props[PROP_INCONSISTENT] =
+ g_param_spec_boolean ("inconsistent",
+ P_("Inconsistent"),
+ P_("If the check button is in an “in between” state"),
+ FALSE,
+ GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
+
+ props[PROP_USE_UNDERLINE] =
+ g_param_spec_boolean ("use-underline",
+ P_("Use underline"),
+ P_("If set, an underline in the text indicates the next character should be used for the mnemonic accelerator key"),
+ FALSE,
+ GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
+
+ g_object_class_install_properties (object_class, LAST_PROP, props);
- gtk_widget_set_receives_default (GTK_WIDGET (check_button), FALSE);
+ g_object_class_override_property (object_class, PROP_ACTION_NAME, "action-name");
+ g_object_class_override_property (object_class, PROP_ACTION_TARGET, "action-target");
- gtk_widget_remove_css_class (GTK_WIDGET (check_button), "toggle");
- priv->draw_indicator = TRUE;
- draw_indicator_changed (check_button);
- gtk_check_button_update_node_state (GTK_WIDGET (check_button));
- update_accessible_state (check_button);
+ /**
+ * GtkCheckButton::toggled:
+ *
+ * Emitted when the buttons's #GtkCheckButton:active flag changes.
+ */
+ signals[TOGGLED] =
+ g_signal_new (I_("toggled"),
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (GtkCheckButtonClass, toggled),
+ NULL, NULL,
+ NULL,
+ G_TYPE_NONE, 0);
+
+ gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BOX_LAYOUT);
+ gtk_widget_class_set_css_name (widget_class, I_("checkbutton"));
+ gtk_widget_class_set_accessible_role (widget_class, GTK_ACCESSIBLE_ROLE_CHECKBOX);
+}
+
+static void
+gtk_check_button_init (GtkCheckButton *self)
+{
+ GtkCheckButtonPrivate *priv = gtk_check_button_get_instance_private (self);
+ GtkGesture *gesture;
+
+ gtk_widget_set_receives_default (GTK_WIDGET (self), FALSE);
+ priv->indicator_widget = gtk_builtin_icon_new ("check");
+ gtk_widget_set_halign (priv->indicator_widget, GTK_ALIGN_CENTER);
+ gtk_widget_set_valign (priv->indicator_widget, GTK_ALIGN_CENTER);
+ gtk_widget_set_parent (priv->indicator_widget, GTK_WIDGET (self));
+
+ update_accessible_state (self);
+
+ gesture = gtk_gesture_click_new ();
+ gtk_gesture_single_set_touch_only (GTK_GESTURE_SINGLE (gesture), FALSE);
+ gtk_gesture_single_set_exclusive (GTK_GESTURE_SINGLE (gesture), TRUE);
+ gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (gesture), GDK_BUTTON_PRIMARY);
+ g_signal_connect (gesture, "pressed", G_CALLBACK (click_pressed_cb), self);
+ g_signal_connect (gesture, "released", G_CALLBACK (click_released_cb), self);
+ gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (gesture), GTK_PHASE_CAPTURE);
+ gtk_widget_add_controller (GTK_WIDGET (self), GTK_EVENT_CONTROLLER (gesture));
+
+ gtk_widget_set_focusable (GTK_WIDGET (self), TRUE);
}
/**
@@ -303,20 +519,20 @@ gtk_check_button_init (GtkCheckButton *check_button)
*
* Returns: a #GtkWidget.
*/
-GtkWidget*
+GtkWidget *
gtk_check_button_new (void)
{
return g_object_new (GTK_TYPE_CHECK_BUTTON, NULL);
}
-
/**
* gtk_check_button_new_with_label:
- * @label: the text for the check button.
+ * @label: (nullable): the text for the check button.
*
- * Creates a new #GtkCheckButton with a #GtkLabel to the right of it.
+ * Creates a new #GtkCheckButton with a #GtkLabel next to it, if
+ * @label is non-%NULL.
*
- * Returns: a #GtkWidget.
+ * Returns: a new #GtkCheckButton
*/
GtkWidget*
gtk_check_button_new_with_label (const char *label)
@@ -326,11 +542,10 @@ gtk_check_button_new_with_label (const char *label)
/**
* gtk_check_button_new_with_mnemonic:
- * @label: The text of the button, with an underscore in front of the
+ * @label: (nullable): The text of the button, with an underscore in front of the
* mnemonic character
*
- * Creates a new #GtkCheckButton containing a label. The label
- * will be created using gtk_label_new_with_mnemonic(), so underscores
+ * Creates a new #GtkCheckButton containing a label. Underscores
* in @label indicate the mnemonic for the check button.
*
* Returns: a new #GtkCheckButton
@@ -338,66 +553,12 @@ gtk_check_button_new_with_label (const char *label)
GtkWidget*
gtk_check_button_new_with_mnemonic (const char *label)
{
- return g_object_new (GTK_TYPE_CHECK_BUTTON,
- "label", label,
- "use-underline", TRUE,
+ return g_object_new (GTK_TYPE_CHECK_BUTTON,
+ "label", label,
+ "use-underline", TRUE,
NULL);
}
-GtkCssNode *
-gtk_check_button_get_indicator_node (GtkCheckButton *check_button)
-{
- GtkCheckButtonPrivate *priv = gtk_check_button_get_instance_private (check_button);
-
- return gtk_widget_get_css_node (priv->indicator_widget);
-}
-
-/**
- * gtk_check_button_set_draw_indicator:
- * @check_button: a #GtkCheckButton
- * @draw_indicator: Whether or not to draw the indicator part of the button
- *
- * Sets whether the indicator part of the button is drawn. This is important for
- * cases where the check button should have the functionality of a check button,
- * but the visuals of a regular button, like in a #GtkStackSwitcher.
- */
-void
-gtk_check_button_set_draw_indicator (GtkCheckButton *check_button,
- gboolean draw_indicator)
-{
- GtkCheckButtonPrivate *priv = gtk_check_button_get_instance_private (check_button);
-
- g_return_if_fail (GTK_IS_CHECK_BUTTON (check_button));
-
- draw_indicator = !!draw_indicator;
-
- if (draw_indicator != priv->draw_indicator)
- {
- priv->draw_indicator = draw_indicator;
- draw_indicator_changed (check_button);
- gtk_widget_queue_resize (GTK_WIDGET (check_button));
- g_object_notify_by_pspec (G_OBJECT (check_button), props[PROP_DRAW_INDICATOR]);
- }
-}
-
-/**
- * gtk_check_button_get_draw_indicator:
- * @check_button: a #GtkCheckButton
- *
- * Returns Whether or not the indicator part of the button gets drawn.
- *
- * Returns: The value of the GtkCheckButton:draw-indicator property.
- */
-gboolean
-gtk_check_button_get_draw_indicator (GtkCheckButton *check_button)
-{
- GtkCheckButtonPrivate *priv = gtk_check_button_get_instance_private (check_button);
-
- g_return_val_if_fail (GTK_IS_CHECK_BUTTON (check_button), FALSE);
-
- return priv->draw_indicator;
-}
-
/**
* gtk_check_button_set_inconsistent:
* @check_button: a #GtkCheckButton
@@ -426,9 +587,15 @@ gtk_check_button_set_inconsistent (GtkCheckButton *check_button,
priv->inconsistent = inconsistent;
if (inconsistent)
- gtk_widget_set_state_flags (GTK_WIDGET (check_button), GTK_STATE_FLAG_INCONSISTENT, FALSE);
+ {
+ gtk_widget_set_state_flags (GTK_WIDGET (check_button), GTK_STATE_FLAG_INCONSISTENT, FALSE);
+ gtk_widget_set_state_flags (priv->indicator_widget, GTK_STATE_FLAG_INCONSISTENT, FALSE);
+ }
else
- gtk_widget_unset_state_flags (GTK_WIDGET (check_button), GTK_STATE_FLAG_INCONSISTENT);
+ {
+ gtk_widget_unset_state_flags (GTK_WIDGET (check_button), GTK_STATE_FLAG_INCONSISTENT);
+ gtk_widget_unset_state_flags (priv->indicator_widget, GTK_STATE_FLAG_INCONSISTENT);
+ }
update_accessible_state (check_button);
@@ -441,7 +608,7 @@ gtk_check_button_set_inconsistent (GtkCheckButton *check_button,
* @check_button: a #GtkCheckButton
*
* Returns whether the check button is in an inconsistent state.
- *
+ *
* Returns: %TRUE if @check_button is currently in an 'in between' state, %FALSE otherwise.
*/
gboolean
@@ -453,3 +620,267 @@ gtk_check_button_get_inconsistent (GtkCheckButton *check_button)
return priv->inconsistent;
}
+
+/**
+ * gtk_check_button_get_active:
+ * @self: a #GtkCheckButton
+ *
+ * Returns the current value of the #GtkCheckButton:active property.
+ *
+ * Returns: The value of the #GtkCheckButton:active property.
+ * See gtk_check_button_set_active() for details on how to set a new value.
+ */
+gboolean
+gtk_check_button_get_active (GtkCheckButton *self)
+{
+ GtkCheckButtonPrivate *priv = gtk_check_button_get_instance_private (self);
+
+ g_return_val_if_fail (GTK_IS_CHECK_BUTTON (self), FALSE);
+
+ return priv->active;
+}
+
+/**
+ * gtk_check_button_set_active:
+ * @self: a #GtkCheckButton
+ * @setting: the new value to set
+ *
+ * Sets the new value of the #GtkCheckButton:active property.
+ * See also gtk_check_button_get_active().
+ *
+ * Setting #GtkCheckButton:active to %TRUE will add the `:checked:` state to
+ * both the checkbutton and the indicator CSS node.
+ */
+void
+gtk_check_button_set_active (GtkCheckButton *self,
+ gboolean setting)
+{
+ GtkCheckButtonPrivate *priv = gtk_check_button_get_instance_private (self);
+
+ g_return_if_fail (GTK_IS_CHECK_BUTTON (self));
+
+ setting = !!setting;
+
+ if (setting == priv->active)
+ return;
+
+ if (setting)
+ {
+ gtk_widget_set_state_flags (GTK_WIDGET (self), GTK_STATE_FLAG_CHECKED, FALSE);
+ gtk_widget_set_state_flags (priv->indicator_widget, GTK_STATE_FLAG_CHECKED, FALSE);
+ }
+ else
+ {
+ gtk_widget_unset_state_flags (GTK_WIDGET (self), GTK_STATE_FLAG_CHECKED);
+ gtk_widget_unset_state_flags (priv->indicator_widget, GTK_STATE_FLAG_CHECKED);
+ }
+
+ if (setting && (priv->group_prev || priv->group_next))
+ {
+ GtkCheckButton *group_first = NULL;
+ GtkCheckButton *iter;
+
+ group_first = get_group_first (self);
+ g_assert (group_first);
+
+ /* Set all buttons in group to !active */
+ for (iter = group_first; iter; iter = get_group_next (iter))
+ gtk_check_button_set_active (iter, FALSE);
+
+ /* ... and the next code block will set this one to active */
+ }
+
+ priv->active = setting;
+ update_accessible_state (self);
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_ACTIVE]);
+ g_signal_emit (self, signals[TOGGLED], 0);
+}
+
+/**
+ * gtk_check_button_get_label:
+ * @self: a #GtkCheckButton
+ *
+ * Returns the label of the checkbutton.
+ *
+ * Returns: (nullable) (transfer none): The label @self shows next to the indicator.
+ * If no label is shown, %NULL will be returned.
+ */
+const char *
+gtk_check_button_get_label (GtkCheckButton *self)
+{
+ GtkCheckButtonPrivate *priv = gtk_check_button_get_instance_private (self);
+
+ g_return_val_if_fail (GTK_IS_CHECK_BUTTON (self), "");
+
+ if (priv->label_widget)
+ return gtk_label_get_label (GTK_LABEL (priv->label_widget));
+
+ return NULL;
+}
+
+/**
+ * gtk_check_button_set_label:
+ * @self: a #GtkCheckButton
+ * @label: (nullable): The text shown next to the indicator, or %NULL
+ * to show no text
+ *
+ * Sets the text of @self. If #GtkCheckButton:use-underline is %TRUE,
+ * the underscore in @label is interpreted as mnemonic indicator,
+ * see gtk_check_button_set_use_underline() for details on this behavior.
+ *
+ */
+void
+gtk_check_button_set_label (GtkCheckButton *self,
+ const char *label)
+{
+ GtkCheckButtonPrivate *priv = gtk_check_button_get_instance_private (self);
+
+ g_return_if_fail (GTK_IS_CHECK_BUTTON (self));
+
+ if (label == NULL || label[0] == '\0')
+ {
+ g_clear_pointer (&priv->label_widget, gtk_widget_unparent);
+ gtk_widget_remove_css_class (GTK_WIDGET (self), "text-button");
+ }
+ else
+ {
+ if (!priv->label_widget)
+ {
+ priv->label_widget = gtk_label_new (NULL);
+ gtk_widget_set_hexpand (priv->label_widget, TRUE);
+ gtk_label_set_xalign (GTK_LABEL (priv->label_widget), 0.0f);
+ gtk_label_set_use_underline (GTK_LABEL (priv->label_widget), priv->use_underline);
+ gtk_widget_insert_after (priv->label_widget, GTK_WIDGET (self), priv->indicator_widget);
+ }
+ gtk_widget_add_css_class (GTK_WIDGET (self), "text-button");
+ gtk_label_set_label (GTK_LABEL (priv->label_widget), label);
+ }
+
+ gtk_accessible_update_property (GTK_ACCESSIBLE (self),
+ GTK_ACCESSIBLE_PROPERTY_LABEL, label,
+ -1);
+
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_LABEL]);
+}
+
+/**
+ * gtk_check_button_set_group:
+ * @self: a #GtkCheckButton
+ * @group: (nullable) (transfer none): another #GtkCheckButton to
+ * form a group with
+ *
+ * Adds @self to the group of @group. In a group of multiple check buttons,
+ * only one button can be active at a time.
+ *
+ * Setting the group of a check button also changes the css name of the
+ * indicator widget's CSS node to 'radio'.
+ *
+ * The behavior of a checkbutton in a group is also commonly known as a 'radio button'.
+ */
+void
+gtk_check_button_set_group (GtkCheckButton *self,
+ GtkCheckButton *group)
+{
+ GtkCheckButtonPrivate *priv = gtk_check_button_get_instance_private (self);
+ GtkCheckButtonPrivate *group_priv = gtk_check_button_get_instance_private (group);
+
+ g_return_if_fail (GTK_IS_CHECK_BUTTON (self));
+
+ if (!group)
+ {
+ if (priv->group_prev)
+ {
+ GtkCheckButtonPrivate *p = gtk_check_button_get_instance_private (priv->group_prev);
+ p->group_next = priv->group_next;
+ }
+ if (priv->group_next)
+ {
+ GtkCheckButtonPrivate *p = gtk_check_button_get_instance_private (priv->group_next);
+ p->group_prev = priv->group_prev;
+ }
+
+ priv->group_next = NULL;
+ priv->group_prev = NULL;
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_GROUP]);
+
+ if (priv->indicator_widget)
+ gtk_css_node_set_name (gtk_widget_get_css_node (priv->indicator_widget),
+ g_quark_from_static_string("check"));
+
+ return;
+ }
+
+ if (priv->group_next == group)
+ return;
+
+ priv->group_prev = NULL;
+ if (group_priv->group_prev)
+ {
+ GtkCheckButtonPrivate *prev = gtk_check_button_get_instance_private (group_priv->group_prev);
+
+ prev->group_next = self;
+ priv->group_prev = group_priv->group_prev;
+ }
+
+ group_priv->group_prev = self;
+ priv->group_next = group;
+
+ if (priv->indicator_widget)
+ gtk_css_node_set_name (gtk_widget_get_css_node (priv->indicator_widget),
+ g_quark_from_static_string("radio"));
+
+ gtk_css_node_set_name (gtk_widget_get_css_node (group_priv->indicator_widget),
+ g_quark_from_static_string("radio"));
+
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_GROUP]);
+}
+
+/**
+ * gtk_check_button_get_use_underline:
+ * @self: a #GtkCheckButton
+ *
+ * Returns the current value of the #GtkCheckButton:use-underline property.
+ *
+ * Returns: The value of the #GtkCheckButton:use-underline property.
+ * See gtk_check_button_set_use_underline() for details on how to set a new value.
+ */
+gboolean
+gtk_check_button_get_use_underline (GtkCheckButton *self)
+{
+ GtkCheckButtonPrivate *priv = gtk_check_button_get_instance_private (self);
+
+ g_return_val_if_fail (GTK_IS_CHECK_BUTTON (self), FALSE);
+
+ return priv->use_underline;
+}
+
+/**
+ * gtk_check_button_set_use_underline:
+ * @self: a #GtkCheckButton
+ * @setting: the new value to set
+ *
+ * Sets the new value of the #GtkCheckButton:use-underline property.
+ * See also gtk_check_button_get_use_underline().
+ *
+ * If @setting is %TRUE, an underscore character in @self's label indicates
+ * a mnemonic accelerator key. This behavior is similar to #GtkLabel:use-underline.
+ */
+void
+gtk_check_button_set_use_underline (GtkCheckButton *self,
+ gboolean setting)
+{
+ GtkCheckButtonPrivate *priv = gtk_check_button_get_instance_private (self);
+
+ g_return_if_fail (GTK_IS_CHECK_BUTTON (self));
+
+ setting = !!setting;
+
+ if (setting == priv->use_underline)
+ return;
+
+ priv->use_underline = setting;
+ if (priv->label_widget)
+ gtk_label_set_use_underline (GTK_LABEL (priv->label_widget), priv->use_underline);
+
+ g_object_notify_by_pspec (G_OBJECT (self), props[PROP_USE_UNDERLINE]);
+}
diff --git a/gtk/gtkcheckbutton.h b/gtk/gtkcheckbutton.h
index 2fd23b33c6..8c9e8c0ddc 100644
--- a/gtk/gtkcheckbutton.h
+++ b/gtk/gtkcheckbutton.h
@@ -48,37 +48,52 @@ typedef struct _GtkCheckButtonClass GtkCheckButtonClass;
struct _GtkCheckButton
{
- GtkToggleButton toggle_button;
+ GtkWidget parent_instance;
};
struct _GtkCheckButtonClass
{
- GtkToggleButtonClass parent_class;
+ GtkWidgetClass parent_class;
- /*< private >*/
+ void (* toggled) (GtkCheckButton *check_button);
+ /*< private >*/
gpointer padding[8];
};
GDK_AVAILABLE_IN_ALL
-GType gtk_check_button_get_type (void) G_GNUC_CONST;
+GType gtk_check_button_get_type (void) G_GNUC_CONST;
+GDK_AVAILABLE_IN_ALL
+GtkWidget * gtk_check_button_new (void);
+GDK_AVAILABLE_IN_ALL
+GtkWidget * gtk_check_button_new_with_label (const char *label);
+GDK_AVAILABLE_IN_ALL
+GtkWidget * gtk_check_button_new_with_mnemonic (const char *label);
+GDK_AVAILABLE_IN_ALL
+void gtk_check_button_set_inconsistent (GtkCheckButton *check_button,
+ gboolean inconsistent);
+GDK_AVAILABLE_IN_ALL
+gboolean gtk_check_button_get_inconsistent (GtkCheckButton *check_button);
+
GDK_AVAILABLE_IN_ALL
-GtkWidget* gtk_check_button_new (void);
+gboolean gtk_check_button_get_active (GtkCheckButton *self);
GDK_AVAILABLE_IN_ALL
-GtkWidget* gtk_check_button_new_with_label (const char *label);
+void gtk_check_button_set_active (GtkCheckButton *self,
+ gboolean setting);
GDK_AVAILABLE_IN_ALL
-GtkWidget* gtk_check_button_new_with_mnemonic (const char *label);
+const char * gtk_check_button_get_label (GtkCheckButton *self);
GDK_AVAILABLE_IN_ALL
-void gtk_check_button_set_draw_indicator (GtkCheckButton *check_button,
- gboolean draw_indicator);
+void gtk_check_button_set_label (GtkCheckButton *self,
+ const char *label);
GDK_AVAILABLE_IN_ALL
-gboolean gtk_check_button_get_draw_indicator (GtkCheckButton *check_button);
+void gtk_check_button_set_group (GtkCheckButton *self,
+ GtkCheckButton *group);
GDK_AVAILABLE_IN_ALL
-void gtk_check_button_set_inconsistent (GtkCheckButton *check_button,
- gboolean inconsistent);
+gboolean gtk_check_button_get_use_underline (GtkCheckButton *self);
GDK_AVAILABLE_IN_ALL
-gboolean gtk_check_button_get_inconsistent (GtkCheckButton *check_button);
+void gtk_check_button_set_use_underline (GtkCheckButton *self,
+ gboolean setting);
G_END_DECLS
diff --git a/gtk/gtkcheckbuttonprivate.h b/gtk/gtkcheckbuttonprivate.h
deleted file mode 100644
index c7ccf5b002..0000000000
--- a/gtk/gtkcheckbuttonprivate.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* GTK - The GIMP Toolkit
- * Copyright (C) 2015 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- */
-
-/*
- * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
- * file for a list of people on the GTK+ Team. See the ChangeLog
- * files for a list of changes. These files are distributed with
- * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
- */
-
-#ifndef __GTK_CHECK_BUTTON_PRIVATE_H__
-#define __GTK_CHECK_BUTTON_PRIVATE_H__
-
-
-#include "gtkcheckbutton.h"
-#include "gtkcssnodeprivate.h"
-
-
-G_BEGIN_DECLS
-
-GtkCssNode *gtk_check_button_get_indicator_node (GtkCheckButton *check_button);
-
-G_END_DECLS
-
-
-#endif /* __GTK_CHECK_BUTTON_PRIVATE_H__ */
diff --git a/gtk/gtkexpression.c b/gtk/gtkexpression.c
index ddf2b560ef..574274ea7e 100644
--- a/gtk/gtkexpression.c
+++ b/gtk/gtkexpression.c
@@ -146,7 +146,7 @@
* To create a closure expression, use the <closure> element. The `type` and `function`
* attributes specify what function to use for the closure, the content of the element
* contains the expressions for the parameters.
- *
+ *
* Example:
* |[
* <closure type='gchararray' function='combine_args_somehow'>
diff --git a/gtk/gtkfilechooserwidget.c b/gtk/gtkfilechooserwidget.c
index ec30098d72..12d7a14001 100644
--- a/gtk/gtkfilechooserwidget.c
+++ b/gtk/gtkfilechooserwidget.c
@@ -8001,8 +8001,8 @@ gtk_file_chooser_widget_set_choice (GtkFileChooser *chooser,
}
}
}
- else if (GTK_IS_TOGGLE_BUTTON (widget))
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), g_str_equal (option, "true"));
+ else if (GTK_IS_CHECK_BUTTON (widget))
+ gtk_check_button_set_active (GTK_CHECK_BUTTON (widget), g_str_equal (option, "true"));
}
static const char *
@@ -8024,8 +8024,8 @@ gtk_file_chooser_widget_get_choice (GtkFileChooser *chooser,
return NULL;
}
- else if (GTK_IS_TOGGLE_BUTTON (widget))
- return gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)) ? "true" : "false";
+ else if (GTK_IS_CHECK_BUTTON (widget))
+ return gtk_check_button_get_active (GTK_CHECK_BUTTON (widget)) ? "true" : "false";
return NULL;
}
diff --git a/gtk/gtkfontchooserwidget.c b/gtk/gtkfontchooserwidget.c
index 4351316300..b3dfa9b348 100644
--- a/gtk/gtkfontchooserwidget.c
+++ b/gtk/gtkfontchooserwidget.c
@@ -28,6 +28,7 @@
#include "gtkbuildable.h"
#include "gtkbox.h"
#include "gtkbinlayout.h"
+#include "gtkcheckbutton.h"
#include "gtkcustomfilter.h"
#include "gtkentry.h"
#include "gtkfilter.h"
@@ -48,7 +49,6 @@
#include "gtkwidgetprivate.h"
#include "gtksettings.h"
#include "gtkdialog.h"
-#include "gtkradiobutton.h"
#include "gtkgestureclick.h"
#include "gtkeventcontrollerscroll.h"
#include "gtkroot.h"
@@ -1340,31 +1340,31 @@ set_inconsistent (GtkCheckButton *button,
}
static void
-feat_clicked (GtkWidget *feat,
- gpointer data)
+feat_pressed (GtkGestureClick *gesture,
+ int n_press,
+ double x,
+ double y,
+ GtkWidget *feat)
{
- g_signal_handlers_block_by_func (feat, feat_clicked, NULL);
+ const guint button = gtk_gesture_single_get_current_button (GTK_GESTURE_SINGLE (gesture));
- if (gtk_check_button_get_inconsistent (GTK_CHECK_BUTTON (feat)))
+ if (button == GDK_BUTTON_PRIMARY)
{
- set_inconsistent (GTK_CHECK_BUTTON (feat), FALSE);
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (feat), TRUE);
- }
-
- g_signal_handlers_unblock_by_func (feat, feat_clicked, NULL);
-}
+ g_signal_handlers_block_by_func (feat, feat_pressed, NULL);
-static void
-feat_pressed (GtkGesture *gesture,
- int n_press,
- double x,
- double y,
- GtkWidget *feat)
-{
- gboolean inconsistent;
+ if (gtk_check_button_get_inconsistent (GTK_CHECK_BUTTON (feat)))
+ {
+ set_inconsistent (GTK_CHECK_BUTTON (feat), FALSE);
+ gtk_check_button_set_active (GTK_CHECK_BUTTON (feat), TRUE);
+ }
- inconsistent = gtk_check_button_get_inconsistent (GTK_CHECK_BUTTON (feat));
- set_inconsistent (GTK_CHECK_BUTTON (feat), !inconsistent);
+ g_signal_handlers_unblock_by_func (feat, feat_pressed, NULL);
+ }
+ else if (button == GDK_BUTTON_SECONDARY)
+ {
+ gboolean inconsistent = gtk_check_button_get_inconsistent (GTK_CHECK_BUTTON (feat));
+ set_inconsistent (GTK_CHECK_BUTTON (feat), !inconsistent);
+ }
}
static char *
@@ -1546,6 +1546,16 @@ update_feature_example (FeatureItem *item,
}
static void
+font_feature_toggled_cb (GtkCheckButton *check_button,
+ gpointer user_data)
+{
+ GtkFontChooserWidget *fontchooser = user_data;
+
+ set_inconsistent (check_button, FALSE);
+ update_font_features (fontchooser);
+}
+
+static void
add_check_group (GtkFontChooserWidget *fontchooser,
const char *title,
const char **tags)
@@ -1581,9 +1591,8 @@ add_check_group (GtkFontChooserWidget *fontchooser,
feat = gtk_check_button_new_with_label (get_feature_display_name (tag));
set_inconsistent (GTK_CHECK_BUTTON (feat), TRUE);
- g_signal_connect_swapped (feat, "notify::active", G_CALLBACK (update_font_features), fontchooser);
+ g_signal_connect (feat, "toggled", G_CALLBACK (font_feature_toggled_cb), fontchooser);
g_signal_connect_swapped (feat, "notify::inconsistent", G_CALLBACK (update_font_features), fontchooser);
- g_signal_connect (feat, "clicked", G_CALLBACK (feat_clicked), NULL);
gesture = gtk_gesture_click_new ();
gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (gesture), GDK_BUTTON_SECONDARY);
@@ -1649,10 +1658,11 @@ add_radio_group (GtkFontChooserWidget *fontchooser,
tag = hb_tag_from_string (tags[i], -1);
name = get_feature_display_name (tag);
- feat = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (group_button),
- name ? name : _("Default"));
+ feat = gtk_check_button_new_with_label (name ? name : _("Default"));
if (group_button == NULL)
group_button = feat;
+ else
+ gtk_check_button_set_group (GTK_CHECK_BUTTON (feat), GTK_CHECK_BUTTON (group_button));
g_signal_connect_swapped (feat, "notify::active", G_CALLBACK (update_font_features), fontchooser);
g_object_set_data (G_OBJECT (feat), "default", group_button);
@@ -1777,14 +1787,17 @@ gtk_font_chooser_widget_update_font_features (GtkFontChooserWidget *fontchooser)
update_feature_example (item, hb_font, script_tag, lang_tag, fontchooser->font_desc);
- if (GTK_IS_RADIO_BUTTON (item->feat))
+ if (GTK_IS_CHECK_BUTTON (item->feat))
{
GtkWidget *def = GTK_WIDGET (g_object_get_data (G_OBJECT (item->feat), "default"));
- gtk_widget_show (gtk_widget_get_parent (def));
- }
- else if (GTK_IS_CHECK_BUTTON (item->feat))
- {
- set_inconsistent (GTK_CHECK_BUTTON (item->feat), TRUE);
+ if (def)
+ {
+ gtk_widget_show (def);
+ gtk_widget_show (gtk_widget_get_parent (def));
+ gtk_check_button_set_active (GTK_CHECK_BUTTON (def), TRUE);
+ }
+ else
+ set_inconsistent (GTK_CHECK_BUTTON (item->feat), TRUE);
}
}
}
@@ -1810,9 +1823,9 @@ update_font_features (GtkFontChooserWidget *fontchooser)
if (!gtk_widget_is_sensitive (item->feat))
continue;
- if (GTK_IS_RADIO_BUTTON (item->feat))
+ if (GTK_IS_CHECK_BUTTON (item->feat) && g_object_get_data (G_OBJECT (item->feat), "default"))
{
- if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (item->feat)) &&
+ if (gtk_check_button_get_active (GTK_CHECK_BUTTON (item->feat)) &&
strcmp (item->name, "xxxx") != 0)
{
g_string_append_printf (s, "%s\"%s\" %d", s->len > 0 ? ", " : "", item->name, 1);
@@ -1825,7 +1838,7 @@ update_font_features (GtkFontChooserWidget *fontchooser)
g_string_append_printf (s, "%s\"%s\" %d",
s->len > 0 ? ", " : "", item->name,
- gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (item->feat)));
+ gtk_check_button_get_active (GTK_CHECK_BUTTON (item->feat)));
}
}
diff --git a/gtk/gtkmodelbutton.c b/gtk/gtkmodelbutton.c
index 7eda4627fd..0e98039193 100644
--- a/gtk/gtkmodelbutton.c
+++ b/gtk/gtkmodelbutton.c
@@ -54,7 +54,7 @@
* @Title: GtkModelButton
*
* GtkModelButton is a button class that can use a #GAction as its model.
- * In contrast to #GtkToggleButton or #GtkRadioButton, which can also
+ * In contrast to #GtkToggleButton or #GtkCheckButton, which can also
* be backed by a #GAction via the #GtkActionable:action-name property,
* GtkModelButton will adapt its appearance according to the kind of
* action it is backed by, and appear either as a plain, check or
diff --git a/gtk/gtkmountoperation.c b/gtk/gtkmountoperation.c
index 395f3eeea4..29d2f288dd 100644
--- a/gtk/gtkmountoperation.c
+++ b/gtk/gtkmountoperation.c
@@ -38,7 +38,7 @@
#include "gtkmessagedialog.h"
#include "gtkmountoperation.h"
#include "gtkprivate.h"
-#include "gtkradiobutton.h"
+#include "gtkcheckbutton.h"
#include "gtkgrid.h"
#include "gtkwindow.h"
#include "gtktreeview.h"
@@ -322,12 +322,12 @@ gtk_mount_operation_proxy_finish (GtkMountOperation *op,
}
static void
-remember_button_toggled (GtkToggleButton *button,
+remember_button_toggled (GtkCheckButton *button,
GtkMountOperation *operation)
{
GtkMountOperationPrivate *priv = operation->priv;
- if (gtk_toggle_button_get_active (button))
+ if (gtk_check_button_get_active (button))
{
gpointer data;
@@ -384,10 +384,10 @@ pw_dialog_got_response (GtkDialog *dialog,
}
}
- if (priv->tcrypt_hidden_toggle && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->tcrypt_hidden_toggle)))
+ if (priv->tcrypt_hidden_toggle && gtk_check_button_get_active (GTK_CHECK_BUTTON (priv->tcrypt_hidden_toggle)))
g_mount_operation_set_is_tcrypt_hidden_volume (op, TRUE);
- if (priv->tcrypt_system_toggle && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->tcrypt_system_toggle)))
+ if (priv->tcrypt_system_toggle && gtk_check_button_get_active (GTK_CHECK_BUTTON (priv->tcrypt_system_toggle)))
g_mount_operation_set_is_tcrypt_system_volume (op, TRUE);
if (priv->ask_flags & G_ASK_PASSWORD_SAVING_SUPPORTED)
@@ -668,7 +668,6 @@ gtk_mount_operation_ask_password_do_gtk (GtkMountOperation *operation,
{
GtkWidget *anon_box;
GtkWidget *choice;
- GSList *group;
label = gtk_label_new (_("Connect As"));
gtk_widget_set_halign (label, GTK_ALIGN_END);
@@ -679,17 +678,15 @@ gtk_mount_operation_ask_password_do_gtk (GtkMountOperation *operation,
anon_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_grid_attach (GTK_GRID (grid), anon_box, 1, rows++, 1, 1);
- choice = gtk_radio_button_new_with_mnemonic (NULL, _("_Anonymous"));
- gtk_box_append (GTK_BOX (anon_box),
- choice);
+ choice = gtk_check_button_new_with_mnemonic (_("_Anonymous"));
+ gtk_box_append (GTK_BOX (anon_box), choice);
g_signal_connect (choice, "toggled",
G_CALLBACK (pw_dialog_anonymous_toggled), operation);
priv->anonymous_toggle = choice;
- group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (choice));
- choice = gtk_radio_button_new_with_mnemonic (group, _("Registered U_ser"));
- gtk_box_append (GTK_BOX (anon_box),
- choice);
+ choice = gtk_check_button_new_with_mnemonic (_("Registered U_ser"));
+ gtk_check_button_set_group (GTK_CHECK_BUTTON (choice), GTK_CHECK_BUTTON (priv->anonymous_toggle));
+ gtk_box_append (GTK_BOX (anon_box), choice);
g_signal_connect (choice, "toggled",
G_CALLBACK (pw_dialog_anonymous_toggled), operation);
}
@@ -742,7 +739,7 @@ gtk_mount_operation_ask_password_do_gtk (GtkMountOperation *operation,
{
GtkWidget *remember_box;
GtkWidget *choice;
- GSList *group;
+ GtkWidget *group;
GPasswordSave password_save;
remember_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
@@ -755,29 +752,31 @@ gtk_mount_operation_ask_password_do_gtk (GtkMountOperation *operation,
password_save = g_mount_operation_get_password_save (G_MOUNT_OPERATION (operation));
priv->password_save = password_save;
- choice = gtk_radio_button_new_with_mnemonic (NULL, _("Forget password _immediately"));
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (choice),
- password_save == G_PASSWORD_SAVE_NEVER);
+ choice = gtk_check_button_new_with_mnemonic (_("Forget password _immediately"));
+ gtk_check_button_set_active (GTK_CHECK_BUTTON (choice),
+ password_save == G_PASSWORD_SAVE_NEVER);
g_object_set_data (G_OBJECT (choice), "password-save",
GINT_TO_POINTER (G_PASSWORD_SAVE_NEVER));
g_signal_connect (choice, "toggled",
G_CALLBACK (remember_button_toggled), operation);
gtk_box_append (GTK_BOX (remember_box), choice);
+ group = choice;
- group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (choice));
- choice = gtk_radio_button_new_with_mnemonic (group, _("Remember password until you _logout"));
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (choice),
- password_save == G_PASSWORD_SAVE_FOR_SESSION);
+ choice = gtk_check_button_new_with_mnemonic (_("Remember password until you _logout"));
+ gtk_check_button_set_group (GTK_CHECK_BUTTON (choice), GTK_CHECK_BUTTON (group));
+ gtk_check_button_set_active (GTK_CHECK_BUTTON (choice),
+ password_save == G_PASSWORD_SAVE_FOR_SESSION);
g_object_set_data (G_OBJECT (choice), "password-save",
GINT_TO_POINTER (G_PASSWORD_SAVE_FOR_SESSION));
g_signal_connect (choice, "toggled",
G_CALLBACK (remember_button_toggled), operation);
gtk_box_append (GTK_BOX (remember_box), choice);
+ group = choice;
- group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (choice));
- choice = gtk_radio_button_new_with_mnemonic (group, _("Remember _forever"));
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (choice),
- password_save == G_PASSWORD_SAVE_PERMANENTLY);
+ choice = gtk_check_button_new_with_mnemonic (_("Remember _forever"));
+ gtk_check_button_set_group (GTK_CHECK_BUTTON (choice), GTK_CHECK_BUTTON (group));
+ gtk_check_button_set_active (GTK_CHECK_BUTTON (choice),
+ password_save == G_PASSWORD_SAVE_PERMANENTLY);
g_object_set_data (G_OBJECT (choice), "password-save",
GINT_TO_POINTER (G_PASSWORD_SAVE_PERMANENTLY));
g_signal_connect (choice, "toggled",
@@ -793,7 +792,7 @@ gtk_mount_operation_ask_password_do_gtk (GtkMountOperation *operation,
/* The anonymous option will be active by default,
* ensure the toggled signal is emitted for it.
*/
- gtk_toggle_button_toggled (GTK_TOGGLE_BUTTON (priv->anonymous_toggle));
+ g_signal_emit_by_name (priv->anonymous_toggle, "toggled");
}
else if (! pw_dialog_input_is_valid (operation))
gtk_dialog_set_response_sensitive (dialog, GTK_RESPONSE_OK, FALSE);
diff --git a/gtk/gtkpagesetupunixdialog.c b/gtk/gtkpagesetupunixdialog.c
index ed8135eb34..4fe2a03191 100644
--- a/gtk/gtkpagesetupunixdialog.c
+++ b/gtk/gtkpagesetupunixdialog.c
@@ -26,8 +26,7 @@
#include "gtkbutton.h"
#include "gtkscrolledwindow.h"
-#include "gtktogglebutton.h"
-#include "gtkradiobutton.h"
+#include "gtkcheckbutton.h"
#include "gtklabel.h"
#include "gtkgrid.h"
#include "gtkcelllayout.h"
@@ -795,11 +794,11 @@ gtk_page_setup_unix_dialog_new (const char *title,
static GtkPageOrientation
get_orientation (GtkPageSetupUnixDialog *dialog)
{
- if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->portrait_radio)))
+ if (gtk_check_button_get_active (GTK_CHECK_BUTTON (dialog->portrait_radio)))
return GTK_PAGE_ORIENTATION_PORTRAIT;
- if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->landscape_radio)))
+ if (gtk_check_button_get_active (GTK_CHECK_BUTTON (dialog->landscape_radio)))
return GTK_PAGE_ORIENTATION_LANDSCAPE;
- if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->reverse_landscape_radio)))
+ if (gtk_check_button_get_active (GTK_CHECK_BUTTON (dialog->reverse_landscape_radio)))
return GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE;
return GTK_PAGE_ORIENTATION_REVERSE_PORTRAIT;
}
@@ -811,16 +810,16 @@ set_orientation (GtkPageSetupUnixDialog *dialog,
switch (orientation)
{
case GTK_PAGE_ORIENTATION_REVERSE_PORTRAIT:
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->reverse_portrait_radio), TRUE);
+ gtk_check_button_set_active (GTK_CHECK_BUTTON (dialog->reverse_portrait_radio), TRUE);
break;
case GTK_PAGE_ORIENTATION_PORTRAIT:
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->portrait_radio), TRUE);
+ gtk_check_button_set_active (GTK_CHECK_BUTTON (dialog->portrait_radio), TRUE);
break;
case GTK_PAGE_ORIENTATION_LANDSCAPE:
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->landscape_radio), TRUE);
+ gtk_check_button_set_active (GTK_CHECK_BUTTON (dialog->landscape_radio), TRUE);
break;
case GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE:
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->reverse_landscape_radio), TRUE);
+ gtk_check_button_set_active (GTK_CHECK_BUTTON (dialog->reverse_landscape_radio), TRUE);
break;
default:
break;
diff --git a/gtk/gtkprintbackend.c b/gtk/gtkprintbackend.c
index 5cab6e6998..63894df2d2 100644
--- a/gtk/gtkprintbackend.c
+++ b/gtk/gtkprintbackend.c
@@ -562,7 +562,7 @@ store_auth_info_toggled (GtkCheckButton *chkbtn,
gpointer user_data)
{
gboolean *data = (gboolean *) user_data;
- *data = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (chkbtn));
+ *data = gtk_check_button_get_active (GTK_CHECK_BUTTON (chkbtn));
}
static void
@@ -670,7 +670,6 @@ request_password (GtkPrintBackend *backend,
gtk_widget_set_size_request (GTK_WIDGET (label), 320, -1);
g_free (markup);
-
/* Packing */
content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
gtk_box_append (GTK_BOX (content_area), main_box);
@@ -719,7 +718,7 @@ request_password (GtkPrintBackend *backend,
chkbtn = gtk_check_button_new_with_mnemonic (_("_Remember password"));
gtk_widget_set_margin_top (chkbtn, 6);
gtk_widget_set_margin_bottom (chkbtn, 6);
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (chkbtn), FALSE);
+ gtk_check_button_set_active (GTK_CHECK_BUTTON (chkbtn), FALSE);
gtk_box_append (GTK_BOX (vbox), chkbtn);
g_signal_connect (chkbtn, "toggled",
G_CALLBACK (store_auth_info_toggled),
diff --git a/gtk/gtkprinteroptionwidget.c b/gtk/gtkprinteroptionwidget.c
index 200eef8a39..9d8aefa480 100644
--- a/gtk/gtkprinteroptionwidget.c
+++ b/gtk/gtkprinteroptionwidget.c
@@ -32,7 +32,7 @@
#include "gtkimage.h"
#include "gtklabel.h"
#include "gtkliststore.h"
-#include "gtkradiobutton.h"
+#include "gtkcheckbutton.h"
#include "gtkgrid.h"
#include "gtktogglebutton.h"
#include "gtkorientable.h"
@@ -867,7 +867,7 @@ radio_changed_cb (GtkWidget *button,
{
GtkPrinterOptionWidgetPrivate *priv = widget->priv;
char *value;
-
+
g_signal_handler_block (priv->source, priv->source_changed_handler);
value = g_object_get_data (G_OBJECT (button), "value");
if (value)
@@ -877,16 +877,6 @@ radio_changed_cb (GtkWidget *button,
}
static void
-select_maybe (GtkWidget *widget,
- const char *value)
-{
- char *v = g_object_get_data (G_OBJECT (widget), "value");
-
- if (strcmp (value, v) == 0)
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), TRUE);
-}
-
-static void
alternative_set (GtkWidget *box,
const char *value)
{
@@ -895,28 +885,37 @@ alternative_set (GtkWidget *box,
for (child = gtk_widget_get_first_child (box);
child != NULL;
child = gtk_widget_get_next_sibling (child))
- select_maybe (child, value);
+ {
+ char *v = g_object_get_data (G_OBJECT (child), "value");
+
+ if (strcmp (value, v) == 0)
+ {
+ gtk_check_button_set_active (GTK_CHECK_BUTTON (child), TRUE);
+ break;
+ }
+ }
}
-static GSList *
+static void
alternative_append (GtkWidget *box,
const char *label,
const char *value,
GtkPrinterOptionWidget *widget,
- GSList *group)
+ GtkWidget **group)
{
GtkWidget *button;
- button = gtk_radio_button_new_with_label (group, label);
- gtk_widget_show (button);
+ button = gtk_check_button_new_with_label (label);
+ if (*group)
+ gtk_check_button_set_group (GTK_CHECK_BUTTON (button), GTK_CHECK_BUTTON (*group));
+ else
+ *group = button;
+
gtk_widget_set_valign (button, GTK_ALIGN_BASELINE);
gtk_box_append (GTK_BOX (box), button);
g_object_set_data (G_OBJECT (button), "value", (gpointer)value);
- g_signal_connect (button, "toggled",
- G_CALLBACK (radio_changed_cb), widget);
-
- return gtk_radio_button_get_group (GTK_RADIO_BUTTON (button));
+ g_signal_connect (button, "toggled", G_CALLBACK (radio_changed_cb), widget);
}
static void
@@ -926,7 +925,7 @@ construct_widgets (GtkPrinterOptionWidget *widget)
GtkPrinterOption *source;
char *text;
int i;
- GSList *group;
+ GtkWidget *group;
source = priv->source;
@@ -1000,14 +999,14 @@ construct_widgets (GtkPrinterOptionWidget *widget)
gtk_box_append (GTK_BOX (widget), priv->box);
for (i = 0; i < source->num_choices; i++)
{
- group = alternative_append (priv->box,
- source->choices_display[i],
- source->choices[i],
- widget,
- group);
+ alternative_append (priv->box,
+ source->choices_display[i],
+ source->choices[i],
+ widget,
+ &group);
/* for mnemonic activation */
if (i == 0)
- priv->button = group->data;
+ priv->button = group;
}
if (source->display_text)
@@ -1124,9 +1123,9 @@ update_widgets (GtkPrinterOptionWidget *widget)
{
case GTK_PRINTER_OPTION_TYPE_BOOLEAN:
if (g_ascii_strcasecmp (source->value, "True") == 0)
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->check), TRUE);
+ gtk_check_button_set_active (GTK_CHECK_BUTTON (priv->check), TRUE);
else
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->check), FALSE);
+ gtk_check_button_set_active (GTK_CHECK_BUTTON (priv->check), FALSE);
break;
case GTK_PRINTER_OPTION_TYPE_PICKONE:
combo_box_set (priv->combo, source->value);
diff --git a/gtk/gtkprintunixdialog.c b/gtk/gtkprintunixdialog.c
index b7e486fb30..5f2baa8489 100644
--- a/gtk/gtkprintunixdialog.c
+++ b/gtk/gtkprintunixdialog.c
@@ -38,7 +38,6 @@
#include "gtknotebook.h"
#include "gtkscrolledwindow.h"
#include "gtktogglebutton.h"
-#include "gtkradiobutton.h"
#include "gtkdrawingarea.h"
#include "gtkbox.h"
#include "gtkgrid.h"
@@ -1361,9 +1360,9 @@ update_print_at_option (GtkPrintUnixDialog *dialog)
if (dialog->updating_print_at)
return;
- if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->print_at_radio)))
+ if (gtk_check_button_get_active (GTK_CHECK_BUTTON (dialog->print_at_radio)))
gtk_printer_option_set (option, "at");
- else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->print_hold_radio)))
+ else if (gtk_check_button_get_active (GTK_CHECK_BUTTON (dialog->print_hold_radio)))
gtk_printer_option_set (option, "on-hold");
else
gtk_printer_option_set (option, "now");
@@ -1388,8 +1387,7 @@ setup_print_at (GtkPrintUnixDialog *dialog)
if (option == NULL)
{
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->print_now_radio),
- TRUE);
+ gtk_check_button_set_active (GTK_CHECK_BUTTON (dialog->print_now_radio), TRUE);
gtk_widget_set_sensitive (dialog->print_at_radio, FALSE);
gtk_widget_set_sensitive (dialog->print_at_entry, FALSE);
gtk_widget_set_sensitive (dialog->print_hold_radio, FALSE);
@@ -1409,14 +1407,11 @@ setup_print_at (GtkPrintUnixDialog *dialog)
update_print_at_option (dialog);
if (strcmp (option->value, "at") == 0)
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->print_at_radio),
- TRUE);
+ gtk_check_button_set_active (GTK_CHECK_BUTTON (dialog->print_at_radio), TRUE);
else if (strcmp (option->value, "on-hold") == 0)
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->print_hold_radio),
- TRUE);
+ gtk_check_button_set_active (GTK_CHECK_BUTTON (dialog->print_hold_radio), TRUE);
else
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->print_now_radio),
- TRUE);
+ gtk_check_button_set_active (GTK_CHECK_BUTTON (dialog->print_now_radio), TRUE);
option = gtk_printer_option_set_lookup (dialog->options, "gtk-print-time-text");
if (option != NULL)
@@ -2013,7 +2008,7 @@ page_range_entry_focus_changed (GtkWidget *entry,
GtkPrintUnixDialog *dialog)
{
if (gtk_widget_has_focus (entry))
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->page_range_radio), TRUE);
+ gtk_check_button_set_active (GTK_CHECK_BUTTON (dialog->page_range_radio), TRUE);
return FALSE;
}
@@ -2024,7 +2019,7 @@ update_page_range_entry_sensitivity (GtkWidget *button,
{
gboolean active;
- active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button));
+ active = gtk_check_button_get_active (GTK_CHECK_BUTTON (button));
if (active)
gtk_widget_grab_focus (dialog->page_range_entry);
@@ -2036,7 +2031,7 @@ update_print_at_entry_sensitivity (GtkWidget *button,
{
gboolean active;
- active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button));
+ active = gtk_check_button_get_active (GTK_CHECK_BUTTON (button));
gtk_widget_set_sensitive (dialog->print_at_entry, active);
@@ -2158,11 +2153,11 @@ dialog_set_page_ranges (GtkPrintUnixDialog *dialog,
static GtkPrintPages
dialog_get_print_pages (GtkPrintUnixDialog *dialog)
{
- if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->all_pages_radio)))
+ if (gtk_check_button_get_active (GTK_CHECK_BUTTON (dialog->all_pages_radio)))
return GTK_PRINT_PAGES_ALL;
- else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->current_page_radio)))
+ else if (gtk_check_button_get_active (GTK_CHECK_BUTTON (dialog->current_page_radio)))
return GTK_PRINT_PAGES_CURRENT;
- else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->selection_radio)))
+ else if (gtk_check_button_get_active (GTK_CHECK_BUTTON (dialog->selection_radio)))
return GTK_PRINT_PAGES_SELECTION;
else
return GTK_PRINT_PAGES_RANGES;
@@ -2173,13 +2168,13 @@ dialog_set_print_pages (GtkPrintUnixDialog *dialog,
GtkPrintPages pages)
{
if (pages == GTK_PRINT_PAGES_RANGES)
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->page_range_radio), TRUE);
+ gtk_check_button_set_active (GTK_CHECK_BUTTON (dialog->page_range_radio), TRUE);
else if (pages == GTK_PRINT_PAGES_CURRENT)
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->current_page_radio), TRUE);
+ gtk_check_button_set_active (GTK_CHECK_BUTTON (dialog->current_page_radio), TRUE);
else if (pages == GTK_PRINT_PAGES_SELECTION)
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->selection_radio), TRUE);
+ gtk_check_button_set_active (GTK_CHECK_BUTTON (dialog->selection_radio), TRUE);
else
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->all_pages_radio), TRUE);
+ gtk_check_button_set_active (GTK_CHECK_BUTTON (dialog->all_pages_radio), TRUE);
}
static double
@@ -2253,7 +2248,7 @@ static gboolean
dialog_get_collate (GtkPrintUnixDialog *dialog)
{
if (gtk_widget_is_sensitive (dialog->collate_check))
- return gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->collate_check));
+ return gtk_check_button_get_active (GTK_CHECK_BUTTON (dialog->collate_check));
return FALSE;
}
@@ -2261,14 +2256,14 @@ static void
dialog_set_collate (GtkPrintUnixDialog *dialog,
gboolean collate)
{
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->collate_check), collate);
+ gtk_check_button_set_active (GTK_CHECK_BUTTON (dialog->collate_check), collate);
}
static gboolean
dialog_get_reverse (GtkPrintUnixDialog *dialog)
{
if (gtk_widget_is_sensitive (dialog->reverse_check))
- return gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->reverse_check));
+ return gtk_check_button_get_active (GTK_CHECK_BUTTON (dialog->reverse_check));
return FALSE;
}
@@ -2276,7 +2271,7 @@ static void
dialog_set_reverse (GtkPrintUnixDialog *dialog,
gboolean reverse)
{
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->reverse_check), reverse);
+ gtk_check_button_set_active (GTK_CHECK_BUTTON (dialog->reverse_check), reverse);
}
static int
diff --git a/gtk/gtkradiobutton.c b/gtk/gtkradiobutton.c
deleted file mode 100644
index a610e361da..0000000000
--- a/gtk/gtkradiobutton.c
+++ /dev/null
@@ -1,780 +0,0 @@
-/* GTK - The GIMP Toolkit
- * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- */
-
-/*
- * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
- * file for a list of people on the GTK+ Team. See the ChangeLog
- * files for a list of changes. These files are distributed with
- * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
- */
-
-#include "config.h"
-
-#include "gtkradiobutton.h"
-
-#include "gtkwidgetprivate.h"
-#include "gtkcheckbuttonprivate.h"
-#include "gtklabel.h"
-#include "gtkmarshalers.h"
-#include "gtkprivate.h"
-#include "gtkintl.h"
-#include "gtkstylecontextprivate.h"
-
-/**
- * SECTION:gtkradiobutton
- * @Short_description: A choice from multiple check buttons
- * @Title: GtkRadioButton
- * @See_also: #GtkComboBox
- *
- * A single radio button performs the same basic function as a #GtkCheckButton,
- * as its position in the object hierarchy reflects. It is only when multiple
- * radio buttons are grouped together that they become a different user
- * interface component in their own right.
- *
- * Every radio button is a member of some group of radio buttons. When one is
- * selected, all other radio buttons in the same group are deselected. A
- * #GtkRadioButton is one way of giving the user a choice from many options.
- *
- * Radio button widgets are created with gtk_radio_button_new(), passing %NULL
- * as the argument if this is the first radio button in a group. In subsequent
- * calls, the group you wish to add this button to should be passed as an
- * argument. Optionally, gtk_radio_button_new_with_label() can be used if you
- * want a text label on the radio button.
- *
- * Alternatively, when adding widgets to an existing group of radio buttons,
- * use gtk_radio_button_new_from_widget() with a #GtkRadioButton that already
- * has a group assigned to it. The convenience function
- * gtk_radio_button_new_with_label_from_widget() is also provided.
- *
- * To retrieve the group a #GtkRadioButton is assigned to, use
- * gtk_radio_button_get_group().
- *
- * To remove a #GtkRadioButton from one group and make it part of a new one,
- * use gtk_radio_button_set_group().
- *
- * The group list does not need to be freed, as each #GtkRadioButton will remove
- * itself and its list item when it is destroyed.
- *
- * ## How to create a group of two radio buttons.
- *
- * |[<!-- language="C" -->
- * void create_radio_buttons (void) {
- *
- * GtkWidget *window, *radio1, *radio2, *box, *entry;
- * window = gtk_window_new ();
- * box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
- * gtk_box_set_homogeneous (GTK_BOX (box), TRUE);
- *
- * // Create a radio button with a GtkEntry widget
- * radio1 = gtk_radio_button_new (NULL);
- * entry = gtk_entry_new ();
- * gtk_box_append (GTK_BOX (radio1), entry);
- *
- *
- * // Create a radio button with a label
- * radio2 = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (radio1),
- * "I’m the second radio button.");
- *
- * // Pack them into a box, then show all the widgets
- * gtk_box_append (GTK_BOX (box), radio1);
- * gtk_box_append (GTK_BOX (box), radio2);
- gtk_window_set_child (GTK_WINDOW (window),box);
- * gtk_widget_show (window);
- * return;
- * }
- * ]|
- *
- * When an unselected button in the group is clicked the clicked button
- * receives the #GtkToggleButton::toggled signal, as does the previously
- * selected button.
- * Inside the #GtkToggleButton::toggled handler, gtk_toggle_button_get_active()
- * can be used to determine if the button has been selected or deselected.
- *
- * # CSS nodes
- *
- * |[<!-- language="plain" -->
- * radiobutton
- * ├── radio
- * ╰── <child>
- * ]|
- *
- * A GtkRadioButton with indicator (see gtk_check_button_set_draw_indicator())) has a
- * main CSS node with name radiobutton and a subnode with name radio.
- *
- * |[<!-- language="plain" -->
- * button.radio
- * ├── radio
- * ╰── <child>
- * ]|
- *
- * A GtkRadioButton without indicator changes the name of its main node
- * to button and adds a .radio style class to it. The subnode is invisible
- * in this case.
- *
- * # Accessibility
- *
- * GtkRadioButton uses the #GTK_ACCESSIBLE_ROLE_RADIO role.
- */
-
-typedef struct _GtkRadioButtonClass GtkRadioButtonClass;
-
-struct _GtkRadioButton
-{
- GtkCheckButton parent_instance;
-};
-
-struct _GtkRadioButtonClass
-{
- GtkCheckButtonClass parent_class;
-
- void (*group_changed) (GtkRadioButton *radio_button);
-};
-
-typedef struct
-{
- GSList *group;
-} GtkRadioButtonPrivate;
-
-enum {
- PROP_0,
- PROP_GROUP,
- LAST_PROP
-};
-
-enum {
- GROUP_CHANGED,
- N_SIGNALS
-};
-
-static GParamSpec *radio_button_props[LAST_PROP] = { NULL, };
-static guint signals[N_SIGNALS] = { 0 };
-
-static void gtk_radio_button_dispose (GObject *object);
-static gboolean gtk_radio_button_focus (GtkWidget *widget,
- GtkDirectionType direction);
-static void gtk_radio_button_clicked (GtkButton *button);
-static void gtk_radio_button_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec);
-static void gtk_radio_button_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec);
-
-G_DEFINE_TYPE_WITH_PRIVATE (GtkRadioButton, gtk_radio_button, GTK_TYPE_CHECK_BUTTON)
-
-static void
-gtk_radio_button_class_init (GtkRadioButtonClass *class)
-{
- GObjectClass *gobject_class;
- GtkButtonClass *button_class;
- GtkWidgetClass *widget_class;
-
- gobject_class = G_OBJECT_CLASS (class);
- widget_class = (GtkWidgetClass*) class;
- button_class = (GtkButtonClass*) class;
-
- gobject_class->dispose = gtk_radio_button_dispose;
- gobject_class->set_property = gtk_radio_button_set_property;
- gobject_class->get_property = gtk_radio_button_get_property;
-
- /**
- * GtkRadioButton:group:
- *
- * Sets a new group for a radio button.
- */
- radio_button_props[PROP_GROUP] =
- g_param_spec_object ("group",
- P_("Group"),
- P_("The radio button whose group this widget belongs to."),
- GTK_TYPE_RADIO_BUTTON,
- GTK_PARAM_WRITABLE);
-
- g_object_class_install_properties (gobject_class, LAST_PROP, radio_button_props);
-
- widget_class->focus = gtk_radio_button_focus;
-
- button_class->clicked = gtk_radio_button_clicked;
-
- class->group_changed = NULL;
-
- /**
- * GtkRadioButton::group-changed:
- * @button: the object which received the signal
- *
- * Emitted when the group of radio buttons that a radio button belongs
- * to changes. This is emitted when a radio button switches from
- * being alone to being part of a group of 2 or more buttons, or
- * vice-versa, and when a button is moved from one group of 2 or
- * more buttons to a different one, but not when the composition
- * of the group that a button belongs to changes.
- */
- signals[GROUP_CHANGED] = g_signal_new (I_("group-changed"),
- G_OBJECT_CLASS_TYPE (gobject_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (GtkRadioButtonClass, group_changed),
- NULL, NULL,
- NULL,
- G_TYPE_NONE, 0);
-
- gtk_widget_class_set_css_name (widget_class, I_("radiobutton"));
- gtk_widget_class_set_accessible_role (widget_class, GTK_ACCESSIBLE_ROLE_RADIO);
-}
-
-static void
-gtk_radio_button_init (GtkRadioButton *self)
-{
- GtkRadioButtonPrivate *priv = gtk_radio_button_get_instance_private (self);
- GtkWidget *widget = GTK_WIDGET (self);
- GtkCssNode *css_node;
-
- gtk_widget_set_receives_default (widget, FALSE);
-
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (self), TRUE);
-
- priv->group = g_slist_prepend (NULL, self);
-
- css_node = gtk_widget_get_css_node (widget);
- gtk_css_node_set_name (css_node, g_quark_from_static_string ("radiobutton"));
- css_node = gtk_check_button_get_indicator_node (GTK_CHECK_BUTTON (self));
- gtk_css_node_set_name (css_node, g_quark_from_static_string ("radio"));
-}
-
-static void
-gtk_radio_button_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- GtkRadioButton *radio_button;
-
- radio_button = GTK_RADIO_BUTTON (object);
-
- switch (prop_id)
- {
- GSList *slist;
- GtkRadioButton *button;
-
- case PROP_GROUP:
- button = g_value_get_object (value);
-
- if (button)
- slist = gtk_radio_button_get_group (button);
- else
- slist = NULL;
- gtk_radio_button_set_group (radio_button, slist);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-static void
-gtk_radio_button_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- switch (prop_id)
- {
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
-/**
- * gtk_radio_button_set_group:
- * @radio_button: a #GtkRadioButton.
- * @group: (element-type GtkRadioButton) (allow-none): an existing radio
- * button group, such as one returned from gtk_radio_button_get_group(), or %NULL.
- *
- * Sets a #GtkRadioButton’s group. It should be noted that this does not change
- * the layout of your interface in any way, so if you are changing the group,
- * it is likely you will need to re-arrange the user interface to reflect these
- * changes.
- */
-void
-gtk_radio_button_set_group (GtkRadioButton *radio_button,
- GSList *group)
-{
- GtkRadioButtonPrivate *priv = gtk_radio_button_get_instance_private (radio_button);
- GtkWidget *old_group_singleton = NULL;
- GtkWidget *new_group_singleton = NULL;
-
- g_return_if_fail (GTK_IS_RADIO_BUTTON (radio_button));
-
- if (g_slist_find (group, radio_button))
- return;
-
- if (priv->group)
- {
- GSList *slist;
-
- priv->group = g_slist_remove (priv->group, radio_button);
-
- if (priv->group && !priv->group->next)
- old_group_singleton = g_object_ref (priv->group->data);
-
- for (slist = priv->group; slist; slist = slist->next)
- {
- GtkRadioButton *tmp_button = slist->data;
- GtkRadioButtonPrivate *tmp_priv = gtk_radio_button_get_instance_private (tmp_button);
-
- tmp_priv->group = priv->group;
- }
- }
-
- if (group && !group->next)
- new_group_singleton = g_object_ref (group->data);
-
- priv->group = g_slist_prepend (group, radio_button);
-
- if (group)
- {
- GSList *slist;
-
- for (slist = group; slist; slist = slist->next)
- {
- GtkRadioButton *tmp_button = slist->data;
- GtkRadioButtonPrivate *tmp_priv = gtk_radio_button_get_instance_private (tmp_button);
-
- tmp_priv->group = priv->group;
- }
- }
-
- g_object_ref (radio_button);
-
- g_object_notify_by_pspec (G_OBJECT (radio_button), radio_button_props[PROP_GROUP]);
- g_signal_emit (radio_button, signals[GROUP_CHANGED], 0);
- if (old_group_singleton)
- {
- g_signal_emit (old_group_singleton, signals[GROUP_CHANGED], 0);
- g_object_unref (old_group_singleton);
- }
- if (new_group_singleton)
- {
- g_signal_emit (new_group_singleton, signals[GROUP_CHANGED], 0);
- g_object_unref (new_group_singleton);
- }
-
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio_button), group == NULL);
-
- g_object_unref (radio_button);
-}
-
-/**
- * gtk_radio_button_join_group:
- * @radio_button: the #GtkRadioButton object
- * @group_source: (allow-none): a radio button object whose group we are
- * joining, or %NULL to remove the radio button from its group
- *
- * Joins a #GtkRadioButton object to the group of another #GtkRadioButton object
- *
- * Use this in language bindings instead of the gtk_radio_button_get_group()
- * and gtk_radio_button_set_group() methods
- *
- * A common way to set up a group of radio buttons is the following:
- * |[<!-- language="C" -->
- * GtkRadioButton *radio_button;
- * GtkRadioButton *last_button;
- *
- * while (some_condition)
- * {
- * radio_button = GTK_RADIO_BUTTON (gtk_radio_button_new (NULL));
- *
- * gtk_radio_button_join_group (radio_button, last_button);
- * last_button = radio_button;
- * }
- * ]|
- */
-void
-gtk_radio_button_join_group (GtkRadioButton *radio_button,
- GtkRadioButton *group_source)
-{
- g_return_if_fail (GTK_IS_RADIO_BUTTON (radio_button));
- g_return_if_fail (group_source == NULL || GTK_IS_RADIO_BUTTON (group_source));
-
- if (group_source)
- {
- GSList *group;
- group = gtk_radio_button_get_group (group_source);
-
- if (!group)
- {
- /* if we are not already part of a group we need to set up a new one
- and then get the newly created group */
- gtk_radio_button_set_group (group_source, NULL);
- group = gtk_radio_button_get_group (group_source);
- }
-
- gtk_radio_button_set_group (radio_button, group);
- }
- else
- {
- gtk_radio_button_set_group (radio_button, NULL);
- }
-}
-
-/**
- * gtk_radio_button_new:
- * @group: (element-type GtkRadioButton) (allow-none): an existing
- * radio button group, or %NULL if you are creating a new group.
- *
- * Creates a new #GtkRadioButton. To be of any practical value, a widget should
- * then be packed into the radio button.
- *
- * Returns: a new radio button
- */
-GtkWidget*
-gtk_radio_button_new (GSList *group)
-{
- GtkRadioButton *radio_button;
-
- radio_button = g_object_new (GTK_TYPE_RADIO_BUTTON, NULL);
-
- if (group)
- gtk_radio_button_set_group (radio_button, group);
-
- return GTK_WIDGET (radio_button);
-}
-
-/**
- * gtk_radio_button_new_with_label:
- * @group: (element-type GtkRadioButton) (allow-none): an existing
- * radio button group, or %NULL if you are creating a new group.
- * @label: the text label to display next to the radio button.
- *
- * Creates a new #GtkRadioButton with a text label.
- *
- * Returns: a new radio button.
- */
-GtkWidget*
-gtk_radio_button_new_with_label (GSList *group,
- const char *label)
-{
- GtkWidget *radio_button;
-
- 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);
-
- return radio_button;
-}
-
-
-/**
- * gtk_radio_button_new_with_mnemonic:
- * @group: (element-type GtkRadioButton) (allow-none): the radio button
- * group, or %NULL
- * @label: the text of the button, with an underscore in front of the
- * mnemonic character
- *
- * Creates a new #GtkRadioButton containing a label, adding it to the same
- * group as @group. The label will be created using
- * gtk_label_new_with_mnemonic(), so underscores in @label indicate the
- * mnemonic for the button.
- *
- * Returns: a new #GtkRadioButton
- */
-GtkWidget*
-gtk_radio_button_new_with_mnemonic (GSList *group,
- const char *label)
-{
- GtkWidget *radio_button;
-
- radio_button = g_object_new (GTK_TYPE_RADIO_BUTTON,
- "label", label,
- "use-underline", TRUE,
- NULL);
-
- if (group)
- gtk_radio_button_set_group (GTK_RADIO_BUTTON (radio_button), group);
-
- return radio_button;
-}
-
-/**
- * gtk_radio_button_new_from_widget: (constructor)
- * @radio_group_member: (allow-none): an existing #GtkRadioButton.
- *
- * Creates a new #GtkRadioButton, adding it to the same group as
- * @radio_group_member. As with gtk_radio_button_new(), a widget
- * should be packed into the radio button.
- *
- * Returns: (transfer none): a new radio button.
- */
-GtkWidget*
-gtk_radio_button_new_from_widget (GtkRadioButton *radio_group_member)
-{
- GSList *l = NULL;
- if (radio_group_member)
- l = gtk_radio_button_get_group (radio_group_member);
- return gtk_radio_button_new (l);
-}
-
-/**
- * gtk_radio_button_new_with_label_from_widget: (constructor)
- * @radio_group_member: (allow-none): widget to get radio group from or %NULL
- * @label: a text string to display next to the radio button.
- *
- * Creates a new #GtkRadioButton with a text label, adding it to
- * the same group as @radio_group_member.
- *
- * Returns: (transfer none): a new radio button.
- */
-GtkWidget*
-gtk_radio_button_new_with_label_from_widget (GtkRadioButton *radio_group_member,
- const char *label)
-{
- GSList *l = NULL;
- if (radio_group_member)
- l = gtk_radio_button_get_group (radio_group_member);
- return gtk_radio_button_new_with_label (l, label);
-}
-
-/**
- * gtk_radio_button_new_with_mnemonic_from_widget: (constructor)
- * @radio_group_member: (allow-none): widget to get radio group from or %NULL
- * @label: the text of the button, with an underscore in front of the
- * mnemonic character
- *
- * Creates a new #GtkRadioButton containing a label. The label
- * will be created using gtk_label_new_with_mnemonic(), so underscores
- * in @label indicate the mnemonic for the button.
- *
- * Returns: (transfer none): a new #GtkRadioButton
- **/
-GtkWidget*
-gtk_radio_button_new_with_mnemonic_from_widget (GtkRadioButton *radio_group_member,
- const char *label)
-{
- GSList *l = NULL;
- if (radio_group_member)
- l = gtk_radio_button_get_group (radio_group_member);
- return gtk_radio_button_new_with_mnemonic (l, label);
-}
-
-
-/**
- * gtk_radio_button_get_group:
- * @radio_button: a #GtkRadioButton.
- *
- * Retrieves the group assigned to a radio button.
- *
- * Returns: (element-type GtkRadioButton) (transfer none): a linked list
- * containing all the radio buttons in the same group
- * as @radio_button. The returned list is owned by the radio button
- * and must not be modified or freed.
- */
-GSList*
-gtk_radio_button_get_group (GtkRadioButton *radio_button)
-{
- GtkRadioButtonPrivate *priv = gtk_radio_button_get_instance_private (radio_button);
-
- g_return_val_if_fail (GTK_IS_RADIO_BUTTON (radio_button), NULL);
-
- return priv->group;
-}
-
-
-static void
-gtk_radio_button_dispose (GObject *object)
-{
- GtkWidget *old_group_singleton = NULL;
- GtkRadioButton *radio_button = GTK_RADIO_BUTTON (object);
- GtkRadioButtonPrivate *priv = gtk_radio_button_get_instance_private (radio_button);
- GSList *tmp_list;
- gboolean was_in_group;
-
- was_in_group = priv->group && priv->group->next;
-
- priv->group = g_slist_remove (priv->group, radio_button);
- if (priv->group && !priv->group->next)
- old_group_singleton = priv->group->data;
-
- tmp_list = priv->group;
-
- while (tmp_list)
- {
- GtkRadioButton *tmp_button = tmp_list->data;
- GtkRadioButtonPrivate *tmp_priv = gtk_radio_button_get_instance_private (tmp_button);
-
- tmp_list = tmp_list->next;
-
- tmp_priv->group = priv->group;
- }
-
- /* this button is no longer in the group */
- priv->group = NULL;
-
- if (old_group_singleton)
- g_signal_emit (old_group_singleton, signals[GROUP_CHANGED], 0);
- if (was_in_group)
- g_signal_emit (radio_button, signals[GROUP_CHANGED], 0);
-
- G_OBJECT_CLASS (gtk_radio_button_parent_class)->dispose (object);
-}
-
-static gboolean
-gtk_radio_button_focus (GtkWidget *widget,
- GtkDirectionType direction)
-{
- GtkRadioButton *radio_button = GTK_RADIO_BUTTON (widget);
- GtkRadioButtonPrivate *priv = gtk_radio_button_get_instance_private (radio_button);
- GSList *tmp_slist;
- GtkRadioButton *selected_button = NULL;
-
- /* Radio buttons with draw_indicator unset focus "normally", since
- * they look like buttons to the user.
- */
- if (!gtk_check_button_get_draw_indicator (GTK_CHECK_BUTTON (widget)))
- return GTK_WIDGET_CLASS (gtk_radio_button_parent_class)->focus (widget, direction);
-
- /* Find the currently active button in the group */
- tmp_slist = priv->group;
- while (tmp_slist)
- {
- if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (tmp_slist->data)) &&
- gtk_widget_get_visible (tmp_slist->data))
- selected_button = tmp_slist->data;
- tmp_slist = tmp_slist->next;
- }
-
- if (gtk_widget_is_focus (widget))
- {
- GPtrArray *child_array;
- GtkWidget *new_focus = NULL;
- GSList *l;
- guint index;
- gboolean found;
- guint i;
-
- if (direction == GTK_DIR_TAB_FORWARD ||
- direction == GTK_DIR_TAB_BACKWARD)
- return FALSE;
-
- child_array = g_ptr_array_sized_new (g_slist_length (priv->group));
- for (l = priv->group; l; l = l->next)
- g_ptr_array_add (child_array, l->data);
-
- gtk_widget_focus_sort (widget, direction, child_array);
- found = g_ptr_array_find (child_array, widget, &index);
-
- if (found)
- {
- /* Start at the *next* widget in the list */
- if (index < child_array->len - 1)
- index ++;
- }
- else
- {
- /* Search from the start of the list */
- index = 0;
- }
-
- for (i = index; i < child_array->len; i ++)
- {
- GtkWidget *child = g_ptr_array_index (child_array, i);
-
- if (gtk_widget_get_mapped (child) && gtk_widget_is_sensitive (child))
- {
- new_focus = child;
- break;
- }
- }
-
-
- if (new_focus)
- {
- gtk_widget_grab_focus (new_focus);
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (new_focus), TRUE);
- if (selected_button && selected_button != (GtkRadioButton *)new_focus)
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (selected_button), FALSE);
- }
-
- g_ptr_array_free (child_array, TRUE);
- return TRUE;
- }
- else
- {
- if (selected_button && selected_button != radio_button)
- return FALSE;
-
- gtk_widget_grab_focus (widget);
- return TRUE;
- }
-}
-
-static void
-gtk_radio_button_clicked (GtkButton *button)
-{
- GtkRadioButton *radio_button = GTK_RADIO_BUTTON (button);
- GtkRadioButtonPrivate *priv = gtk_radio_button_get_instance_private (radio_button);
- GtkToggleButton *toggle_button = GTK_TOGGLE_BUTTON (button);
- GtkToggleButton *tmp_button;
- GSList *tmp_list;
-
- g_object_ref (GTK_WIDGET (button));
-
- if (gtk_toggle_button_get_active (toggle_button))
- {
- tmp_button = NULL;
- tmp_list = priv->group;
-
- while (tmp_list)
- {
- tmp_button = tmp_list->data;
- tmp_list = tmp_list->next;
-
- if (tmp_button != toggle_button &&
- gtk_toggle_button_get_active (tmp_button))
- break;
-
- tmp_button = NULL;
- }
-
- if (tmp_button)
- gtk_toggle_button_set_active (toggle_button,
- !gtk_toggle_button_get_active (toggle_button));
- }
- else
- {
- gtk_toggle_button_set_active (toggle_button,
- !gtk_toggle_button_get_active (toggle_button));
-
- tmp_list = priv->group;
- while (tmp_list)
- {
- tmp_button = tmp_list->data;
- tmp_list = tmp_list->next;
-
- if (gtk_toggle_button_get_active (tmp_button) && (tmp_button != toggle_button))
- {
- g_signal_emit_by_name (tmp_button, "clicked");
- break;
- }
- }
- }
-
- gtk_widget_queue_draw (GTK_WIDGET (button));
-
- g_object_unref (button);
-}
diff --git a/gtk/gtkradiobutton.h b/gtk/gtkradiobutton.h
deleted file mode 100644
index d2922fd3da..0000000000
--- a/gtk/gtkradiobutton.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/* GTK - The GIMP Toolkit
- * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- */
-
-/*
- * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
- * file for a list of people on the GTK+ Team. See the ChangeLog
- * files for a list of changes. These files are distributed with
- * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
- */
-
-#ifndef __GTK_RADIO_BUTTON_H__
-#define __GTK_RADIO_BUTTON_H__
-
-
-#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
-#error "Only <gtk/gtk.h> can be included directly."
-#endif
-
-#include <gtk/gtkcheckbutton.h>
-
-
-G_BEGIN_DECLS
-
-#define GTK_TYPE_RADIO_BUTTON (gtk_radio_button_get_type ())
-#define GTK_RADIO_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_RADIO_BUTTON, GtkRadioButton))
-#define GTK_IS_RADIO_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_RADIO_BUTTON))
-
-
-typedef struct _GtkRadioButton GtkRadioButton;
-
-GDK_AVAILABLE_IN_ALL
-GType gtk_radio_button_get_type (void) G_GNUC_CONST;
-
-GDK_AVAILABLE_IN_ALL
-GtkWidget* gtk_radio_button_new (GSList *group);
-GDK_AVAILABLE_IN_ALL
-GtkWidget* gtk_radio_button_new_from_widget (GtkRadioButton *radio_group_member);
-GDK_AVAILABLE_IN_ALL
-GtkWidget* gtk_radio_button_new_with_label (GSList *group,
- const char *label);
-GDK_AVAILABLE_IN_ALL
-GtkWidget* gtk_radio_button_new_with_label_from_widget (GtkRadioButton *radio_group_member,
- const char *label);
-GDK_AVAILABLE_IN_ALL
-GtkWidget* gtk_radio_button_new_with_mnemonic (GSList *group,
- const char *label);
-GDK_AVAILABLE_IN_ALL
-GtkWidget* gtk_radio_button_new_with_mnemonic_from_widget (GtkRadioButton *radio_group_member,
- const char *label);
-GDK_AVAILABLE_IN_ALL
-GSList* gtk_radio_button_get_group (GtkRadioButton *radio_button);
-GDK_AVAILABLE_IN_ALL
-void gtk_radio_button_set_group (GtkRadioButton *radio_button,
- GSList *group);
-GDK_AVAILABLE_IN_ALL
-void gtk_radio_button_join_group (GtkRadioButton *radio_button,
- GtkRadioButton *group_source);
-G_END_DECLS
-
-#endif /* __GTK_RADIO_BUTTON_H__ */
diff --git a/gtk/gtkrender.c b/gtk/gtkrender.c
index e095832cc3..4abb9fbc0e 100644
--- a/gtk/gtkrender.c
+++ b/gtk/gtkrender.c
@@ -104,7 +104,7 @@ gtk_render_check (GtkStyleContext *context,
* @width: rectangle width
* @height: rectangle height
*
- * Renders an option mark (as in a #GtkRadioButton), the %GTK_STATE_FLAG_CHECKED
+ * Renders an option mark (as in a radio button), the %GTK_STATE_FLAG_CHECKED
* state will determine whether the option is on or off, and
* %GTK_STATE_FLAG_INCONSISTENT whether it should be marked as undefined.
*
diff --git a/gtk/gtkspinbutton.c b/gtk/gtkspinbutton.c
index 2792dd5ac0..7cd5b7d01a 100644
--- a/gtk/gtkspinbutton.c
+++ b/gtk/gtkspinbutton.c
@@ -777,9 +777,9 @@ swipe_gesture_update (GtkGesture *gesture,
static gboolean
scroll_controller_scroll (GtkEventControllerScroll *Scroll,
- double dx,
- double dy,
- GtkWidget *widget)
+ double dx,
+ double dy,
+ GtkWidget *widget)
{
GtkSpinButton *spin = GTK_SPIN_BUTTON (widget);
diff --git a/gtk/gtkstackswitcher.c b/gtk/gtkstackswitcher.c
index cf452db7cc..b295862108 100644
--- a/gtk/gtkstackswitcher.c
+++ b/gtk/gtkstackswitcher.c
@@ -27,9 +27,9 @@
#include "gtkintl.h"
#include "gtklabel.h"
#include "gtkprivate.h"
-#include "gtkradiobutton.h"
#include "gtkselectionmodel.h"
#include "gtkstylecontext.h"
+#include "gtktogglebutton.h"
#include "gtktypebuiltins.h"
#include "gtkwidgetprivate.h"
diff --git a/gtk/gtktogglebutton.c b/gtk/gtktogglebutton.c
index bb6a3e8adf..edce7e0368 100644
--- a/gtk/gtktogglebutton.c
+++ b/gtk/gtktogglebutton.c
@@ -101,6 +101,9 @@
typedef struct _GtkToggleButtonPrivate GtkToggleButtonPrivate;
struct _GtkToggleButtonPrivate
{
+ GtkToggleButton *group_next;
+ GtkToggleButton *group_prev;
+
guint active : 1;
};
@@ -112,6 +115,7 @@ enum {
enum {
PROP_0,
PROP_ACTIVE,
+ PROP_GROUP,
NUM_PROPERTIES
};
@@ -134,6 +138,9 @@ gtk_toggle_button_set_property (GObject *object,
case PROP_ACTIVE:
gtk_toggle_button_set_active (tb, g_value_get_boolean (value));
break;
+ case PROP_GROUP:
+ gtk_toggle_button_set_group (GTK_TOGGLE_BUTTON (object), g_value_get_object (value));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -188,12 +195,57 @@ gtk_toggle_button_clicked (GtkButton *button)
}
static void
+gtk_toggle_button_dispose (GObject *object)
+{
+ GtkToggleButton *toggle_button = GTK_TOGGLE_BUTTON (object);
+
+ gtk_toggle_button_set_group (toggle_button, NULL);
+
+ G_OBJECT_CLASS (gtk_toggle_button_parent_class)->dispose (object);
+}
+
+static GtkToggleButton *
+get_group_next (GtkToggleButton *self)
+{
+ return ((GtkToggleButtonPrivate *)gtk_toggle_button_get_instance_private (self))->group_next;
+}
+
+static GtkToggleButton *
+get_group_prev (GtkToggleButton *self)
+{
+ return ((GtkToggleButtonPrivate *)gtk_toggle_button_get_instance_private (self))->group_prev;
+}
+
+static GtkToggleButton *
+get_group_first (GtkToggleButton *self)
+{
+ GtkToggleButton *group_first = NULL;
+ GtkToggleButton *iter;
+
+ /* Find first in group */
+ iter = self;
+ while (iter)
+ {
+ group_first = iter;
+
+ iter = get_group_prev (iter);
+ if (!iter)
+ break;
+ }
+
+ g_assert (group_first);
+
+ return group_first;
+}
+
+static void
gtk_toggle_button_class_init (GtkToggleButtonClass *class)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (class);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
GtkButtonClass *button_class = GTK_BUTTON_CLASS (class);
+ gobject_class->dispose = gtk_toggle_button_dispose;
gobject_class->set_property = gtk_toggle_button_set_property;
gobject_class->get_property = gtk_toggle_button_get_property;
@@ -210,6 +262,13 @@ gtk_toggle_button_class_init (GtkToggleButtonClass *class)
FALSE,
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);
+ toggle_button_props[PROP_GROUP] =
+ g_param_spec_object ("group",
+ P_("Group"),
+ P_("The toggle button whose group this widget belongs to."),
+ GTK_TYPE_TOGGLE_BUTTON,
+ GTK_PARAM_WRITABLE);
+
g_object_class_install_properties (gobject_class, NUM_PROPERTIES, toggle_button_props);
/**
@@ -313,6 +372,21 @@ gtk_toggle_button_set_active (GtkToggleButton *toggle_button,
if (priv->active == is_active)
return;
+ if (is_active && (priv->group_prev || priv->group_next))
+ {
+ GtkToggleButton *group_first = NULL;
+ GtkToggleButton *iter;
+
+ group_first = get_group_first (toggle_button);
+ g_assert (group_first);
+
+ /* Set all buttons in group to !active */
+ for (iter = group_first; iter; iter = get_group_next (iter))
+ gtk_toggle_button_set_active (iter, FALSE);
+
+ /* ... and the next code block will set this one to active */
+ }
+
priv->active = is_active;
if (is_active)
@@ -363,3 +437,58 @@ gtk_toggle_button_toggled (GtkToggleButton *toggle_button)
g_signal_emit (toggle_button, toggle_button_signals[TOGGLED], 0);
}
+
+/**
+ * gtk_toggle_button_set_group:
+ * @self: a #GtkToggleButton
+ * @group: (nullable) (transfer none): another #GtkToggleButton to
+ * form a group with
+ *
+ * Adds @self to the group of @group. In a group of multiple toggle buttons,
+ * only one button can be active at a time.
+ */
+void
+gtk_toggle_button_set_group (GtkToggleButton *self,
+ GtkToggleButton *group)
+{
+ GtkToggleButtonPrivate *priv = gtk_toggle_button_get_instance_private (self);
+ GtkToggleButtonPrivate *group_priv = gtk_toggle_button_get_instance_private (group);
+
+ g_return_if_fail (GTK_IS_TOGGLE_BUTTON (self));
+
+ if (!group)
+ {
+ if (priv->group_prev)
+ {
+ GtkToggleButtonPrivate *p = gtk_toggle_button_get_instance_private (priv->group_prev);
+ p->group_next = priv->group_next;
+ }
+ if (priv->group_next)
+ {
+ GtkToggleButtonPrivate *p = gtk_toggle_button_get_instance_private (priv->group_next);
+ p->group_prev = priv->group_prev;
+ }
+
+ priv->group_next = NULL;
+ priv->group_prev = NULL;
+ g_object_notify_by_pspec (G_OBJECT (self), toggle_button_props[PROP_GROUP]);
+ return;
+ }
+
+ if (priv->group_next == group)
+ return;
+
+ priv->group_prev = NULL;
+ if (group_priv->group_prev)
+ {
+ GtkToggleButtonPrivate *prev = gtk_toggle_button_get_instance_private (group_priv->group_prev);
+
+ prev->group_next = self;
+ priv->group_prev = group_priv->group_prev;
+ }
+
+ group_priv->group_prev = self;
+ priv->group_next = group;
+
+ g_object_notify_by_pspec (G_OBJECT (self), toggle_button_props[PROP_GROUP]);
+}
diff --git a/gtk/gtktogglebutton.h b/gtk/gtktogglebutton.h
index 8f5923d9b2..44219bb106 100644
--- a/gtk/gtktogglebutton.h
+++ b/gtk/gtktogglebutton.h
@@ -79,6 +79,10 @@ GDK_AVAILABLE_IN_ALL
gboolean gtk_toggle_button_get_active (GtkToggleButton *toggle_button);
GDK_AVAILABLE_IN_ALL
void gtk_toggle_button_toggled (GtkToggleButton *toggle_button);
+GDK_AVAILABLE_IN_ALL
+void gtk_toggle_button_set_group (GtkToggleButton *toggle_button,
+ GtkToggleButton *group);
+
G_END_DECLS
diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c
index 235480b7c7..40673a037c 100644
--- a/gtk/gtkwindow.c
+++ b/gtk/gtkwindow.c
@@ -6591,7 +6591,7 @@ warn_response (GtkDialog *dialog,
display = gtk_inspector_window_get_inspected_display (GTK_INSPECTOR_WINDOW (inspector_window));
check = g_object_get_data (G_OBJECT (dialog), "check");
- remember = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (check));
+ remember = gtk_check_button_get_active (GTK_CHECK_BUTTON (check));
gtk_window_destroy (GTK_WINDOW (dialog));
g_object_set_data (G_OBJECT (inspector_window), "warning_dialog", NULL);
diff --git a/gtk/inspector/logs.c b/gtk/inspector/logs.c
index 59bc1a4ca7..b8f22b9504 100644
--- a/gtk/inspector/logs.c
+++ b/gtk/inspector/logs.c
@@ -29,7 +29,7 @@
#include "gtktextview.h"
#include "gtkmessagedialog.h"
#include "gtkfilechooserdialog.h"
-#include "gtktogglebutton.h"
+#include "gtkcheckbutton.h"
#include "gtklabel.h"
#include "gtktooltip.h"
#include "gtktextiter.h"
@@ -112,7 +112,7 @@ update_flag (GtkWidget *widget,
guint *flags,
guint flag)
{
- if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)))
+ if (gtk_check_button_get_active (GTK_CHECK_BUTTON (widget)))
*flags = *flags | flag;
else
*flags = *flags & ~flag;
diff --git a/gtk/inspector/prop-editor.c b/gtk/inspector/prop-editor.c
index 53cc37cd5c..dc2f6f2648 100644
--- a/gtk/inspector/prop-editor.c
+++ b/gtk/inspector/prop-editor.c
@@ -36,7 +36,6 @@
#include "gtkiconview.h"
#include "gtklabel.h"
#include "gtkpopover.h"
-#include "gtkradiobutton.h"
#include "gtkscrolledwindow.h"
#include "gtkspinbutton.h"
#include "gtksettingsprivate.h"
@@ -419,12 +418,13 @@ strv_changed (GObject *object, GParamSpec *pspec, gpointer data)
}
static void
-bool_modified (GtkToggleButton *tb, ObjectProperty *p)
+bool_modified (GtkCheckButton *cb,
+ ObjectProperty *p)
{
GValue val = G_VALUE_INIT;
g_value_init (&val, G_TYPE_BOOLEAN);
- g_value_set_boolean (&val, gtk_toggle_button_get_active (tb));
+ g_value_set_boolean (&val, gtk_check_button_get_active (cb));
set_property_value (p->obj, p->spec, &val);
g_value_unset (&val);
}
@@ -432,17 +432,17 @@ bool_modified (GtkToggleButton *tb, ObjectProperty *p)
static void
bool_changed (GObject *object, GParamSpec *pspec, gpointer data)
{
- GtkToggleButton *tb = GTK_TOGGLE_BUTTON (data);
+ GtkCheckButton *cb = GTK_CHECK_BUTTON (data);
GValue val = G_VALUE_INIT;
g_value_init (&val, G_TYPE_BOOLEAN);
get_property_value (object, pspec, &val);
- if (g_value_get_boolean (&val) != gtk_toggle_button_get_active (tb))
+ if (g_value_get_boolean (&val) != gtk_check_button_get_active (cb))
{
- block_controller (G_OBJECT (tb));
- gtk_toggle_button_set_active (tb, g_value_get_boolean (&val));
- unblock_controller (G_OBJECT (tb));
+ block_controller (G_OBJECT (cb));
+ gtk_check_button_set_active (cb, g_value_get_boolean (&val));
+ unblock_controller (G_OBJECT (cb));
}
g_value_unset (&val);
@@ -498,7 +498,7 @@ flags_modified (GtkCheckButton *button, ObjectProperty *p)
int i;
GValue val = G_VALUE_INIT;
- active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button));
+ active = gtk_check_button_get_active (button);
i = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (button), "index"));
fclass = G_FLAGS_CLASS (g_type_class_peek (p->spec->value_type));
@@ -583,8 +583,8 @@ flags_changed (GObject *object, GParamSpec *pspec, gpointer data)
for (child = gtk_widget_get_first_child (box), i = 0;
child != NULL;
child = gtk_widget_get_next_sibling (child), i++)
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (child),
- (fclass->values[i].value & flags) != 0);
+ gtk_check_button_set_active (GTK_CHECK_BUTTON (child),
+ (fclass->values[i].value & flags) != 0);
for (child = gtk_widget_get_first_child (box);
child != NULL;
diff --git a/gtk/meson.build b/gtk/meson.build
index dee33baa5e..0f55ece382 100644
--- a/gtk/meson.build
+++ b/gtk/meson.build
@@ -331,7 +331,6 @@ gtk_public_sources = files([
'gtkprintsettings.c',
'gtkprogressbar.c',
'gtkpropertylookuplistmodel.c',
- 'gtkradiobutton.c',
'gtkrange.c',
'gtktreerbtree.c',
'gtkrecentmanager.c',
@@ -610,7 +609,6 @@ gtk_public_headers = files([
'gtkprintoperationpreview.h',
'gtkprintsettings.h',
'gtkprogressbar.h',
- 'gtkradiobutton.h',
'gtkrange.h',
'gtkrecentmanager.h',
'gtkrender.h',
diff --git a/gtk/theme/Adwaita/_common.scss b/gtk/theme/Adwaita/_common.scss
index 3e1b33802a..e882f2bc3e 100644
--- a/gtk/theme/Adwaita/_common.scss
+++ b/gtk/theme/Adwaita/_common.scss
@@ -2271,8 +2271,7 @@ switch {
}
}
-checkbutton,
-radiobutton {
+checkbutton {
border-spacing: 4px;
border-radius: $button_radius;
transition: $focus_transition;
diff --git a/gtk/tools/gtk-builder-tool-simplify.c b/gtk/tools/gtk-builder-tool-simplify.c
index fdac7a93c0..0650f54941 100644
--- a/gtk/tools/gtk-builder-tool-simplify.c
+++ b/gtk/tools/gtk-builder-tool-simplify.c
@@ -1718,6 +1718,58 @@ rewrite_bin_child (Element *element,
}
}
+static gboolean
+remove_boolean_prop (Element *element,
+ MyParserData *data,
+ const char *prop_name,
+ gboolean *value)
+{
+ GList *l;
+
+ for (l = element->children; l; l = l->next)
+ {
+ Element *child = l->data;
+
+ if (g_str_equal (child->element_name, "property") &&
+ has_attribute (child, "name", prop_name))
+ {
+ *value = strcmp (canonical_boolean_value (data, child->data), "1") == 0;
+ element->children = g_list_remove (element->children, child);
+ free_element (child);
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+static void
+rewrite_radio_button (Element *element,
+ MyParserData *data)
+{
+ int i;
+ gboolean draw_indicator = TRUE;
+ const char *new_class;
+
+ if (!remove_boolean_prop (element, data, "draw-indicator", &draw_indicator))
+ remove_boolean_prop (element, data, "draw_indicator", &draw_indicator);
+
+ if (draw_indicator)
+ new_class = "GtkCheckButton";
+ else
+ new_class = "GtkToggleButton";
+
+ for (i = 0; element->attribute_names[i]; i++)
+ {
+ if (strcmp (element->attribute_names[i], "class") == 0)
+ {
+ g_free (element->attribute_values[i]);
+ element->attribute_values[i] = g_strdup (new_class);
+ break;
+ }
+ }
+}
+
/* returns TRUE to remove the element from the parent */
static gboolean
simplify_element (Element *element,
@@ -1863,6 +1915,10 @@ rewrite_element (Element *element,
g_str_equal (get_class_name (element), "GtkWindow")))
rewrite_bin_child (element, data);
+ if (element_is_object_or_template (element) &&
+ g_str_equal (get_class_name (element), "GtkRadioButton"))
+ rewrite_radio_button (element, data);
+
if (g_str_equal (element->element_name, "property"))
maybe_rename_property (element, data);
diff --git a/gtk/ui/gtkpagesetupunixdialog.ui b/gtk/ui/gtkpagesetupunixdialog.ui
index 9d3aae94a8..1fe89e5575 100644
--- a/gtk/ui/gtkpagesetupunixdialog.ui
+++ b/gtk/ui/gtkpagesetupunixdialog.ui
@@ -93,24 +93,9 @@
</object>
</child>
<child>
- <object class="GtkRadioButton" id="portrait_radio">
- <property name="hexpand">1</property>
+ <object class="GtkCheckButton" id="portrait_radio">
<property name="active">1</property>
- <child>
- <object class="GtkBox" id="box1">
- <property name="spacing">6</property>
- <child>
- <object class="GtkImage" id="image1">
- <property name="icon-name">orientation-portrait-symbolic</property>
- </object>
- </child>
- <child>
- <object class="GtkLabel" id="label1">
- <property name="label" translatable="yes">Portrait</property>
- </object>
- </child>
- </object>
- </child>
+ <property name="label" translatable="yes">Portrait</property>
<layout>
<property name="column">1</property>
<property name="row">3</property>
@@ -118,25 +103,10 @@
</object>
</child>
<child>
- <object class="GtkRadioButton" id="reverse_portrait_radio">
- <property name="hexpand">1</property>
+ <object class="GtkCheckButton" id="reverse_portrait_radio">
<property name="active">1</property>
<property name="group">portrait_radio</property>
- <child>
- <object class="GtkBox" id="box2">
- <property name="spacing">6</property>
- <child>
- <object class="GtkImage" id="image2">
- <property name="icon-name">orientation-portrait-inverse-symbolic</property>
- </object>
- </child>
- <child>
- <object class="GtkLabel" id="label2">
- <property name="label" translatable="yes">Reverse portrait</property>
- </object>
- </child>
- </object>
- </child>
+ <property name="label" translatable="yes">Reverse portrait</property>
<layout>
<property name="column">2</property>
<property name="row">3</property>
@@ -144,25 +114,11 @@
</object>
</child>
<child>
- <object class="GtkRadioButton" id="landscape_radio">
+ <object class="GtkCheckButton" id="landscape_radio">
<property name="hexpand">1</property>
<property name="active">1</property>
<property name="group">portrait_radio</property>
- <child>
- <object class="GtkBox" id="box3">
- <property name="spacing">6</property>
- <child>
- <object class="GtkImage" id="image3">
- <property name="icon-name">orientation-landscape-symbolic</property>
- </object>
- </child>
- <child>
- <object class="GtkLabel" id="label3">
- <property name="label" translatable="yes">Landscape</property>
- </object>
- </child>
- </object>
- </child>
+ <property name="label" translatable="yes">Landscape</property>
<layout>
<property name="column">1</property>
<property name="row">4</property>
@@ -170,24 +126,10 @@
</object>
</child>
<child>
- <object class="GtkRadioButton" id="reverse_landscape_radio">
+ <object class="GtkCheckButton" id="reverse_landscape_radio">
<property name="hexpand">1</property>
<property name="group">portrait_radio</property>
- <child>
- <object class="GtkBox" id="box4">
- <property name="spacing">6</property>
- <child>
- <object class="GtkImage" id="image4">
- <property name="icon-name">orientation-landscape-inverse-symbolic</property>
- </object>
- </child>
- <child>
- <object class="GtkLabel" id="label4">
- <property name="label" translatable="yes">Reverse landscape</property>
- </object>
- </child>
- </object>
- </child>
+ <property name="label" translatable="yes">Reverse landscape</property>
<layout>
<property name="column">2</property>
<property name="row">4</property>
diff --git a/gtk/ui/gtkprintunixdialog.ui b/gtk/ui/gtkprintunixdialog.ui
index 69f0a2c027..eecc472628 100644
--- a/gtk/ui/gtkprintunixdialog.ui
+++ b/gtk/ui/gtkprintunixdialog.ui
@@ -210,7 +210,7 @@
<property name="row-spacing">6</property>
<property name="column-spacing">12</property>
<child>
- <object class="GtkRadioButton" id="all_pages_radio">
+ <object class="GtkCheckButton" id="all_pages_radio">
<property name="label" translatable="yes">_All Pages</property>
<property name="use-underline">1</property>
<property name="active">1</property>
@@ -222,7 +222,7 @@
</object>
</child>
<child>
- <object class="GtkRadioButton" id="current_page_radio">
+ <object class="GtkCheckButton" id="current_page_radio">
<property name="label" translatable="yes">C_urrent Page</property>
<property name="sensitive">0</property>
<property name="use-underline">1</property>
@@ -235,7 +235,7 @@
</object>
</child>
<child>
- <object class="GtkRadioButton" id="selection_radio">
+ <object class="GtkCheckButton" id="selection_radio">
<property name="label" translatable="yes">Se_lection</property>
<property name="sensitive">0</property>
<property name="use-underline">1</property>
@@ -248,7 +248,7 @@
</object>
</child>
<child>
- <object class="GtkRadioButton" id="page_range_radio">
+ <object class="GtkCheckButton" id="page_range_radio">
<property name="label" translatable="yes">Pag_es:</property>
<property name="tooltip-text" translatable="yes">Specify one or more page ranges,
e.g. 1–3, 7, 11</property>
@@ -347,7 +347,7 @@
<child>
<object class="GtkDrawingArea" id="collate_image">
<property name="content-width">70</property>
- <property name="content-height">90</property>
+ <property name="content-height">50</property>
<layout>
<property name="column">1</property>
<property name="row">1</property>
@@ -812,7 +812,7 @@
<property name="row-spacing">6</property>
<property name="column-spacing">12</property>
<child>
- <object class="GtkRadioButton" id="print_now_radio">
+ <object class="GtkCheckButton" id="print_now_radio">
<property name="label" translatable="yes" comments="this is one of the choices for the print at option in the print dialog">_Now</property>
<property name="use-underline">1</property>
<property name="active">1</property>
@@ -825,7 +825,7 @@
</object>
</child>
<child>
- <object class="GtkRadioButton" id="print_at_radio">
+ <object class="GtkCheckButton" id="print_at_radio">
<property name="sensitive">0</property>
<property name="label" translatable="yes" comments="this is one of the choices for the print at option in the print dialog. It also serves as the label for an entry that allows the user to enter a time.">A_t:</property>
<property name="has-tooltip">1</property>
@@ -859,7 +859,7 @@
</object>
</child>
<child>
- <object class="GtkRadioButton" id="print_hold_radio">
+ <object class="GtkCheckButton" id="print_hold_radio">
<property name="sensitive">0</property>
<property name="label" translatable="yes" comments="this is one of the choices for the print at option in the print dialog. It means that the print job will not be printed until it explicitly gets &apos;released&apos;.">On _hold</property>
<property name="has-tooltip">1</property>