gtktogglebutton.c 18.6 KB
Newer Older
Cody Russell's avatar
Cody Russell committed
1
/* GTK - The GIMP Toolkit
Elliot Lee's avatar
Elliot Lee committed
2 3 4
 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
 *
 * This library is free software; you can redistribute it and/or
5
 * modify it under the terms of the GNU Lesser General Public
Elliot Lee's avatar
Elliot Lee committed
6 7 8 9 10 11
 * 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
12
 * Lesser General Public License for more details.
Elliot Lee's avatar
Elliot Lee committed
13
 *
14
 * You should have received a copy of the GNU Lesser General Public
Javier Jardón's avatar
Javier Jardón committed
15
 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
Elliot Lee's avatar
Elliot Lee committed
16
 */
17 18

/*
19
 * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
20 21 22 23 24
 * 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/. 
 */

25
#include "config.h"
26 27 28 29

#include "gtktogglebutton.h"

#include "gtkbuttonprivate.h"
30
#include "gtktogglebuttonprivate.h"
Elliot Lee's avatar
Elliot Lee committed
31 32
#include "gtklabel.h"
#include "gtkmain.h"
33
#include "gtkmarshalers.h"
34 35
#include "deprecated/gtktoggleaction.h"
#include "deprecated/gtkactivatable.h"
36
#include "gtkprivate.h"
37
#include "gtkintl.h"
38
#include "a11y/gtktogglebuttonaccessible.h"
39

Elliot Lee's avatar
Elliot Lee committed
40

41 42 43 44 45 46
/**
 * SECTION:gtktogglebutton
 * @Short_description: Create buttons which retain their state
 * @Title: GtkToggleButton
 * @See_also: #GtkButton, #GtkCheckButton, #GtkCheckMenuItem
 *
47
 * A #GtkToggleButton is a #GtkButton which will remain “pressed-in” when
48 49 50 51 52
 * clicked. Clicking again will cause the toggle button to return to its
 * normal state.
 *
 * A toggle button is created by calling either gtk_toggle_button_new() or
 * gtk_toggle_button_new_with_label(). If using the former, it is advisable to
53
 * pack a widget, (such as a #GtkLabel and/or a #GtkImage), into the toggle
54
 * button’s container. (See #GtkButton for more information).
55 56 57 58 59 60 61
 *
 * The state of a #GtkToggleButton can be set specifically using
 * gtk_toggle_button_set_active(), and retrieved using
 * gtk_toggle_button_get_active().
 *
 * To simply switch the state of a toggle button, use gtk_toggle_button_toggled().
 *
62 63 64 65 66
 * # CSS nodes
 *
 * GtkToggleButton has a single CSS node with name button. To differentiate
 * it from a plain #GtkButton, it gets the .toggle style class.
 *
67 68
 * ## Creating two #GtkToggleButton widgets.
 *
69
 * |[<!-- language="C" -->
70 71
 * void make_toggles (void) {
 *    GtkWidget *dialog, *toggle1, *toggle2;
72 73
 *    GtkWidget *content_area;
 *    const char *text;
74
 *
75 76 77 78 79
 *    dialog = gtk_dialog_new (text);
 *    content_area = gtk_dialog_get_content_area ();
 *
 *    text = "Hi, i’m a toggle button.";
 *    toggle1 = gtk_toggle_button_new_with_label (text);
80
 *
81
 *    // Makes this toggle button invisible
82 83
 *    gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (toggle1),
 *                                TRUE);
84 85
 *
 *    g_signal_connect (toggle1, "toggled",
86 87 88
 *                      G_CALLBACK (output_state),
 *                      NULL);
 *    gtk_box_pack_start (GTK_BOX (content_area),
89 90
 *                        toggle1, FALSE, FALSE, 2);
 *
91 92 93 94
 *    text = "Hi, i’m a toggle button.";
 *    toggle2 = gtk_toggle_button_new_with_label (text);
 *    gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (toggle2),
 *                                FALSE);
95
 *    g_signal_connect (toggle2, "toggled",
96 97 98
 *                      G_CALLBACK (output_state),
 *                      NULL);
 *    gtk_box_pack_start (GTK_BOX (content_area),
99 100 101 102
 *                        toggle2, FALSE, FALSE, 2);
 *
 *    gtk_widget_show_all (dialog);
 * }
103
 * ]|
104 105 106
 */


Elliot Lee's avatar
Elliot Lee committed
107 108 109 110
#define DEFAULT_LEFT_POS  4
#define DEFAULT_TOP_POS   4
#define DEFAULT_SPACING   7

111 112 113 114 115 116 117
struct _GtkToggleButtonPrivate
{
  guint active         : 1;
  guint draw_indicator : 1;
  guint inconsistent   : 1;
};

Elliot Lee's avatar
Elliot Lee committed
118 119 120 121 122
enum {
  TOGGLED,
  LAST_SIGNAL
};

123
enum {
124 125 126
  PROP_0,
  PROP_ACTIVE,
  PROP_INCONSISTENT,
127 128
  PROP_DRAW_INDICATOR,
  NUM_PROPERTIES
129 130
};

131
static GParamSpec *toggle_button_props[NUM_PROPERTIES] = { NULL, };
Elliot Lee's avatar
Elliot Lee committed
132

133 134
static gboolean gtk_toggle_button_mnemonic_activate  (GtkWidget            *widget,
                                                      gboolean              group_cycling);
135 136 137 138 139 140 141 142 143
static void gtk_toggle_button_clicked       (GtkButton            *button);
static void gtk_toggle_button_set_property  (GObject              *object,
					     guint                 prop_id,
					     const GValue         *value,
					     GParamSpec           *pspec);
static void gtk_toggle_button_get_property  (GObject              *object,
					     guint                 prop_id,
					     GValue               *value,
					     GParamSpec           *pspec);
Elliot Lee's avatar
Elliot Lee committed
144 145


146
static void gtk_toggle_button_activatable_interface_init (GtkActivatableIface  *iface);
147 148 149 150 151
static void gtk_toggle_button_update         	     (GtkActivatable       *activatable,
					 	      GtkAction            *action,
						      const gchar          *property_name);
static void gtk_toggle_button_sync_action_properties (GtkActivatable       *activatable,
						      GtkAction            *action);
152 153 154 155

static GtkActivatableIface *parent_activatable_iface;
static guint                toggle_button_signals[LAST_SIGNAL] = { 0 };

156
G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
157
G_DEFINE_TYPE_WITH_CODE (GtkToggleButton, gtk_toggle_button, GTK_TYPE_BUTTON,
158
                         G_ADD_PRIVATE (GtkToggleButton)
159 160
			 G_IMPLEMENT_INTERFACE (GTK_TYPE_ACTIVATABLE,
						gtk_toggle_button_activatable_interface_init))
161
G_GNUC_END_IGNORE_DEPRECATIONS;
Elliot Lee's avatar
Elliot Lee committed
162 163 164 165

static void
gtk_toggle_button_class_init (GtkToggleButtonClass *class)
{
Manish Singh's avatar
Manish Singh committed
166
  GObjectClass *gobject_class;
Elliot Lee's avatar
Elliot Lee committed
167 168 169
  GtkWidgetClass *widget_class;
  GtkButtonClass *button_class;

170
  gobject_class = G_OBJECT_CLASS (class);
Elliot Lee's avatar
Elliot Lee committed
171 172 173
  widget_class = (GtkWidgetClass*) class;
  button_class = (GtkButtonClass*) class;

174 175
  gobject_class->set_property = gtk_toggle_button_set_property;
  gobject_class->get_property = gtk_toggle_button_get_property;
176

177
  widget_class->mnemonic_activate = gtk_toggle_button_mnemonic_activate;
Elliot Lee's avatar
Elliot Lee committed
178 179 180 181

  button_class->clicked = gtk_toggle_button_clicked;

  class->toggled = NULL;
182

183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204
  toggle_button_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);

  toggle_button_props[PROP_INCONSISTENT] =
      g_param_spec_boolean ("inconsistent",
                            P_("Inconsistent"),
                            P_("If the toggle button is in an \"in between\" state"),
                            FALSE,
                            GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY);

  toggle_button_props[PROP_DRAW_INDICATOR] =
      g_param_spec_boolean ("draw-indicator",
                            P_("Draw Indicator"),
                            P_("If the toggle part of the button is displayed"),
                            FALSE,
                            GTK_PARAM_READWRITE);

  g_object_class_install_properties (gobject_class, NUM_PROPERTIES, toggle_button_props);
205

206 207 208 209 210 211 212
  /**
   * GtkToggleButton::toggled:
   * @togglebutton: the object which received the signal.
   *
   * Should be connected if you wish to perform an action whenever the
   * #GtkToggleButton's state is changed.
   */
213
  toggle_button_signals[TOGGLED] =
214
    g_signal_new (I_("toggled"),
Manish Singh's avatar
Manish Singh committed
215 216 217 218 219 220
		  G_OBJECT_CLASS_TYPE (gobject_class),
		  G_SIGNAL_RUN_FIRST,
		  G_STRUCT_OFFSET (GtkToggleButtonClass, toggled),
		  NULL, NULL,
		  _gtk_marshal_VOID__VOID,
		  G_TYPE_NONE, 0);
221

222
  gtk_widget_class_set_accessible_type (widget_class, GTK_TYPE_TOGGLE_BUTTON_ACCESSIBLE);
223
  gtk_widget_class_set_css_name (widget_class, "button");
Elliot Lee's avatar
Elliot Lee committed
224 225 226 227 228
}

static void
gtk_toggle_button_init (GtkToggleButton *toggle_button)
{
229 230
  GtkStyleContext *context;

231 232 233
  toggle_button->priv = gtk_toggle_button_get_instance_private (toggle_button);
  toggle_button->priv->active = FALSE;
  toggle_button->priv->draw_indicator = FALSE;
234 235 236

  context = gtk_widget_get_style_context (GTK_WIDGET (toggle_button));
  gtk_style_context_add_class (context, "toggle");
Elliot Lee's avatar
Elliot Lee committed
237 238
}

239 240
static void
gtk_toggle_button_activatable_interface_init (GtkActivatableIface *iface)
241 242
{
  parent_activatable_iface = g_type_interface_peek_parent (iface);
243 244
  iface->update = gtk_toggle_button_update;
  iface->sync_action_properties = gtk_toggle_button_sync_action_properties;
245 246 247
}

static void
248 249 250
gtk_toggle_button_update (GtkActivatable *activatable,
			  GtkAction      *action,
			  const gchar    *property_name)
251 252 253 254 255 256 257 258 259
{
  GtkToggleButton *button;

  parent_activatable_iface->update (activatable, action, property_name);

  button = GTK_TOGGLE_BUTTON (activatable);

  if (strcmp (property_name, "active") == 0)
    {
260
      G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
261 262 263
      gtk_action_block_activate (action);
      gtk_toggle_button_set_active (button, gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)));
      gtk_action_unblock_activate (action);
264
      G_GNUC_END_IGNORE_DEPRECATIONS;
265 266 267 268 269
    }

}

static void
270 271
gtk_toggle_button_sync_action_properties (GtkActivatable *activatable,
				          GtkAction      *action)
272 273
{
  GtkToggleButton *button;
274
  gboolean is_toggle_action;
275

276
  parent_activatable_iface->sync_action_properties (activatable, action);
277

278 279 280 281 282
  G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
  is_toggle_action = GTK_IS_TOGGLE_ACTION (action);
  G_GNUC_END_IGNORE_DEPRECATIONS;

  if (!is_toggle_action)
283 284 285 286
    return;

  button = GTK_TOGGLE_BUTTON (activatable);

287
  G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
288 289 290
  gtk_action_block_activate (action);
  gtk_toggle_button_set_active (button, gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)));
  gtk_action_unblock_activate (action);
291
  G_GNUC_END_IGNORE_DEPRECATIONS;
292 293
}

294 295 296 297 298 299 300
/**
 * gtk_toggle_button_new:
 *
 * Creates a new toggle button. A widget should be packed into the button, as in gtk_button_new().
 *
 * Returns: a new toggle button.
 */
Elliot Lee's avatar
Elliot Lee committed
301
GtkWidget*
302
gtk_toggle_button_new (void)
Elliot Lee's avatar
Elliot Lee committed
303
{
Manish Singh's avatar
Manish Singh committed
304
  return g_object_new (GTK_TYPE_TOGGLE_BUTTON, NULL);
Elliot Lee's avatar
Elliot Lee committed
305 306
}

307 308 309 310 311 312 313 314
/**
 * gtk_toggle_button_new_with_label:
 * @label: a string containing the message to be placed in the toggle button.
 *
 * Creates a new toggle button with a text label.
 *
 * Returns: a new toggle button.
 */
Elliot Lee's avatar
Elliot Lee committed
315 316 317
GtkWidget*
gtk_toggle_button_new_with_label (const gchar *label)
{
318
  return g_object_new (GTK_TYPE_TOGGLE_BUTTON, "label", label, NULL);
Elliot Lee's avatar
Elliot Lee committed
319 320
}

321 322 323 324 325 326 327 328
/**
 * gtk_toggle_button_new_with_mnemonic:
 * @label: the text of the button, with an underscore in front of the
 *         mnemonic character
 *
 * Creates a new #GtkToggleButton containing a label. The label
 * will be created using gtk_label_new_with_mnemonic(), so underscores
 * in @label indicate the mnemonic for the button.
Matthias Clasen's avatar
Matthias Clasen committed
329 330 331
 *
 * Returns: a new #GtkToggleButton
 */
332 333 334
GtkWidget*
gtk_toggle_button_new_with_mnemonic (const gchar *label)
{
335 336 337 338
  return g_object_new (GTK_TYPE_TOGGLE_BUTTON, 
		       "label", label, 
		       "use-underline", TRUE, 
		       NULL);
339 340
}

341
static void
342 343 344 345
gtk_toggle_button_set_property (GObject      *object,
				guint         prop_id,
				const GValue *value,
				GParamSpec   *pspec)
346 347 348 349 350
{
  GtkToggleButton *tb;

  tb = GTK_TOGGLE_BUTTON (object);

351
  switch (prop_id)
352
    {
353 354 355 356 357
    case PROP_ACTIVE:
      gtk_toggle_button_set_active (tb, g_value_get_boolean (value));
      break;
    case PROP_INCONSISTENT:
      gtk_toggle_button_set_inconsistent (tb, g_value_get_boolean (value));
358
      break;
359 360
    case PROP_DRAW_INDICATOR:
      gtk_toggle_button_set_mode (tb, g_value_get_boolean (value));
361 362
      break;
    default:
363
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
364 365 366 367 368
      break;
    }
}

static void
369 370 371 372
gtk_toggle_button_get_property (GObject      *object,
				guint         prop_id,
				GValue       *value,
				GParamSpec   *pspec)
373
{
374 375
  GtkToggleButton *tb = GTK_TOGGLE_BUTTON (object);
  GtkToggleButtonPrivate *priv = tb->priv;
376

377
  switch (prop_id)
378
    {
379
    case PROP_ACTIVE:
380
      g_value_set_boolean (value, priv->active);
381 382
      break;
    case PROP_INCONSISTENT:
383
      g_value_set_boolean (value, priv->inconsistent);
384
      break;
385
    case PROP_DRAW_INDICATOR:
386
      g_value_set_boolean (value, priv->draw_indicator);
387 388
      break;
    default:
389
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
390 391 392 393
      break;
    }
}

394 395 396 397 398 399 400 401
/**
 * gtk_toggle_button_set_mode:
 * @toggle_button: a #GtkToggleButton
 * @draw_indicator: if %TRUE, draw the button as a separate indicator
 * and label; if %FALSE, draw the button like a normal button
 *
 * Sets whether the button is displayed as a separate indicator and label.
 * You can call this function on a checkbutton or a radiobutton with
402 403 404 405
 * @draw_indicator = %FALSE to make the button look like a normal button.
 *
 * This can be used to create linked strip of buttons that work like
 * a #GtkStackSwitcher.
406
 *
407
 * This function only affects instances of classes like #GtkCheckButton
408 409 410
 * and #GtkRadioButton that derive from #GtkToggleButton,
 * not instances of #GtkToggleButton itself.
 */
Elliot Lee's avatar
Elliot Lee committed
411 412
void
gtk_toggle_button_set_mode (GtkToggleButton *toggle_button,
413
			    gboolean         draw_indicator)
Elliot Lee's avatar
Elliot Lee committed
414
{
415 416
  GtkToggleButtonPrivate *priv;

Elliot Lee's avatar
Elliot Lee committed
417 418
  g_return_if_fail (GTK_IS_TOGGLE_BUTTON (toggle_button));

419 420
  priv = toggle_button->priv;

Elliot Lee's avatar
Elliot Lee committed
421 422
  draw_indicator = draw_indicator ? TRUE : FALSE;

423
  if (priv->draw_indicator != draw_indicator)
Elliot Lee's avatar
Elliot Lee committed
424
    {
425
      priv->draw_indicator = draw_indicator;
426

427
      if (gtk_widget_get_visible (GTK_WIDGET (toggle_button)))
Elliot Lee's avatar
Elliot Lee committed
428
	gtk_widget_queue_resize (GTK_WIDGET (toggle_button));
429

430
      g_object_notify_by_pspec (G_OBJECT (toggle_button), toggle_button_props[PROP_DRAW_INDICATOR]);
Elliot Lee's avatar
Elliot Lee committed
431 432 433
    }
}

434 435 436 437 438 439 440
/**
 * gtk_toggle_button_get_mode:
 * @toggle_button: a #GtkToggleButton
 *
 * Retrieves whether the button is displayed as a separate indicator
 * and label. See gtk_toggle_button_set_mode().
 *
441
 * Returns: %TRUE if the togglebutton is drawn as a separate indicator
442 443 444 445 446 447 448
 *   and label.
 **/
gboolean
gtk_toggle_button_get_mode (GtkToggleButton *toggle_button)
{
  g_return_val_if_fail (GTK_IS_TOGGLE_BUTTON (toggle_button), FALSE);

449
  return toggle_button->priv->draw_indicator;
450
}
451

452 453 454 455 456 457
/**
 * gtk_toggle_button_set_active:
 * @toggle_button: a #GtkToggleButton.
 * @is_active: %TRUE or %FALSE.
 *
 * Sets the status of the toggle button. Set to %TRUE if you want the
458
 * GtkToggleButton to be “pressed in”, and %FALSE to raise it.
459 460
 * This action causes the #GtkToggleButton::toggled signal and the
 * #GtkButton::clicked signal to be emitted.
461
 */
Elliot Lee's avatar
Elliot Lee committed
462
void
463 464
gtk_toggle_button_set_active (GtkToggleButton *toggle_button,
			      gboolean         is_active)
Elliot Lee's avatar
Elliot Lee committed
465
{
466 467
  GtkToggleButtonPrivate *priv;

Elliot Lee's avatar
Elliot Lee committed
468 469
  g_return_if_fail (GTK_IS_TOGGLE_BUTTON (toggle_button));

470 471
  priv = toggle_button->priv;

472
  is_active = is_active != FALSE;
473

474
  if (priv->active != is_active)
475 476
    {
      gtk_button_clicked (GTK_BUTTON (toggle_button));
477
      g_object_notify_by_pspec (G_OBJECT (toggle_button), toggle_button_props[PROP_ACTIVE]);
478
    }
Elliot Lee's avatar
Elliot Lee committed
479 480
}

481 482 483 484
void
_gtk_toggle_button_set_active (GtkToggleButton *toggle_button,
                               gboolean         is_active)
{
485
  toggle_button->priv->active = is_active;
486 487 488 489 490 491

  if (is_active)
    gtk_widget_set_state_flags (GTK_WIDGET (toggle_button), GTK_STATE_FLAG_CHECKED, FALSE);
  else
    gtk_widget_unset_state_flags (GTK_WIDGET (toggle_button), GTK_STATE_FLAG_CHECKED);

492 493
}

494 495 496 497 498 499 500 501 502
/**
 * gtk_toggle_button_get_active:
 * @toggle_button: a #GtkToggleButton.
 *
 * Queries a #GtkToggleButton and returns its current state. Returns %TRUE if
 * the toggle button is pressed in and %FALSE if it is raised.
 *
 * Returns: a #gboolean value.
 */
503 504 505 506 507
gboolean
gtk_toggle_button_get_active (GtkToggleButton *toggle_button)
{
  g_return_val_if_fail (GTK_IS_TOGGLE_BUTTON (toggle_button), FALSE);

508
  return toggle_button->priv->active;
509 510
}

511 512 513 514 515 516 517 518
/**
 * gtk_toggle_button_toggled:
 * @toggle_button: a #GtkToggleButton.
 *
 * Emits the #GtkToggleButton::toggled signal on the
 * #GtkToggleButton. There is no good reason for an
 * application ever to call this function.
 */
Elliot Lee's avatar
Elliot Lee committed
519 520 521
void
gtk_toggle_button_toggled (GtkToggleButton *toggle_button)
{
522 523
  g_return_if_fail (GTK_IS_TOGGLE_BUTTON (toggle_button));

Manish Singh's avatar
Manish Singh committed
524
  g_signal_emit (toggle_button, toggle_button_signals[TOGGLED], 0);
Elliot Lee's avatar
Elliot Lee committed
525 526
}

527 528 529 530 531 532 533 534
/**
 * gtk_toggle_button_set_inconsistent:
 * @toggle_button: a #GtkToggleButton
 * @setting: %TRUE if state is inconsistent
 *
 * If the user has selected a range of elements (such as some text or
 * spreadsheet cells) that are affected by a toggle button, and the
 * current values in that range are inconsistent, you may want to
535 536
 * display the toggle in an “in between” state. This function turns on
 * “in between” display.  Normally you would turn off the inconsistent
537 538
 * state again if the user toggles the toggle button. This has to be
 * done manually, gtk_toggle_button_set_inconsistent() only affects
539
 * visual appearance, it doesn’t affect the semantics of the button.
540 541 542 543 544 545
 * 
 **/
void
gtk_toggle_button_set_inconsistent (GtkToggleButton *toggle_button,
                                    gboolean         setting)
{
546 547
  GtkToggleButtonPrivate *priv;

548
  g_return_if_fail (GTK_IS_TOGGLE_BUTTON (toggle_button));
549 550 551

  priv = toggle_button->priv;

552 553
  setting = setting != FALSE;

554
  if (setting != priv->inconsistent)
555
    {
556 557
      priv->inconsistent = setting;

558 559 560 561
      if (setting)
        gtk_widget_set_state_flags (GTK_WIDGET (toggle_button), GTK_STATE_FLAG_INCONSISTENT, FALSE);
      else
        gtk_widget_unset_state_flags (GTK_WIDGET (toggle_button), GTK_STATE_FLAG_INCONSISTENT);
562

563
      g_object_notify_by_pspec (G_OBJECT (toggle_button), toggle_button_props[PROP_INCONSISTENT]);
564 565 566 567 568 569 570 571 572
    }
}

/**
 * gtk_toggle_button_get_inconsistent:
 * @toggle_button: a #GtkToggleButton
 * 
 * Gets the value set by gtk_toggle_button_set_inconsistent().
 * 
573
 * Returns: %TRUE if the button is displayed as inconsistent, %FALSE otherwise
574 575 576 577 578 579
 **/
gboolean
gtk_toggle_button_get_inconsistent (GtkToggleButton *toggle_button)
{
  g_return_val_if_fail (GTK_IS_TOGGLE_BUTTON (toggle_button), FALSE);

580
  return toggle_button->priv->inconsistent;
581
}
Elliot Lee's avatar
Elliot Lee committed
582

583 584 585 586 587 588 589 590 591
static gboolean
gtk_toggle_button_mnemonic_activate (GtkWidget *widget,
                                     gboolean   group_cycling)
{
  /*
   * We override the standard implementation in 
   * gtk_widget_real_mnemonic_activate() in order to focus the widget even
   * if there is no mnemonic conflict.
   */
592
  if (gtk_widget_get_can_focus (widget))
593 594 595 596 597 598 599 600
    gtk_widget_grab_focus (widget);

  if (!group_cycling)
    gtk_widget_activate (widget);

  return TRUE;
}

Elliot Lee's avatar
Elliot Lee committed
601 602 603
static void
gtk_toggle_button_clicked (GtkButton *button)
{
604
  GtkToggleButton *toggle_button = GTK_TOGGLE_BUTTON (button);
605 606
  GtkToggleButtonPrivate *priv = toggle_button->priv;

607
  _gtk_toggle_button_set_active (toggle_button, !priv->active);
Elliot Lee's avatar
Elliot Lee committed
608 609 610

  gtk_toggle_button_toggled (toggle_button);

611
  g_object_notify_by_pspec (G_OBJECT (toggle_button), toggle_button_props[PROP_ACTIVE]);
612

Matthias Clasen's avatar
Matthias Clasen committed
613 614
  if (GTK_BUTTON_CLASS (gtk_toggle_button_parent_class)->clicked)
    GTK_BUTTON_CLASS (gtk_toggle_button_parent_class)->clicked (button);
Elliot Lee's avatar
Elliot Lee committed
615 616
}