From: Rajeev Ranjan <rajeev.r@samsung.com>
authorraster <raster@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Mon, 5 Mar 2012 23:51:56 +0000 (23:51 +0000)
committerraster <raster@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Mon, 5 Mar 2012 23:51:56 +0000 (23:51 +0000)
Subject: [E-devel]  [Patch]  Elementary: New custom widget Popup

Hi All,
   Attached to the mail is the patch for a new custom elementary
widget  elm_popup for your review.

Change description:
New custom widget Popup added.

elm_popup is an enhancement over elm_notify widget with widely used
parts such as Title, Content and Action Buttons.
Items are supported as well and they are put inside the content area
which can have either an Evas Object/Set of items/Description text.

git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/elementary@68747 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

19 files changed:
data/themes/default.edc
data/themes/widgets/button.edc
data/themes/widgets/popup.edc [new file with mode: 0644]
doc/Makefile.am
doc/examples.dox
doc/index.doxy
doc/widgets/Makefile.am
doc/widgets/widget_preview_popup.c [new file with mode: 0644]
src/bin/Makefile.am
src/bin/test.c
src/bin/test_popup.c [new file with mode: 0644]
src/examples/Makefile.am
src/examples/popup_example_01.c [new file with mode: 0644]
src/examples/popup_example_02.c [new file with mode: 0644]
src/examples/popup_example_03.c [new file with mode: 0644]
src/lib/Elementary.h.in
src/lib/Makefile.am
src/lib/elc_popup.c [new file with mode: 0644]
src/lib/elc_popup.h [new file with mode: 0644]

index 5111d77..d8e937e 100644 (file)
@@ -366,6 +366,7 @@ collections {
 #include "widgets/video.edc"
 #include "widgets/naviframe.edc"
 #include "widgets/multibuttonentry.edc"
+#include "widgets/popup.edc"
 #include "ews.edc"
 #include "widgets/pointer.edc"
 }
index ee50891..11dcd42 100644 (file)
@@ -1,4 +1,5 @@
 group { name: "elm/button/base/default";
+   alias: "elm/button/base/popup_button/default";
    images {
       image: "bt_base1.png" COMP;
       image: "bt_base2.png" COMP;
diff --git a/data/themes/widgets/popup.edc b/data/themes/widgets/popup.edc
new file mode 100644 (file)
index 0000000..11143fc
--- /dev/null
@@ -0,0 +1,899 @@
+#define POPUP_ITEM_STATE_ENABLED  0
+#define POPUP_ITEM_STATE_DISABLED 1
+
+/*popup widget specific notify style style*/
+group { name: "elm/notify/block_events/popup";
+   parts {
+      part { name: "block_events";
+         type: RECT;
+         description { state: "default" 0.0;
+            color: 61 59 56 180;
+         }
+      }
+   }
+   programs {
+      program { name: "block_clicked";
+         signal: "mouse,clicked,1";
+         source: "block_events";
+         action: SIGNAL_EMIT "elm,action,click" "elm";
+      }
+   }
+}
+
+group { name: "elm/label/base/popup/default";
+   styles
+     {
+        style { name: "popup_desc_style";
+           base: "font=Sans font_size=10 align=center color=#000000 text_class=label";
+           tag:  "br" "\n";
+           tag:  "ps" "ps";
+           tag:  "whitecolor" "+ color=#ffffff";
+           tag:  "tab" "\t";
+        }
+     }
+   parts {
+      part { name: "left_top_padding";
+         type: RECT;
+         scale: 1;
+         description { state: "default" 0.0;
+            fixed: 1 1;
+            visible: 0;
+            align: 0.0 0.0;
+            min: 10 0;
+            rel2.relative: 0 0;
+         }
+      }
+      part { name: "right_bottom_padding";
+         type: RECT;
+         scale: 1;
+         description { state: "default" 0.0;
+            fixed: 1 1;
+            visible: 0;
+            align: 1.0 1.0;
+            min: 10 0;
+            rel1.relative: 1 1;
+         }
+      }
+      part { name: "elm.text";
+         type: TEXTBLOCK;
+         mouse_events: 0;
+         scale: 1;
+         description { state: "default" 0.0;
+            min: 380 0;
+            text {
+               style: "popup_desc_style";
+               min: 0 1;
+               max: 0 1;
+            }
+            rel1 {
+               relative: 1.0 1.0;
+               to: left_top_padding;
+            }
+            rel2 {
+               relative: 0.0 0.0;
+               to: right_bottom_padding;
+            }
+         }
+      }
+   }
+}
+
+group { name: "elm/popup/base/default";
+   styles {
+      style { name: "popup_title_style";
+         base: "font=Sans font_size=15 align=center color=#ffffff wrap=mixed ellipsis=1.0";
+         tag:  "br" "\n";
+         tag:  "tab" "\t";
+      }
+   }
+   parts {
+      part { name: "base";
+         type: RECT;
+         scale : 1;
+         description { state: "default" 0.0;
+            min: 400 0;
+            color: 237 237 237 255;
+            align: 0.0 0.0;
+         }
+      }
+      part { name: "elm.bg.title";
+         type: RECT;
+         scale : 1;
+         description { state: "default" 0.0;
+            min: 400 50;
+            fixed : 1 1;
+            align: 0.5 0.0;
+            visible: 0;
+            color: 172 172 172 255;
+            rel1 {
+               relative: 0.5 0.0;
+               to: "base";
+            }
+            rel2 {
+               relative: 0.5 0.0;
+               to: "base";
+            }
+         }
+         description { state: "visible" 0.0;
+            inherit: "default" 0.0;
+            visible: 1;
+         }
+      }
+      part { name: "left_pad";
+         type: RECT;
+         scale: 1;
+         description { state: "default" 0.0;
+            min: 10 0;
+            max: 10 0;
+            fixed: 1 1;
+            align: 0.0 0.0;
+            visible: 0;
+            rel1.to: "elm.bg.title";
+         }
+      }
+      part { name: "right_pad";
+         type: RECT;
+         scale: 1;
+         description { state: "default" 0.0;
+            min: 10 0;
+            max: 10 0;
+            fixed: 1 1;
+            align: 1.0 1.0;
+            visible: 0;
+            rel2.to: "elm.bg.title";
+         }
+      }
+      part { name: "elm.swallow.title.icon";
+         type: SWALLOW;
+         scale: 1;
+         description { state: "default" 0.0;
+            min: 48 48;
+            max: 48 48;
+            fixed: 1 1;
+            align: 0.0 0.5;
+            rel1 {
+               to: "left_pad";
+               relative: 1.0 0.0;
+            }
+            rel2 {
+               to: "right_pad";
+               relative: 0.0 1.0;
+            }
+            visible: 0;
+         }
+         description { state: "visible" 0.0;
+            inherit: "default" 0.0;
+            visible: 1;
+         }
+      }
+      part { name: "elm.text.title";
+         type: TEXTBLOCK;
+         scale:1;
+         description { state: "default" 0.0;
+            text {
+              style: "popup_title_style";
+              min: 0 0;
+              max: 0 1;
+            }
+            color: 255 255 255 255;
+            visible:0;
+            rel1 {
+               relative: 1.0 0.0;
+               to: "left_pad";
+            }
+            rel2 {
+               relative: 0.0 1.0;
+               to: "right_pad";
+            }
+         }
+         description { state: "visible" 0.0;
+            inherit: "default" 0.0;
+            visible: 1;
+         }
+      }
+      part { name: "elm.swallow.content";
+         type: SWALLOW;
+         scale : 1;
+         description { state: "default" 0.0;
+            min: 400 0;
+            fixed: 1 0;
+            rel1 {
+               relative: 0.5 0.0;
+               to: "base";
+            }
+            rel2 {
+               relative: 0.5 1.0;
+               to: "base";
+            }
+         }
+         description { state: "show_title_area" 0.0;
+            inherit: "default" 0.0;
+            rel1 {
+               relative: 0.5 1.0;
+               to: "elm.bg.title";
+            }
+         }
+         description { state: "show_action_area" 0.0;
+            inherit: "default" 0.0;
+            rel2 {
+               relative: 0.5 0.0;
+               to: "elm.bg.action_area";
+            }
+         }
+         description { state: "show_action_title_area" 0.0;
+            inherit: "default" 0.0;
+            rel1 {
+               relative: 0.5 1.0;
+               to: "elm.bg.title";
+            }
+            rel2 {
+               relative: 0.5 0.0;
+               to: "elm.bg.action_area";
+            }
+         }
+      }
+      part { name: "elm.bg.action_area";
+         type: RECT;
+         scale : 1;
+         description { state: "default" 0.0;
+            min: 400 60;
+            fixed : 1 1;
+            align: 0.5 1.0;
+            visible: 0;
+            color: 183 183 183 255;
+            rel1 {
+               relative: 0.0 1.0;
+               to: "base";
+            }
+            rel2.to: "base";
+         }
+         description { state: "visible" 0.0;
+            inherit: "default" 0.0;
+            visible: 1;
+         }
+      }
+      part { name: "elm.swallow.action_area";
+         type: SWALLOW;
+         scale : 1;
+         description { state: "default" 0.0;
+            align: 0.0 0.0;
+            visible: 0;
+            rel1.to: "elm.bg.action_area";
+            rel2.to: "elm.bg.action_area";
+         }
+         description { state: "visible" 0.0;
+            inherit: "default" 0.0;
+            visible: 1;
+         }
+      }
+   }
+   programs {
+      program { name: show_title_icon;
+         signal: "elm,state,title,icon,visible";
+         source: "elm";
+         action: STATE_SET "visible" 0.0;
+         target: "elm.swallow.title.icon";
+      }
+      program { name: hide_title_icon;
+         signal: "elm,state,title,icon,hidden";
+         source: "elm";
+         action: STATE_SET "default" 0.0;
+         target: "elm.swallow.title.icon";
+      }
+      program { name: show_title_text;
+         signal: "elm,state,title,text,visible";
+         source: "elm";
+         action: STATE_SET "visible" 0.0;
+         target: "elm.text.title";
+      }
+      program { name: hide_title_text;
+         signal: "elm,state,title,text,hidden";
+         source: "elm";
+         action: STATE_SET "default" 0.0;
+         target: "elm.text.title";
+      }
+      program { name: show_title_area;
+         signal: "elm,state,title_area,visible";
+         source: "elm";
+         script {
+            new st[31];
+            new Float:vl;
+            get_state(PART:"elm.swallow.action_area", st, 30, vl);
+            if (!strcmp(st, "visible"))
+              set_state(PART:"elm.swallow.content", "show_action_title_area", 0.0);
+            else
+              set_state(PART:"elm.swallow.content", "show_title_area", 0.0);
+            set_state(PART:"elm.bg.title", "visible", 0.0);
+         }
+      }
+      program { name: hide_title_area;
+         signal: "elm,state,title_area,hidden";
+         source: "elm";
+         action: STATE_SET "default" 0.0;
+         script {
+            new st[31];
+            new Float:vl;
+            get_state(PART:"elm.swallow.action_area", st, 30, vl);
+            if (!strcmp(st, "visible"))
+              set_state(PART:"elm.swallow.content", "show_action_area", 0.0);
+            else
+              set_state(PART:"elm.swallow.content", "default", 0.0);
+            set_state(PART:"elm.bg.title", "default", 0.0);
+         }
+      }
+      program { name: show_action_area;
+         signal: "elm,state,action_area,visible";
+         source: "elm";
+         script {
+            new st[31];
+            new Float:vl;
+            get_state(PART:"elm.bg.title", st, 30, vl);
+            if (!strcmp(st, "visible"))
+              set_state(PART:"elm.swallow.content", "show_action_title_area", 0.0);
+            else
+              set_state(PART:"elm.swallow.content", "show_action_area", 0.0);
+            set_state(PART:"elm.bg.action_area", "visible", 0.0);
+            set_state(PART:"elm.swallow.action_area", "visible", 0.0);
+         }
+      }
+      program { name: hide_action_area;
+         signal: "elm,state,action_area,hidden";
+         source: "elm";
+         action: STATE_SET "default" 0.0;
+         script {
+            new st[31];
+            new Float:vl;
+            get_state(PART:"elm.bg.title", st, 30, vl);
+            if (!strcmp(st, "visible"))
+              set_state(PART:"elm.swallow.content", "show_title_area", 0.0);
+            else
+              set_state(PART:"elm.swallow.content", "default", 0.0);
+            set_state(PART:"elm.bg.action_area", "default", 0.0);
+            set_state(PART:"elm.swallow.action_area", "default", 0.0);
+         }
+      }
+   } /* end of programs */
+}
+
+group { name: "elm/popup/content/default";
+   parts{
+      part { name: "pad_t";
+         type: RECT;
+         scale : 1;
+         mouse_events: 0;
+         description { state: "default" 0.0;
+            align: 0.5 0.0;
+            min: 0 14;
+            fixed: 0 1;
+            visible: 0;
+            rel1 {
+               relative: 1.0 0.0;
+               to_x: "pad_l";
+            }
+            rel2 {
+               relative: 0.0 0.0;
+               to_x: "pad_r";
+            }
+         }
+      }
+      part { name: "pad_l";
+         type: RECT;
+         scale: 1;
+         description { state: "default" 0.0;
+            min : 10 0;
+            fixed: 1 0;
+            rel2.relative: 0.0 1.0;
+            visible: 0;
+            align: 0.0 0.0;
+         }
+      }
+      part { name: "pad_r";
+         type: RECT;
+         scale: 1;
+         description { state: "default" 0.0;
+            min : 10 0;
+            fixed: 1 0;
+            rel1.relative: 1.0 0.0;
+            visible: 0;
+            align: 1.0 0.0;
+         }
+      }
+      part{ name:"elm.swallow.content";
+         type: SWALLOW;
+         scale : 1;
+         description { state: "default" 0.0;
+            min: 380 0;
+            fixed: 1 0;
+            rel1 {
+               relative: 0.5 1.0;
+               to: "pad_t";
+            }
+            rel2 {
+               relative: 0.5 0.0;
+               to: "pad_b";
+            }
+         }
+      }
+      part { name: "pad_b";
+         type: RECT;
+         scale : 1;
+         mouse_events: 0;
+         description { state: "default" 0.0;
+            align: 0.5 1.0;
+            min: 0 14;
+            fixed: 0 1;
+            visible: 0;
+            rel1 {
+               relative: 0.0 1.0;
+               to_x: "pad_l";
+            }
+            rel2.to_x: "pad_r";
+         }
+      }
+   }
+}
+
+   group { name: "elm/popup/item/default";
+      script {
+         public item_state = POPUP_ITEM_STATE_ENABLED;
+      }
+      parts {
+         part { name: "event_blocker";
+            description { state: "default" 0.0;
+            }
+         }
+         part { name: "bg";
+            mouse_events: 0;
+            type: RECT;
+            description { state: "default" 0.0;
+               color: 240 240 240 255;
+               min: 0 71;
+               align: 0.5 0.0;
+            }
+            description { state: "clicked" 0.0;
+               color: 190 170 150 255;
+            }
+         }
+         part { name: "padding_left_top";
+            type: RECT;
+            scale: 1;
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               align: 0.0 0.0;
+               rel2.relative: 0.0 0.0;
+               min: 10 10;
+               fixed: 1 1;
+               visible: 0;
+            }
+         }
+         part { name: "padding_right_bottom";
+            type: RECT;
+            scale: 1;
+            mouse_events: 0;
+            description { state: "default" 0.0;
+               align: 1.0 1.0;
+               rel1.relative: 1.0 1.0;
+               min: 10 10;
+               fixed: 1 1;
+               visible: 0;
+            }
+         }
+         part { name: "separator";
+            mouse_events: 0;
+            type: RECT;
+            scale: 1;
+            description { state: "dafault" 0.0;
+               color: 180 180 180 255;
+               align: 0.5 1.0;
+               min: 0 1;
+               max: 999999 1;
+            }
+         }
+         part { name: "padding_icon_text";
+            type: RECT;
+            scale: 1;
+            mouse_events: 0;
+            description { state: "default" 0.0; //when only icon or no icon is there
+               align: 0.0 0.0;
+               rel1 {
+                  relative: 1.0 0.0;
+                  to: "elm.swallow.content";
+               }
+               rel2.to: "elm.swallow.content";
+               fixed: 1 0;
+               min: 0 0;
+               visible: 0;
+            }
+            description { state: "visible" 0.0; //when icon is visible
+               inherit: "default" 0.0;
+               min: 10 0;
+            }
+            description { state: "icononly" 0.0;
+               inherit: "default" 0.0;
+            }
+         }
+         part { name: "elm.swallow.content";
+            type: SWALLOW;
+            scale: 1;
+            description { state: "default" 0.0;
+               visible: 0;
+               align: 0.0 0.5;
+               rel1 {
+                  relative: 1.0 1.0;
+                  to: "padding_left_top";
+               }
+               rel2 {
+                  relative: 1.0 0.0;
+                  to_x: "padding_left_top";
+                  to_y: "padding_right_bottom";
+               }
+               fixed: 1 0;
+            }
+            description { state: "visible" 0.0;
+               fixed: 1 0;
+               min: 40 40;
+               max: 40 40;
+               align: 0.0 0.5;
+               rel1 {
+                  relative: 1.0 1.0;
+                  to: "padding_left_top";
+               }
+               rel2 {
+                  relative: 1.0 0.0;
+                  to_x: "padding_left_top";
+                  to_y: "padding_right_bottom";
+               }
+               aspect: 1.0 1.0;
+               aspect_preference: VERTICAL;
+            }
+            description { state: "icononly" 0.0;
+               min: 40 40;
+               max: 40 40;
+               rel1 {
+                  relative: 1.0 1.0;
+                  to: "padding_left_top";
+               }
+               rel2 {
+                  relative: 0.0 0.0;
+                  to: "padding_right_bottom";
+               }
+               aspect: 1.0 1.0;
+               aspect_preference: VERTICAL;
+            }
+         }
+         part { name: "elm.text";
+            type: TEXT;
+            mouse_events: 0;
+            scale: 1;
+            description { state: "default" 0.0;
+               visible: 0;
+               rel1 {
+                  relative: 1.0 1.0;
+                  to_x: "padding_icon_text";
+                  to_y: "padding_left_top";
+               }
+               rel2 {
+                  relative: 0.0 0.0;
+                  to:"padding_right_bottom";
+               }
+               align: 0.0 0.5;
+               color: 0 0 0 255;
+               text {
+                  font: "Sans:style=Bold";
+                  size: 20;
+                  min:  0 0;
+                  align: 0.0 0.5;
+               }
+            }
+            description { state: "visible" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               min: 90 40;
+            }
+            description { state: "clicked" 0.0;
+               inherit: "default" 0.0;
+               visible: 1;
+               min: 0 0;
+               color: 255 255 255 255;
+            }
+            description { state: "disabled" 0.0;
+               inherit: "default" 0.0;
+               color: 128 128 128 255;
+            }
+            description { state: "disabled_visible" 0.0;
+               inherit: "default" 0.0;
+               color: 128 128 128 255;
+               visible: 1;
+               min: 90 40;
+            }
+         }
+         part { name: "over1";
+            repeat_events: 1;
+            ignore_flags: ON_HOLD;
+            description { state: "default" 0.0;
+            }
+         }
+         part { name: "over2";
+            repeat_events: 1;
+            description { state: "default" 0.0;
+            }
+         }
+         part { name: "disclip";
+            type: RECT;
+            description { state: "default" 0.0;
+               visible: 0;
+            }
+            description { state: "disabled" 0.0;
+               color: 87 87 87 128;
+            }
+         }
+      }
+      programs {
+         program { name: "item_unclick";
+            signal: "mouse,up,1";
+            source: "over1";
+            action: SIGNAL_EMIT "elm,action,click" "";
+         }
+         program { name: "disable";
+            signal: "elm,state,item,disabled";
+            source: "elm";
+            action: STATE_SET "disabled" 0.0;
+            target: "disclip";
+            after: "disable_text";
+         }
+         program { name: "enable";
+            signal: "elm,state,item,enabled";
+            source: "elm";
+            action: STATE_SET "default" 0.0;
+            target: "disclip";
+            after: "enable_text";
+         }
+         program { name: "item_click2";
+            signal: "mouse,down,1";
+            source: "over2";
+            script {
+               new st[31];
+               new Float:vl;
+               get_state(PART:"elm.text", st, 30, vl);
+               if (!strcmp(st, "visible"))
+                 set_state(PART:"elm.text", "clicked", 0.0);
+               set_state(PART:"bg", "clicked", 0.0);
+            }
+         }
+         program { name: "item_unclick2";
+            signal: "mouse,up,1";
+            source: "over2";
+            script {
+               new st[31];
+               new Float:vl;
+               get_state(PART:"elm.text", st, 30, vl);
+               if (!strcmp(st, "clicked"))
+                 set_state(PART:"elm.text", "visible", 0.0);
+               set_state(PART:"bg", "default", 0.0);
+            }
+         }
+         program { name: "disable_text";
+            script {
+               new st[31];
+               new Float:vl;
+               get_state(PART:"elm.text", st, 30, vl);
+               if (!strcmp(st, "visible"))
+                 set_state(PART:"elm.text", "disabled_visible", 0.0);
+               else
+                 set_state(PART:"elm.text", "disabled", 0.0);
+               set_int(item_state, POPUP_ITEM_STATE_DISABLED);
+            }
+         }
+         program { name: "enable_text";
+            script {
+               new st[31];
+               new Float:vl;
+               get_state(PART:"elm.text", st, 30, vl);
+               if (!strcmp(st, "disabled_visible"))
+                 set_state(PART:"elm.text", "visible", 0.0);
+               else
+                 set_state(PART:"elm.text", "default", 0.0);
+               set_int(item_state, POPUP_ITEM_STATE_ENABLED);
+            }
+         }
+         program { name: "text_show";
+            signal: "elm,state,item,text,visible";
+            source: "elm";
+            script {
+               new st[31];
+               new Float:vl;
+               get_state(PART:"elm.swallow.content", st, 30, vl);
+               if (!strcmp(st, "icononly")) {
+                  set_state(PART:"elm.swallow.content", "visible", 0.0);
+                  set_state(PART:"padding_icon_text", "visible", 0.0);
+               }
+               if(get_int(item_state) != POPUP_ITEM_STATE_DISABLED)
+                 set_state(PART:"elm.text", "visible", 0.0);
+               else
+                 set_state(PART:"elm.text", "disabled_visible", 0.0);
+            }
+         }
+         program { name: "text_hide";
+            signal: "elm,state,item,text,hidden";
+            source: "elm";
+            script {
+               new st[31];
+               new Float:vl;
+               get_state(PART:"elm.swallow.content", st, 30, vl);
+               if (!strcmp(st, "visible")) {
+                  set_state(PART:"elm.swallow.content", "icononly", 0.0);
+                  set_state(PART:"padding_icon_text", "icononly", 0.0);
+               }
+               set_state(PART:"elm.text", "default", 0.0);
+            }
+         }
+         program { name: "icon_show";
+            signal: "elm,state,item,icon,visible";
+            source: "elm";
+            script {
+               new st[31];
+               new Float:vl;
+               get_state(PART:"elm.text", st, 30, vl);
+               if (!strcmp(st, "visible")) {
+                  set_state(PART:"elm.swallow.content", "visible", 0.0);
+                  set_state(PART:"padding_icon_text", "visible", 0.0);
+               }
+               else {
+                  set_state(PART:"elm.swallow.content", "icononly", 0.0);
+                  set_state(PART:"padding_icon_text", "icononly", 0.0);
+               }
+            }
+         }
+         program { name: "icon_hide";
+            signal: "elm,state,item,icon,hidden";
+            source: "elm";
+            action:  STATE_SET "default" 0.0;
+            target: "elm.swallow.content";
+         }
+      }
+   }
+
+group { name: "elm/popup/buttons1/default";
+   data.item: "action_area_height" "140";
+   parts{
+      part{ name:"actionbtn1";
+         type: SWALLOW;
+         scale : 1;
+         description { state: "default" 0.0;
+            min: 252 46;
+            max: 252 46;
+            fixed : 1 1;
+            rel1.relative: 0.5 0.0;
+            rel2.relative: 0.5 1.0;
+         }
+      }
+   }
+}
+
+group { name: "elm/popup/buttons2/default";
+   data.item: "action_area_height" "140";
+   parts{
+      part{ name:"actionbtn1";
+         type: SWALLOW;
+         scale : 1;
+         description { state: "default" 0.0;
+            min: 172 46;
+            max: 172 46;
+            fixed : 1 1;
+            align: 1.0 0.5;
+            rel1.to: "elm.rect.pad_btn";
+            rel2 {
+               relative: 0.0 1.0;
+               to: "elm.rect.pad_btn";
+            }
+         }
+      }
+      part { name: "elm.rect.pad_btn";
+         type: RECT;
+         scale : 1;
+         description { state: "default" 0.0;
+            min: 6 46;
+            max: 6 46;
+            fixed : 1 1;
+            visible: 0;
+            rel1.relative: 0.5 0.0;
+            rel2.relative: 0.5 1.0;
+         }
+      }
+      part{ name:"actionbtn2";
+         type: SWALLOW;
+         scale : 1;
+         description { state: "default" 0.0;
+            min: 172 46;
+            max: 172 46;
+            fixed : 1 1;
+            align: 0.0 0.5;
+            rel1 {
+               relative: 1.0 0.0;
+               to: "elm.rect.pad_btn";
+            }
+            rel2.to: "elm.rect.pad_btn";
+         }
+      }
+   }
+}
+
+group { name: "elm/popup/buttons3/default";
+   data.item: "action_area_height" "140";
+   parts{
+      part{ name:"actionbtn1";
+         type: SWALLOW;
+         scale : 1;
+         description { state: "default" 0.0;
+            min: 120 46;
+            max: 120 46;
+            fixed : 1 1;
+            align: 1.0 0.5;
+            rel1.to: "elm.rect.pad_btn";
+            rel2 {
+               relative: 0.0 1.0;
+               to: "elm.rect.pad_btn";
+            }
+         }
+      }
+      part { name: "elm.rect.pad_btn";
+         type: RECT;
+         scale : 1;
+         description { state: "default" 0.0;
+            min: 6 46;
+            max: 6 46;
+            fixed : 1 1;
+            visible: 0;
+            rel1.to: "actionbtn2";
+            rel2 {
+               relative: 0.0 1.0;
+               to: "actionbtn2";
+            }
+         }
+      }
+      part{ name:"actionbtn2";
+         type: SWALLOW;
+         scale : 1;
+         description { state: "default" 0.0;
+            min: 120 46;
+            max: 120 46;
+            fixed : 1 1;
+            rel1.relative: 0.5 0.0;
+            rel2.relative: 0.5 1.0;
+         }
+      }
+      part { name: "elm.rect.pad_btn2";
+         type: RECT;
+         scale : 1;
+         description { state: "default" 0.0;
+            min: 6 46;
+            max: 6 46;
+            fixed : 1 1;
+            visible: 0;
+            rel1 {
+               relative: 1.0 0.0;
+               to: "actionbtn2";
+            }
+            rel2.to: "actionbtn2";
+         }
+      }
+      part{ name:"actionbtn3";
+         type: SWALLOW;
+         scale : 1;
+         description { state: "default" 0.0;
+            min: 120 46;
+            max: 120 46;
+            fixed : 1 1;
+            align: 0.0 0.5;
+            rel1 {
+               relative: 1.0 0.0;
+               to: "elm.rect.pad_btn2";
+            }
+            rel2.to: "elm.rect.pad_btn2";
+         }
+      }
+   }
+}
+
+#undef POPUP_ITEM_STATE_ENABLED
+#undef POPUP_ITEM_STATE_DISABLED
index bdb4731..fb77e2b 100644 (file)
@@ -73,6 +73,7 @@ WGT_PREVIEW = \
        progressbar:preview-00.png:widget_preview_progressbar:150:50 \
        box:preview-00.png:widget_preview_box:200:160 \
        notify:preview-00.png:widget_preview_notify:60:30 \
+       popup:preview-00.png:widget_preview_popup:480:400 \
        slideshow:preview-00.png:widget_preview_slideshow:50:50 \
        photocam:preview-00.png:widget_preview_photocam:243:162 \
        inwin:preview-00.png:widget_preview_inwin1:200:160 \
index edebd38..680213e 100644 (file)
  */
 
 /**
+ * @page popup_example_01_c popup_example_01.c
+ * @include popup_example_01.c
+ *
+ * This example will initially look like this:
+ *
+ * @image html screenshots/popup_example_01.png
+ * @image latex screenshots/popup_example_01.eps width=\textwidth
+ *
+ * Once the popup is hidden after timeout:
+ *
+ * @image html screenshots/popup_example_01_a.png
+ * @image latex screenshots/popup_example_01_a.eps width=\textwidth
+ *
+ * @example popup_example_01.c
+ */
+
+ /** @page popup_example_02_c popup_example_02.c
+ * @include popup_example_02.c
+ *
+ * This example will look like this:
+ *
+ * @image html screenshots/popup_example_02.png
+ * @image latex screenshots/popup_example_02.eps width=\textwidth
+ *
+ * @example popup_example_02.c
+ */
+
+/**
+ * @page popup_example_03_c popup_example_03.c
+ * @include popup_example_03.c
+ *
+ * This example will look like this:
+ *
+ * @image html screenshots/popup_example_03.png
+ * @image latex screenshots/popup_example_03.eps width=\textwidth
+ *
+ * @example popup_example_03.c
+ */
+
+/**
  * @page tutorial_frame Frame example
  * @dontinclude frame_example_01.c
  *
index 61c42ca..b9982d7 100644 (file)
  *
  * @image html img/widget/photocam/preview-00.png
  * @image latex img/widget/photocam/preview-00.eps
+ * @li @ref Popup
+ *
+ * @image html img/widget/popup/preview-00.png
+ * @image latex img/widget/popup/preview-00.eps
  * @li @ref Progressbar
  *
  * @image html img/widget/progressbar/preview-00.png
index d9ec6e0..9f6efd1 100644 (file)
@@ -84,6 +84,7 @@ widget_preview_genlist5 \
 widget_preview_progressbar \
 widget_preview_box \
 widget_preview_notify \
+widget_preview_popup \
 widget_preview_slideshow \
 widget_preview_photocam \
 widget_preview_inwin1 \
@@ -150,6 +151,7 @@ EXTRA_DIST = \
        widget_preview_layout.c \
        widget_preview_list.c \
        widget_preview_segment_control.c \
+       widget_preview_popup.c \
        widget_preview_separator.c \
        widget_preview_radio.c \
        widget_preview_toggle.c \
diff --git a/doc/widgets/widget_preview_popup.c b/doc/widgets/widget_preview_popup.c
new file mode 100644 (file)
index 0000000..5eee96b
--- /dev/null
@@ -0,0 +1,15 @@
+#include "widget_preview_tmpl_head.c"
+
+Evas_Object *o = elm_popup_add(win);
+evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+evas_object_size_hint_weight_set(o, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+elm_win_resize_object_add(win, o);
+elm_object_part_text_set(o, "title,text", "Title");
+elm_object_text_set(o, "Content");
+
+Evas_Object *o2 = elm_button_add(win);
+elm_object_text_set(o2, "Close");
+elm_object_part_content_set(o, "button1", o2);
+evas_object_show(o);
+#include "widget_preview_tmpl_foot.c"
+
index 4019795..8e0d75f 100644 (file)
@@ -90,6 +90,7 @@ test_panel.c \
 test_panes.c \
 test_photo.c \
 test_photocam.c \
+test_popup.c \
 test_progressbar.c \
 test_radio.c \
 test_scaling.c \
index 7cf3c38..e24bdd1 100644 (file)
@@ -165,6 +165,7 @@ void test_3d(void *data, Evas_Object *obj, void *event_info);
 void test_naviframe(void *data, Evas_Object *obj, void *event_info);
 //void test_factory(void *data, Evas_Object *obj, void *event_info);
 void test_datetime(void *data, Evas_Object *obj, void *event_info);
+void test_popup(void *data, Evas_Object *obj, void *event_info);
 #ifdef HAVE_EMOTION
 void test_video(void *data, Evas_Object *obj, void *event_info);
 #endif
@@ -504,6 +505,7 @@ add_tests:
    ADD_TEST(NULL, "Popups", "Notify", test_notify);
    ADD_TEST(NULL, "Popups", "Tooltip", test_tooltip);
    ADD_TEST(NULL, "Popups", "Tooltip 2", test_tooltip2);
+   ADD_TEST(NULL, "Popups", "Popup", test_popup);
 
    //------------------------------//
    ADD_TEST(NULL, "Times & Dates", "Calendar", test_calendar);
diff --git a/src/bin/test_popup.c b/src/bin/test_popup.c
new file mode 100644 (file)
index 0000000..d2e6e8d
--- /dev/null
@@ -0,0 +1,262 @@
+#include <Elementary.h>
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#endif
+#ifndef ELM_LIB_QUICKLAUNCH
+
+static void
+_response_cb(void *data, Evas_Object *obj __UNUSED__,
+             void *event_info __UNUSED__)
+{
+   evas_object_hide(data);
+   evas_object_del(data);
+}
+
+static void
+_block_clicked_cb(void *data __UNUSED__, Evas_Object *obj,
+                  void *event_info __UNUSED__)
+{
+   printf("\nblock,clicked callback\n");
+   evas_object_del(obj);
+}
+
+static void
+_item_selected_cb(void *data __UNUSED__, Evas_Object *obj __UNUSED__,
+                  void *event_info)
+{
+   printf("popup item selected: %s\n", elm_object_item_text_get(event_info));
+}
+
+static void
+_list_click(void *data __UNUSED__, Evas_Object *obj,
+            void *event_info __UNUSED__)
+{
+   Elm_Object_Item *it = elm_list_selected_item_get(obj);
+   if (!it) return;
+   elm_list_item_selected_set(it, EINA_FALSE);
+}
+
+static void
+_popup_center_text_cb(void *data, Evas_Object *obj __UNUSED__,
+                      void *event_info __UNUSED__)
+{
+   Evas_Object *popup;
+
+   popup = elm_popup_add(data);
+   evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_object_text_set(popup, "This Popup has content area and "
+                       "timeout value is 3 seconds");
+   elm_popup_timeout_set(popup, 3.0);
+   evas_object_smart_callback_add(popup, "timeout", _response_cb, popup);
+   evas_object_show(popup);
+}
+
+static void
+_popup_center_text_1button_cb(void *data, Evas_Object *obj __UNUSED__,
+                              void *event_info __UNUSED__)
+{
+   Evas_Object *popup;
+   Evas_Object *btn;
+
+   popup = elm_popup_add(data);
+   evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_object_text_set(popup, "This Popup has content area and "
+                       "action area set, action area has one button Close");
+   btn = elm_button_add(popup);
+   elm_object_text_set(btn, "Close");
+   elm_object_part_content_set(popup, "button1", btn);
+   evas_object_smart_callback_add(btn, "clicked", _response_cb, popup);
+   evas_object_show(popup);
+}
+
+static void
+_popup_center_title_text_1button_cb(void *data, Evas_Object *obj __UNUSED__,
+                                    void *event_info __UNUSED__)
+{
+   Evas_Object *popup;
+   Evas_Object *btn;
+
+   popup = elm_popup_add(data);
+   evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_object_text_set(popup, "This Popup has title area, content area and "
+                       "action area set, action area has one button Close");
+   elm_object_part_text_set(popup, "title,text", "Title");
+   btn = elm_button_add(popup);
+   elm_object_text_set(btn, "Close");
+   elm_object_part_content_set(popup, "button1", btn);
+   evas_object_smart_callback_add(btn, "clicked", _response_cb, popup);
+   evas_object_show(popup);
+}
+
+static void
+_popup_center_title_text_block_clicked_event_cb(void *data,
+                                                Evas_Object *obj __UNUSED__,
+                                                void *event_info __UNUSED__)
+{
+   Evas_Object *popup;
+
+   popup = elm_popup_add(data);
+   evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_object_text_set(popup, "This Popup has title area and content area. "
+                       "When clicked on blocked event region, popup gets "
+                       "deleted");
+   elm_object_part_text_set(popup, "title,text", "Title");
+   evas_object_smart_callback_add(popup, "block,clicked", _block_clicked_cb,
+                                  NULL);
+   evas_object_show(popup);
+}
+
+static void
+_popup_bottom_title_text_3button_cb(void *data, Evas_Object *obj __UNUSED__,
+                                    void *event_info __UNUSED__)
+{
+   Evas_Object *popup;
+   Evas_Object *icon, *btn1, *btn2, *btn3;
+   char buf[256];
+
+   popup = elm_popup_add(data);
+   elm_popup_orient_set(popup, ELM_POPUP_ORIENT_BOTTOM);
+   evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_object_text_set(popup, "This Popup has title area, content area and "
+                       "action area set with content being character wrapped. "
+                       "action area has three buttons OK, Cancel and Close");
+   elm_popup_content_text_wrap_type_set(popup, ELM_WRAP_CHAR);
+   elm_object_part_text_set(popup, "title,text", "Title");
+   icon = elm_icon_add(popup);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png",
+            elm_app_data_dir_get());
+   elm_icon_file_set(icon, buf, NULL);
+   elm_object_part_content_set(popup, "title,icon", icon);
+   btn1 = elm_button_add(popup);
+   elm_object_text_set(btn1, "OK");
+   elm_object_part_content_set(popup, "button1", btn1);
+   btn2 = elm_button_add(popup);
+   elm_object_text_set(btn2, "Cancel");
+   elm_object_part_content_set(popup, "button2", btn2);
+   btn3 = elm_button_add(popup);
+   elm_object_text_set(btn3, "Close");
+   elm_object_part_content_set(popup, "button3", btn3);
+   evas_object_smart_callback_add(btn1, "clicked", _response_cb, popup);
+   evas_object_smart_callback_add(btn2, "clicked", _response_cb, popup);
+   evas_object_smart_callback_add(btn3, "clicked", _response_cb, popup);
+   evas_object_show(popup);
+}
+
+static void
+_popup_center_title_content_3button_cb(void *data, Evas_Object *obj __UNUSED__,
+                                       void *event_info __UNUSED__)
+{
+   Evas_Object *popup;
+   Evas_Object *icon, *btn, *btn1, *btn2, *btn3;
+   char buf[256];
+
+   popup = elm_popup_add(data);
+   evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   btn = elm_button_add(popup);
+   elm_object_text_set(btn, "Content");
+   icon = elm_icon_add(btn);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png",
+            elm_app_data_dir_get());
+   elm_icon_file_set(icon, buf, NULL);
+   elm_object_content_set(btn, icon);
+   elm_object_content_set(popup, btn);
+   elm_object_part_text_set(popup, "title,text", "Title");
+   btn1 = elm_button_add(popup);
+   elm_object_text_set(btn1, "OK");
+   elm_object_part_content_set(popup, "button1", btn1);
+   btn2 = elm_button_add(popup);
+   elm_object_text_set(btn2, "Cancel");
+   elm_object_part_content_set(popup, "button2", btn2);
+   btn3 = elm_button_add(popup);
+   elm_object_text_set(btn3, "Close");
+   elm_object_part_content_set(popup, "button3", btn3);
+   evas_object_smart_callback_add(btn1, "clicked", _response_cb, popup);
+   evas_object_smart_callback_add(btn2, "clicked", _response_cb, popup);
+   evas_object_smart_callback_add(btn3, "clicked", _response_cb, popup);
+   evas_object_show(popup);
+}
+
+static void
+_popup_center_title_item_3button_cb(void *data, Evas_Object *obj __UNUSED__,
+                                    void *event_info __UNUSED__)
+{
+   char buf[256];
+   unsigned int i;
+   Evas_Object *popup, *icon1, *btn1, *btn2, *btn3;
+
+   popup = elm_popup_add(data);
+   evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   icon1 = elm_icon_add(popup);
+   elm_object_part_text_set(popup, "title,text", "Title");
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png",
+            elm_app_data_dir_get());
+   elm_icon_file_set(icon1, buf, NULL);
+   for (i = 0; i < 10; i++)
+     {
+        snprintf(buf, sizeof(buf), "Item%u", i+1);
+        if (i == 3)
+          elm_popup_item_append(popup, buf, icon1, _item_selected_cb, NULL);
+        else
+          elm_popup_item_append(popup, buf, NULL, _item_selected_cb, NULL);
+     }
+   btn1 = elm_button_add(popup);
+   elm_object_text_set(btn1, "OK");
+   elm_object_part_content_set(popup, "button1", btn1);
+   btn2 = elm_button_add(popup);
+   elm_object_text_set(btn2, "Cancel");
+   elm_object_part_content_set(popup, "button2", btn2);
+   btn3 = elm_button_add(popup);
+   elm_object_text_set(btn3, "Close");
+   elm_object_part_content_set(popup, "button3", btn3);
+   evas_object_smart_callback_add(btn1, "clicked", _response_cb, popup);
+   evas_object_smart_callback_add(btn2, "clicked", _response_cb, popup);
+   evas_object_smart_callback_add(btn3, "clicked", _response_cb, popup);
+   evas_object_show(popup);
+}
+
+void
+test_popup(void *data __UNUSED__, Evas_Object *obj __UNUSED__,
+           void *event_info __UNUSED__)
+{
+   Evas_Object *win, *bg, *list;
+
+   win = elm_win_add(NULL, "popup", ELM_WIN_BASIC);
+   elm_win_title_set(win, "popup");
+   elm_win_autodel_set(win, EINA_TRUE);
+
+   bg = elm_bg_add(win);
+   elm_win_resize_object_add(win, bg);
+   evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_show(bg);
+
+   list = elm_list_add(win);
+   elm_win_resize_object_add(win, list);
+   elm_list_mode_set(list, ELM_LIST_LIMIT);
+   evas_object_size_hint_weight_set(list, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_smart_callback_add(list, "selected", _list_click, NULL);
+
+   elm_list_item_append(list, "popup-center-text", NULL, NULL,
+                        _popup_center_text_cb, win);
+   elm_list_item_append(list, "popup-center-text + 1 button", NULL, NULL,
+                        _popup_center_text_1button_cb, win);
+   elm_list_item_append(list, "popup-center-title + text + 1 button", NULL,
+                        NULL, _popup_center_title_text_1button_cb, win);
+
+   elm_list_item_append(list,
+                        "popup-center-title + text (block,clicked handling)",
+                        NULL, NULL,
+                        _popup_center_title_text_block_clicked_event_cb, win);
+   elm_list_item_append(list, "popup-bottom-title + text + 3 buttons", NULL,
+                        NULL, _popup_bottom_title_text_3button_cb, win);
+   elm_list_item_append(list, "popup-center-title + content + 3 buttons", NULL,
+                        NULL, _popup_center_title_content_3button_cb, win);
+   elm_list_item_append(list, "popup-center-title + items + 3 buttons", NULL,
+                        NULL, _popup_center_title_item_3button_cb, win);
+   elm_list_go(list);
+   evas_object_show(list);
+   evas_object_show(win);
+   evas_object_resize(win, 480, 800);
+}
+
+#endif
+
index 4747336..405e04a 100644 (file)
@@ -109,6 +109,9 @@ SRCS = \
        progressbar_example.c \
        notify_example_01.c \
        photocam_example_01.c \
+       popup_example_01.c \
+       popup_example_02.c \
+       popup_example_03.c \
        inwin_example.c \
        scroller_example_01.c \
        table_example_01.c \
@@ -218,6 +221,9 @@ examples_PROGRAMS += \
        progressbar_example \
        notify_example_01 \
        photocam_example_01 \
+       popup_example_01 \
+       popup_example_02 \
+       popup_example_03 \
        inwin_example \
        scroller_example_01 \
        table_example_01 \
@@ -303,6 +309,10 @@ SCREENSHOTS = \
        progressbar_example:progressbar_example.png:0.0 \
        notify_example_01:notify_example_01.png:0.0 \
        notify_example_01:notify_example_01_a.png:6.0 \
+       popup_example_01:popup_example_01.png:1.0 \
+       popup_example_01:popup_example_01_a.png:6.0 \
+       popup_example_02:popup_example_02.png:0.2 \
+       popup_example_03:popup_example_03.png:0.2 \
        slideshow_example:slideshow_example.png:1.0 \
        photocam_example_01:photocam_example_01.png:3 \
        scroller_example_01:scroller_example_01.png:0.0 \
diff --git a/src/examples/popup_example_01.c b/src/examples/popup_example_01.c
new file mode 100644 (file)
index 0000000..27eb0e3
--- /dev/null
@@ -0,0 +1,64 @@
+//Compile with:
+//gcc -g `pkg-config --cflags --libs elementary` popup_example_01.c -o popup_example_01
+
+#include <Elementary.h>
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#else
+# define __UNUSED__ __attribute__((unused))
+# define PACKAGE_DATA_DIR "../../data"
+#endif
+
+static void _block_clicked(void *data, Evas_Object *obj, void *event_info);
+static void _timeout(void *data, Evas_Object *obj, void *event_info);
+
+EAPI_MAIN int
+elm_main(int argc __UNUSED__, char **argv __UNUSED__)
+{
+   Evas_Object *win, *bg, *popup, *content;
+
+   win = elm_win_add(NULL, "popup", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Popup");
+   elm_win_autodel_set(win, EINA_TRUE);
+   elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
+
+   bg = elm_bg_add(win);
+   elm_bg_color_set(bg, 128, 128, 128);
+   elm_win_resize_object_add(win, bg);
+   evas_object_show(bg);
+
+   content = elm_label_add(win);
+   elm_object_text_set(content, "<align=center>Content</align>");
+
+   popup = elm_popup_add(win);
+   elm_popup_timeout_set(popup, 3.0);
+   evas_object_smart_callback_add(popup, "timeout", _timeout, NULL);
+
+   //Setting popup content
+   elm_object_content_set(popup, content);
+   //Seting popup title-text
+   elm_object_part_text_set(popup, "title,text", "Title");
+   evas_object_show(popup);
+   evas_object_smart_callback_add(popup, "block,clicked", _block_clicked, NULL);
+
+   evas_object_show(win);
+   evas_object_resize(win, 480, 800);
+
+   elm_run();
+
+   return 0;
+}
+ELM_MAIN()
+
+static void
+_block_clicked(void *data __UNUSED__, Evas_Object *obj,
+               void *event_info __UNUSED__)
+{
+   evas_object_hide(obj);
+}
+
+static void
+_timeout(void *data __UNUSED__, Evas_Object *obj, void *event_info __UNUSED__)
+{
+   evas_object_hide(obj);
+}
diff --git a/src/examples/popup_example_02.c b/src/examples/popup_example_02.c
new file mode 100644 (file)
index 0000000..9ecd03a
--- /dev/null
@@ -0,0 +1,85 @@
+//Compile with:
+//gcc -g `pkg-config --cflags --libs elementary` popup_example_02.c -o popup_example_02
+
+#include <Elementary.h>
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#else
+# define __UNUSED__ __attribute__((unused))
+# define PACKAGE_DATA_DIR "../../data"
+#endif
+
+static void _response_cb(void *data, Evas_Object *obj, void *event_info);
+
+EAPI_MAIN int
+elm_main(int argc __UNUSED__, char **argv __UNUSED__)
+{
+   Evas_Object *win, *bg, *popup, *btn1, *btn2, *btn3, *icon1;
+   char buf[256];
+
+   win = elm_win_add(NULL, "popup", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Popup");
+   elm_win_autodel_set(win, EINA_TRUE);
+   elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
+
+   bg = elm_bg_add(win);
+   elm_win_resize_object_add(win, bg);
+   evas_object_show(bg);
+
+   popup = elm_popup_add(win);
+
+   // Setting popup content-text
+   elm_object_text_set(popup, "This is the Content-Text for popup. The wrap"
+            "for the content-text is character wrapping");
+   // Setting the wrapping type to character wrapping
+   elm_popup_content_text_wrap_type_set(popup, ELM_WRAP_CHAR);
+
+   // Seting popup title-text
+   elm_object_part_text_set(popup, "title,text", "Title");
+
+   icon1 = elm_icon_add(popup);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(icon1, buf, NULL);
+   //Setting popup title-icon
+   elm_object_part_content_set(popup, "title,icon", icon1);
+
+   // Creating the first action button
+   btn1 = elm_button_add(popup);
+   elm_object_text_set(btn1, "OK");
+
+   // Setting the fist action button
+   elm_object_part_content_set(popup, "button1", btn1);
+   evas_object_smart_callback_add(btn1, "clicked", _response_cb, popup);
+
+   // Creating the second action button
+   btn2 = elm_button_add(popup);
+   elm_object_text_set(btn2, "Cancel");
+
+   // Setting the second action button
+   elm_object_part_content_set(popup, "button2", btn2);
+   evas_object_smart_callback_add(btn2, "clicked", _response_cb, popup);
+
+   btn3 = elm_button_add(popup);
+   elm_object_text_set(btn3, "Close");
+   // Setting this action button
+   elm_object_part_content_set(popup, "button3", btn3);
+   // Setting the orientation of popup to Top
+   elm_popup_orient_set(popup, ELM_POPUP_ORIENT_TOP);
+   // Display the popup object
+   evas_object_show(popup);
+
+   evas_object_resize(win, 480, 800);
+   evas_object_show(win);
+
+   elm_run();
+
+   return 0;
+}
+ELM_MAIN()
+static void
+_response_cb(void *data, Evas_Object *obj __UNUSED__,
+             void *event_info __UNUSED__)
+{
+   evas_object_del(data);
+}
+
diff --git a/src/examples/popup_example_03.c b/src/examples/popup_example_03.c
new file mode 100644 (file)
index 0000000..92d598f
--- /dev/null
@@ -0,0 +1,102 @@
+//Compile with:
+//gcc -g `pkg-config --cflags --libs elementary` popup_example_03.c -o popup_example_03
+
+#include <Elementary.h>
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#else
+# define __UNUSED__ __attribute__((unused))
+# define PACKAGE_DATA_DIR "../../data"
+#endif
+
+static void _item_selected_cb(void *data, Evas_Object *obj, void *event_info);
+static void _response_cb(void *data, Evas_Object *obj, void *event_info);
+
+EAPI_MAIN int
+elm_main(int argc __UNUSED__, char **argv __UNUSED__)
+{
+   Evas_Object *win, *bg, *popup, *btn1, *btn2, *icon1;
+   Elm_Object_Item *popup_it1;
+   char buf[256];
+
+   win = elm_win_add(NULL, "popup", ELM_WIN_BASIC);
+   elm_win_title_set(win, "Popup");
+   elm_win_autodel_set(win, EINA_TRUE);
+   elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
+
+   bg = elm_bg_add(win);
+   elm_win_resize_object_add(win, bg);
+   evas_object_show(bg);
+
+   popup = elm_popup_add(win);
+
+   icon1 = elm_icon_add(popup);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png", PACKAGE_DATA_DIR);
+   elm_icon_file_set(icon1, buf, NULL);
+
+   //Seting popup title-text
+   elm_object_part_text_set(popup, "title,text", "Title");
+
+   //Appending popup content-items
+   elm_popup_item_append(popup, "Message", NULL, _item_selected_cb, NULL);
+   elm_popup_item_append(popup, "Email", NULL, _item_selected_cb, NULL);
+   elm_popup_item_append(popup, "Contacts", NULL, _item_selected_cb, NULL);
+   elm_popup_item_append(popup, "Video", NULL, _item_selected_cb, NULL);
+   elm_popup_item_append(popup, "Music", NULL, _item_selected_cb, NULL);
+   elm_popup_item_append(popup, "Memo", NULL, _item_selected_cb, NULL);
+   popup_it1 = elm_popup_item_append(popup, "Radio", NULL, _item_selected_cb,
+                                     NULL);
+
+   //Changing the label of the item
+   elm_object_item_text_set(popup_it1, "FM");
+   elm_popup_item_append(popup, "Messenger", NULL, _item_selected_cb, NULL);
+   elm_popup_item_append(popup, "Settings", NULL, _item_selected_cb, NULL);
+   elm_popup_item_append(popup, "App Installer", NULL, _item_selected_cb, NULL);
+   elm_popup_item_append(popup, "Browser", NULL, _item_selected_cb, NULL);
+   elm_popup_item_append(popup, "Weather", icon1, _item_selected_cb, NULL);
+   elm_popup_item_append(popup, "News Feeds", NULL, _item_selected_cb, NULL);
+
+   //Seting popup title-text
+   elm_object_part_text_set(popup, "title,text", "Title");
+
+   // Creating the first action button
+   btn1 = elm_button_add(popup);
+   elm_object_text_set(btn1, "OK");
+
+   //Appending the fist action button
+   elm_object_part_content_set(popup, "button1", btn1);
+   evas_object_smart_callback_add(btn1, "clicked", _response_cb, popup);
+
+   //Creating the second action button
+   btn2 = elm_button_add(popup);
+   elm_object_text_set(btn2, "Cancel");
+   evas_object_smart_callback_add(btn2, "clicked", _response_cb, popup);
+
+   //Appending the second action button
+   elm_object_part_content_set(popup, "button1", btn2);
+
+   //Display the popup object
+   evas_object_show(popup);
+
+   evas_object_resize(win, 480, 800);
+   evas_object_show(win);
+
+   elm_run();
+
+   return 0;
+}
+ELM_MAIN()
+
+static void
+_item_selected_cb(void *data __UNUSED__, Evas_Object *obj __UNUSED__,
+                  void *event_info)
+{
+   printf("popup item selected: %s\n", elm_object_item_text_get(event_info));
+}
+
+static void
+_response_cb(void *data, Evas_Object *obj __UNUSED__,
+             void *event_info __UNUSED__)
+{
+   evas_object_hide(data);
+}
index 7bbc108..3789759 100644 (file)
@@ -172,6 +172,7 @@ EAPI extern Elm_Version *elm_version;
 #include <elc_hoversel.h>
 #include <elc_multibuttonentry.h>
 #include <elc_naviframe.h>
+#include <elc_popup.h>
 #include <elm_actionslider.h> //ok
 #include <elm_app.h> //ok
 #include <elm_bg.h>
index 43917f2..63ed752 100644 (file)
@@ -54,6 +54,7 @@ elc_fileselector.h \
 elc_hoversel.h \
 elc_multibuttonentry.h \
 elc_naviframe.h \
+elc_popup.h \
 elm_actionslider.h \
 elm_app.h \
 elm_authors.h \
@@ -141,6 +142,7 @@ elm_priv.h \
 elc_anchorblock.c \
 elc_anchorview.c \
 elc_ctxpopup.c \
+elc_popup.c \
 elc_fileselector_button.c \
 elc_fileselector.c \
 elc_fileselector_entry.c \
diff --git a/src/lib/elc_popup.c b/src/lib/elc_popup.c
new file mode 100644 (file)
index 0000000..3a9c314
--- /dev/null
@@ -0,0 +1,1417 @@
+#include <Elementary.h>
+#include "elm_priv.h"
+
+#define ELM_POPUP_ACTION_BUTTON_MAX 3
+typedef struct _Widget_Data Widget_Data;
+typedef struct _Elm_Popup_Content_Item Elm_Popup_Content_Item;
+typedef struct _Action_Area_Data Action_Area_Data;
+
+struct _Widget_Data
+{
+   Evas_Object *base;
+   Evas_Object *notify;
+   Evas_Object *title_icon;
+   Evas_Object *content_area;
+   Evas_Object *content_text_obj;
+   Evas_Object *action_area;
+   Evas_Object *box;
+   Evas_Object *scr;
+   Evas_Object *content;
+   Eina_List *items;
+   const char *title_text;
+   Action_Area_Data *buttons[ELM_POPUP_ACTION_BUTTON_MAX];
+   Elm_Wrap_Type content_text_wrap_type;
+   unsigned int button_count;
+   Evas_Coord max_sc_w;
+   Evas_Coord max_sc_h;
+   Eina_Bool scr_size_recalc:1;
+};
+
+struct _Elm_Popup_Content_Item
+{
+   Elm_Widget_Item base;
+   const char *label;
+   Evas_Object *icon;
+   Evas_Smart_Cb func;
+   Eina_Bool disabled:1;
+};
+
+struct _Action_Area_Data
+{
+   Evas_Object *obj;
+   Evas_Object *btn;
+   Eina_Bool delete_me;
+};
+
+static const char *widtype = NULL;
+static void _del_hook(Evas_Object *obj);
+static void _theme_hook(Evas_Object *obj);
+static void _text_set_hook(Evas_Object *obj, const char *part,
+                                          const char *label);
+static const char *_text_get_hook(const Evas_Object *obj,
+                                                 const char *part);
+static void _content_set_hook(Evas_Object *obj, const char *part,
+                                             Evas_Object *content);
+static Evas_Object *_content_get_hook(Evas_Object *obj,
+                                                     const char *part);
+static Evas_Object *_content_unset_hook(Evas_Object *obj,
+                                                       const char *part);
+static void _item_text_set_hook(Elm_Object_Item *it, const char *part,
+                                const char *label);
+static const char *_item_text_get_hook(const Elm_Object_Item *it,
+                                       const char *part);
+static void _item_content_set_hook(Elm_Object_Item *it, const char *part,
+                                   Evas_Object *content);
+static Evas_Object *_item_content_unset_hook(const Elm_Object_Item *it,
+                                             const char *part);
+static Evas_Object *_item_content_get_hook(const Elm_Object_Item *it,
+                                           const char *part);
+static void _item_disable_hook(Elm_Object_Item *it);
+static void _item_del_pre_hook(Elm_Object_Item *it);
+static void _item_signal_emit_hook(Elm_Object_Item *it, const char *emission,
+                                   const char *source);
+static void _sizing_eval(Evas_Object *obj);
+static void _block_clicked_cb(void *data, Evas_Object *obj, void *event_info);
+static void _notify_resize(void *data, Evas *e, Evas_Object *obj,
+                           void *event_info);
+static void _scroller_resize(void *data, Evas *e, Evas_Object *obj,
+                             void *event_info);
+static void _timeout(void *data, Evas_Object *obj , void *event_info);
+static void _sub_del(void *data, Evas_Object *obj, void *event_info);
+static void _mirrored_set(Evas_Object *obj, Eina_Bool rtl);
+static void _restack(void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _layout_change_cb(void *data, Evas_Object *obj __UNUSED__,
+                              const char *emission __UNUSED__,
+                              const char *source __UNUSED__);
+static void _item_new(Elm_Popup_Content_Item *item);
+static void _remove_items(Widget_Data *wd);
+static void _list_new(Evas_Object *obj);
+static void _list_del(Widget_Data *wd);
+static void _item_sizing_eval(Elm_Popup_Content_Item *item);
+static void _item_select_cb(void *data, Evas_Object *obj __UNUSED__,
+                            const char *emission __UNUSED__,
+                            const char *source __UNUSED__);
+static void _scroller_size_calc(Evas_Object *obj);
+static void _action_button_set(Evas_Object *obj, Evas_Object *btn,
+                               unsigned int idx);
+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 const char SIG_BLOCK_CLICKED[] = "block,clicked";
+static const char SIG_TIMEOUT[] = "timeout";
+static const Evas_Smart_Cb_Description _signals[] = {
+       {SIG_BLOCK_CLICKED, ""},
+       {SIG_TIMEOUT, ""},
+       {NULL, NULL}
+};
+
+#define ELM_POPUP_CONTENT_ITEM_CHECK_RETURN(it, ...)                        \
+  ELM_WIDGET_ITEM_CHECK_OR_RETURN((Elm_Widget_Item *)it, __VA_ARGS__); \
+  ELM_CHECK_WIDTYPE(WIDGET(item), widtype) __VA_ARGS__;
+
+static void
+_layout_set(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd) return;
+   if ((!(wd->title_text)) && (!(wd->title_icon)))
+     elm_object_signal_emit(wd->base, "elm,state,title_area,hidden", "elm");
+   else
+     elm_object_signal_emit(wd->base, "elm,state,title_area,visible", "elm");
+   if (wd->button_count)
+     elm_object_signal_emit(wd->base, "elm,state,action_area,visible", "elm");
+   else
+     elm_object_signal_emit(wd->base, "elm,state,action_area,hidden", "elm");
+}
+
+static void
+_del_hook(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd) return;
+   free(wd);
+}
+
+static void
+_del_pre_hook(Evas_Object *obj)
+{
+   unsigned int i;
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd) return;
+   evas_object_smart_callback_del(wd->notify, "block,clicked",
+                                  _block_clicked_cb);
+   evas_object_smart_callback_del(wd->notify, "timeout", _timeout);
+   evas_object_event_callback_del(wd->notify, EVAS_CALLBACK_RESIZE,
+                                  _notify_resize);
+   wd->button_count = 0;
+   for (i = 0; i < ELM_POPUP_ACTION_BUTTON_MAX; i++)
+     if (wd->buttons[i])
+       {
+          evas_object_del(wd->buttons[i]->btn);
+          free(wd->buttons[i]);
+          wd->buttons[i] = NULL;
+       }
+   if (wd->items)
+     {
+        _remove_items(wd);
+        _list_del(wd);
+     }
+}
+
+static void
+_theme_hook(Evas_Object *obj)
+{
+   Eina_List *elist;
+   Elm_Popup_Content_Item *item;
+   char buf[128];
+   unsigned int i = 0;
+   Widget_Data *wd = elm_widget_data_get(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)
+     {
+        snprintf(buf, sizeof(buf), "buttons%u", wd->button_count);
+        elm_layout_theme_set(wd->action_area, "popup", buf,
+                             elm_widget_style_get(obj));
+        for (i = 0; i < ELM_POPUP_ACTION_BUTTON_MAX; i++)
+          {
+             if (!wd->buttons[i]) continue;
+             elm_object_style_set(wd->buttons[i]->btn, buf);
+          }
+     }
+   elm_layout_theme_set(wd->content_area, "popup", "content",
+                        elm_widget_style_get(obj));
+   if (wd->content_text_obj)
+     {
+        snprintf(buf, sizeof(buf), "popup/%s", elm_widget_style_get(obj));
+        elm_object_style_set(wd->content_text_obj, buf);
+     }
+   else if (wd->items)
+     {
+        EINA_LIST_FOREACH(wd->items, elist, item)
+          {
+             _elm_theme_object_set(obj, VIEW(item), "popup",
+                                   "item", elm_widget_style_get(obj));
+             if (item->label)
+               {
+                  edje_object_part_text_set(VIEW(item), "elm.text",
+                                            item->label);
+                  edje_object_signal_emit(VIEW(item),
+                                          "elm,state,item,text,visible", "elm");
+               }
+             if (item->icon)
+               edje_object_signal_emit(VIEW(item),
+                                       "elm,state,item,icon,visible", "elm");
+             if (item->disabled)
+               edje_object_signal_emit(VIEW(item),
+                                       "elm,state,item,disabled", "elm");
+             evas_object_show(VIEW(item));
+             edje_object_message_signal_process(VIEW(item));
+          }
+        _scroller_size_calc(obj);
+     }
+   if (wd->title_text)
+     {
+        elm_object_part_text_set(wd->base, "elm.text.title", wd->title_text);
+        elm_object_signal_emit(wd->base, "elm,state,title,text,visible", "elm");
+     }
+   if (wd->title_icon)
+     elm_object_signal_emit(wd->base, "elm,state,title,icon,visible", "elm");
+   _layout_set(obj);
+   edje_object_message_signal_process(elm_layout_edje_get(wd->base));
+   _sizing_eval(obj);
+}
+
+static void
+_item_sizing_eval(Elm_Popup_Content_Item *item)
+{
+   Evas_Coord min_w = -1, min_h = -1, max_w = -1, max_h = -1;
+
+   edje_object_size_min_restricted_calc(VIEW(item), &min_w, &min_h, min_w,
+                                        min_h);
+   evas_object_size_hint_min_set(VIEW(item), min_w, min_h);
+   evas_object_size_hint_max_set(VIEW(item), max_w, max_h);
+}
+
+static void
+_sizing_eval(Evas_Object *obj)
+{
+   Eina_List *elist;
+   Elm_Popup_Content_Item *item;
+   Evas_Coord w_box = 0, h_box = 0;
+   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);
+
+   if (!wd) return;
+   if (wd->items)
+     {
+        EINA_LIST_FOREACH(wd->items, elist, item)
+          {
+             _item_sizing_eval(item);
+             evas_object_size_hint_min_get(VIEW(item), &minw_box,
+                                           &minh_box);
+             if (minw_box > w_box)
+               w_box = minw_box;
+             if (minh_box != -1)
+               h_box += minh_box;
+          }
+        evas_object_size_hint_min_set(wd->box, w_box, h_box);
+        evas_object_size_hint_min_set(wd->scr, w_box, MIN(h_box, wd->max_sc_h));
+        evas_object_size_hint_max_set(wd->scr, w_box, wd->max_sc_h);
+        evas_object_smart_calculate(wd->scr);
+     }
+   edje_object_size_min_calc(elm_layout_edje_get(wd->base), &minw, &minh);
+   evas_object_size_hint_min_set(wd->base, minw, minh);
+   evas_object_size_hint_max_set(wd->base, maxw, maxh);
+   evas_object_size_hint_min_set(obj, minw, minh);
+   evas_object_size_hint_max_set(obj, maxw, maxh);
+   elm_layout_sizing_eval(wd->base);
+}
+
+static void
+_changed_size_hints(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__,
+                    void *event_info __UNUSED__)
+{
+   _sizing_eval(data);
+}
+
+static void
+_sub_del(void *data, Evas_Object *obj, void *event_info)
+{
+   Elm_Popup_Content_Item *item;
+   unsigned int i;
+   Evas_Object *sub = event_info;
+   Widget_Data *wd = elm_widget_data_get(data);
+
+   if (!wd) return;
+   if (obj == data)
+     {
+        if ((item = evas_object_data_get(sub, "_popup_content_item")) != NULL)
+          {
+             if (sub == item->icon)
+               {
+                  edje_object_part_unswallow(VIEW(item), sub);
+                  edje_object_signal_emit(VIEW(item),
+                                          "elm,state,item,icon,hidden", "elm");
+                  item->icon = NULL;
+               }
+          }
+     }
+   else if (obj == wd->content_area)
+     {
+        if (sub == wd->content)
+          {
+             wd->content = NULL;
+             elm_object_part_content_unset(wd->base, "elm.swallow.content");
+             _sizing_eval(data);
+          }
+        else if (sub == wd->content_text_obj)
+          {
+             wd->content_text_obj = NULL;
+             elm_object_part_content_unset(wd->base, "elm.swallow.content");
+             _sizing_eval(data);
+          }
+        else if (sub == wd->scr)
+          {
+             wd->scr = NULL;
+             wd->box = NULL;
+             elm_object_part_content_unset(wd->base, "elm.swallow.content");
+             _sizing_eval(data);
+          }
+     }
+   else if (obj == wd->action_area)
+     {
+        for (i = 0; i < ELM_POPUP_ACTION_BUTTON_MAX; i++)
+          {
+             if (wd->buttons[i] && sub == wd->buttons[i]->btn &&
+                      wd->buttons[i]->delete_me == EINA_TRUE)
+               {
+                  _button_remove(data, sub, EINA_FALSE);
+                  break;
+               }
+          }
+     }
+   else if (obj == wd->base)
+     {
+        if (sub == wd->title_icon)
+          {
+             elm_object_signal_emit(wd->base, "elm,state,title,icon,hidden",
+                                    "elm");
+             edje_object_message_signal_process(wd->base);
+             wd->title_icon = NULL;
+          }
+     }
+}
+
+static void
+_block_clicked_cb(void *data, Evas_Object *obj __UNUSED__,
+                  void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+
+   if (!wd) return;
+   evas_object_smart_callback_call(data, SIG_BLOCK_CLICKED, NULL);
+}
+
+static void
+_timeout(void *data, Evas_Object *obj __UNUSED__, void *event_info __UNUSED__)
+{
+   evas_object_hide(data);
+   evas_object_smart_callback_call(data, SIG_TIMEOUT, NULL);
+}
+
+static void
+_mirrored_set(Evas_Object *obj, Eina_Bool rtl)
+{
+   Eina_List *elist;
+   Elm_Popup_Content_Item *item;
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd) return;
+   elm_object_mirrored_set(wd->notify, rtl);
+   if (wd->items)
+     EINA_LIST_FOREACH(wd->items, elist, item)
+       edje_object_mirrored_set(VIEW(item), rtl);
+}
+
+static void
+_layout_change_cb(void *data, Evas_Object *obj __UNUSED__,
+                  const char *emission __UNUSED__,
+                  const char *source __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get((Evas_Object*)data);
+
+   if (!wd) return;
+   if (wd->base)
+     elm_layout_sizing_eval(wd->base);
+}
+
+static void
+_restack(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *obj,
+         void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd) return;
+   evas_object_layer_set(wd->notify, evas_object_layer_get(obj));
+}
+
+static void
+_scroller_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj,
+                 void *event_info __UNUSED__)
+{
+   Evas_Coord w, h;
+   Widget_Data *wd = elm_widget_data_get(data);
+
+   if (!wd || wd->scr_size_recalc) return;
+   evas_object_geometry_get(obj, NULL, NULL, &w, &h);
+   if (w && h)
+     {
+        if ((w <= wd->max_sc_w) && (h <= wd->max_sc_h))
+          {
+             _sizing_eval(data);
+             wd->scr_size_recalc = EINA_TRUE;
+             return;
+          }
+     }
+   if (wd->max_sc_w < w)
+     wd->max_sc_w = w;
+   if (wd->max_sc_h < h)
+     wd->max_sc_h = h;
+   _sizing_eval(data);
+}
+
+static void
+_list_new(Evas_Object *obj)
+{
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd) return;
+   //Scroller
+   wd->scr = elm_scroller_add(obj);
+   elm_scroller_bounce_set(wd->scr, EINA_FALSE, EINA_TRUE);
+   elm_object_content_set(wd->scr, wd->box);
+   evas_object_size_hint_weight_set(wd->scr, EVAS_HINT_EXPAND,
+                                    EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(wd->scr, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_event_callback_add(wd->scr, EVAS_CALLBACK_RESIZE,
+                                  _scroller_resize, obj);
+   evas_object_event_callback_add(wd->scr,
+                                  EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+                                  _changed_size_hints, obj);
+   elm_object_part_content_set(wd->base, "elm.swallow.content", wd->scr);
+
+   //Box
+   wd->box = elm_box_add(obj);
+   evas_object_size_hint_weight_set(wd->box, EVAS_HINT_EXPAND,
+                                    EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(wd->box, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+   elm_object_content_set(wd->scr, wd->box);
+}
+
+static void
+_list_del(Widget_Data *wd)
+{
+   if (!wd->scr) return;
+   elm_object_part_content_unset(wd->base, "elm.swallow.content");
+   evas_object_event_callback_del(wd->scr, EVAS_CALLBACK_RESIZE,
+                                  _scroller_resize);
+   evas_object_event_callback_del(wd->scr, EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+                                  _changed_size_hints);
+   evas_object_del(wd->scr);
+   wd->scr = NULL;
+   wd->box = NULL;
+}
+
+static void
+_scroller_size_calc(Evas_Object *obj)
+{
+   Evas_Coord h;
+   Evas_Coord h_title = 0;
+   Evas_Coord h_action_area = 0;
+   Evas_Coord h_content = 0;
+   const char *action_area_height;
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd || !wd->items) return;
+   wd->scr_size_recalc = EINA_FALSE;
+   wd->max_sc_h = -1;
+   wd->max_sc_w = -1;
+   evas_object_geometry_get(wd->notify, NULL, NULL, NULL, &h);
+   if (wd->title_text || wd->title_icon)
+     edje_object_part_geometry_get(elm_layout_edje_get(wd->base),
+                                   "elm.bg.title", NULL, NULL, NULL, &h_title);
+   if (wd->button_count)
+     {
+        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));
+     }
+   h_content = h - (h_title + h_action_area);
+   wd->max_sc_h = h_content;
+}
+
+static void
+_item_select_cb(void *data, Evas_Object *obj __UNUSED__,
+                const char *emission __UNUSED__, const char *source __UNUSED__)
+{
+   Elm_Popup_Content_Item *item = data;
+
+   if (!item || item->disabled) return;
+   if (item->func)
+     item->func((void*) item->base.data, WIDGET(item), data);
+}
+
+static void
+_item_new(Elm_Popup_Content_Item *item)
+{
+   Widget_Data *wd = elm_widget_data_get(WIDGET(item));
+
+   if (!wd) return;
+   elm_widget_item_text_set_hook_set(item, _item_text_set_hook);
+   elm_widget_item_text_get_hook_set(item, _item_text_get_hook);
+   elm_widget_item_content_set_hook_set(item, _item_content_set_hook);
+   elm_widget_item_content_get_hook_set(item, _item_content_get_hook);
+   elm_widget_item_content_unset_hook_set(item, _item_content_unset_hook);
+   elm_widget_item_disable_hook_set(item, _item_disable_hook);
+   elm_widget_item_del_pre_hook_set(item, _item_del_pre_hook);
+   elm_widget_item_signal_emit_hook_set(item, _item_signal_emit_hook);
+   VIEW(item) = edje_object_add(evas_object_evas_get(wd->base));
+   _elm_theme_object_set(WIDGET(item), VIEW(item), "popup", "item",
+                         elm_widget_style_get(WIDGET(item)));
+   edje_object_mirrored_set(VIEW(item), elm_widget_mirrored_get(WIDGET(item)));
+   edje_object_signal_callback_add(VIEW(item), "elm,action,click", "",
+                                   _item_select_cb, item);
+   evas_object_size_hint_align_set(VIEW(item), EVAS_HINT_FILL,
+                                   EVAS_HINT_FILL);
+   evas_object_show(VIEW(item));
+}
+
+static void
+_remove_items(Widget_Data *wd)
+{
+   Eina_List *elist;
+   Elm_Popup_Content_Item *item;
+
+   if (!wd->items) return;
+   EINA_LIST_FOREACH(wd->items, elist, item)
+     {
+        if (item->label)
+          eina_stringshare_del(item->label);
+        if (item->icon)
+          {
+             evas_object_del(item->icon);
+             item->icon = NULL;
+          }
+        evas_object_del(VIEW(item));
+        wd->items = eina_list_remove(wd->items, item);
+        free(item);
+     }
+   wd->items = NULL;
+}
+
+static void
+_notify_resize(void *data, Evas *e __UNUSED__, Evas_Object *obj __UNUSED__,
+               void *event_info __UNUSED__)
+{
+   Widget_Data *wd = elm_widget_data_get(data);
+
+   if (wd->items)
+     _scroller_size_calc(data);
+   _sizing_eval(data);
+}
+
+static void
+_title_text_set(Evas_Object *obj, const char *text)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Eina_Bool title_visibility_old, title_visibility_current;
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd) return;
+   if (wd->title_text == text) return;
+   title_visibility_old = (wd->title_text) || (wd->title_icon);
+   eina_stringshare_replace(&wd->title_text, text);
+   elm_object_part_text_set(wd->base, "elm.text.title", text);
+   if (wd->title_text)
+     elm_object_signal_emit(wd->base, "elm,state,title,text,visible", "elm");
+   else
+     elm_object_signal_emit(wd->base, "elm,state,title,text,hidden", "elm");
+   title_visibility_current = (wd->title_text) || (wd->title_icon);
+   if (title_visibility_old != title_visibility_current)
+     _layout_set(obj);
+   edje_object_message_signal_process(wd->base);
+   _sizing_eval(obj);
+}
+
+static void
+_content_text_set(Evas_Object *obj, const char *text)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Evas_Object *prev_content;
+   char buf[128];
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd) return;
+   if (wd->items)
+     {
+        _remove_items(wd);
+        _list_del(wd);
+     }
+   prev_content = elm_object_part_content_get(wd->content_area,
+                                              "elm.swallow.content");
+   if (prev_content)
+     evas_object_del(prev_content);
+   if (text)
+     {
+        elm_object_part_content_set(wd->base, "elm.swallow.content",
+                                    wd->content_area);
+        wd->content_text_obj = elm_label_add(obj);
+        snprintf(buf, sizeof(buf), "popup/%s",
+                 elm_widget_style_get(obj));
+        elm_object_style_set(wd->content_text_obj, buf);
+        elm_label_line_wrap_set(wd->content_text_obj,
+                                wd->content_text_wrap_type);
+        elm_object_text_set(wd->content_text_obj, text);
+        evas_object_size_hint_weight_set(wd->content_text_obj, EVAS_HINT_EXPAND,
+                                         0.0);
+        evas_object_size_hint_align_set(wd->content_text_obj, EVAS_HINT_FILL,
+                                        EVAS_HINT_FILL);
+        elm_object_part_content_set(wd->content_area, "elm.swallow.content",
+                                    wd->content_text_obj);
+     }
+   _sizing_eval(obj);
+}
+
+static void
+_text_set_hook(Evas_Object *obj, const char *part,
+                              const char *label)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd) return;
+   if (!part || !strcmp(part, "default"))
+     _content_text_set(obj, label);
+   else if (!strcmp(part, "title,text"))
+     _title_text_set(obj, label);
+   else
+     WRN("The part name is invalid! : popup=%p", obj);
+}
+
+static const char*
+_title_text_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd) return NULL;
+   return wd->title_text;
+}
+
+static const char*
+_content_text_get(const Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   const char *str = NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd) return NULL;
+   if (wd->content_text_obj)
+     str = elm_object_text_get(wd->content_text_obj);
+   return str;
+}
+
+static const char *
+_text_get_hook(const Evas_Object *obj, const char *part)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   const char *str = NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd) return NULL;
+   if (!part || !strcmp(part, "default"))
+     str = _content_text_get(obj);
+   else if (!strcmp(part, "title,text"))
+     str = _title_text_get(obj);
+   else
+     WRN("The part name is invalid! : popup=%p", obj);
+   return str;
+}
+
+static void
+_title_icon_set(Evas_Object *obj, Evas_Object *icon)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Eina_Bool title_visibility_old, title_visibility_current;
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   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;
+     }
+   wd->title_icon = icon;
+   title_visibility_current = (wd->title_text) || (wd->title_icon);
+   elm_object_part_content_set(wd->base, "elm.swallow.title.icon",
+                               wd->title_icon);
+   if (wd->title_icon)
+     elm_object_signal_emit(wd->base, "elm,state,title,icon,visible", "elm");
+   if (title_visibility_old != title_visibility_current) _layout_set(obj);
+   edje_object_message_signal_process(wd->base);
+   _sizing_eval(obj);
+}
+
+static void
+_content_set(Evas_Object *obj, Evas_Object *content)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Evas_Object *prev_content;
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd) return;
+   if (wd->content && wd->content == content) return;
+   if (wd->items)
+     {
+        _remove_items(wd);
+        _list_del(wd);
+     }
+   prev_content = elm_object_part_content_get(wd->content_area,
+                                              "elm.swallow.content");
+   if (prev_content)
+     evas_object_del(prev_content);
+   wd->content = content;
+   if (content)
+     {
+        elm_object_part_content_set(wd->base, "elm.swallow.content",
+                                    wd->content_area);
+        elm_object_part_content_set(wd->content_area, "elm.swallow.content",
+                                    content);
+     }
+   _sizing_eval(obj);
+}
+
+static void
+_button_remove(Evas_Object *obj, Evas_Object *content, Eina_Bool delete)
+{
+   unsigned int i = 0, position = 0;
+   char buf[128];
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd->button_count) return;
+   for (i = 0; i < ELM_POPUP_ACTION_BUTTON_MAX; i++)
+    {
+       if (wd->buttons[i])
+         {
+            position++;
+            wd->buttons[i]->delete_me = EINA_FALSE;
+            if (wd->buttons[i]->btn == content)
+              {
+                 snprintf(buf, sizeof(buf), "actionbtn%u", position);
+                 elm_object_part_content_unset(wd->action_area, buf);
+                 evas_object_hide(content);
+                 if (delete) evas_object_del(content);
+                 free(wd->buttons[i]);
+                 wd->buttons[i] = NULL;
+                 wd->button_count -= 1;
+               }
+         }
+    }
+   position = 0;
+   for (i = 0; i < ELM_POPUP_ACTION_BUTTON_MAX; i++)
+    {
+       if (!wd->buttons[i]) continue;
+       position++;
+       snprintf(buf, sizeof(buf), "actionbtn%u", position);
+       elm_object_part_content_unset(wd->action_area, buf);
+       elm_object_part_content_set(wd->action_area, buf,
+                                   wd->buttons[i]->btn);
+       wd->buttons[i]->delete_me = EINA_TRUE;
+    }
+   if (!wd->button_count)
+    {
+       _layout_set(obj);
+       edje_object_message_signal_process(elm_layout_edje_get(wd->base));
+    }
+   else
+    {
+       snprintf(buf, sizeof(buf), "buttons%u", wd->button_count);
+       elm_layout_theme_set(wd->action_area, "popup", buf,
+                            elm_widget_style_get(obj));
+    }
+}
+
+static void
+_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;
+   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 (btn)
+     {
+        wd->button_count++;
+        snprintf(buf, sizeof(buf), "buttons%u", wd->button_count);
+        elm_layout_theme_set(wd->action_area, "popup", buf,
+                             elm_widget_style_get(obj));
+        adata = ELM_NEW(Action_Area_Data);
+        adata->obj = obj;
+        adata->btn = btn;
+        wd->buttons[index] = 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
+            of buttons can be achieved in action area.
+         */
+        for (i = 0; i < ELM_POPUP_ACTION_BUTTON_MAX; i++)
+          if (wd->buttons[i])
+            wd->buttons[i]->delete_me = EINA_FALSE;
+        for (i = 0; i < ELM_POPUP_ACTION_BUTTON_MAX; i++)
+          {
+             if (!wd->buttons[i]) continue;
+             position++;
+             snprintf(buf, sizeof(buf), "actionbtn%u", position);
+             elm_object_part_content_unset(wd->action_area, buf);
+             elm_object_part_content_set(wd->action_area, buf,
+                                         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.
+              */
+             wd->buttons[i]->delete_me = EINA_TRUE;
+          }
+        elm_object_part_content_set(wd->base, "elm.swallow.action_area",
+                                    wd->action_area);
+        if (wd->button_count == 1)
+          _layout_set(obj);
+        edje_object_message_signal_process(wd->base);
+        if (wd->items)
+          _scroller_size_calc(obj);
+        _sizing_eval(obj);
+     }
+}
+
+static void
+_content_set_hook(Evas_Object *obj, const char *part,
+                                 Evas_Object *content)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   char buff[3];
+   unsigned int i;
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd) return;
+   if (!part || !strcmp(part, "default"))
+     _content_set(obj, content);
+   else if (!strcmp(part, "title,icon"))
+     _title_icon_set(obj, content);
+   else if (!strncmp(part, "button", 6))
+     {
+        part += 6;
+        for (i = 0; i < ELM_POPUP_ACTION_BUTTON_MAX; i++)
+          {
+             snprintf(buff, sizeof(buff), "%u", i+1);
+             if (!strncmp(part, buff, sizeof(buff)))
+               {
+                  _action_button_set(obj, content, i+1);
+                  break;
+               }
+          }
+      }
+   else
+     WRN("The part name is invalid! : popup=%p", obj);
+}
+
+static Evas_Object *
+_title_icon_get(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd) return NULL;
+   return wd->title_icon;
+}
+
+static Evas_Object *
+_content_get(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd) return NULL;
+   return wd->content;
+}
+
+static Evas_Object *
+_action_button_get(Evas_Object *obj, unsigned int idx)
+{
+   unsigned int index = 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;
+   return button;
+}
+
+static Evas_Object *
+_content_get_hook(Evas_Object *obj, const char *part)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Evas_Object *content = NULL;
+   char buff[3];
+   unsigned int i;
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd) return NULL;
+   if (!part || !strcmp(part, "default"))
+     content = _content_get(obj);
+   else if (!strcmp(part, "title,text"))
+     content = _title_icon_get(obj);
+   else if (!strncmp(part, "button", 6))
+     {
+        part += 6;
+        for (i = 0; i < ELM_POPUP_ACTION_BUTTON_MAX; i++)
+          {
+             snprintf(buff, sizeof(buff), "%u", i+1);
+             if (!strncmp(part, buff, sizeof(buff)))
+               {
+                  content = _action_button_get(obj, i+1);
+                  break;
+               }
+          }
+      }
+   else
+     WRN("The part name is invalid! : popup=%p", obj);
+   return content;
+}
+
+static Evas_Object *
+_content_unset(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Evas_Object *content;
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd || !wd->content) return NULL;
+   content = elm_object_part_content_unset(wd->content_area,
+                                           "elm.swallow.content");
+   wd->content = NULL;
+   _sizing_eval(obj);
+   return content;
+}
+
+static Evas_Object *
+_title_icon_unset(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Evas_Object *icon;
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd || !wd->title_icon) return NULL;
+   icon = elm_object_part_content_unset(wd->base, "elm.swallow.title.icon");
+   wd->title_icon = NULL;
+   return icon;
+}
+
+static Evas_Object *
+_action_button_unset(Evas_Object *obj, unsigned int idx)
+{
+   unsigned int index = 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))
+     return NULL;
+
+   if (wd->buttons[index])
+     {
+        button = wd->buttons[index]->btn;
+        _button_remove(obj, button, EINA_FALSE);
+      }
+   return button;
+}
+
+static Evas_Object *
+_content_unset_hook(Evas_Object *obj, const char *part)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Evas_Object *content = NULL;
+   char buff[3];
+   unsigned int i;
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd) return NULL;
+   if (!part || !strcmp(part, "default"))
+     content = _content_unset(obj);
+   else if (!strcmp(part, "title,icon"))
+     content = _title_icon_unset(obj);
+   else if (!strncmp(part, "button", 6))
+     {
+        part += 6;
+        for (i = 0; i < ELM_POPUP_ACTION_BUTTON_MAX; i++)
+          {
+             snprintf(buff, sizeof(buff), "%u", i+1);
+             if (!strncmp(part, buff, sizeof(buff)))
+               {
+                  content = _action_button_unset(obj, i+1);
+                  break;
+               }
+          }
+      }
+   else
+     WRN("The part name is invalid! : popup=%p", obj);
+   return content;
+}
+
+static Eina_Bool
+_focus_next_hook(const Evas_Object *obj __UNUSED__,
+                 Elm_Focus_Direction dir __UNUSED__,
+                 Evas_Object **next __UNUSED__)
+{
+   //TODO: Implement Focus chanin Handling in Popup for action area buttons
+   return EINA_FALSE;
+}
+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);
+   if (item->label)
+     edje_object_signal_emit(VIEW(item),
+                             "elm,state,item,text,visible", "elm");
+   else
+     edje_object_signal_emit(VIEW(item),
+                             "elm,state,item,text,hidden", "elm");
+   edje_object_message_signal_process(VIEW(item));
+}
+
+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;
+
+   if ((!part) || (!strcmp(part, "default")))
+     {
+        _item_text_set(item, label);
+        return;
+     }
+   WRN("The part name is invalid! : popup=%p", WIDGET(item));
+}
+
+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;
+
+   if ((!part) || (!strcmp(part, "default")))
+     return item->label;
+   WRN("The part name is invalid! : popup=%p", WIDGET(item));
+   return NULL;
+}
+
+static void
+_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);
+     }
+   item->icon = icon;
+   if (item->icon)
+     {
+        elm_widget_sub_object_add(WIDGET(item), item->icon);
+        evas_object_data_set(item->icon, "_popup_content_item", item);
+        edje_object_part_swallow(VIEW(item), "elm.swallow.content",
+                                 item->icon);
+        edje_object_signal_emit(VIEW(item),
+                                "elm,state,item,icon,visible", "elm");
+     }
+   else
+     edje_object_signal_emit(VIEW(item),
+                             "elm,state,item,icon,hidden", "elm");
+   edje_object_message_signal_process(item->base.view);
+}
+
+static void
+_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;
+
+   if ((!(part)) || (!strcmp(part, "default")))
+     _item_icon_set(item, content);
+   else
+     WRN("The part name is invalid! : popup=%p", WIDGET(item));
+}
+
+static Evas_Object *
+_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;
+
+   if ((!(part)) || (!strcmp(part, "default")))
+     return item->icon;
+   WRN("The part name is invalid! : popup=%p", WIDGET(item));
+   return NULL;
+}
+
+static Evas_Object *
+_item_icon_unset(Elm_Popup_Content_Item *item)
+{
+   Evas_Object *icon = item->icon;
+
+   if (!item->icon) return NULL;
+   elm_widget_sub_object_del(WIDGET(item), icon);
+   evas_object_data_del(icon, "_popup_content_item");
+   edje_object_part_unswallow(item->base.view, icon);
+   edje_object_signal_emit(VIEW(item),
+                           "elm,state,item,icon,hidden", "elm");
+   item->icon = NULL;
+   return icon;
+}
+
+static Evas_Object *
+_item_content_unset_hook(const Elm_Object_Item *it,
+                         const char *part)
+{
+   ELM_OBJ_ITEM_CHECK_OR_RETURN(it, NULL);
+   Evas_Object *content = NULL;
+   Elm_Popup_Content_Item *item = (Elm_Popup_Content_Item *) it;
+
+   if ((!(part)) || (!strcmp(part, "default")))
+     content = _item_icon_unset(item);
+   else
+     WRN("The part name is invalid! : popup=%p", WIDGET(item));
+   return content;
+}
+
+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;
+   Widget_Data *wd = elm_widget_data_get(WIDGET(item));
+
+   if (!wd) return;
+   if (elm_widget_item_disabled_get(it))
+     edje_object_signal_emit(VIEW(item), "elm,state,item,disabled", "elm");
+   else
+     edje_object_signal_emit(VIEW(item), "elm,state,item,enabled", "elm");
+}
+
+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;
+   Widget_Data *wd = elm_widget_data_get(WIDGET(item));
+
+   if (!wd) return;
+   if (item->icon)
+     evas_object_del(item->icon);
+   eina_stringshare_del(item->label);
+   wd->items = eina_list_remove(wd->items, item);
+   if (!eina_list_count(wd->items))
+     {
+        wd->items = NULL;
+        _list_del(wd);
+     }
+}
+
+static void
+_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;
+
+   edje_object_signal_emit(VIEW(item), emission, source);
+}
+
+EAPI Evas_Object *
+elm_popup_add(Evas_Object *parent)
+{
+   Evas_Object *obj;
+   Evas *e;
+   int i = 0;
+   Widget_Data *wd;
+
+   ELM_WIDGET_STANDARD_SETUP(wd, Widget_Data, parent, e, obj, NULL);
+   ELM_SET_WIDTYPE(widtype, "popup");
+   elm_widget_type_set(obj, widtype);
+   elm_widget_sub_object_add(parent, obj);
+   elm_widget_data_set(obj, wd);
+   elm_widget_del_pre_hook_set(obj, _del_pre_hook);
+   elm_widget_del_hook_set(obj, _del_hook);
+   elm_widget_theme_hook_set(obj, _theme_hook);
+   elm_widget_text_set_hook_set(obj, _text_set_hook);
+   elm_widget_text_get_hook_set(obj, _text_get_hook);
+   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_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);
+   evas_object_size_hint_weight_set(wd->notify,
+                                    EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(wd->notify, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_object_style_set(wd->notify, "popup");
+
+   evas_object_event_callback_add(wd->notify, EVAS_CALLBACK_RESIZE,
+                                  _notify_resize, obj);
+   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,
+                                    EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(wd->base, EVAS_HINT_FILL, EVAS_HINT_FILL);
+
+   elm_layout_theme_set(wd->base, "popup", "base", elm_widget_style_get(obj));
+   elm_object_content_set(wd->notify, wd->base);
+
+   elm_object_signal_callback_add(wd->base, "elm,state,title_area,visible",
+                                  "elm", _layout_change_cb, obj);
+   elm_object_signal_callback_add(wd->base, "elm,state,title_area,hidden",
+                                  "elm", _layout_change_cb, obj);
+   elm_object_signal_callback_add(wd->base, "elm,state,action_area,visible",
+                                  "elm", _layout_change_cb, obj);
+   elm_object_signal_callback_add(wd->base, "elm,state,action_area,hidden",
+                                  "elm", _layout_change_cb, obj);
+   wd->content_area = elm_layout_add(obj);
+   elm_layout_theme_set(wd->content_area, "popup", "content",
+                        elm_widget_style_get(obj));
+   wd->action_area = elm_layout_add(obj);
+   evas_object_size_hint_weight_set(wd->action_area, EVAS_HINT_EXPAND,
+                                    EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(wd->action_area, EVAS_HINT_FILL,
+                                   EVAS_HINT_FILL);
+   evas_object_event_callback_add(wd->action_area,
+                                  EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+                                  _changed_size_hints, obj);
+   evas_object_event_callback_add(wd->content_area,
+                                  EVAS_CALLBACK_CHANGED_SIZE_HINTS,
+                                  _changed_size_hints, obj);
+   evas_object_smart_callback_add(wd->base, "sub-object-del",
+                                  _sub_del, obj);
+   evas_object_smart_callback_add(wd->content_area, "sub-object-del",
+                                  _sub_del, obj);
+   evas_object_smart_callback_add(wd->action_area, "sub-object-del",
+                                  _sub_del, obj);
+   evas_object_smart_callback_add(obj, "sub-object-del",
+                                  _sub_del, obj);
+
+   wd->content_text_wrap_type = ELM_WRAP_MIXED;
+   evas_object_smart_callback_add(wd->notify, "block,clicked",
+                                  _block_clicked_cb, obj);
+   evas_object_smart_callback_add(wd->notify, "timeout", _timeout, obj);
+   for (i = 0; i < ELM_POPUP_ACTION_BUTTON_MAX; i++)
+     wd->buttons[i] = NULL;
+   _layout_set(obj);
+   //TODO: To use scroller for description also
+   return obj;
+}
+
+EAPI void
+elm_popup_content_text_wrap_type_set(Evas_Object *obj, Elm_Wrap_Type wrap)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Evas_Object *content_text_obj;
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd) return;
+   if (wd->content_text_wrap_type == ELM_WRAP_NONE) return;
+   //Need to wrap the content text, so not allowing ELM_WRAP_NONE
+   wd->content_text_wrap_type = wrap;
+   if (wd->content_text_obj)
+     {
+        content_text_obj = elm_object_part_content_get(wd->content_area,
+                                                       "elm.swallow.content");
+        elm_label_line_wrap_set(content_text_obj, wrap);
+     }
+}
+
+EAPI Elm_Wrap_Type
+elm_popup_content_text_wrap_type_get(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) ELM_WRAP_LAST;
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd) return ELM_WRAP_LAST;
+   return wd->content_text_wrap_type;
+}
+
+EAPI void
+elm_popup_orient_set(Evas_Object *obj, Elm_Popup_Orient orient)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd) return;
+   if (orient >= ELM_POPUP_ORIENT_LAST) return;
+   elm_notify_orient_set(wd->notify, (Elm_Notify_Orient)orient);
+}
+
+EAPI Elm_Popup_Orient
+elm_popup_orient_get(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) -1;
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd) return ELM_POPUP_ORIENT_LAST;
+   return (Elm_Popup_Orient)elm_notify_orient_get(wd->notify);
+}
+
+EAPI void
+elm_popup_timeout_set(Evas_Object *obj, double timeout)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd) return;
+   elm_notify_timeout_set(wd->notify, timeout);
+}
+
+EAPI double
+elm_popup_timeout_get(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) 0.0;
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd) return 0.0;
+   return elm_notify_timeout_get(wd->notify);
+}
+
+EAPI void
+elm_popup_allow_events_set(Evas_Object *obj, Eina_Bool allow)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype);
+   Eina_Bool allow_events = !!allow;
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd) return;
+   elm_notify_allow_events_set(wd->notify, allow_events);
+}
+
+EAPI Eina_Bool
+elm_popup_allow_events_get(Evas_Object *obj)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) EINA_FALSE;
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd) return EINA_FALSE;
+   return elm_notify_allow_events_get(wd->notify);
+}
+
+EAPI Elm_Object_Item *
+elm_popup_item_append(Evas_Object *obj, const char *label,
+                              Evas_Object *icon, Evas_Smart_Cb func,
+                              const void *data)
+{
+   ELM_CHECK_WIDTYPE(obj, widtype) NULL;
+   Evas_Object *prev_content;
+   Elm_Popup_Content_Item *item;
+   Widget_Data *wd = elm_widget_data_get(obj);
+
+   if (!wd) return NULL;
+   item = elm_widget_item_new(obj, Elm_Popup_Content_Item);
+   if (!item) return NULL;
+   if (wd->content || wd->content_text_obj)
+     {
+        prev_content = elm_object_part_content_get(wd->content_area,
+                                                   "elm.swallow.content");
+        if (prev_content)
+          evas_object_del(prev_content);
+     }
+
+   //The first item is appended.
+   if (!wd->items)
+     _list_new(obj);
+
+   item->func = func;
+   item->base.data = data;
+
+   _item_new(item);
+   _item_icon_set(item, icon);
+   _item_text_set(item, label);
+   elm_box_pack_end(wd->box, VIEW(item));
+   wd->items = eina_list_append(wd->items, item);
+
+   _scroller_size_calc(obj);
+   _sizing_eval(obj);
+   return (Elm_Object_Item *) item;
+}
diff --git a/src/lib/elc_popup.h b/src/lib/elc_popup.h
new file mode 100644 (file)
index 0000000..c2c7cb1
--- /dev/null
@@ -0,0 +1,269 @@
+/**
+ * @defgroup Popup Popup
+ * @ingroup Elementary
+ *
+ * This widget is an enhancement of @ref Notify.
+ * In addition to Content area, there are two optional sections namely Title
+ * area and Action area.
+ *
+ * Popup Widget displays its content with a particular orientation in the parent
+ * area. This orientation can be one among top, center, bottom, left, top-left,
+ * top-right, bottom-left and bottom-right.
+ * Content part of Popup can be an Evas Object set by application or it can be
+ * Text set by application or set of items containing an icon and/or text.
+ * The content/item-list can be removed using elm_object_content_set with second
+ * parameter passed as NULL.
+ *
+ * Following figures shows the textual layouts of popup in which Title Area and
+ * Action area area are optional ones.
+ * Action area can have upto 3 buttons handled using elm_object common APIs
+ * mentioned below. If user wants to have more than 3 buttons then these buttons
+ * can be put inside the items of a list as content.
+ * User needs to handle the clicked signal of these action buttons if required.
+ * No event is processed by the widget automatically when clicked on these
+ * action buttons.
+ *
+ * <pre>
+ *
+ * |-------------------- |    |----------------- ---|    |----------------- ---|
+ * |     Title Area      |    |     Title Area      |    |     Title Area      |
+ * |Icon|    Text        |    |Icon|    Text        |    |Icon|    Text        |
+ * |------------------- -|    |---------------- ----|    |------------------ --|
+ * |       Item 1        |    |                     |    |                     |
+ * |------------------- -|    |                     |    |                     |
+ * |       Item 2        |    |                     |    |    Description      |
+ * |------------------ --|    |       Content       |    |                     |
+ * |       Item 3        |    |                     |    |                     |
+ * |------------------ --|    |                     |    |                     |
+ * |         .           |    |------------------ --|    |------------------- -|
+ * |         .           |    |     Action Area     |    |     Action Area     |
+ * |         .           |    | Btn1  |Btn2|. |Btn3 |    | Btn1  |Btn2|  |Btn3 |
+ * |------------------ --|    |------------------- -|    |------------------- -|
+ * |       Item N        |     Content Based Layout     Description based Layout
+ * |------------------ --|
+ * |     Action Area     |
+ * | Btn1  |Btn2|. |Btn3 |
+ * |------------------- -|
+ *    Item Based Layout
+ *
+ * </pre>
+ *
+ * Timeout can be set on expiry of which popup instance hides and sends a smart
+ * signal "timeout" to the user.
+ * The visible region of popup is surrounded by a translucent region called
+ * Blocked Event area.
+ * By clicking on Blocked Event area, the signal "block,clicked" is sent to
+ * the application. This block event area can be avoided by using
+ * API elm_popup_allow_events_set.
+ * When gets hidden, popup does not get destroyed automatically, application
+ * should destroy the popup instance after use.
+ * To control the maximum height of the internal scroller for item, we use the
+ * height of the action area which is passed by theme based on the number of
+ * buttons currently set to popup.
+ *
+ * Signals that you can add callbacks for are:
+ * @li "timeout" - when ever popup is closed as a result of timeout.
+ * @li "block,clicked" - when ever user taps on Blocked Event area.
+ *
+ * Styles available for Popup
+ * @li "default"
+ *
+ * Default contents parts of the popup widget that you can use for are:
+ * @li "default" - The content of the popup
+ * @li "title,icon" - Title area's icon
+ * @li "button1" - 1st button of the action area
+ * @li "button2" - 2nd button of the action area
+ * @li "button3" - 3rd button of the action area
+ *
+ * Default text parts of the popup widget that you can use for are:
+ * @li "title,text" - This operates on Title area's label
+ * @li "default" - content-text set in the content area of the widget
+ *
+ * Default contents parts of the popup items that you can use for are:
+ * @li "default" -Item's icon
+ *
+ * Default text parts of the popup items that you can use for are:
+ * @li "default" - Item's label
+ *
+ * Supported elm_object common APIs.
+ * @li elm_object_part_content_set
+ * @li elm_object_part_content_get
+ * @li elm_object_part_content_unset
+ *
+ * Supported elm_object_item common APIs.
+ * @li elm_object_item_disabled_set
+ * @li elm_object_item_disabled_get
+ * @li elm_object_item_part_text_set
+ * @li elm_object_item_part_text_get
+ * @li elm_object_item_part_content_set
+ * @li elm_object_item_part_content_get
+ * @li elm_object_item_signal_emit
+ * @li elm_object_item_del
+ *
+ * Here are some sample code to illustrate Popup usage:
+ * @li @ref popup_example_01_c
+ * @li @ref popup_example_02_c
+ * @li @ref popup_example_03_c
+ */
+
+/**
+ * @brief Possible orient values for popup.
+ *
+ * These values should be used in conjunction to elm_popup_orient_set() to
+ * set the position in which the popup should appear(relative to its parent)
+ * and in conjunction with elm_popup_orient_get() to know where the popup
+ * is appearing.
+ *
+ * @ingroup Popup
+ */
+typedef enum
+{
+   ELM_POPUP_ORIENT_TOP = 0, /**< Popup should appear in the top of parent, default */
+   ELM_POPUP_ORIENT_CENTER, /**< Popup should appear in the center of parent */
+   ELM_POPUP_ORIENT_BOTTOM, /**< Popup should appear in the bottom of parent */
+   ELM_POPUP_ORIENT_LEFT, /**< Popup should appear in the left of parent */
+   ELM_POPUP_ORIENT_RIGHT, /**< Popup should appear in the right of parent */
+   ELM_POPUP_ORIENT_TOP_LEFT, /**< Popup should appear in the top left of parent */
+   ELM_POPUP_ORIENT_TOP_RIGHT, /**< Popup should appear in the top right of parent */
+   ELM_POPUP_ORIENT_BOTTOM_LEFT, /**< Popup should appear in the bottom left of parent */
+   ELM_POPUP_ORIENT_BOTTOM_RIGHT, /**< Notify should appear in the bottom right of parent */
+   ELM_POPUP_ORIENT_LAST /**< Sentinel value, @b don't use */
+ } Elm_Popup_Orient;
+
+/**
+ * @brief Adds a new Popup to the parent
+ *
+ * @param parent The parent object
+ * @return The new object or NULL if it cannot be created
+ *
+ * @ingroup Popup
+ */
+EAPI Evas_Object *elm_popup_add(Evas_Object *parent) EINA_ARG_NONNULL(1);
+
+/**
+ * @brief Add a new item to a Popup object
+ *
+ * Both an item list and a content could not be set at the same time!
+ * once you add an item, the previous content will be removed.
+ *
+ * @param obj popup object
+ * @param icon Icon to be set on new item
+ * @param label The Label of the new item
+ * @param func Convenience function called when item selected
+ * @param data Data passed to @p func above
+ * @return A handle to the item added or @c NULL, on errors
+ *
+ * @ingroup Popup
+ * @warning When the first item is appended to popup object, any previous content
+ * of the content area is deleted. At a time, only one of content, content-text
+ * and item(s) can be there in a popup content area.
+ */
+EAPI Elm_Object_Item *elm_popup_item_append(Evas_Object *obj, const char *label, Evas_Object *icon, Evas_Smart_Cb func, const void *data) EINA_ARG_NONNULL(1);
+
+/**
+ * @brief Sets the wrapping type of content text packed in content
+ * area of popup object.
+ *
+ * @param obj The Popup object
+ * @param wrap wrapping type of type Elm_Wrap_Type
+ *
+ * @ingroup Popup
+ * @see elm_popup_content_text_wrap_type_get()
+ */
+EAPI void elm_popup_content_text_wrap_type_set(Evas_Object *obj, Elm_Wrap_Type wrap) EINA_ARG_NONNULL(1);
+
+/**
+ * @brief Returns the wrapping type of content text packed in content area of
+ * popup object.
+ *
+ * @param obj The Popup object
+ * @return wrap type of the content text
+ *
+ * @ingroup Popup
+ * @see elm_popup_content_text_wrap_type_set
+ */
+EAPI Elm_Wrap_Type elm_popup_content_text_wrap_type_get(Evas_Object *obj) EINA_ARG_NONNULL(1);
+
+/**
+ * @brief Sets the orientation of the popup in the parent region
+ *
+ * @param obj The popup object
+ * @param orient  the orientation of the popup
+ *
+ * Sets the position in which popup will appear in its parent
+ *
+ * @ingroup Popup
+ * @see @ref Elm_Popup_Orient for possible values.
+ */
+EAPI void elm_popup_orient_set(Evas_Object *obj, Elm_Popup_Orient orient) EINA_ARG_NONNULL(1);
+
+/**
+ * @brief Returns the orientation of Popup
+ *
+ * @param obj The popup object
+ * @return the orientation of the popup
+ *
+ * @ingroup Popup
+ * @see elm_popup_orient_set()
+ * @see Elm_Popup_Orient
+ */
+EAPI Elm_Popup_Orient elm_popup_orient_get(Evas_Object *obj) EINA_ARG_NONNULL(1);
+
+/**
+ * @brief Sets a timeout to hide popup automatically
+ *
+ * @param obj The popup object
+ * @param timeout The timeout in seconds
+ *
+ * This function sets a timeout and starts the timer controlling when the
+ * popup is hidden. Since calling evas_object_show() on a popup restarts
+ * the timer controlling when it is hidden, setting this before the
+ * popup is shown will in effect mean starting the timer when the popup is
+ * shown. Smart signal "timeout" is called afterwards which can be handled
+ * if needed.
+ *
+ * @note Set a value <= 0.0 to disable a running timer.
+ *
+ * @note If the value > 0.0 and the popup is previously visible, the
+ * timer will be started with this value, canceling any running timer.
+ * @ingroup Popup
+ */
+EAPI void elm_popup_timeout_set(Evas_Object *obj, double timeout) EINA_ARG_NONNULL(1);
+
+/**
+ * @brief Returns the timeout value set to the popup (in seconds)
+ *
+ * @param obj The popup object
+ * @return the timeout value
+ *
+ * @ingroup Popup
+ * @see elm_popup_timeout_set()
+ */
+EAPI double elm_popup_timeout_get(Evas_Object *obj) EINA_ARG_NONNULL(1);
+
+/**
+ * @brief Sets whether events should be passed to by a click outside.
+ *
+ * @param obj The popup object
+ * @param allow EINA_TRUE Events are passed to lower objects, else not
+ *
+ * Enabling allow event will remove the Blocked event area and events will
+ * pass to the lowever layer objects otherwise they are blocked.
+ *
+ * @ingroup Popup
+ * @see elm_popup_allow_events_get()
+ * @note The default value is EINA_FALSE.
+ */
+EAPI void elm_popup_allow_events_set(Evas_Object *obj, Eina_Bool allow);
+
+/**
+ * @brief Returns value indicating whether allow event is enabled or not
+ *
+ * @param obj The popup object
+ * @return EINA_FALSE if Blocked event area is present else EINA_TRUE
+ *
+ * @ingroup Popup
+ * @see elm_popup_allow_events_set()
+ * @note By default the Blocked event area is present
+ */
+EAPI Eina_Bool elm_popup_allow_events_get(Evas_Object *obj);