]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtkradiobutton.c
entrycompletion: Don't reconnect signals all the time
[~andy/gtk] / gtk / gtkradiobutton.c
index d760d4f9209edc886edf3dac005cb77e92a935d7..82ab28cb9da467ae73eac8844675c8daffc136ce 100644 (file)
@@ -12,9 +12,7 @@
  * 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, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
  */
 
 /*
  */
 
 #include "config.h"
+
+#include "gtkradiobutton.h"
+
+#include "gtkbuttonprivate.h"
 #include "gtklabel.h"
 #include "gtkmarshalers.h"
-#include "gtkradiobutton.h"
 #include "gtkprivate.h"
 #include "gtkintl.h"
+#include "a11y/gtkradiobuttonaccessible.h"
 
 /**
  * SECTION:gtkradiobutton
@@ -73,7 +75,8 @@
  *
  *    GtkWidget *window, *radio1, *radio2, *box, *entry;
  *    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
- *    box = gtk_vbox_new (TRUE, 2);
+ *    box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
+ *    gtk_box_set_homogeneous (GTK_BOX (box), TRUE);
  *
  *    /&ast; Create a radio button with a GtkEntry widget &ast;/
  *    radio1 = gtk_radio_button_new (NULL);
@@ -172,7 +175,7 @@ gtk_radio_button_class_init (GtkRadioButtonClass *class)
 
   /**
    * GtkRadioButton::group-changed:
-   * @style: the object which received the signal
+   * @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
@@ -192,6 +195,8 @@ gtk_radio_button_class_init (GtkRadioButtonClass *class)
                                       G_TYPE_NONE, 0);
 
   g_type_class_add_private (class, sizeof (GtkRadioButtonPrivate));
+
+  gtk_widget_class_set_accessible_type (widget_class, GTK_TYPE_RADIO_BUTTON_ACCESSIBLE);
 }
 
 static void
@@ -204,17 +209,16 @@ gtk_radio_button_init (GtkRadioButton *radio_button)
                                                     GtkRadioButtonPrivate);
   priv = radio_button->priv;
 
-  gtk_widget_set_has_window (GTK_WIDGET (radio_button), FALSE);
   gtk_widget_set_receives_default (GTK_WIDGET (radio_button), FALSE);
 
-  GTK_TOGGLE_BUTTON (radio_button)->active = TRUE;
+  _gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio_button), TRUE);
 
-  GTK_BUTTON (radio_button)->depress_on_activate = FALSE;
+  GTK_BUTTON (radio_button)->priv->depress_on_activate = FALSE;
 
   priv->group = g_slist_prepend (NULL, radio_button);
 
   _gtk_button_set_depressed (GTK_BUTTON (radio_button), TRUE);
-  gtk_widget_set_state (GTK_WIDGET (radio_button), GTK_STATE_ACTIVE);
+  gtk_widget_set_state_flags (GTK_WIDGET (radio_button), GTK_STATE_FLAG_ACTIVE, TRUE);
 }
 
 static void
@@ -400,7 +404,8 @@ gtk_radio_button_join_group (GtkRadioButton *radio_button,
 
 /**
  * gtk_radio_button_new:
- * @group: an existing radio button group, or %NULL if you are creating a new group.
+ * @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.
@@ -422,13 +427,13 @@ gtk_radio_button_new (GSList *group)
 
 /**
  * gtk_radio_button_new_with_label:
- * @group: an existing radio button group, or %NULL if you are creating a new
- *  group.
+ * @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: (transfer full): a new radio button.
+ * Returns: a new radio button.
  */
 GtkWidget*
 gtk_radio_button_new_with_label (GSList      *group,
@@ -447,7 +452,8 @@ gtk_radio_button_new_with_label (GSList      *group,
 
 /**
  * gtk_radio_button_new_with_mnemonic:
- * @group: the radio button group
+ * @group: (element-type GtkRadioButton) (allow-none): the radio button
+ *         group
  * @label: the text of the button, with an underscore in front of the
  *         mnemonic character
  *
@@ -456,7 +462,7 @@ gtk_radio_button_new_with_label (GSList      *group,
  * gtk_label_new_with_mnemonic(), so underscores in @label indicate the
  * mnemonic for the button.
  *
- * Returns: (transfer full): a new #GtkRadioButton
+ * Returns: a new #GtkRadioButton
  */
 GtkWidget*
 gtk_radio_button_new_with_mnemonic (GSList      *group,
@@ -476,14 +482,14 @@ gtk_radio_button_new_with_mnemonic (GSList      *group,
 }
 
 /**
- * gtk_radio_button_new_from_widget:
- * @radio_group_member: an existing #GtkRadioButton.
+ * 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 full): a new radio button.
+ * Returns: (transfer none): a new radio button.
  */
 GtkWidget*
 gtk_radio_button_new_from_widget (GtkRadioButton *radio_group_member)
@@ -495,8 +501,8 @@ gtk_radio_button_new_from_widget (GtkRadioButton *radio_group_member)
 }
 
 /**
- * gtk_radio_button_new_with_label_from_widget:
- * @radio_group_member: widget to get radio group from or %NULL
+ * 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
@@ -515,7 +521,7 @@ gtk_radio_button_new_with_label_from_widget (GtkRadioButton *radio_group_member,
 }
 
 /**
- * gtk_radio_button_new_with_mnemonic_from_widget:
+ * 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
@@ -524,7 +530,7 @@ gtk_radio_button_new_with_label_from_widget (GtkRadioButton *radio_group_member,
  * will be created using gtk_label_new_with_mnemonic(), so underscores
  * in @label indicate the mnemonic for the button.
  *
- * Returns: (transfer full): a new #GtkRadioButton
+ * Returns: (transfer none): a new #GtkRadioButton
  **/
 GtkWidget*
 gtk_radio_button_new_with_mnemonic_from_widget (GtkRadioButton *radio_group_member,
@@ -652,7 +658,7 @@ gtk_radio_button_focus (GtkWidget         *widget,
   /* Radio buttons with draw_indicator unset focus "normally", since
    * they look like buttons to the user.
    */
-  if (!GTK_TOGGLE_BUTTON (widget)->draw_indicator)
+  if (!gtk_toggle_button_get_mode (GTK_TOGGLE_BUTTON (widget)))
     return GTK_WIDGET_CLASS (gtk_radio_button_parent_class)->focus (widget, direction);
   
   if (gtk_widget_is_focus (widget))
@@ -766,7 +772,7 @@ gtk_radio_button_focus (GtkWidget         *widget,
       tmp_slist = priv->group;
       while (tmp_slist)
        {
-         if (GTK_TOGGLE_BUTTON (tmp_slist->data)->active)
+         if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (tmp_slist->data)))
            selected_button = tmp_slist->data;
          tmp_slist = tmp_slist->next;
        }
@@ -786,7 +792,7 @@ gtk_radio_button_clicked (GtkButton *button)
   GtkRadioButtonPrivate *priv = radio_button->priv;
   GtkToggleButton *toggle_button = GTK_TOGGLE_BUTTON (button);
   GtkToggleButton *tmp_button;
-  GtkStateType new_state;
+  GtkStateFlags new_state = 0;
   GSList *tmp_list;
   gint toggled;
   gboolean depressed;
@@ -795,7 +801,11 @@ gtk_radio_button_clicked (GtkButton *button)
 
   g_object_ref (GTK_WIDGET (button));
 
-  if (toggle_button->active)
+  new_state = gtk_widget_get_state_flags (GTK_WIDGET (button)) &
+    ~(GTK_STATE_FLAG_PRELIGHT |
+      GTK_STATE_FLAG_ACTIVE);
+
+  if (gtk_toggle_button_get_active (toggle_button))
     {
       tmp_button = NULL;
       tmp_list = priv->group;
@@ -805,7 +815,8 @@ gtk_radio_button_clicked (GtkButton *button)
          tmp_button = tmp_list->data;
          tmp_list = tmp_list->next;
 
-         if (tmp_button->active && tmp_button != toggle_button)
+          if (tmp_button != toggle_button &&
+              gtk_toggle_button_get_active (tmp_button))
            break;
 
          tmp_button = NULL;
@@ -813,19 +824,26 @@ gtk_radio_button_clicked (GtkButton *button)
 
       if (!tmp_button)
        {
-         new_state = (button->in_button ? GTK_STATE_PRELIGHT : GTK_STATE_ACTIVE);
+          if (button->priv->in_button)
+            new_state |= GTK_STATE_FLAG_PRELIGHT;
+
+         new_state |= GTK_STATE_FLAG_ACTIVE;
        }
       else
        {
          toggled = TRUE;
-         toggle_button->active = !toggle_button->active;
-         new_state = (button->in_button ? GTK_STATE_PRELIGHT : GTK_STATE_NORMAL);
+          _gtk_toggle_button_set_active (toggle_button,
+                                         !gtk_toggle_button_get_active (toggle_button));
+
+         if (button->priv->in_button)
+           new_state |= GTK_STATE_FLAG_PRELIGHT;
        }
     }
   else
     {
       toggled = TRUE;
-      toggle_button->active = !toggle_button->active;
+      _gtk_toggle_button_set_active (toggle_button,
+                                     !gtk_toggle_button_get_active (toggle_button));
 
       tmp_list = priv->group;
       while (tmp_list)
@@ -833,25 +851,28 @@ gtk_radio_button_clicked (GtkButton *button)
          tmp_button = tmp_list->data;
          tmp_list = tmp_list->next;
 
-         if (tmp_button->active && (tmp_button != toggle_button))
+         if (gtk_toggle_button_get_active (tmp_button) && (tmp_button != toggle_button))
            {
              gtk_button_clicked (GTK_BUTTON (tmp_button));
              break;
            }
        }
 
-      new_state = (button->in_button ? GTK_STATE_PRELIGHT : GTK_STATE_ACTIVE);
+      if (button->priv->in_button)
+        new_state |= GTK_STATE_FLAG_PRELIGHT;
+
+      new_state |= GTK_STATE_FLAG_ACTIVE;
     }
 
-  if (toggle_button->inconsistent)
+  if (gtk_toggle_button_get_inconsistent (toggle_button))
     depressed = FALSE;
-  else if (button->in_button && button->button_down)
-    depressed = !toggle_button->active;
+  else if (button->priv->in_button && button->priv->button_down)
+    depressed = !gtk_toggle_button_get_active (toggle_button);
   else
-    depressed = toggle_button->active;
+    depressed = gtk_toggle_button_get_active (toggle_button);
 
-  if (gtk_widget_get_state (GTK_WIDGET (button)) != new_state)
-    gtk_widget_set_state (GTK_WIDGET (button), new_state);
+  if (gtk_widget_get_state_flags (GTK_WIDGET (button)) != new_state)
+    gtk_widget_set_state_flags (GTK_WIDGET (button), new_state, TRUE);
 
   if (toggled)
     {
@@ -876,10 +897,8 @@ gtk_radio_button_draw_indicator (GtkCheckButton *check_button,
   GtkWidget *child;
   GtkButton *button;
   GtkToggleButton *toggle_button;
-  GtkStateType state_type;
-  GtkShadowType shadow_type;
-  GtkStyle *style;
-  GdkWindow *window;
+  GtkStyleContext *context;
+  GtkStateFlags state = 0;
   gint x, y;
   gint indicator_size, indicator_spacing;
   gint focus_width;
@@ -890,18 +909,17 @@ gtk_radio_button_draw_indicator (GtkCheckButton *check_button,
   widget = GTK_WIDGET (check_button);
   button = GTK_BUTTON (check_button);
   toggle_button = GTK_TOGGLE_BUTTON (check_button);
+  context = gtk_widget_get_style_context (widget);
+  state = gtk_widget_get_state_flags (widget);
 
   border_width = gtk_container_get_border_width (GTK_CONTAINER (widget));
 
-  style = gtk_widget_get_style (widget);
   gtk_widget_style_get (widget,
                         "interior-focus", &interior_focus,
                         "focus-line-width", &focus_width,
                         "focus-padding", &focus_pad,
                         NULL);
 
-  window = gtk_widget_get_window (widget);
-
   _gtk_check_button_get_props (check_button, &indicator_size, &indicator_spacing);
 
   gtk_widget_get_allocation (widget, &allocation);
@@ -911,40 +929,41 @@ gtk_radio_button_draw_indicator (GtkCheckButton *check_button,
 
   child = gtk_bin_get_child (GTK_BIN (check_button));
   if (!interior_focus || !(child && gtk_widget_get_visible (child)))
-    x += focus_width + focus_pad;      
+    x += focus_width + focus_pad;
 
-  if (toggle_button->inconsistent)
-    shadow_type = GTK_SHADOW_ETCHED_IN;
-  else if (toggle_button->active)
-    shadow_type = GTK_SHADOW_IN;
-  else
-    shadow_type = GTK_SHADOW_OUT;
-
-  if (button->activate_timeout || (button->button_down && button->in_button))
-    state_type = GTK_STATE_ACTIVE;
-  else if (button->in_button)
-    state_type = GTK_STATE_PRELIGHT;
-  else if (!gtk_widget_is_sensitive (widget))
-    state_type = GTK_STATE_INSENSITIVE;
-  else
-    state_type = GTK_STATE_NORMAL;
+  state &= ~(GTK_STATE_FLAG_INCONSISTENT |
+             GTK_STATE_FLAG_ACTIVE |
+             GTK_STATE_FLAG_SELECTED |
+             GTK_STATE_FLAG_PRELIGHT);
+
+  if (gtk_toggle_button_get_inconsistent (toggle_button))
+    state |= GTK_STATE_FLAG_INCONSISTENT;
+  else if (gtk_toggle_button_get_active (toggle_button))
+    state |= GTK_STATE_FLAG_ACTIVE;
+
+  if (button->priv->activate_timeout ||
+      (button->priv->button_down && button->priv->in_button))
+    state |= GTK_STATE_FLAG_SELECTED;
+
+  if (button->priv->in_button && !(state & GTK_STATE_FLAG_INSENSITIVE))
+    state |= GTK_STATE_FLAG_PRELIGHT;
 
   if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
     x = allocation.width - (indicator_size + x);
 
-  if (gtk_widget_get_state (widget) == GTK_STATE_PRELIGHT)
-    {
-      gtk_paint_flat_box (style, cr,
-                          GTK_STATE_PRELIGHT,
-                          GTK_SHADOW_ETCHED_OUT, 
-                          widget, "checkbutton",
-                          border_width, border_width,
-                          allocation.width - (2 * border_width),
-                          allocation.height - (2 * border_width));
-    }
+  gtk_style_context_save (context);
+  gtk_style_context_set_state (context, state);
+
+  if (state & GTK_STATE_FLAG_PRELIGHT)
+    gtk_render_background (context, cr,
+                           border_width, border_width,
+                           allocation.width - (2 * border_width),
+                           allocation.height - (2 * border_width));
+
+  gtk_style_context_add_class (context, GTK_STYLE_CLASS_RADIO);
+
+  gtk_render_option (context, cr,
+                     x, y, indicator_size, indicator_size);
 
-  gtk_paint_option (style, cr,
-                    state_type, shadow_type,
-                    widget, "radiobutton",
-                    x, y, indicator_size, indicator_size);
+  gtk_style_context_restore (context);
 }