[access] elm_access_action(); elm_access_action_cb_set(); added
authorShinwoo Kim <cinoo.kim@samsung.com>
Mon, 25 Mar 2013 10:40:31 +0000 (19:40 +0900)
committerSungho Kwak <sungho1.kwak@samsung.com>
Thu, 28 Mar 2013 02:51:19 +0000 (11:51 +0900)
src/lib/elm_access.c
src/lib/elm_access.h

index f5a023b..652c29d 100644 (file)
@@ -7,6 +7,22 @@ ELM_INTERNAL_SMART_SUBCLASS_NEW
   (ACCESS_SMART_NAME, _elm_access, Elm_Widget_Smart_Class,
   Elm_Widget_Smart_Class, elm_widget_smart_class_get, NULL);
 
+struct _Func_Data
+{
+   void                *user_data; /* Holds user data to CB */
+   Elm_Access_Action_Cb cb;
+};
+
+typedef struct _Func_Data Func_Data;
+
+struct _Action_Info
+{
+   Evas_Object      *obj;
+   Func_Data         fn[ELM_ACCESS_ACTION_LAST + 1]; /* Callback for specific action */
+};
+
+typedef struct _Action_Info Action_Info;
+
 static Eina_Bool mouse_event_enable = EINA_TRUE;
 static Eina_Bool read_mode = EINA_FALSE;
 
@@ -32,6 +48,44 @@ _elm_access_smart_on_focus(Evas_Object *obj)
 static Eina_Bool
 _elm_access_smart_activate(Evas_Object *obj, Elm_Activate act)
 {
+   int type = ELM_ACCESS_ACTION_FIRST;
+
+   Action_Info *a;
+   a = evas_object_data_get(obj, "_elm_access_action_info");
+
+   switch (act)
+     {
+      case ELM_ACTIVATE_DEFAULT:
+        type = ELM_ACCESS_ACTION_ACTIVATE;
+        break;
+
+      case ELM_ACTIVATE_UP:
+        type = ELM_ACCESS_ACTION_VALUE_CHANGE;
+        break;
+
+      case ELM_ACTIVATE_DOWN:
+        type = ELM_ACCESS_ACTION_VALUE_CHANGE;
+        break;
+
+      case ELM_ACTIVATE_RIGHT:
+        break;
+
+      case ELM_ACTIVATE_LEFT:
+        break;
+
+      default:
+        break;
+     }
+
+   if ((a) && (type > ELM_ACCESS_ACTION_FIRST) &&
+              (type < ELM_ACCESS_ACTION_LAST) &&
+              (a->fn[type].cb))
+     {
+        a->fn[type].cb(a->fn[type].user_data, obj, NULL);
+        return EINA_TRUE;
+     }
+
+   /* TODO: deprecate below? and change above with _access_action_callback_call(); */
    if (act != ELM_ACTIVATE_DEFAULT) return EINA_FALSE;
 
    Elm_Access_Info *ac = evas_object_data_get(obj, "_elm_access");
@@ -394,6 +448,76 @@ _elm_access_widget_item_access_order_unset(Elm_Widget_Item *item)
         item->access_order = eina_list_remove_list(item->access_order, l);
      }
 }
+
+static Eina_Bool
+_access_action_callback_call(Evas_Object *obj,
+                             Elm_Access_Action_Type type,
+                             void *data)
+{
+   Action_Info *a;
+   Eina_Bool ret;
+
+   ret = EINA_FALSE;
+   a = evas_object_data_get(obj, "_elm_access_action_info");
+
+   if (a && (a->fn[type].cb))
+     ret = a->fn[type].cb(a->fn[type].user_data, obj, data);
+
+   return ret;
+}
+
+static Eina_Bool
+_access_highlight_next_get(Evas_Object *obj, Elm_Focus_Direction dir)
+{
+   int type;
+   Evas_Object *ho, *parent, *target;
+   Eina_Bool ret;
+
+   target = NULL;
+   ret = EINA_FALSE;
+
+   if (!elm_widget_is(obj)) return ret;
+
+   ho = _access_highlight_object_get(obj);
+   if (!ho) return ret;
+
+   parent = ho;
+
+   /* find highlight root */
+   do
+     {
+        ELM_WIDGET_DATA_GET(parent, sd);
+        if (sd->highlight_root)
+          {
+             /* change highlight root */
+             obj = parent;
+             break;
+          }
+        parent = elm_widget_parent_get(parent);
+     }
+   while (parent);
+
+   _elm_access_read_mode_set(EINA_TRUE);
+
+   ret = elm_widget_focus_next_get(obj, dir, &target);
+   if (ret && target)
+     {
+        if (dir == ELM_FOCUS_NEXT)
+          type = ELM_ACCESS_ACTION_HIGHLIGHT_NEXT;
+        else
+          type = ELM_ACCESS_ACTION_HIGHLIGHT_PREV;
+
+        if (!_access_action_callback_call(ho, type, NULL))
+          {
+             _elm_access_highlight_set(target);
+             ret = EINA_FALSE;
+          }
+     }
+
+   _elm_access_read_mode_set(EINA_FALSE);
+
+   return ret;
+}
 //-------------------------------------------------------------------------//
 EAPI void
 _elm_access_highlight_set(Evas_Object* obj)
@@ -490,26 +614,38 @@ _elm_access_highlight_object_activate(Evas_Object *obj, Elm_Activate act)
 EAPI void
 _elm_access_highlight_cycle(Evas_Object *obj, Elm_Focus_Direction dir)
 {
-   Evas_Object *ho;
+   int type;
+   Evas_Object *ho, *parent;
+
    ho = _access_highlight_object_get(obj);
    if (!ho) return;
 
+   parent = ho;
+
    /* find highlight root */
    do
      {
-        ELM_WIDGET_DATA_GET(ho, sd);
+        ELM_WIDGET_DATA_GET(parent, sd);
         if (sd->highlight_root)
           {
              /* change highlight root */
-             obj = ho;
+             obj = parent;
              break;
           }
-        ho = elm_widget_parent_get(ho);
+        parent = elm_widget_parent_get(parent);
      }
-   while (ho);
+   while (parent);
 
    _elm_access_read_mode_set(EINA_TRUE);
-   elm_widget_focus_cycle(obj, dir);
+
+   if (dir == ELM_FOCUS_NEXT)
+     type = ELM_ACCESS_ACTION_HIGHLIGHT_NEXT;
+   else
+     type = ELM_ACCESS_ACTION_HIGHLIGHT_PREV;
+
+   if (!_access_action_callback_call(ho, type, NULL))
+     elm_widget_focus_cycle(obj, dir);
+
    _elm_access_read_mode_set(EINA_FALSE);
 }
 
@@ -636,7 +772,13 @@ _elm_access_object_hilight(Evas_Object *obj)
    evas_object_geometry_get(obj, &x, &y, &w, &h);
    evas_object_move(o, x, y);
    evas_object_resize(o, w, h);
-   evas_object_show(o);
+
+   /* use callback, should an access object do below every time when
+       * a window gets a client message ECORE_X_ATOM_E_ILLMUE_ACTION_READ? */
+   if (!_access_action_callback_call(obj, ELM_ACCESS_ACTION_HIGHLIGHT, NULL))
+     evas_object_show(o);
+   else
+     evas_object_hide(o);
 }
 
 EAPI void
@@ -853,6 +995,10 @@ _elm_access_object_unregister(Evas_Object *obj, Evas_Object *hoverobj)
         _elm_access_clear(ac);
         free(ac);
      }
+
+   Action_Info *a;
+   a = evas_object_data_get(obj, "_elm_access_action_info");
+   if (a) free(a);
 }
 
 EAPI void
@@ -1015,6 +1161,80 @@ elm_access_highlight_set(Evas_Object* obj)
    _elm_access_highlight_set(obj);
 }
 
+EAPI Eina_Bool
+elm_access_action(Evas_Object *obj, const Elm_Access_Action_Type type, void *action_info)
+{
+   Evas *evas;
+   Elm_Access_Action_Info *a;
+
+   a = (Elm_Access_Action_Info *) action_info;
+
+   switch (type)
+     {
+      case ELM_ACCESS_ACTION_HIGHLIGHT:
+        evas = evas_object_evas_get(obj);
+        if (!evas) return EINA_FALSE;
+
+        _elm_access_mouse_event_enabled_set(EINA_TRUE);
+
+        evas_event_feed_mouse_in(evas, 0, NULL);
+        evas_event_feed_mouse_move(evas, a->x1, a->y1, 0, NULL);
+
+        _elm_access_mouse_event_enabled_set(EINA_FALSE);
+        break;
+
+      case ELM_ACCESS_ACTION_HIGHLIGHT_NEXT:
+        if (a->highlight_cycle)
+          _elm_access_highlight_cycle(obj, ELM_FOCUS_NEXT);
+        else
+          return _access_highlight_next_get(obj, ELM_FOCUS_NEXT);
+        break;
+
+      case ELM_ACCESS_ACTION_HIGHLIGHT_PREV:
+        if (a->highlight_cycle)
+          _elm_access_highlight_cycle(obj, ELM_FOCUS_PREVIOUS);
+        else
+          return _access_highlight_next_get(obj, ELM_FOCUS_PREVIOUS);
+        break;
+
+      case ELM_ACCESS_ACTION_ACTIVATE:
+        _elm_access_highlight_object_activate(obj, ELM_ACTIVATE_DEFAULT);
+        break;
+
+      case ELM_ACCESS_ACTION_VALUE_CHANGE:
+        _elm_access_highlight_object_activate(obj, ELM_ACTIVATE_UP);
+        break;
+
+      case ELM_ACCESS_ACTION_SCROLL:
+        break;
+
+      case ELM_ACCESS_ACTION_BACK:
+        break;
+
+      default:
+        break;
+     }
+
+   return EINA_TRUE;
+}
+
+EAPI void
+elm_access_action_cb_set(Evas_Object *obj, const Elm_Access_Action_Type type, const Elm_Access_Action_Cb cb, const void *data)
+{
+   Action_Info *a;
+   a =  evas_object_data_get(obj, "_elm_access_action_info");
+
+   if (!a)
+     {
+        a = calloc(1, sizeof(Action_Info));
+        evas_object_data_set(obj, "_elm_access_action_info", a);
+     }
+
+   a->obj = obj;
+   a->fn[type].cb = cb;
+   a->fn[type].user_data = (void *)data;
+}
+
 EAPI void
 elm_access_external_info_set(Evas_Object *obj, const char *text)
 {
index c28a747..dffae82 100644 (file)
@@ -27,6 +27,58 @@ typedef enum _Elm_Access_Info_Type Elm_Access_Info_Type;
 typedef char *(*Elm_Access_Info_Cb)(void *data, Evas_Object *obj);
 typedef void (*Elm_Access_Activate_Cb)(void *data, Evas_Object *part_obj, Elm_Object_Item *item);
 
+struct _Elm_Access_Action_Info
+{
+   Evas_Coord   x1;
+   Evas_Coord   y1;
+   Evas_Coord   x2;
+   Evas_Coord   y2;
+
+   unsigned int tx;
+   unsigned int ty;
+
+
+   Eina_Bool    highlight_cycle : 1;
+};
+
+typedef struct _Elm_Access_Action_Info Elm_Access_Action_Info;
+
+/**
+ * @typedef Elm_Access_Action_Cb
+ * User callback to make access object do specific action
+ * @param data user data
+ * @param action_info information to classify the action
+ * Returns EINA_TRUE on success, EINA FALSE otherwise
+ *
+ */
+typedef Eina_Bool (*Elm_Access_Action_Cb)(void *data, Evas_Object *obj, void *action_info);
+
+/**
+ * @enum _Elm_Access_Action_Type
+ * Enum of supported access action types.
+ */
+enum _Elm_Access_Action_Type
+{
+   ELM_ACCESS_ACTION_FIRST = -1,
+
+   ELM_ACCESS_ACTION_HIGHLIGHT, /* highlight a object */
+   ELM_ACCESS_ACTION_HIGHLIGHT_NEXT, /* set highlight to next object */
+   ELM_ACCESS_ACTION_HIGHLIGHT_PREV, /* set highlight to previous object */
+   ELM_ACCESS_ACTION_ACTIVATE, /* activate a highlight object */
+   ELM_ACCESS_ACTION_VALUE_CHANGE, /* change value of highlight object */
+   ELM_ACCESS_ACTION_SCROLL, /* scroll if one of highlight object parents
+                              * is scrollable */
+   ELM_ACCESS_ACTION_BACK, /* go back to a previous view
+                              ex: pop naviframe item */
+
+   ELM_ACCESS_ACTION_LAST
+};
+
+/**
+ * @typedef Elm_Access_Action_Type
+ */
+typedef enum _Elm_Access_Action_Type Elm_Access_Action_Type;
+
 /**
  * @brief Register evas object as an accessible object.
  * @since 1.8
@@ -143,6 +195,9 @@ EAPI void elm_access_say(const char *text);
  */
 EAPI void elm_access_highlight_set(Evas_Object* obj);
 
+EAPI Eina_Bool elm_access_action(Evas_Object *obj, const Elm_Access_Action_Type type, void *action_info);
+
+EAPI void elm_access_action_cb_set(Evas_Object *obj, const Elm_Access_Action_Type type, const Elm_Access_Action_Cb cb, const void *data);
 //TODO: remvoe below - use elm_access_text_set(); or elm_access_cb_set();
 EINA_DEPRECATED EAPI void elm_access_external_info_set(Evas_Object *obj, const char *text);
 EINA_DEPRECATED EAPI char *elm_access_external_info_get(const Evas_Object *obj);