From: Kim Shinwoo <kimcinoo.efl@gmail.com>
authorKim Shinwoo <kimcinoo.efl@gmail.com>
Wed, 12 Sep 2012 08:25:10 +0000 (08:25 +0000)
committerCarsten Haitzler <raster@rasterman.com>
Wed, 12 Sep 2012 08:25:10 +0000 (08:25 +0000)
Subject: [E-devel] [patch][elementary] calendar - add access feature,
access - add _elm_access_edje_object_part_object_unregister();

the attachment has accessibility feature which is for the
elm_calendar. and
moreover..
it would be better to keep one more api for the access which name is
_elm_access_edje_object_part_object_unregister();
in the case of calendar item, its text part could be set with empty
value
in run time(dynamically), even though it had a value (1~31) previously.
so if there is an empty field(item), then previously registered item
should
be unregistered. the api would be useful not only this case but also
others.
then, please review the patch and give feedback. thanks.

SVN revision: 76502

ChangeLog
data/themes/widgets/calendar.edc
src/lib/elm_access.c
src/lib/elm_calendar.c
src/lib/elm_widget.h
src/lib/elm_widget_calendar.h

index 65dbf74..ab6a8e3 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
         * When the number of item is changed, the toolbar emits the signal
         to theme. The theme can be changed something according the number
         of item.
+
+2012-09-12  Shinwoo Kim (kimcinoo)
+
+        * Add access features to calendar.
+
index 090a11e..a4d3b67 100644 (file)
          visible: 1; \
       } \
    } \
+   part { name: "cit_"#_pos".access"; \
+      type: RECT; \
+      repeat_events: 1; \
+      description { state: "default" 0.0; \
+         rel1.to: "cit_"#_pos".event"; \
+         rel2.to: "cit_"#_pos".event"; \
+         visible: 1; \
+         color: 0 0 0 0; \
+      } \
+   } \
    programs { \
       program { \
          name:    "cit_"#_pos".go_active"; \
index 4de3517..5224882 100644 (file)
@@ -164,6 +164,9 @@ _access_obj_del_cb(void *data, Evas *e __UNUSED__, Evas_Object *obj, void *event
         _elm_access_clear(ac);
         free(ac);
      }
+
+   // _elm_access_edje_object_part_object_register(); set below object data
+   evas_object_data_del(obj, "_part_access_obj");
 }
 
 static void
@@ -506,6 +509,11 @@ _elm_access_edje_object_part_object_register(Evas_Object* obj,
 
    if (!obj || !po) return NULL;
 
+   // check previous access object
+   ao = evas_object_data_get(po, "_part_access_obj");
+   if (ao)
+     _elm_access_edje_object_part_object_unregister(obj, eobj, part);
+
    // create access object
    ao = _elm_access_add(obj);
    evas_object_event_callback_add(po, EVAS_CALLBACK_RESIZE,
@@ -528,10 +536,44 @@ _elm_access_edje_object_part_object_register(Evas_Object* obj,
    _elm_access_callback_set(_elm_access_object_get(ao),
                             ELM_ACCESS_INFO,
                             _part_access_info_cb, eobj);
+
+   // set access object
+   evas_object_data_set(po, "_part_access_obj", ao);
+
    return ao;
 }
 
 EAPI void
+_elm_access_edje_object_part_object_unregister(Evas_Object* obj,
+                                               const Evas_Object *eobj,
+                                               const char* part)
+{
+   Evas_Object *ao;
+   Evas_Object *po = (Evas_Object *)edje_object_part_object_get(eobj, part);
+
+   if (!obj || !po) return;
+
+   ao = evas_object_data_get(po, "_part_access_obj");
+   if (!ao) return;
+
+   evas_object_data_del(po, "_part_access_obj");
+
+   // delete callbacks
+   evas_object_event_callback_del_full(po, EVAS_CALLBACK_RESIZE,
+                                       _content_resize, ao);
+   evas_object_event_callback_del_full(po, EVAS_CALLBACK_MOVE,
+                                       _content_move, ao);
+
+   evas_object_event_callback_del_full(po, EVAS_CALLBACK_MOUSE_IN,
+                                      _access_obj_mouse_in_cb, ao);
+   evas_object_event_callback_del_full(po, EVAS_CALLBACK_MOUSE_OUT,
+                                      _access_obj_mouse_out_cb, ao);
+   evas_object_event_callback_del_full(po, EVAS_CALLBACK_DEL,
+                                       _access_obj_del_cb, ao);
+   evas_object_del(ao);
+}
+
+EAPI void
 _elm_access_object_hilight_disable(Evas *e)
 {
    Evas_Object *o, *ptarget;
index ff38a4f..a33c098 100644 (file)
@@ -194,6 +194,97 @@ _set_month_year(Elm_Calendar_Smart_Data *sd)
    else elm_layout_text_set(ELM_WIDGET_DATA(sd)->obj, "month_text", "");
 }
 
+static char *
+_access_info_cb(void *data __UNUSED__,
+                Evas_Object *obj,
+                Elm_Widget_Item *item __UNUSED__)
+{
+   char *ret;
+   Eina_Strbuf *buf;
+   buf = eina_strbuf_new();
+
+   eina_strbuf_append_printf(buf, "day %s", elm_widget_access_info_get(obj));
+
+   ret = eina_strbuf_string_steal(buf);
+   eina_strbuf_free(buf);
+   return ret;
+}
+
+static void
+_access_calendar_item_register(Evas_Object *obj)
+{
+   int maxdays, day, i;
+   char day_s[3], pname[14];
+   Evas_Object *ao;
+
+   ELM_CALENDAR_DATA_GET(obj, sd);
+
+   day = 0;
+   maxdays = _maxdays_get(&sd->shown_time);
+   for (i = 0; i < 42; i++)
+     {
+        if ((!day) && (i == sd->first_day_it)) day = 1;
+        if ((day) && (day <= maxdays))
+          {
+             snprintf(pname, sizeof(pname), "cit_%i.access", i);
+
+             ao = _elm_access_edje_object_part_object_register
+                        (obj, elm_layout_edje_get(obj), pname);
+             _elm_access_text_set(_elm_access_object_get(ao),
+                         ELM_ACCESS_TYPE, E_("calendar item"));
+             _elm_access_callback_set(_elm_access_object_get(ao),
+                           ELM_ACCESS_INFO, _access_info_cb, NULL);
+
+             snprintf(day_s, sizeof(day_s), "%i", day++);
+             elm_widget_access_info_set(ao, (const char*)day_s);
+          }
+        else
+          {
+             snprintf(pname, sizeof(pname), "cit_%i.access", i);
+             _elm_access_edje_object_part_object_unregister
+                     (obj, elm_layout_edje_get(obj), pname);
+          }
+     }
+}
+
+static void
+_access_calendar_spinner_register(Evas_Object *obj)
+{
+   Evas_Object *po;
+   Elm_Access_Info *ai;
+   ELM_CALENDAR_DATA_GET(obj, sd);
+
+   // decrement button
+   sd->dec_btn_access = _elm_access_edje_object_part_object_register
+                            (obj, elm_layout_edje_get(obj), "left_bt");
+   ai = _elm_access_object_get(sd->dec_btn_access);
+   _elm_access_text_set(ai, ELM_ACCESS_TYPE, E_("calendar decrement button"));
+
+   // increment button
+   sd->inc_btn_access = _elm_access_edje_object_part_object_register
+                            (obj, elm_layout_edje_get(obj), "right_bt");
+   ai = _elm_access_object_get(sd->inc_btn_access);
+   _elm_access_text_set(ai, ELM_ACCESS_TYPE, E_("calendar increment button"));
+
+   // month text
+   sd->month_access = _elm_access_edje_object_part_object_register
+                          (obj, elm_layout_edje_get(obj), "month_text");
+   ai = _elm_access_object_get(sd->month_access);
+   _elm_access_text_set(ai, ELM_ACCESS_TYPE, E_("calendar month"));
+
+   po = (Evas_Object *)edje_object_part_object_get
+          (elm_layout_edje_get(obj), "month_text");
+   evas_object_pass_events_set(po, EINA_FALSE);
+
+}
+
+static void
+_access_calendar_register(Evas_Object *obj)
+{
+   _access_calendar_spinner_register(obj);
+   _access_calendar_item_register(obj);
+}
+
 static void
 _populate(Evas_Object *obj)
 {
@@ -310,6 +401,10 @@ _populate(Evas_Object *obj)
         _cit_mark(obj, i, "clear");
      }
 
+   // ACCESS
+   if ((_elm_config->access_mode != ELM_ACCESS_MODE_OFF))
+     _access_calendar_item_register(obj);
+
    /* Set marks */
    EINA_LIST_FOREACH (sd->marks, l, mark)
      {
@@ -757,6 +852,10 @@ _elm_calendar_smart_add(Evas_Object *obj)
 
    elm_layout_theme_set(obj, "calendar", "base", elm_object_style_get(obj));
    evas_object_smart_changed(obj);
+
+   // ACCESS
+   if ((_elm_config->access_mode != ELM_ACCESS_MODE_OFF))
+      _access_calendar_spinner_register(obj);
 }
 
 static void
@@ -783,6 +882,96 @@ _elm_calendar_smart_del(Evas_Object *obj)
    ELM_WIDGET_CLASS(_elm_calendar_parent_sc)->base.del(obj);
 }
 
+static Eina_Bool
+_elm_calendar_smart_focus_next(const Evas_Object *obj,
+                               Elm_Focus_Direction dir,
+                               Evas_Object **next)
+{
+   int maxdays, day, i;
+   Eina_List *items = NULL;
+   Evas_Object *ao;
+   Evas_Object *po;
+
+   ELM_CALENDAR_CHECK(obj) EINA_FALSE;
+   ELM_CALENDAR_DATA_GET(obj, sd);
+
+   items = eina_list_append(items, sd->month_access);
+   items = eina_list_append(items, sd->dec_btn_access);
+   items = eina_list_append(items, sd->inc_btn_access);
+
+   day = 0;
+   maxdays = _maxdays_get(&sd->shown_time);
+   for (i = 0; i < 42; i++)
+     {
+        if ((!day) && (i == sd->first_day_it)) day = 1;
+        if ((day) && (day <= maxdays))
+          {
+             char pname[14];
+             snprintf(pname, sizeof(pname), "cit_%i.access", i);
+
+             po = (Evas_Object *)edje_object_part_object_get
+                           (elm_layout_edje_get(obj), pname);
+             ao = evas_object_data_get(po, "_part_access_obj");
+             items = eina_list_append(items, ao);
+          }
+     }
+
+   return elm_widget_focus_list_next_get
+            (obj, items, eina_list_data_get, dir, next);
+}
+
+static void
+_access_obj_process(Evas_Object *obj, Eina_Bool is_access)
+{
+   int maxdays, day, i;
+
+   ELM_CALENDAR_DATA_GET(obj, sd);
+
+   if (is_access)
+     _access_calendar_register(obj);
+   else
+     {
+        day = 0;
+        maxdays = _maxdays_get(&sd->shown_time);
+        for (i = 0; i < 42; i++)
+          {
+             if ((!day) && (i == sd->first_day_it)) day = 1;
+             if ((day) && (day <= maxdays))
+               {
+                  char pname[14];
+                  snprintf(pname, sizeof(pname), "cit_%i.access", i);
+
+                  _elm_access_edje_object_part_object_unregister
+                          (obj, elm_layout_edje_get(obj), pname);
+               }
+          }
+
+        if (sd->dec_btn_access)
+          _elm_access_edje_object_part_object_unregister
+            (obj, elm_layout_edje_get(obj), "left_bt");
+        if (sd->inc_btn_access)
+          _elm_access_edje_object_part_object_unregister
+            (obj, elm_layout_edje_get(obj), "right_bt");
+        if (sd->month_access)
+          _elm_access_edje_object_part_object_unregister
+            (obj, elm_layout_edje_get(obj), "month_text");
+     }
+}
+
+static void
+_access_hook(Evas_Object *obj, Eina_Bool is_access)
+{
+   ELM_CALENDAR_CHECK(obj);
+   ELM_CALENDAR_DATA_GET(obj, sd);
+
+   if (is_access)
+     ELM_WIDGET_CLASS(ELM_WIDGET_DATA(sd)->api)->focus_next =
+     _elm_calendar_smart_focus_next;
+   else
+     ELM_WIDGET_CLASS(ELM_WIDGET_DATA(sd)->api)->focus_next = NULL;
+   _access_obj_process(obj, is_access);
+}
+
 static void
 _elm_calendar_smart_set_user(Elm_Calendar_Smart_Class *sc)
 {
@@ -798,6 +987,12 @@ _elm_calendar_smart_set_user(Elm_Calendar_Smart_Class *sc)
    ELM_WIDGET_CLASS(sc)->focus_direction = NULL;
 
    ELM_LAYOUT_CLASS(sc)->sizing_eval = _elm_calendar_smart_sizing_eval;
+
+   // ACCESS
+   if (_elm_config->access_mode != ELM_ACCESS_MODE_OFF)
+     ELM_WIDGET_CLASS(sc)->focus_next = _elm_calendar_smart_focus_next;
+
+   ELM_WIDGET_CLASS(sc)->access = _access_hook;
 }
 
 EAPI const Elm_Calendar_Smart_Class *
index f49c419..5dcebdf 100644 (file)
@@ -547,6 +547,7 @@ typedef Eina_Bool             (*Elm_Widget_Del_Pre_Cb)(void *data);
 
 typedef char *(*Elm_Access_Content_Cb)(void *data, Evas_Object *obj, Elm_Widget_Item *item);
 typedef void (*Elm_Access_On_Highlight_Cb)(void *data);
+typedef void (*Elm_Access_Activate_Cb)(Evas_Object *obj, void *data);
 
 struct _Elm_Access_Item
 {
@@ -562,6 +563,8 @@ struct _Elm_Access_Info
    Ecore_Timer               *delay_timer;
    void                      *on_highlight_data;
    Elm_Access_On_Highlight_Cb on_highlight;
+   void                      *activate_data;
+   Elm_Access_Activate_Cb     activate;
 };
 
 EAPI void             _elm_access_clear(Elm_Access_Info *ac);
@@ -581,6 +584,7 @@ EAPI void             _elm_access_item_register(Elm_Widget_Item *item, Evas_Obje
 EAPI Eina_Bool        _elm_access_2nd_click_timeout(Evas_Object *obj);
 EAPI void             _elm_access_highlight_set(Evas_Object* obj);
 EAPI Evas_Object *    _elm_access_edje_object_part_object_register(Evas_Object *obj, const Evas_Object *partobj, const char* part);
+EAPI void             _elm_access_edje_object_part_object_unregister(Evas_Object* obj, const Evas_Object *eobj, const char* part);
 EAPI void             _elm_access_widget_item_register(Elm_Widget_Item *item);
 EAPI void             _elm_access_widget_item_unregister(Elm_Widget_Item *item);
 EAPI void             _elm_access_on_highlight_hook_set(Elm_Access_Info *ac, Elm_Access_On_Highlight_Cb func, void *data);
index ba7e507..a6fe78e 100644 (file)
@@ -142,6 +142,9 @@ struct _Elm_Calendar_Smart_Data
    struct tm                current_time, selected_time, shown_time;
    Day_Color                day_color[42]; // EINA_DEPRECATED
    Elm_Calendar_Select_Mode select_mode;
+   Evas_Object             *inc_btn_access;
+   Evas_Object             *dec_btn_access;
+   Evas_Object             *month_access;
    Eina_Bool                selected : 1;
    Elm_Calendar_Selectable  selectable;
 };