]> Pileus Git - ~andy/gtk/blobdiff - modules/other/gail/gailbutton.c
gail: we cant access button->in_button directly now.
[~andy/gtk] / modules / other / gail / gailbutton.c
index 46b7db33a856e217ffa6ee7c666302275f3050f5..8a187261c3a09ab515e29cf82e298a7162954d2e 100644 (file)
@@ -17,6 +17,8 @@
  * Boston, MA 02111-1307, USA.
  */
 
+#include "config.h"
+
 #include <string.h>
 #include <gtk/gtk.h>
 #include <gdk/gdkkeysyms.h>
@@ -26,7 +28,7 @@
 #define GAIL_BUTTON_ATTACHED_MENUS "gtk-attached-menus"
 
 static void                  gail_button_class_init       (GailButtonClass *klass);
-static void                  gail_button_object_init      (GailButton      *button);
+static void                  gail_button_init             (GailButton      *button);
 
 static G_CONST_RETURN gchar* gail_button_get_name         (AtkObject       *obj);
 static gint                  gail_button_get_n_children   (AtkObject       *obj);
@@ -142,80 +144,22 @@ static gint                  get_n_attached_menus       (GtkWidget      *widget)
 static GtkWidget*            get_nth_attached_menu      (GtkWidget      *widget,
                                                          gint           index);
 
-static GailContainer* parent_class = NULL;
-
-GType
-gail_button_get_type (void)
-{
-  static GType type = 0;
-
-  if (!type)
-    {
-      static const GTypeInfo tinfo =
-      {
-        sizeof (GailButtonClass),
-        (GBaseInitFunc) NULL, /* base init */
-        (GBaseFinalizeFunc) NULL, /* base finalize */
-        (GClassInitFunc) gail_button_class_init, /* class init */
-        (GClassFinalizeFunc) NULL, /* class finalize */
-        NULL, /* class data */
-        sizeof (GailButton), /* instance size */
-        0, /* nb preallocs */
-        (GInstanceInitFunc) gail_button_object_init, /* instance init */
-        NULL /* value table */
-      };
-
-      static const GInterfaceInfo atk_action_info =
-      {
-        (GInterfaceInitFunc) atk_action_interface_init,
-        (GInterfaceFinalizeFunc) NULL,
-        NULL
-      };
-
-      static const GInterfaceInfo atk_image_info =
-      {
-        (GInterfaceInitFunc) atk_image_interface_init,
-        (GInterfaceFinalizeFunc) NULL,
-        NULL
-      };
-
-      static const GInterfaceInfo atk_text_info =
-      {
-        (GInterfaceInitFunc) atk_text_interface_init,
-        (GInterfaceFinalizeFunc) NULL,
-        NULL
-      };
-
-      type = g_type_register_static (GAIL_TYPE_CONTAINER,
-                                     "GailButton", &tinfo, 0);
-
-      g_type_add_interface_static (type, ATK_TYPE_ACTION,
-                                   &atk_action_info);
-      g_type_add_interface_static (type, ATK_TYPE_IMAGE,
-                                   &atk_image_info);
-      g_type_add_interface_static (type, ATK_TYPE_TEXT,
-                                   &atk_text_info);
-
-    }
-
-  return type;
-}
+G_DEFINE_TYPE_WITH_CODE (GailButton, gail_button, GAIL_TYPE_CONTAINER,
+                         G_IMPLEMENT_INTERFACE (ATK_TYPE_ACTION, atk_action_interface_init)
+                         G_IMPLEMENT_INTERFACE (ATK_TYPE_IMAGE, atk_image_interface_init)
+                         G_IMPLEMENT_INTERFACE (ATK_TYPE_TEXT, atk_text_interface_init))
 
 static void
 gail_button_class_init (GailButtonClass *klass)
 {
   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
   AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
-  GailWidgetClass *widget_class;
   GailContainerClass *container_class;
 
-  widget_class = (GailWidgetClass*)klass;
   container_class = (GailContainerClass*)klass;
 
   gobject_class->finalize = gail_button_finalize;
 
-  parent_class = g_type_class_peek_parent (klass);
-
   class->get_name = gail_button_get_name;
   class->get_n_children = gail_button_get_n_children;
   class->ref_child = gail_button_ref_child;
@@ -227,7 +171,7 @@ gail_button_class_init (GailButtonClass *klass)
 }
 
 static void
-gail_button_object_init (GailButton      *button)
+gail_button_init (GailButton *button)
 {
   button->click_description = NULL;
   button->press_description = NULL;
@@ -238,22 +182,6 @@ gail_button_object_init (GailButton      *button)
   button->textutil = NULL;
 }
 
-AtkObject* 
-gail_button_new (GtkWidget *widget)
-{
-  GObject *object;
-  AtkObject *accessible;
-
-  g_return_val_if_fail (GTK_IS_BUTTON (widget), NULL);
-
-  object = g_object_new (GAIL_TYPE_BUTTON, NULL);
-
-  accessible = ATK_OBJECT (object);
-  atk_object_initialize (accessible, widget);
-
-  return accessible;
-}
-
 static G_CONST_RETURN gchar*
 gail_button_get_name (AtkObject *obj)
 {
@@ -261,7 +189,7 @@ gail_button_get_name (AtkObject *obj)
 
   g_return_val_if_fail (GAIL_IS_BUTTON (obj), NULL);
 
-  name = ATK_OBJECT_CLASS (parent_class)->get_name (obj);
+  name = ATK_OBJECT_CLASS (gail_button_parent_class)->get_name (obj);
   if (name == NULL)
     {
       /*
@@ -270,7 +198,7 @@ gail_button_get_name (AtkObject *obj)
       GtkWidget *widget;
       GtkWidget *child;
 
-      widget = GTK_ACCESSIBLE (obj)->widget;
+      widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
       if (widget == NULL)
         /*
          * State is defunct
@@ -306,21 +234,28 @@ gail_button_get_name (AtkObject *obj)
 static gboolean
 gail_button_is_default_press (GtkWidget *widget)
 {
+  GtkArrowType arrow_type;
   GtkWidget  *child;
   GtkWidget  *parent;
   gboolean ret = FALSE;
   const gchar *parent_type_name;
 
-  child = GTK_BIN (widget)->child;
-  if (GTK_IS_ARROW (child) &&
-      GTK_ARROW (child)->arrow_type == GTK_ARROW_DOWN)
+  child = gtk_bin_get_child (GTK_BIN (widget));
+  if (GTK_IS_ARROW (child))
     {
-      parent = gtk_widget_get_parent (widget);
-      if (parent)
+      g_object_get (child,
+                    "arrow_type", &arrow_type,
+                    NULL);
+
+      if (arrow_type == GTK_ARROW_DOWN)
         {
-          parent_type_name = g_type_name (G_OBJECT_TYPE (parent));
-          if (strcmp (parent_type_name, "ColorCombo"))
-            return TRUE;
+          parent = gtk_widget_get_parent (widget);
+          if (parent)
+            {
+              parent_type_name = g_type_name (G_OBJECT_TYPE (parent));
+              if (g_strcmp0 (parent_type_name, "ColorCombo"))
+                return TRUE;
+            }
         }
     }
 
@@ -335,7 +270,7 @@ gail_button_real_initialize (AtkObject *obj,
   GtkWidget  *label;
   GtkWidget  *widget;
 
-  ATK_OBJECT_CLASS (parent_class)->initialize (obj, data);
+  ATK_OBJECT_CLASS (gail_button_parent_class)->initialize (obj, data);
 
   button->state = GTK_STATE_NORMAL;
 
@@ -361,7 +296,7 @@ gail_button_real_initialize (AtkObject *obj,
   label = get_label_from_button (widget, 0, FALSE);
   if (GTK_IS_LABEL (label))
     {
-      if (GTK_WIDGET_MAPPED (label))
+      if (gtk_widget_get_mapped (label))
         gail_button_init_textutil (button, label);
       else 
         g_signal_connect (label,
@@ -462,6 +397,8 @@ gail_button_init_textutil (GailButton  *button,
 {
   const gchar *label_text;
 
+  if (button->textutil)
+    g_object_unref (button->textutil);
   button->textutil = gail_text_util_new ();
   label_text = gtk_label_get_text (GTK_LABEL (label));
   gail_text_util_text_setup (button->textutil, label_text);
@@ -506,8 +443,6 @@ gail_button_real_add_gtk (GtkContainer *container,
 static void
 atk_action_interface_init (AtkActionIface *iface)
 {
-  g_return_if_fail (iface != NULL);
-
   iface->do_action = gail_button_do_action;
   iface->get_n_actions = gail_button_get_n_actions;
   iface->get_description = gail_button_get_description;
@@ -524,14 +459,14 @@ gail_button_do_action (AtkAction *action,
   GailButton *button;
   gboolean return_value = TRUE;
 
-  widget = GTK_ACCESSIBLE (action)->widget;
+  widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (action));
   if (widget == NULL)
     /*
      * State is defunct
      */
     return FALSE;
 
-  if (!GTK_WIDGET_IS_SENSITIVE (widget) || !GTK_WIDGET_VISIBLE (widget))
+  if (!gtk_widget_is_sensitive (widget) || !gtk_widget_get_visible (widget))
     return FALSE;
 
   button = GAIL_BUTTON (action); 
@@ -545,9 +480,9 @@ gail_button_do_action (AtkAction *action,
        {
          button->action_queue = g_queue_new ();
        }
-      g_queue_push_head (button->action_queue, (gpointer) i);
+      g_queue_push_head (button->action_queue, GINT_TO_POINTER(i));
       if (!button->action_idle_handler)
-       button->action_idle_handler = g_idle_add (idle_do_action, button);
+       button->action_idle_handler = gdk_threads_add_idle (idle_do_action, button);
       break;
     default:
       return_value = FALSE;
@@ -563,23 +498,26 @@ idle_do_action (gpointer data)
   GtkWidget *widget;
   GailButton *gail_button;
   GdkEvent tmp_event;
-
-  GDK_THREADS_ENTER ();
+  GdkWindow *window;
 
   gail_button = GAIL_BUTTON (data);
   gail_button->action_idle_handler = 0;
-  widget = GTK_ACCESSIBLE (gail_button)->widget;
+  widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (gail_button));
+  window = gtk_widget_get_window (widget);
+
   tmp_event.button.type = GDK_BUTTON_RELEASE;
-  tmp_event.button.window = widget->window;
+  tmp_event.button.window = window;
   tmp_event.button.button = 1;
   tmp_event.button.send_event = TRUE;
   tmp_event.button.time = GDK_CURRENT_TIME;
   tmp_event.button.axes = NULL;
-  
+
+  g_object_ref (gail_button);
+
   if (widget == NULL /* State is defunct */ ||
-      !GTK_WIDGET_IS_SENSITIVE (widget) || !GTK_WIDGET_VISIBLE (widget))
+      !gtk_widget_is_sensitive (widget) || !gtk_widget_get_visible (widget))
     {
-      GDK_THREADS_LEAVE ();
+      g_object_unref (gail_button);
       return FALSE;
     }
   else
@@ -588,7 +526,7 @@ idle_do_action (gpointer data)
   button = GTK_BUTTON (widget); 
   while (!g_queue_is_empty (gail_button->action_queue)) 
     {
-      gint action_number = (gint) g_queue_pop_head (gail_button->action_queue);
+      gint action_number = GPOINTER_TO_INT(g_queue_pop_head (gail_button->action_queue));
       if (gail_button->default_is_press)
         {
           if (action_number == 0)
@@ -599,17 +537,44 @@ idle_do_action (gpointer data)
       switch (action_number)
        {
        case 0:
-         gtk_widget_activate (widget);
+         /* first a press */ 
+
+          /* FIXME: Do not access public member
+         button->in_button = TRUE;
+          */
+         g_signal_emit_by_name (button, "enter");
+         /*
+          * Simulate a button press event. calling gtk_button_pressed() does
+          * not get the job done for a GtkOptionMenu.  
+          */
+         tmp_event.button.type = GDK_BUTTON_PRESS;
+         tmp_event.button.window = window;
+         tmp_event.button.button = 1;
+         tmp_event.button.send_event = TRUE;
+         tmp_event.button.time = GDK_CURRENT_TIME;
+         tmp_event.button.axes = NULL;
+         
+         gtk_widget_event (widget, &tmp_event);
+
+         /* then a release */
+         tmp_event.button.type = GDK_BUTTON_RELEASE;
+         gtk_widget_event (widget, &tmp_event);
+          /* FIXME: Do not access public member
+         button->in_button = FALSE;
+          */
+         g_signal_emit_by_name (button, "leave");
          break;
        case 1:
+          /* FIXME: Do not access public member
          button->in_button = TRUE;
-         gtk_button_enter (button);
+          */
+         g_signal_emit_by_name (button, "enter");
          /*
           * Simulate a button press event. calling gtk_button_pressed() does
           * not get the job done for a GtkOptionMenu.  
           */
          tmp_event.button.type = GDK_BUTTON_PRESS;
-         tmp_event.button.window = widget->window;
+         tmp_event.button.window = window;
          tmp_event.button.button = 1;
          tmp_event.button.send_event = TRUE;
          tmp_event.button.time = GDK_CURRENT_TIME;
@@ -618,18 +583,18 @@ idle_do_action (gpointer data)
          gtk_widget_event (widget, &tmp_event);
          break;
        case 2:
+          /* FIXME: Do not access public member
          button->in_button = FALSE;
-         gtk_button_leave (button);
+          */
+         g_signal_emit_by_name (button, "leave");
          break;
        default:
          g_assert_not_reached ();
          break;
        }
     }
-
-  GDK_THREADS_LEAVE ();
-
-  return FALSE; 
+  g_object_unref (gail_button);
+  return FALSE;
 }
 
 static gint
@@ -698,7 +663,7 @@ gail_button_get_keybinding (AtkAction *action,
         GtkWidget *label;
         guint key_val; 
 
-        widget = GTK_ACCESSIBLE (button)->widget;
+        widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (button));
         if (widget == NULL)
           /*
            * State is defunct
@@ -711,7 +676,7 @@ gail_button_get_keybinding (AtkAction *action,
         if (GTK_IS_LABEL (label))
           {
             key_val = gtk_label_get_mnemonic_keyval (GTK_LABEL (label)); 
-            if (key_val != GDK_VoidSymbol)
+            if (key_val != GDK_KEY_VoidSymbol)
               return_value = gtk_accelerator_name (key_val, GDK_MOD1_MASK);
           }
         if (return_value == NULL)
@@ -731,10 +696,7 @@ gail_button_get_keybinding (AtkAction *action,
                     target = atk_relation_get_target (relation);
             
                     target_object = g_ptr_array_index (target, 0);
-                    if (GTK_IS_ACCESSIBLE (target_object))
-                      {
-                        label = GTK_ACCESSIBLE (target_object)->widget;
-                      } 
+                    label = gtk_accessible_get_widget (GTK_ACCESSIBLE (target_object));
                   }
                 g_object_unref (set);
               }
@@ -742,7 +704,7 @@ gail_button_get_keybinding (AtkAction *action,
             if (GTK_IS_LABEL (label))
               {
                 key_val = gtk_label_get_mnemonic_keyval (GTK_LABEL (label)); 
-                if (key_val != GDK_VoidSymbol)
+                if (key_val != GDK_KEY_VoidSymbol)
                   return_value = gtk_accelerator_name (key_val, GDK_MOD1_MASK);
               }
           }
@@ -855,7 +817,7 @@ gail_button_get_n_children (AtkObject* obj)
 
   g_return_val_if_fail (GAIL_IS_BUTTON (obj), 0);
 
-  widget = GTK_ACCESSIBLE (obj)->widget;
+  widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
   if (widget == NULL)
     /*
      * State is defunct
@@ -886,7 +848,7 @@ gail_button_ref_child (AtkObject *obj,
 
   g_return_val_if_fail (GAIL_IS_BUTTON (obj), NULL);
 
-  widget = GTK_ACCESSIBLE (obj)->widget;
+  widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
   if (widget == NULL)
     /*
      * State is defunct
@@ -927,19 +889,20 @@ gail_button_ref_state_set (AtkObject *obj)
 {
   AtkStateSet *state_set;
   GtkWidget *widget;
-  GtkButton *button;
 
-  state_set = ATK_OBJECT_CLASS (parent_class)->ref_state_set (obj);
-  widget = GTK_ACCESSIBLE (obj)->widget;
+  state_set = ATK_OBJECT_CLASS (gail_button_parent_class)->ref_state_set (obj);
+  widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj));
 
   if (widget == NULL)
     return state_set;
 
-  button = GTK_BUTTON (widget);
-
-  if (GTK_WIDGET_STATE (widget) == GTK_STATE_ACTIVE)
+  if (gtk_widget_get_state (widget) == GTK_STATE_ACTIVE)
     atk_state_set_add_state (state_set, ATK_STATE_ARMED);
 
+  if (!gtk_widget_get_can_focus (widget))
+    atk_state_set_remove_state (state_set, ATK_STATE_SELECTABLE);
+
+
   return state_set;
 }
 
@@ -954,7 +917,7 @@ gail_button_pressed_enter_handler (GtkWidget       *widget)
 {
   AtkObject *accessible;
 
-  if (GTK_WIDGET_STATE (widget) == GTK_STATE_ACTIVE)
+  if (gtk_widget_get_state (widget) == GTK_STATE_ACTIVE)
     {
       accessible = gtk_widget_get_accessible (widget);
       atk_object_notify_state_change (accessible, ATK_STATE_ARMED, TRUE);
@@ -984,8 +947,6 @@ gail_button_released_leave_handler (GtkWidget       *widget)
 static void
 atk_image_interface_init (AtkImageIface *iface)
 {
-  g_return_if_fail (iface != NULL);
-
   iface->get_image_description = gail_button_get_image_description;
   iface->get_image_position = gail_button_get_image_position;
   iface->get_image_size = gail_button_get_image_size;
@@ -1027,8 +988,7 @@ gail_button_get_image_description (AtkImage *image) {
   GtkImage  *button_image;
   AtkObject *obj;
 
-  widget = GTK_ACCESSIBLE (image)->widget;
-
+  widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (image));
   if (widget == NULL)
     /*
      * State is defunct
@@ -1056,7 +1016,7 @@ gail_button_get_image_position (AtkImage     *image,
   GtkImage  *button_image;
   AtkObject *obj;
 
-  widget = GTK_ACCESSIBLE (image)->widget;
+  widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (image));
 
   if (widget == NULL)
     {
@@ -1091,7 +1051,7 @@ gail_button_get_image_size (AtkImage *image,
   GtkImage  *button_image;
   AtkObject *obj;
 
-  widget = GTK_ACCESSIBLE (image)->widget;
+  widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (image));
 
   if (widget == NULL)
     {
@@ -1125,7 +1085,7 @@ gail_button_set_image_description (AtkImage    *image,
   GtkImage  *button_image;
   AtkObject *obj;
 
-  widget = GTK_ACCESSIBLE (image)->widget;
+  widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (image));
 
   if (widget == NULL)
     /*
@@ -1149,7 +1109,6 @@ gail_button_set_image_description (AtkImage    *image,
 static void
 atk_text_interface_init (AtkTextIface *iface)
 {
-  g_return_if_fail (iface != NULL);
   iface->get_text = gail_button_get_text;
   iface->get_character_at_offset = gail_button_get_character_at_offset;
   iface->get_text_before_offset = gail_button_get_text_before_offset;
@@ -1172,7 +1131,8 @@ gail_button_get_text (AtkText *text,
   GailButton *button;
   const gchar *label_text;
 
-  widget = GTK_ACCESSIBLE (text)->widget;
+  widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+
   if (widget == NULL)
     /* State is defunct */
     return NULL;
@@ -1207,9 +1167,9 @@ gail_button_get_text_before_offset (AtkText         *text,
   GtkWidget *widget;
   GtkWidget *label;
   GailButton *button;
-  
-  widget = GTK_ACCESSIBLE (text)->widget;
-  
+
+  widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+
   if (widget == NULL)
     /* State is defunct */
     return NULL;
@@ -1239,9 +1199,9 @@ gail_button_get_text_at_offset (AtkText         *text,
   GtkWidget *widget;
   GtkWidget *label;
   GailButton *button;
+
+  widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
  
-  widget = GTK_ACCESSIBLE (text)->widget;
-  
   if (widget == NULL)
     /* State is defunct */
     return NULL;
@@ -1272,8 +1232,8 @@ gail_button_get_text_after_offset (AtkText         *text,
   GtkWidget *label;
   GailButton *button;
 
-  widget = GTK_ACCESSIBLE (text)->widget;
-  
+  widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+
   if (widget == NULL)
   {
     /* State is defunct */
@@ -1301,7 +1261,8 @@ gail_button_get_character_count (AtkText *text)
   GtkWidget *widget;
   GtkWidget *label;
 
-  widget = GTK_ACCESSIBLE (text)->widget;
+  widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+
   if (widget == NULL)
     /* State is defunct */
     return 0;
@@ -1328,8 +1289,8 @@ gail_button_get_character_extents (AtkText      *text,
   PangoRectangle char_rect;
   gint index, x_layout, y_layout;
   const gchar *label_text;
-  widget = GTK_ACCESSIBLE (text)->widget;
+
+  widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
 
   if (widget == NULL)
     /* State is defunct */
@@ -1360,10 +1321,12 @@ gail_button_get_offset_at_point (AtkText      *text,
   gint index, x_layout, y_layout;
   const gchar *label_text;
 
-  widget = GTK_ACCESSIBLE (text)->widget;
+  widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+
   if (widget == NULL)
     /* State is defunct */
     return -1;
+
   label = get_label_from_button (widget, 0, FALSE);
 
   if (!GTK_IS_LABEL(label))
@@ -1398,7 +1361,8 @@ gail_button_get_run_attributes (AtkText        *text,
   GtkJustification justify;
   GtkTextDirection dir;
 
-  widget = GTK_ACCESSIBLE (text)->widget;
+  widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+
   if (widget == NULL)
     /* State is defunct */
     return NULL;
@@ -1440,7 +1404,8 @@ gail_button_get_default_attributes (AtkText        *text)
   GtkWidget *label;
   AtkAttributeSet *at_set = NULL;
 
-  widget = GTK_ACCESSIBLE (text)->widget;
+  widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+
   if (widget == NULL)
     /* State is defunct */
     return NULL;
@@ -1465,7 +1430,8 @@ gail_button_get_character_at_offset (AtkText               *text,
   const gchar *string;
   gchar *index;
 
-  widget = GTK_ACCESSIBLE (text)->widget;
+  widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
+
   if (widget == NULL)
     /* State is defunct */
     return '\0';
@@ -1504,7 +1470,7 @@ gail_button_finalize (GObject            *object)
     {
       g_object_unref (button->textutil);
     }
-  G_OBJECT_CLASS (parent_class)->finalize (object);
+  G_OBJECT_CLASS (gail_button_parent_class)->finalize (object);
 }
 
 static GtkWidget*