[*]Un-Rollback to 'Merge [elm_multibuttonentry]Changed edc TEXT part to TEXTBLOCK...
[framework/uifw/elementary.git] / src / lib / elm_widget.c
index 97d71aa..0a61b9c 100644 (file)
@@ -10,6 +10,12 @@ static const char SMART_NAME[] = "elm_widget";
   Smart_Data * sd = evas_object_smart_data_get(obj); \
   if (!sd) return;
 
+#undef elm_widget_text_set_hook_set
+#undef elm_widget_text_get_hook_set
+#undef elm_widget_content_set_hook_set
+#undef elm_widget_content_get_hook_set
+#undef elm_widget_content_unset_hook_set
+
 typedef struct _Smart_Data        Smart_Data;
 typedef struct _Edje_Signal_Data  Edje_Signal_Data;
 typedef struct _Elm_Event_Cb_Data Elm_Event_Cb_Data;
@@ -70,6 +76,11 @@ struct _Smart_Data
                                       Evas_Coord        *y,
                                       Evas_Coord        *w,
                                       Evas_Coord        *h);
+   Elm_Widget_On_Text_Set_Cb on_text_set_func;
+   Elm_Widget_On_Text_Get_Cb on_text_get_func;
+   Elm_Widget_On_Content_Set_Cb on_content_set_func;
+   Elm_Widget_On_Content_Get_Cb on_content_get_func;
+   Elm_Widget_On_Content_Unset_Cb on_content_unset_func;
    void        *data;
    Evas_Coord   rx, ry, rw, rh;
    int          scroll_hold;
@@ -91,6 +102,8 @@ struct _Smart_Data
    Eina_Bool    can_focus : 1;
    Eina_Bool    child_can_focus : 1;
    Eina_Bool    focused : 1;
+   Eina_Bool    top_win_focused : 1;
+   Eina_Bool    tree_unfocusable : 1;
    Eina_Bool    highlight_ignore : 1;
    Eina_Bool    highlight_in_theme : 1;
    Eina_Bool    disabled : 1;
@@ -215,7 +228,7 @@ _sub_obj_hide(void        *data __UNUSED__,
               Evas_Object *obj,
               void        *event_info __UNUSED__)
 {
-   _if_focused_revert(obj, EINA_TRUE);
+   elm_widget_focus_hide_handle(obj);
 }
 
 static void
@@ -224,16 +237,7 @@ _sub_obj_mouse_down(void        *data __UNUSED__,
                     Evas_Object *obj,
                     void        *event_info __UNUSED__)
 {
-   Evas_Object *o = obj;
-   do
-     {
-        if (_elm_widget_is(o)) break;
-        o = evas_object_smart_parent_get(o);
-     }
-   while (o);
-   if (!o) return;
-   if (!_is_focusable(o)) return;
-   elm_widget_focus_steal(o);
+   elm_widget_focus_mouse_down_handle(obj);
 }
 
 static void
@@ -312,23 +316,12 @@ static void
 _parent_focus(Evas_Object *obj)
 {
    API_ENTRY return;
+   if (sd->focused) return;
 
    Evas_Object *o = elm_widget_parent_get(obj);
    sd->focus_order_on_calc = EINA_TRUE;
 
-   if (sd->focused) return;
-   if (o)
-     {
-        unsigned int i = 0;
-        Evas_Object *ret;
-
-        ret = _newest_focus_order_get(o, &i, EINA_TRUE);
-
-        /* we don't want to bump a common widget ancestor's
-           focus_order *twice* while parent focusing */
-        if (!ret || (!i) || (i != focus_order))
-          _parent_focus(o);
-     }
+   if (o) _parent_focus(o);
 
    if (!sd->focus_order_on_calc)
      return; /* we don't want to override it if by means of any of the
@@ -337,12 +330,13 @@ _parent_focus(Evas_Object *obj)
 
    focus_order++;
    sd->focus_order = focus_order;
-   sd->focused = EINA_TRUE;
-   if (sd->on_focus_func) sd->on_focus_func(sd->on_focus_data, obj);
-   if (sd->focus_func) sd->focus_func(obj);
-
-   _elm_widget_focus_region_show(obj);
-
+   if (sd->top_win_focused)
+     {
+        sd->focused = EINA_TRUE;
+        if (sd->on_focus_func) sd->on_focus_func(sd->on_focus_data, obj);
+        if (sd->focus_func) sd->focus_func(obj);
+        _elm_widget_focus_region_show(obj);
+     }
    sd->focus_order_on_calc = EINA_FALSE;
 }
 
@@ -417,6 +411,18 @@ elm_widget_type_register(const char **ptr)
    widtypes = eina_list_append(widtypes, (void *)ptr);
 }
 
+/**
+ * @defgroup Widget Widget
+ *
+ * @internal
+ * Disposed api for making widgets
+ */
+EAPI void
+elm_widget_type_unregister(const char **ptr)
+{
+   widtypes = eina_list_remove(widtypes, (void *)ptr);
+}
+
 EAPI Eina_Bool
 elm_widget_api_check(int ver)
 {
@@ -498,6 +504,46 @@ elm_widget_event_hook_set(Evas_Object *obj,
 }
 
 EAPI void
+elm_widget_text_set_hook_set(Evas_Object *obj,
+                             Elm_Widget_On_Text_Set_Cb func)
+{
+   API_ENTRY return;
+   sd->on_text_set_func = func;
+}
+
+EAPI void
+elm_widget_text_get_hook_set(Evas_Object *obj,
+                             Elm_Widget_On_Text_Get_Cb func)
+{
+   API_ENTRY return;
+   sd->on_text_get_func = func;
+}
+
+EAPI void
+elm_widget_content_set_hook_set(Evas_Object *obj,
+                                Elm_Widget_On_Content_Set_Cb func)
+{
+   API_ENTRY return;
+   sd->on_content_set_func = func;
+}
+
+EAPI void
+elm_widget_content_get_hook_set(Evas_Object *obj,
+                                Elm_Widget_On_Content_Get_Cb func)
+{
+   API_ENTRY return;
+   sd->on_content_get_func = func;
+}
+
+EAPI void
+elm_widget_content_unset_hook_set(Evas_Object *obj,
+                                  Elm_Widget_On_Content_Unset_Cb func)
+{
+   API_ENTRY return;
+   sd->on_content_unset_func = func;
+}
+
+EAPI void
 elm_widget_changed_hook_set(Evas_Object *obj,
                             void       (*func)(Evas_Object *obj))
 {
@@ -825,6 +871,7 @@ elm_widget_sub_object_add(Evas_Object *obj,
              if (sd2->parent_obj)
                elm_widget_sub_object_del(sd2->parent_obj, sobj);
              sd2->parent_obj = obj;
+             sd2->top_win_focused = sd->top_win_focused;
              if (!sd->child_can_focus && (_is_focusable(sobj)))
                sd->child_can_focus = EINA_TRUE;
           }
@@ -875,10 +922,6 @@ elm_widget_sub_object_del(Evas_Object *obj,
           }
         if (abort_on_warn == 1) abort();
      }
-   if (!sd->child_can_focus)
-     {
-        if (_is_focusable(sobj)) sd->child_can_focus = 0;
-     }
    if (_elm_widget_is(sobj))
      {
         Smart_Data *sd2 = evas_object_smart_data_get(sobj);
@@ -893,6 +936,20 @@ elm_widget_sub_object_del(Evas_Object *obj,
         else
           sd->subobjs = eina_list_remove(sd->subobjs, sobj);
         if (elm_widget_focus_get(sobj)) _unfocus_parents(obj);
+        if ((sd->child_can_focus) && (_is_focusable(sobj)))
+          {
+             Evas_Object *subobj;
+             const Eina_List *l;
+             sd->child_can_focus = EINA_FALSE;
+             EINA_LIST_FOREACH(sd->subobjs, l, subobj)
+               {
+                  if (_is_focusable(subobj))
+                    {
+                       sd->child_can_focus = EINA_TRUE;
+                       break;
+                    }
+               }
+          }
      }
    else
      sd->subobjs = eina_list_remove(sd->subobjs, sobj);
@@ -959,7 +1016,11 @@ elm_widget_resize_object_set(Evas_Object *obj,
         if (_elm_widget_is(sd->resize_obj))
           {
              Smart_Data *sd2 = evas_object_smart_data_get(sd->resize_obj);
-             if (sd2) sd2->parent_obj = obj;
+             if (sd2)
+               {
+                  sd2->parent_obj = obj;
+                  sd2->top_win_focused = sd->top_win_focused;
+               }
              evas_object_event_callback_add(sobj, EVAS_CALLBACK_HIDE,
                                             _sub_obj_hide, sd);
           }
@@ -1041,6 +1102,49 @@ elm_widget_child_can_focus_get(const Evas_Object *obj)
    return sd->child_can_focus;
 }
 
+/**
+ * @internal
+ *
+ * This API makes the widget object and its children to be unfocusable.
+ *
+ * This API can be helpful for an object to be deleted.
+ * When an object will be deleted soon, it and its children may not
+ * want to get focus (by focus reverting or by other focus controls).
+ * Then, just use this API before deleting.
+ *
+ * @param obj The widget root of sub-tree
+ * @param tree_unfocusable If true, set the object sub-tree as unfocusable
+ *
+ * @ingroup Widget
+ */
+EAPI void
+elm_widget_tree_unfocusable_set(Evas_Object *obj,
+                                Eina_Bool    tree_unfocusable)
+{
+   API_ENTRY return;
+
+   if (sd->tree_unfocusable == tree_unfocusable) return;
+   sd->tree_unfocusable = !!tree_unfocusable;
+   elm_widget_focus_tree_unfocusable_handle(obj);
+}
+
+/**
+ * @internal
+ *
+ * This returns true, if the object sub-tree is unfocusable.
+ *
+ * @param obj The widget root of sub-tree
+ * @return EINA_TRUE if the object sub-tree is unfocusable
+ *
+ * @ingroup Widget
+ */
+EAPI Eina_Bool
+elm_widget_tree_unfocusable_get(const Evas_Object *obj)
+{
+   API_ENTRY return EINA_FALSE;
+   return sd->tree_unfocusable;
+}
+
 EAPI void
 elm_widget_highlight_ignore_set(Evas_Object *obj,
                                 Eina_Bool    ignore)
@@ -1431,7 +1535,9 @@ elm_widget_focus_next_get(const Evas_Object  *obj,
    API_ENTRY return EINA_FALSE;
 
    /* Ignore if disabled */
-   if ((!evas_object_visible_get(obj)) || (elm_widget_disabled_get(obj)))
+   if ((!evas_object_visible_get(obj))
+       || (elm_widget_disabled_get(obj))
+       || (elm_widget_tree_unfocusable_get(obj)))
      return EINA_FALSE;
 
    /* Try use hook */
@@ -1731,12 +1837,15 @@ elm_widget_focus_steal(Evas_Object *obj)
 
    if (sd->focused) return;
    if (sd->disabled) return;
+   if (!sd->can_focus) return;
+   if (sd->tree_unfocusable) return;
    parent = obj;
    for (;;)
      {
         o = elm_widget_parent_get(parent);
         if (!o) break;
         sd = evas_object_smart_data_get(o);
+        if (sd->disabled || sd->tree_unfocusable) return;
         if (sd->focused) break;
         parent = o;
      }
@@ -1767,6 +1876,45 @@ elm_widget_focus_steal(Evas_Object *obj)
 }
 
 EAPI void
+elm_widget_focus_restore(Evas_Object *obj)
+{
+   Evas_Object *newest = NULL;
+   unsigned int newest_focus_order = 0;
+   API_ENTRY return;
+
+   newest = _newest_focus_order_get(obj, &newest_focus_order, EINA_TRUE);
+   if (newest)
+     {
+        elm_object_unfocus(newest);
+        elm_object_focus(newest);
+     }
+}
+
+void
+_elm_widget_top_win_focused_set(Evas_Object *obj, Eina_Bool top_win_focused)
+{
+   const Eina_List *l;
+   Evas_Object *child;
+   API_ENTRY return;
+
+   if (sd->top_win_focused == top_win_focused) return;
+   if (sd->resize_obj)
+     _elm_widget_top_win_focused_set(sd->resize_obj, top_win_focused);
+   EINA_LIST_FOREACH(sd->subobjs, l, child)
+     {
+        _elm_widget_top_win_focused_set(child, top_win_focused);
+     }
+   sd->top_win_focused = top_win_focused;
+}
+
+Eina_Bool
+_elm_widget_top_win_focused_get(const Evas_Object *obj)
+{
+   API_ENTRY return EINA_FALSE;
+   return sd->top_win_focused;
+}
+
+EAPI void
 elm_widget_activate(Evas_Object *obj)
 {
    API_ENTRY return;
@@ -1784,30 +1932,17 @@ elm_widget_change(Evas_Object *obj)
 
 EAPI void
 elm_widget_disabled_set(Evas_Object *obj,
-                        int          disabled)
+                        Eina_Bool    disabled)
 {
    API_ENTRY return;
 
    if (sd->disabled == disabled) return;
-   sd->disabled = disabled;
-   if (sd->focused)
-     {
-        Evas_Object *o, *parent;
-
-        parent = obj;
-        for (;;)
-          {
-             o = elm_widget_parent_get(parent);
-             if (!o) break;
-             parent = o;
-          }
-        if (elm_widget_focus_get(obj))
-          elm_widget_focus_cycle(parent, ELM_FOCUS_NEXT);
-     }
+   sd->disabled = !!disabled;
+   elm_widget_focus_disabled_handle(obj);
    if (sd->disable_func) sd->disable_func(obj);
 }
 
-EAPI int
+EAPI Eina_Bool
 elm_widget_disabled_get(const Evas_Object *obj)
 {
    API_ENTRY return 0;
@@ -1819,13 +1954,15 @@ elm_widget_show_region_set(Evas_Object *obj,
                            Evas_Coord   x,
                            Evas_Coord   y,
                            Evas_Coord   w,
-                           Evas_Coord   h)
+                           Evas_Coord   h,
+                           Eina_Bool    forceshow)
 {
    Evas_Object *parent_obj, *child_obj;
    Evas_Coord px, py, cx, cy;
 
    API_ENTRY return;
-   if ((x == sd->rx) && (y == sd->ry) && (w == sd->rw) && (h == sd->rh)) return;
+   if (!forceshow && (x == sd->rx) && (y == sd->ry)
+            && (w == sd->rw) && (h == sd->rh)) return;
    sd->rx = x;
    sd->ry = y;
    sd->rw = w;
@@ -2015,6 +2152,55 @@ elm_widget_theme_set(Evas_Object *obj,
      }
 }
 
+EAPI void
+elm_widget_text_part_set(Evas_Object *obj, const char *item, const char *label)
+{
+   API_ENTRY return;
+
+   if (!sd->on_text_set_func)
+     return;
+
+   sd->on_text_set_func(obj, item, label);
+}
+
+EAPI const char *
+elm_widget_text_part_get(const Evas_Object *obj, const char *item)
+{
+   API_ENTRY return NULL;
+
+   if (!sd->on_text_get_func)
+     return NULL;
+
+   return sd->on_text_get_func(obj, item);
+}
+
+EAPI void
+elm_widget_content_part_set(Evas_Object *obj, const char *part, Evas_Object *content)
+{
+   API_ENTRY return;
+
+   if (!sd->on_content_set_func)  return;
+   sd->on_content_set_func(obj, part, content);
+}
+
+EAPI Evas_Object *
+elm_widget_content_part_get(const Evas_Object *obj, const char *part)
+{
+   API_ENTRY return NULL;
+
+   if (!sd->on_content_get_func) return NULL;
+   return sd->on_content_get_func(obj, part);
+}
+
+EAPI Evas_Object *
+elm_widget_content_part_unset(Evas_Object *obj, const char *part)
+{
+   API_ENTRY return NULL;
+
+   if (!sd->on_content_unset_func) return NULL;
+   return sd->on_content_unset_func(obj, part);
+}
+
 EAPI Elm_Theme *
 elm_widget_theme_get(const Evas_Object *obj)
 {
@@ -2224,6 +2410,46 @@ elm_widget_stringlist_free(Eina_List *list)
    EINA_LIST_FREE(list, s) eina_stringshare_del(s);
 }
 
+EAPI void
+elm_widget_focus_hide_handle(Evas_Object *obj)
+{
+   _if_focused_revert(obj, EINA_TRUE);
+}
+
+EAPI void
+elm_widget_focus_mouse_down_handle(Evas_Object *obj)
+{
+   Evas_Object *o = obj;
+   do
+     {
+        if (_elm_widget_is(o)) break;
+        o = evas_object_smart_parent_get(o);
+     }
+   while (o);
+   if (!o) return;
+   if (!_is_focusable(o)) return;
+   elm_widget_focus_steal(o);
+}
+
+EAPI void
+elm_widget_focus_tree_unfocusable_handle(Evas_Object *obj)
+{
+   API_ENTRY return;
+
+   if (!elm_widget_parent_get(obj))
+     elm_widget_focused_object_clear(obj);
+   else
+     _if_focused_revert(obj, EINA_TRUE);
+}
+
+EAPI void
+elm_widget_focus_disabled_handle(Evas_Object *obj)
+{
+   API_ENTRY return;
+
+   elm_widget_focus_tree_unfocusable_handle(obj);
+}
+
 /**
  * @internal
  *
@@ -2408,7 +2634,7 @@ _elm_widget_item_tooltip_label_create(void        *data,
    if (!label)
      return NULL;
    elm_object_style_set(label, "tooltip");
-   elm_label_label_set(label, data);
+   elm_object_text_set(label, data);
    return label;
 }
 
@@ -2704,6 +2930,93 @@ _smart_reconfigure(Smart_Data *sd)
      }
 }
 
+EAPI void
+_elm_widget_item_content_part_set(Elm_Widget_Item *item,
+                                 const char *part,
+                                 Evas_Object *content)
+{
+   ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
+   if (!item->on_content_set_func) return;
+   item->on_content_set_func((Elm_Object_Item *) item, part, content);
+}
+
+EAPI Evas_Object *
+_elm_widget_item_content_part_get(const Elm_Widget_Item *item,
+                                  const char *part)
+{
+   ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
+   if (!item->on_content_get_func) return NULL;
+   return item->on_content_get_func((Elm_Object_Item *) item, part);
+}
+
+EAPI Evas_Object *
+_elm_widget_item_content_part_unset(Elm_Widget_Item *item,
+                                    const char *part)
+{
+   ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
+   if (!item->on_content_unset_func) return NULL;
+   return item->on_content_unset_func((Elm_Object_Item *) item, part);
+}
+
+EAPI void
+_elm_widget_item_text_part_set(Elm_Widget_Item *item,
+                              const char *part,
+                              const char *label)
+{
+   ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
+   if (!item->on_text_set_func) return;
+   item->on_text_set_func((Elm_Object_Item *) item, part, label);
+}
+
+EAPI const char *
+_elm_widget_item_text_part_get(const Elm_Widget_Item *item,
+                               const char *part)
+{
+   ELM_WIDGET_ITEM_CHECK_OR_RETURN(item, NULL);
+   if (!item->on_text_get_func) return NULL;
+   return item->on_text_get_func((Elm_Object_Item *) item, part);
+}
+
+EAPI void
+_elm_widget_item_content_set_hook_set(Elm_Widget_Item *item,
+                                      Elm_Widget_On_Content_Set_Cb func)
+{
+   ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
+   item->on_content_set_func = func;
+}
+
+EAPI void
+_elm_widget_item_content_get_hook_set(Elm_Widget_Item *item,
+                                      Elm_Widget_On_Content_Get_Cb func)
+{
+   ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
+   item->on_content_get_func = func;
+}
+
+EAPI void
+_elm_widget_item_content_unset_hook_set(Elm_Widget_Item *item,
+                                        Elm_Widget_On_Content_Unset_Cb func)
+{
+   ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
+   item->on_content_unset_func = func;
+}
+
+EAPI void
+_elm_widget_item_text_set_hook_set(Elm_Widget_Item *item,
+                                   Elm_Widget_On_Text_Set_Cb func)
+{
+   ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
+   item->on_text_set_func = func;
+}
+
+EAPI void
+_elm_widget_item_text_get_hook_set(Elm_Widget_Item *item,
+                                   Elm_Widget_On_Text_Get_Cb func)
+{
+   ELM_WIDGET_ITEM_CHECK_OR_RETURN(item);
+   item->on_text_get_func = func;
+}
+
 static void
 _smart_add(Evas_Object *obj)
 {
@@ -2727,7 +3040,12 @@ _newest_focus_order_get(Evas_Object  *obj,
    Evas_Object *child, *ret, *best;
 
    API_ENTRY return NULL;
-   if (!evas_object_visible_get(obj)) return NULL;
+
+   if (!evas_object_visible_get(obj)
+       || (elm_widget_disabled_get(obj))
+       || (elm_widget_tree_unfocusable_get(obj)))
+     return NULL;
+
    best = NULL;
    if (*newest_focus_order < sd->focus_order)
      {
@@ -2865,7 +3183,8 @@ _smart_hide(Evas_Object *obj)
    Eina_List *list;
    Evas_Object *o;
    INTERNAL_ENTRY
-     list = evas_object_smart_members_get(obj);
+
+   list = evas_object_smart_members_get(obj);
    EINA_LIST_FREE(list, o)
      {
         if (evas_object_data_get(o, "_elm_leaveme")) continue;
@@ -3069,4 +3388,4 @@ elm_widget_tree_dot_dump(const Evas_Object *top,
    (void)top;
    (void)output;
 #endif
-}
\ No newline at end of file
+}