[multibuttenentry] merged with opensource r75453.
[framework/uifw/elementary.git] / src / lib / elc_popup.c
index 3a9c314..18c6240 100644 (file)
@@ -98,6 +98,10 @@ static Evas_Object *_action_button_get(Evas_Object *obj, unsigned int idx);
 static Evas_Object *_action_button_unset(Evas_Object *obj, unsigned int idx);
 static void _button_remove(Evas_Object *obj, Evas_Object *content,
                            Eina_Bool delete);
+static void _popup_show(void *data, Evas *e, Evas_Object *obj,
+                        void *event_info);
+static void _popup_hide(void *data, Evas *e, Evas_Object *obj,
+                        void *event_info);
 static const char SIG_BLOCK_CLICKED[] = "block,clicked";
 static const char SIG_TIMEOUT[] = "timeout";
 static const Evas_Smart_Cb_Description _signals[] = {
@@ -147,6 +151,7 @@ _del_pre_hook(Evas_Object *obj)
    evas_object_smart_callback_del(wd->notify, "timeout", _timeout);
    evas_object_event_callback_del(wd->notify, EVAS_CALLBACK_RESIZE,
                                   _notify_resize);
+   evas_object_event_callback_del(obj, EVAS_CALLBACK_SHOW, _popup_show);
    wd->button_count = 0;
    for (i = 0; i < ELM_POPUP_ACTION_BUTTON_MAX; i++)
      if (wd->buttons[i])
@@ -173,8 +178,6 @@ _theme_hook(Evas_Object *obj)
 
    if (!wd) return;
    elm_layout_theme_set(wd->base, "popup", "base", elm_widget_style_get(obj));
-   elm_widget_scale_set(wd->base, elm_widget_scale_get(obj) *
-                        _elm_config->scale);
    _elm_widget_mirrored_reload(obj);
    _mirrored_set(obj, elm_widget_mirrored_get(obj));
    if (wd->button_count)
@@ -203,8 +206,8 @@ _theme_hook(Evas_Object *obj)
                                    "item", elm_widget_style_get(obj));
              if (item->label)
                {
-                  edje_object_part_text_set(VIEW(item), "elm.text",
-                                            item->label);
+                  edje_object_part_text_escaped_set(VIEW(item), "elm.text",
+                                                    item->label);
                   edje_object_signal_emit(VIEW(item),
                                           "elm,state,item,text,visible", "elm");
                }
@@ -251,6 +254,7 @@ _sizing_eval(Evas_Object *obj)
    Evas_Coord minw_box = 0, minh_box = 0;
    Evas_Coord minw = -1, minh = -1, maxw = -1, maxh = -1;
    Widget_Data *wd = elm_widget_data_get(obj);
+   Evas_Coord bx, by, bw, bh;
 
    if (!wd) return;
    if (wd->items)
@@ -276,6 +280,11 @@ _sizing_eval(Evas_Object *obj)
    evas_object_size_hint_min_set(obj, minw, minh);
    evas_object_size_hint_max_set(obj, maxw, maxh);
    elm_layout_sizing_eval(wd->base);
+
+   // hack hack hack. this widget needs a ... redo.
+   evas_object_geometry_get(wd->base, &bx, &by, &bw, &bh);
+   evas_object_resize(obj, bw, bh);
+   evas_object_move(obj, bx, by);
 }
 
 static void
@@ -497,7 +506,7 @@ _scroller_size_calc(Evas_Object *obj)
         action_area_height = edje_object_data_get(
                  elm_layout_edje_get(wd->action_area), "action_area_height");
         if (action_area_height) h_action_area = (int)(atoi(action_area_height)
-                 * elm_scale_get()* elm_object_scale_get(obj));
+                 * _elm_config->scale * elm_object_scale_get(obj));
      }
    h_content = h - (h_title + h_action_area);
    wd->max_sc_h = h_content;
@@ -511,7 +520,7 @@ _item_select_cb(void *data, Evas_Object *obj __UNUSED__,
 
    if (!item || item->disabled) return;
    if (item->func)
-     item->func((void*) item->base.data, WIDGET(item), data);
+     item->func((void*)item->base.data, WIDGET(item), data);
 }
 
 static void
@@ -701,11 +710,8 @@ _title_icon_set(Evas_Object *obj, Evas_Object *icon)
    if (!wd) return;
    if (wd->title_icon == icon) return;
    title_visibility_old = (wd->title_text) || (wd->title_icon);
-   if (wd->title_icon)
-     {
-        evas_object_del(wd->title_icon);
-        wd->title_icon = NULL;
-     }
+   if (wd->title_icon) evas_object_del(wd->title_icon);
+
    wd->title_icon = icon;
    title_visibility_current = (wd->title_text) || (wd->title_icon);
    elm_object_part_content_set(wd->base, "elm.swallow.title.icon",
@@ -742,6 +748,7 @@ _content_set(Evas_Object *obj, Evas_Object *content)
                                     wd->content_area);
         elm_object_part_content_set(wd->content_area, "elm.swallow.content",
                                     content);
+        evas_object_show(content);
      }
    _sizing_eval(obj);
 }
@@ -781,11 +788,14 @@ _button_remove(Evas_Object *obj, Evas_Object *content, Eina_Bool delete)
        elm_object_part_content_unset(wd->action_area, buf);
        elm_object_part_content_set(wd->action_area, buf,
                                    wd->buttons[i]->btn);
+       evas_object_show(wd->buttons[i]->btn);
        wd->buttons[i]->delete_me = EINA_TRUE;
     }
    if (!wd->button_count)
     {
        _layout_set(obj);
+       elm_object_part_content_unset(wd->base, "elm.swallow.action_area");
+       evas_object_hide(wd->action_area);
        edje_object_message_signal_process(elm_layout_edje_get(wd->base));
     }
    else
@@ -801,13 +811,13 @@ _action_button_set(Evas_Object *obj, Evas_Object *btn, unsigned int idx)
 {
    Action_Area_Data *adata;
    char buf[128];
-   unsigned int index = idx - 1, i = 0, position = 0;
+   unsigned int num = idx - 1, i = 0, position = 0;
    Widget_Data *wd = elm_widget_data_get(obj);
 
    if (!wd) return;
-   if (index >= ELM_POPUP_ACTION_BUTTON_MAX) return;
-   if (wd->buttons[index])
-     _button_remove(obj, wd->buttons[index]->btn, EINA_TRUE);
+   if (num >= ELM_POPUP_ACTION_BUTTON_MAX) return;
+   if (wd->buttons[num])
+     _button_remove(obj, wd->buttons[num]->btn, EINA_TRUE);
    if (btn)
      {
         wd->button_count++;
@@ -817,7 +827,7 @@ _action_button_set(Evas_Object *obj, Evas_Object *btn, unsigned int idx)
         adata = ELM_NEW(Action_Area_Data);
         adata->obj = obj;
         adata->btn = btn;
-        wd->buttons[index] = adata;
+        wd->buttons[num] = adata;
         /* Adding delete_me state inside action data as unset calls _sub_del
            too and before setting a new content, the previous one needs to
            be unset in order to avoid unwanted deletion. This way rearrangement
@@ -834,6 +844,7 @@ _action_button_set(Evas_Object *obj, Evas_Object *btn, unsigned int idx)
              elm_object_part_content_unset(wd->action_area, buf);
              elm_object_part_content_set(wd->action_area, buf,
                                          wd->buttons[i]->btn);
+             evas_object_show(wd->buttons[i]->btn);
              /* Setting delete_me to TRUE in order to let _sub_del handle it
                 if deleted externally and update the buttons array after freeing
                 action data allocated earlier.
@@ -842,6 +853,7 @@ _action_button_set(Evas_Object *obj, Evas_Object *btn, unsigned int idx)
           }
         elm_object_part_content_set(wd->base, "elm.swallow.action_area",
                                     wd->action_area);
+        evas_object_show(wd->action_area);
         if (wd->button_count == 1)
           _layout_set(obj);
         edje_object_message_signal_process(wd->base);
@@ -905,13 +917,13 @@ _content_get(Evas_Object *obj)
 static Evas_Object *
 _action_button_get(Evas_Object *obj, unsigned int idx)
 {
-   unsigned int index = idx - 1;
+   unsigned int num = idx - 1;
    Evas_Object *button = NULL;
    Widget_Data *wd = elm_widget_data_get(obj);
 
    if (!wd || !wd->button_count) return NULL;
-   if (wd->buttons[index])
-     button = wd->buttons[index]->btn;
+   if (wd->buttons[num])
+     button = wd->buttons[num]->btn;
    return button;
 }
 
@@ -978,17 +990,17 @@ _title_icon_unset(Evas_Object *obj)
 static Evas_Object *
 _action_button_unset(Evas_Object *obj, unsigned int idx)
 {
-   unsigned int index = idx -1;
+   unsigned int num = idx -1;
    Evas_Object *button = NULL;
    Widget_Data *wd = elm_widget_data_get(obj);
 
    if (!wd) return NULL;
-   if ((!wd->button_count) || (index >= ELM_POPUP_ACTION_BUTTON_MAX))
+   if ((!wd->button_count) || (num >= ELM_POPUP_ACTION_BUTTON_MAX))
      return NULL;
 
-   if (wd->buttons[index])
+   if (wd->buttons[num])
      {
-        button = wd->buttons[index]->btn;
+        button = wd->buttons[num]->btn;
         _button_remove(obj, button, EINA_FALSE);
       }
    return button;
@@ -1027,18 +1039,22 @@ _content_unset_hook(Evas_Object *obj, const char *part)
 }
 
 static Eina_Bool
-_focus_next_hook(const Evas_Object *obj __UNUSED__,
-                 Elm_Focus_Direction dir __UNUSED__,
-                 Evas_Object **next __UNUSED__)
+_focus_next_hook(const Evas_Object *obj,
+                 Elm_Focus_Direction dir,
+                 Evas_Object **next)
 {
-   //TODO: Implement Focus chanin Handling in Popup for action area buttons
-   return EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd)
+     return EINA_FALSE;
+   return elm_widget_focus_next_get(wd->notify, dir, next);
 }
+
 static void
 _item_text_set(Elm_Popup_Content_Item *item, const char *label)
 {
    if (!eina_stringshare_replace(&item->label, label)) return;
-   edje_object_part_text_set(VIEW(item), "elm.text", label);
+   edje_object_part_text_escaped_set(VIEW(item), "elm.text", label);
    if (item->label)
      edje_object_signal_emit(VIEW(item),
                              "elm,state,item,text,visible", "elm");
@@ -1052,7 +1068,7 @@ static void
 _item_text_set_hook(Elm_Object_Item *it, const char *part, const char *label)
 {
    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
-   Elm_Popup_Content_Item *item = (Elm_Popup_Content_Item *) it;
+   Elm_Popup_Content_Item *item = (Elm_Popup_Content_Item *)it;
 
    if ((!part) || (!strcmp(part, "default")))
      {
@@ -1066,7 +1082,7 @@ static const char *
 _item_text_get_hook(const Elm_Object_Item *it, const char *part)
 {
    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
-   Elm_Popup_Content_Item *item = (Elm_Popup_Content_Item *) it;
+   Elm_Popup_Content_Item *item = (Elm_Popup_Content_Item *)it;
 
    if ((!part) || (!strcmp(part, "default")))
      return item->label;
@@ -1080,7 +1096,6 @@ _item_icon_set(Elm_Popup_Content_Item *item, Evas_Object *icon)
    if (item->icon == icon) return;
    if (item->icon)
      {
-        elm_widget_sub_object_del(WIDGET(item), item->icon);
         evas_object_data_del(item->icon, "_popup_content_item");
         evas_object_del(item->icon);
      }
@@ -1105,7 +1120,7 @@ _item_content_set_hook(Elm_Object_Item *it, const char *part,
                        Evas_Object *content)
 {
    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
-   Elm_Popup_Content_Item *item = (Elm_Popup_Content_Item *) it;
+   Elm_Popup_Content_Item *item = (Elm_Popup_Content_Item *)it;
 
    if ((!(part)) || (!strcmp(part, "default")))
      _item_icon_set(item, content);
@@ -1118,7 +1133,7 @@ _item_content_get_hook(const Elm_Object_Item *it,
                        const char *part)
 {
    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
-   Elm_Popup_Content_Item *item = (Elm_Popup_Content_Item *) it;
+   Elm_Popup_Content_Item *item = (Elm_Popup_Content_Item *)it;
 
    if ((!(part)) || (!strcmp(part, "default")))
      return item->icon;
@@ -1147,7 +1162,7 @@ _item_content_unset_hook(const Elm_Object_Item *it,
 {
    ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
    Evas_Object *content = NULL;
-   Elm_Popup_Content_Item *item = (Elm_Popup_Content_Item *) it;
+   Elm_Popup_Content_Item *item = (Elm_Popup_Content_Item *)it;
 
    if ((!(part)) || (!strcmp(part, "default")))
      content = _item_icon_unset(item);
@@ -1160,7 +1175,7 @@ static void
 _item_disable_hook(Elm_Object_Item *it)
 {
    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
-   Elm_Popup_Content_Item *item = (Elm_Popup_Content_Item *) it;
+   Elm_Popup_Content_Item *item = (Elm_Popup_Content_Item *)it;
    Widget_Data *wd = elm_widget_data_get(WIDGET(item));
 
    if (!wd) return;
@@ -1174,7 +1189,7 @@ static void
 _item_del_pre_hook(Elm_Object_Item *it)
 {
    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
-   Elm_Popup_Content_Item *item = (Elm_Popup_Content_Item *) it;
+   Elm_Popup_Content_Item *item = (Elm_Popup_Content_Item *)it;
    Widget_Data *wd = elm_widget_data_get(WIDGET(item));
 
    if (!wd) return;
@@ -1194,11 +1209,35 @@ _item_signal_emit_hook(Elm_Object_Item *it, const char *emission,
                        const char *source)
 {
    ELM_OBJ_ITEM_CHECK_OR_RETURN(it);
-   Elm_Popup_Content_Item *item = (Elm_Popup_Content_Item *) it;
+   Elm_Popup_Content_Item *item = (Elm_Popup_Content_Item *)it;
 
    edje_object_signal_emit(VIEW(item), emission, source);
 }
 
+static void
+_popup_show(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj,
+               void *event_info __UNUSED__)
+{
+   Widget_Data *wd;
+
+   wd = elm_widget_data_get(obj);
+   if (!wd) return;
+
+   evas_object_show(wd->notify);
+}
+
+static void
+_popup_hide(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj,
+               void *event_info __UNUSED__)
+{
+   Widget_Data *wd;
+
+   wd = elm_widget_data_get(obj);
+   if (!wd) return;
+
+   evas_object_hide(wd->notify);
+}
+
 EAPI Evas_Object *
 elm_popup_add(Evas_Object *parent)
 {
@@ -1220,11 +1259,11 @@ elm_popup_add(Evas_Object *parent)
    elm_widget_content_set_hook_set(obj, _content_set_hook);
    elm_widget_content_get_hook_set(obj, _content_get_hook);
    elm_widget_content_unset_hook_set(obj,_content_unset_hook);
+   elm_widget_can_focus_set(obj, EINA_FALSE);
    elm_widget_focus_next_hook_set(obj, _focus_next_hook);
    evas_object_smart_callbacks_descriptions_set(obj, _signals);
 
    wd->notify = elm_notify_add(obj);
-   elm_widget_resize_object_set(obj, wd->notify);
    elm_notify_parent_set(wd->notify, parent);
    elm_notify_orient_set(wd->notify, ELM_NOTIFY_ORIENT_CENTER);
    elm_notify_allow_events_set(wd->notify, EINA_FALSE);
@@ -1235,6 +1274,10 @@ elm_popup_add(Evas_Object *parent)
 
    evas_object_event_callback_add(wd->notify, EVAS_CALLBACK_RESIZE,
                                   _notify_resize, obj);
+   evas_object_event_callback_add(obj, EVAS_CALLBACK_SHOW, _popup_show,
+                                  NULL);
+   evas_object_event_callback_add(obj, EVAS_CALLBACK_HIDE, _popup_hide,
+                                  NULL);
    evas_object_event_callback_add(obj, EVAS_CALLBACK_RESTACK, _restack, NULL);
    wd->base = elm_layout_add(obj);
    evas_object_size_hint_weight_set(wd->base, EVAS_HINT_EXPAND,
@@ -1306,7 +1349,7 @@ elm_popup_content_text_wrap_type_set(Evas_Object *obj, Elm_Wrap_Type wrap)
 }
 
 EAPI Elm_Wrap_Type
-elm_popup_content_text_wrap_type_get(Evas_Object *obj)
+elm_popup_content_text_wrap_type_get(const Evas_Object *obj)
 {
    ELM_CHECK_WIDTYPE(obj, widtype) ELM_WRAP_LAST;
    Widget_Data *wd = elm_widget_data_get(obj);
@@ -1327,7 +1370,7 @@ elm_popup_orient_set(Evas_Object *obj, Elm_Popup_Orient orient)
 }
 
 EAPI Elm_Popup_Orient
-elm_popup_orient_get(Evas_Object *obj)
+elm_popup_orient_get(const Evas_Object *obj)
 {
    ELM_CHECK_WIDTYPE(obj, widtype) -1;
    Widget_Data *wd = elm_widget_data_get(obj);
@@ -1347,7 +1390,7 @@ elm_popup_timeout_set(Evas_Object *obj, double timeout)
 }
 
 EAPI double
-elm_popup_timeout_get(Evas_Object *obj)
+elm_popup_timeout_get(const Evas_Object *obj)
 {
    ELM_CHECK_WIDTYPE(obj, widtype) 0.0;
    Widget_Data *wd = elm_widget_data_get(obj);
@@ -1368,7 +1411,7 @@ elm_popup_allow_events_set(Evas_Object *obj, Eina_Bool allow)
 }
 
 EAPI Eina_Bool
-elm_popup_allow_events_get(Evas_Object *obj)
+elm_popup_allow_events_get(const Evas_Object *obj)
 {
    ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
    Widget_Data *wd = elm_widget_data_get(obj);
@@ -1413,5 +1456,5 @@ elm_popup_item_append(Evas_Object *obj, const char *label,
 
    _scroller_size_calc(obj);
    _sizing_eval(obj);
-   return (Elm_Object_Item *) item;
+   return (Elm_Object_Item *)item;
 }