efl_animation: Add scale animation
authorJaehyun Cho <jae_hyun.cho@samsung.com>
Fri, 25 Aug 2017 02:34:28 +0000 (11:34 +0900)
committerJaehyun Cho <jae_hyun.cho@samsung.com>
Thu, 12 Oct 2017 12:03:49 +0000 (21:03 +0900)
src/Makefile_Evas.am
src/bin/elementary/test_event_animation.c [new file with mode: 0644]
src/lib/evas/Evas_Common.h
src/lib/evas/Evas_Eo.h
src/lib/evas/canvas/efl_animation_scale.c [new file with mode: 0644]
src/lib/evas/canvas/efl_animation_scale.eo [new file with mode: 0644]
src/lib/evas/canvas/efl_animation_scale_private.h [new file with mode: 0644]

index 3fcb08b..3fb44c2 100644 (file)
@@ -47,6 +47,7 @@ evas_eolian_pub_files = \
        lib/evas/canvas/efl_animation.eo \
        lib/evas/canvas/efl_animation_alpha.eo \
        lib/evas/canvas/efl_animation_rotate.eo \
+       lib/evas/canvas/efl_animation_scale.eo \
        lib/evas/canvas/efl_animation_object.eo \
        lib/evas/canvas/efl_animation_object_alpha.eo \
        lib/evas/canvas/efl_animation_object_rotate.eo \
@@ -131,6 +132,7 @@ lib/evas/common3d/primitives/primitive_common.h \
 lib/evas/canvas/efl_animation_private.h \
 lib/evas/canvas/efl_animation_alpha_private.h \
 lib/evas/canvas/efl_animation_rotate_private.h \
+lib/evas/canvas/efl_animation_scale_private.h \
 lib/evas/canvas/efl_animation_object_private.h \
 lib/evas/canvas/efl_animation_object_alpha_private.h \
 lib/evas/canvas/efl_animation_object_rotate_private.h
@@ -222,6 +224,7 @@ lib/evas/canvas/efl_input_focus.c \
 lib/evas/canvas/efl_animation.c \
 lib/evas/canvas/efl_animation_alpha.c \
 lib/evas/canvas/efl_animation_rotate.c \
+lib/evas/canvas/efl_animation_scale.c \
 lib/evas/canvas/efl_animation_object.c \
 lib/evas/canvas/efl_animation_object_alpha.c \
 lib/evas/canvas/efl_animation_object_rotate.c \
diff --git a/src/bin/elementary/test_event_animation.c b/src/bin/elementary/test_event_animation.c
new file mode 100644 (file)
index 0000000..8169614
--- /dev/null
@@ -0,0 +1,396 @@
+#ifdef HAVE_CONFIG_H
+# include "elementary_config.h"
+#endif
+#include <Elementary.h>
+
+#define BUTTON_TEXT_SET(BT, TEXT) \
+   elm_object_text_set((BT), (TEXT)); \
+   elm_object_tooltip_text_set((BT), (TEXT)); \
+   elm_object_tooltip_window_mode_set((BT), EINA_TRUE)
+
+static char img1[PATH_MAX];
+static char img2[PATH_MAX];
+static char img3[PATH_MAX];
+static char img4[PATH_MAX];
+static char img5[PATH_MAX];
+static char img6[PATH_MAX];
+static char img7[PATH_MAX];
+
+Evas_Object *
+_content_new(Evas_Object *parent, const char *img)
+{
+   Evas_Object *photo = elm_photo_add(parent);
+   elm_photo_file_set(photo, img);
+   elm_photo_fill_inside_set(photo, EINA_TRUE);
+   elm_object_style_set(photo, "shadow");
+   return photo;
+}
+
+void
+_navi_pop(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
+{
+   elm_naviframe_item_pop(data);
+}
+
+void
+_navi_it_del(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
+{
+   elm_object_item_del(data);
+}
+
+void
+_title_clicked(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
+{
+   printf("Title Clicked!\n");
+}
+
+void
+_item_activated(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info)
+{
+   Elm_Object_Item *it = event_info;
+   printf("Item(%p) is activated! The Title is \"%s\"\n", it, elm_object_item_text_get(it));
+}
+
+void
+_title_visible(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
+{
+   elm_naviframe_item_title_enabled_set(data,
+                                        !elm_naviframe_item_title_enabled_get(data),
+                                        EINA_TRUE);
+}
+
+void
+_promote(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
+{
+   elm_naviframe_item_promote(data);
+}
+
+void
+_page8(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
+{
+   Evas_Object *bt, *bt2, *content, *nf = data;
+   Elm_Object_Item *it;
+
+   snprintf(img6, sizeof(img6), "%s/images/sky_02.jpg", elm_app_data_dir_get());
+   bt = elm_button_add(nf);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   BUTTON_TEXT_SET(bt, "Page 7");
+
+   bt2 = elm_button_add(nf);
+   evas_object_size_hint_align_set(bt2, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   BUTTON_TEXT_SET(bt2, "Page 1");
+   evas_object_smart_callback_add(bt2, "clicked", _promote,
+                                  evas_object_data_get(nf, "page1"));
+   content = _content_new(nf, img6);
+   it = elm_naviframe_item_push(nf, "Page 8", bt, bt2, content, NULL);
+   elm_object_item_part_text_set(it, "subtitle", "Overlap style!");
+
+   evas_object_smart_callback_add(bt, "clicked", _navi_pop, nf);
+}
+
+static void
+_page7_btn_down_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj,
+                   void *event_info EINA_UNUSED)
+{
+   evas_object_color_set(obj, 100, 0, 0, 100);
+   _page8(data, NULL, NULL);
+}
+
+static void
+_page7_btn_up_cb(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj,
+                 void *event_info EINA_UNUSED)
+{
+   evas_object_color_set(obj, 255, 255, 255, 255);
+   printf("Page7 Button Mouse Up!\n");
+}
+
+Evas_Object *
+_page7_content_new(Evas_Object *nf)
+{
+   Evas_Object *bt;
+
+   bt = elm_button_add(nf);
+   elm_object_text_set(bt, "Page 8");
+   evas_object_event_callback_add(bt, EVAS_CALLBACK_MOUSE_DOWN,
+                                  _page7_btn_down_cb, nf);
+   evas_object_event_callback_add(bt, EVAS_CALLBACK_MOUSE_UP,
+                                  _page7_btn_up_cb, NULL);
+
+   return bt;
+}
+
+void
+_page7(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
+{
+   Evas_Object *bt, *bt2, *content, *nf = data;
+   Elm_Object_Item *it;
+
+   bt = elm_button_add(nf);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   BUTTON_TEXT_SET(bt, "Page 6");
+
+   bt2 = elm_button_add(nf);
+   evas_object_size_hint_align_set(bt2, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   BUTTON_TEXT_SET(bt2, "Page 8");
+   evas_object_smart_callback_add(bt2, "clicked", _page8, nf);
+   content = _page7_content_new(nf);
+   it = elm_naviframe_item_push(nf, "Page 7", bt, bt2, content, "overlap");
+   elm_object_item_part_text_set(it, "subtitle", "Overlap style!");
+
+   evas_object_smart_callback_add(bt, "clicked", _navi_pop, nf);
+}
+
+void
+_page6(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
+{
+   Evas_Object *bt, *bt2, *content, *nf = data;
+   Elm_Object_Item *it;
+
+   snprintf(img7, sizeof(img7), "%s/images/sky_03.jpg", elm_app_data_dir_get());
+   bt = elm_button_add(nf);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   BUTTON_TEXT_SET(bt, "Page 5");
+
+   bt2 = elm_button_add(nf);
+   evas_object_size_hint_align_set(bt2, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   BUTTON_TEXT_SET(bt2, "Page 7");
+   evas_object_smart_callback_add(bt2, "clicked", _page7, nf);
+
+   content = _content_new(nf, img7);
+   it = elm_naviframe_item_push(nf, "Page 6", bt, bt2, content, "overlap");
+   elm_object_item_part_text_set(it, "subtitle", "Overlap style!");
+
+   evas_object_smart_callback_add(bt, "clicked", _navi_pop, nf);
+}
+
+void
+_page5(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
+{
+   Evas_Object *bt, *bt2, *content, *nf = data;
+   Elm_Object_Item *it;
+
+   snprintf(img5, sizeof(img5), "%s/images/sky_01.jpg", elm_app_data_dir_get());
+   bt = elm_button_add(nf);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   BUTTON_TEXT_SET(bt, "Page 4");
+
+   bt2 = elm_button_add(nf);
+   evas_object_size_hint_align_set(bt2, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   BUTTON_TEXT_SET(bt2, "Page 6");
+   evas_object_smart_callback_add(bt2, "clicked", _page6, nf);
+
+   content = _content_new(nf, img5);
+   it = elm_naviframe_item_insert_after(nf,
+                                        elm_naviframe_top_item_get(nf),
+                                        "Page 5",
+                                        bt,
+                                        bt2,
+                                        content,
+                                        NULL);
+   elm_object_item_part_text_set(it, "subtitle", "This page is inserted after top item without transition");
+   evas_object_smart_callback_add(bt, "clicked", _navi_it_del, it);
+}
+
+void
+_page4(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
+{
+   Evas_Object *bt, *ic, *content, *nf = data;
+   char buf[PATH_MAX];
+   Elm_Object_Item *it;
+
+   snprintf(img4, sizeof(img4), "%s/images/rock_02.jpg", elm_app_data_dir_get());
+   ic = elm_icon_add(nf);
+   elm_icon_standard_set(ic, "go-right");
+
+   bt = elm_button_add(nf);
+   evas_object_smart_callback_add(bt, "clicked", _page5, nf);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_layout_content_set(bt, "icon", ic);
+
+   content = _content_new(nf, img4);
+
+   it = elm_naviframe_item_push(nf,
+                                "Page 4",
+                                NULL,
+                                bt,
+                                content,
+                                NULL);
+   elm_object_item_part_text_set(it, "subtitle", "Title area visibility test");
+
+   ic = elm_icon_add(nf);
+   snprintf(buf, sizeof(buf), "%s/images/logo_small.png",
+            elm_app_data_dir_get());
+   elm_image_file_set(ic, buf, NULL);
+   evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
+   elm_object_item_part_content_set(it, "icon", ic);
+   elm_naviframe_item_title_enabled_set(it, EINA_FALSE, EINA_FALSE);
+   evas_object_smart_callback_add(content, "clicked", _title_visible, it);
+}
+
+void
+_page3(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
+{
+   Evas_Object *bt2, *content, *nf = data;
+
+   snprintf(img3, sizeof(img3), "%s/images/rock_01.jpg", elm_app_data_dir_get());
+   bt2 = elm_button_add(nf);
+   evas_object_size_hint_align_set(bt2, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   BUTTON_TEXT_SET(bt2, "Next");
+   evas_object_smart_callback_add(bt2, "clicked", _page4, nf);
+
+   content = _content_new(nf, img3);
+
+   elm_naviframe_item_push(nf,
+                           "Page 3",
+                           NULL,
+                           bt2,
+                           content,
+                           NULL);
+}
+
+void
+_page2(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
+{
+   Evas_Object *bt, *content, *ic, *nf = data;
+   Elm_Object_Item *it;
+
+   snprintf(img2, sizeof(img2), "%s/images/plant_01.jpg", elm_app_data_dir_get());
+   bt = elm_button_add(nf);
+   evas_object_size_hint_align_set(bt, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_smart_callback_add(bt, "clicked", _page3, nf);
+
+   ic = elm_icon_add(nf);
+   elm_icon_standard_set(ic, "arrow_right");
+   evas_object_size_hint_aspect_set(ic, EVAS_ASPECT_CONTROL_VERTICAL, 1, 1);
+   elm_layout_content_set(bt, "icon", ic);
+
+   content = _content_new(nf, img2);
+
+   it = elm_naviframe_item_push(nf, "Page 2 - Long Title Here",
+                                NULL, bt, content,  NULL);
+   elm_object_item_part_text_set(it, "subtitle", "Here is sub-title part!");
+}
+
+void
+test_naviframe(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
+{
+   Evas_Object *win, *nf, *btn, *content;
+   Elm_Object_Item *it;
+
+   snprintf(img1, sizeof(img1), "%s/images/logo.png", elm_app_data_dir_get());
+   win = elm_win_util_standard_add("naviframe", "Naviframe");
+   elm_win_focus_highlight_enabled_set(win, EINA_TRUE);
+   elm_win_autodel_set(win, EINA_TRUE);
+
+   nf = elm_naviframe_add(win);
+   evas_object_size_hint_weight_set(nf, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, nf);
+   evas_object_show(nf);
+   evas_object_smart_callback_add(nf, "title,clicked", _title_clicked, 0);
+   evas_object_smart_callback_add(nf, "item,activated", _item_activated, NULL);
+
+   btn = elm_button_add(nf);
+   evas_object_size_hint_align_set(btn, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_smart_callback_add(btn, "clicked", _page2, nf);
+   BUTTON_TEXT_SET(btn, "Next");
+   evas_object_show(btn);
+
+   content = _content_new(nf, img1);
+   it = elm_naviframe_item_push(nf, "Page 1", NULL, btn, content, NULL);
+   evas_object_data_set(nf, "page1", it);
+
+   evas_object_resize(win, 400, 400);
+   evas_object_show(win);
+}
+
+void
+test_naviframe2(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
+{
+   Evas_Object *win, *nf, *sc, *btn, *ico, *content;
+   Elm_Object_Item *it;
+
+   snprintf(img1, sizeof(img1), "%s/images/logo.png", elm_app_data_dir_get());
+   win = elm_win_util_standard_add("naviframe", "Naviframe");
+   elm_win_focus_highlight_enabled_set(win, EINA_TRUE);
+   elm_win_autodel_set(win, EINA_TRUE);
+
+   nf = elm_naviframe_add(win);
+   evas_object_size_hint_weight_set(nf, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_win_resize_object_add(win, nf);
+   evas_object_show(nf);
+
+   sc = elm_segment_control_add(nf);
+   elm_segment_control_item_add(sc, NULL, "Show All");
+   elm_segment_control_item_add(sc, NULL, "Just Filtered");
+
+   btn = elm_button_add(nf);
+   ico = elm_icon_add(btn);
+   elm_icon_standard_set(ico, "refresh");
+   elm_layout_content_set(btn, "icon", ico);
+
+   content = _content_new(nf, img1);
+   it = elm_naviframe_item_push(nf, NULL, NULL, btn, content, NULL);
+   evas_object_data_set(nf, "page1", it);
+
+   elm_object_item_part_content_set(it, "icon", sc);
+
+   evas_object_resize(win, 400, 400);
+   evas_object_show(win);
+}
+
+static void
+_bt_pop_all(void *data, Evas_Object *obj, void *event_info EINA_UNUSED)
+{
+   Elm_Object_Item *it = evas_object_data_get(obj, "root");
+
+   while (elm_naviframe_top_item_get(data) != it)
+     elm_naviframe_item_pop(data);
+}
+
+void
+test_naviframe3(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
+{
+   Evas_Object *win, *tb, *bxh, *nf, *btn, *content;
+   Elm_Object_Item *it;
+
+   snprintf(img1, sizeof(img1), "%s/images/logo.png", elm_app_data_dir_get());
+   win = elm_win_util_standard_add("naviframe", "Naviframe");
+   elm_win_focus_highlight_enabled_set(win, EINA_TRUE);
+   elm_win_autodel_set(win, EINA_TRUE);
+
+   bxh = elm_box_add(win);
+   evas_object_size_hint_weight_set(bxh, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   elm_box_horizontal_set(bxh, EINA_TRUE);
+   elm_win_resize_object_add(win, bxh);
+   evas_object_show(bxh);
+
+   tb = elm_toolbar_add(win);
+   evas_object_size_hint_weight_set(tb, 0.0, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(tb, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_toolbar_horizontal_set(tb, EINA_FALSE);
+   elm_toolbar_select_mode_set(tb, ELM_OBJECT_SELECT_MODE_ALWAYS);
+   elm_box_pack_end(bxh, tb);
+   evas_object_show(tb);
+
+   nf = elm_naviframe_add(win);
+   evas_object_size_hint_weight_set(nf, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+   evas_object_size_hint_align_set(nf, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   elm_box_pack_end(bxh, nf);
+   evas_object_show(nf);
+
+   btn = elm_button_add(nf);
+   evas_object_size_hint_align_set(btn, EVAS_HINT_FILL, EVAS_HINT_FILL);
+   evas_object_smart_callback_add(btn, "clicked", _page2, nf);
+   BUTTON_TEXT_SET(btn, "Next");
+   evas_object_show(btn);
+
+   content = _content_new(nf, img1);
+   it = elm_naviframe_item_push(nf, "Page 1", NULL, btn, content, NULL);
+   evas_object_data_set(nf, "page1", it);
+
+   evas_object_data_set(tb, "root", it);
+   elm_toolbar_item_append(tb, NULL, "Pop all", _bt_pop_all, nf);
+
+   evas_object_resize(win, 400, 400);
+   evas_object_show(win);
+}
index fd5c591..d12e028 100644 (file)
@@ -3351,6 +3351,13 @@ typedef Eo Efl_Animation_Rotate;
 
 #endif
 
+#ifndef _EFL_ANIMATION_SCALE_EO_CLASS_TYPE
+#define _EFL_ANIMATION_SCALE_EO_CLASS_TYPE
+
+typedef Eo Efl_Animation_Scale;
+
+#endif
+
 #ifndef _EFL_ANIMATION_OBJECT_EO_CLASS_TYPE
 #define _EFL_ANIMATION_OBJECT_EO_CLASS_TYPE
 
index d0d0cac..4a7e5e5 100644 (file)
@@ -58,6 +58,7 @@
 #include "canvas/efl_animation.eo.h"
 #include "canvas/efl_animation_alpha.eo.h"
 #include "canvas/efl_animation_rotate.eo.h"
+#include "canvas/efl_animation_scale.eo.h"
 #include "canvas/efl_animation_object.eo.h"
 #include "canvas/efl_animation_object_alpha.eo.h"
 #include "canvas/efl_animation_object_rotate.eo.h"
diff --git a/src/lib/evas/canvas/efl_animation_scale.c b/src/lib/evas/canvas/efl_animation_scale.c
new file mode 100644 (file)
index 0000000..2b2d411
--- /dev/null
@@ -0,0 +1,224 @@
+#include "efl_animation_scale_private.h"
+
+EOLIAN static void
+_efl_animation_scale_scale_set(Eo *eo_obj,
+                               Efl_Animation_Scale_Data *pd,
+                               double from_scale_x,
+                               double from_scale_y,
+                               double to_scale_x,
+                               double to_scale_y,
+                               Efl_Canvas_Object *pivot,
+                               double cx,
+                               double cy)
+{
+   EFL_ANIMATION_SCALE_CHECK_OR_RETURN(eo_obj);
+
+   pd->from.scale_x = from_scale_x;
+   pd->from.scale_y = from_scale_y;
+
+   pd->to.scale_x = to_scale_x;
+   pd->to.scale_y = to_scale_y;
+
+   pd->rel_pivot.obj = pivot;
+   pd->rel_pivot.cx = cx;
+   pd->rel_pivot.cy = cy;
+
+   //Update absolute pivot based on relative pivot
+   Evas_Coord x = 0;
+   Evas_Coord y = 0;
+   Evas_Coord w = 0;
+   Evas_Coord h = 0;
+
+   if (pivot)
+     evas_object_geometry_get(pivot, &x, &y, &w, &h);
+   else
+     {
+        Efl_Canvas_Object *target = efl_animation_target_get(eo_obj);
+        if (target)
+          evas_object_geometry_get(target, &x, &y, &w, &h);
+     }
+
+   pd->abs_pivot.cx = x + (w * cx);
+   pd->abs_pivot.cy = y + (h * cy);
+
+   pd->use_rel_pivot = EINA_TRUE;
+}
+
+EOLIAN static void
+_efl_animation_scale_scale_get(Eo *eo_obj,
+                               Efl_Animation_Scale_Data *pd,
+                               double *from_scale_x,
+                               double *from_scale_y,
+                               double *to_scale_x,
+                               double *to_scale_y,
+                               Efl_Canvas_Object **pivot,
+                               double *cx,
+                               double *cy)
+{
+   EFL_ANIMATION_SCALE_CHECK_OR_RETURN(eo_obj);
+
+   //Update relative pivot based on absolute pivot
+   if (!pd->use_rel_pivot)
+     {
+        Evas_Coord x = 0;
+        Evas_Coord y = 0;
+        Evas_Coord w = 0;
+        Evas_Coord h = 0;
+
+        Efl_Canvas_Object *target = efl_animation_target_get(eo_obj);
+        if (target)
+          evas_object_geometry_get(target, &x, &y, &w, &h);
+
+        if (w != 0)
+          pd->rel_pivot.cx = (double)(pd->abs_pivot.cx - x) / w;
+        else
+          pd->rel_pivot.cx = 0.0;
+
+        if (h != 0)
+          pd->rel_pivot.cy = (double)(pd->abs_pivot.cy - y) / h;
+        else
+          pd->rel_pivot.cy = 0.0;
+     }
+
+   if (from_scale_x)
+     *from_scale_x = pd->from.scale_x;
+
+   if (from_scale_y)
+     *from_scale_y = pd->from.scale_y;
+
+   if (to_scale_x)
+     *to_scale_x = pd->to.scale_x;
+
+   if (to_scale_y)
+     *to_scale_y = pd->to.scale_y;
+
+   if (pivot)
+     *pivot = pd->rel_pivot.obj;
+
+   if (cx)
+     *cx = pd->rel_pivot.cx;
+
+   if (cy)
+     *cy = pd->rel_pivot.cy;
+}
+
+EOLIAN static void
+_efl_animation_scale_scale_absolute_set(Eo *eo_obj,
+                                        Efl_Animation_Scale_Data *pd,
+                                        double from_scale_x,
+                                        double from_scale_y,
+                                        double to_scale_x,
+                                        double to_scale_y,
+                                        Evas_Coord cx,
+                                        Evas_Coord cy)
+{
+   EFL_ANIMATION_SCALE_CHECK_OR_RETURN(eo_obj);
+
+   pd->from.scale_x = from_scale_x;
+   pd->from.scale_y = from_scale_y;
+
+   pd->to.scale_x = to_scale_x;
+   pd->to.scale_y = to_scale_y;
+
+   pd->abs_pivot.cx = cx;
+   pd->abs_pivot.cy = cy;
+
+   //Update relative pivot based on absolute pivot
+   Evas_Coord x = 0;
+   Evas_Coord y = 0;
+   Evas_Coord w = 0;
+   Evas_Coord h = 0;
+
+   Efl_Canvas_Object *target = efl_animation_target_get(eo_obj);
+   if (target)
+     evas_object_geometry_get(target, &x, &y, &w, &h);
+
+   pd->rel_pivot.obj = NULL;
+
+   if (w != 0)
+     pd->rel_pivot.cx = (double)(cx - x) / w;
+   else
+     pd->rel_pivot.cx = 0.0;
+
+   if (h != 0)
+     pd->rel_pivot.cy = (double)(cy - y) / h;
+   else
+     pd->rel_pivot.cy = 0.0;
+
+   pd->use_rel_pivot = EINA_FALSE;
+}
+
+EOLIAN static void
+_efl_animation_scale_scale_absolute_get(Eo *eo_obj,
+                                        Efl_Animation_Scale_Data *pd,
+                                        double *from_scale_x,
+                                        double *from_scale_y,
+                                        double *to_scale_x,
+                                        double *to_scale_y,
+                                        Evas_Coord *cx,
+                                        Evas_Coord *cy)
+{
+   EFL_ANIMATION_SCALE_CHECK_OR_RETURN(eo_obj);
+
+   //Update absolute pivot based on relative pivot
+   if (pd->use_rel_pivot)
+     {
+        Evas_Coord x = 0;
+        Evas_Coord y = 0;
+        Evas_Coord w = 0;
+        Evas_Coord h = 0;
+
+        if (pd->rel_pivot.obj)
+          evas_object_geometry_get(pd->rel_pivot.obj, &x, &y, &w, &h);
+        else
+          {
+             Efl_Canvas_Object *target = efl_animation_target_get(eo_obj);
+             if (target)
+               evas_object_geometry_get(target, &x, &y, &w, &h);
+          }
+
+        pd->abs_pivot.cx = x + (w * pd->rel_pivot.cx);
+        pd->abs_pivot.cy = y + (h * pd->rel_pivot.cy);
+     }
+
+   if (from_scale_x)
+     *from_scale_x = pd->from.scale_x;
+
+   if (from_scale_y)
+     *from_scale_y = pd->from.scale_y;
+
+   if (to_scale_x)
+     *to_scale_x = pd->to.scale_x;
+
+   if (to_scale_y)
+     *to_scale_y = pd->to.scale_y;
+
+   if (cx)
+     *cx = pd->abs_pivot.cx;
+
+   if (cy)
+     *cy = pd->abs_pivot.cy;
+}
+
+EOLIAN static Efl_Object *
+_efl_animation_scale_efl_object_constructor(Eo *eo_obj,
+                                            Efl_Animation_Scale_Data *pd)
+{
+   eo_obj = efl_constructor(efl_super(eo_obj, MY_CLASS));
+
+   pd->from.scale_x = 1.0;
+   pd->from.scale_y = 1.0;
+
+   pd->rel_pivot.obj = NULL;
+   pd->rel_pivot.cx = 0.5;
+   pd->rel_pivot.cy = 0.5;
+
+   pd->abs_pivot.cx = 0;
+   pd->abs_pivot.cy = 0;
+
+   pd->use_rel_pivot = EINA_TRUE;
+
+   return eo_obj;
+}
+
+#include "efl_animation_scale.eo.c"
diff --git a/src/lib/evas/canvas/efl_animation_scale.eo b/src/lib/evas/canvas/efl_animation_scale.eo
new file mode 100644 (file)
index 0000000..28eb0e2
--- /dev/null
@@ -0,0 +1,41 @@
+import efl_animation_types;
+
+class Efl.Animation.Scale (Efl.Animation)
+{
+   [[Efl scale animation class]]
+   data: Efl_Animation_Scale_Data;
+   methods {
+      @property scale {
+         set {
+         }
+         get {
+         }
+         values {
+            from_scale_x: double; [[Scale factor along x axis when animation starts]]
+            from_scale_y: double; [[Scale factor along y axis when animation starts]]
+            to_scale_x: double; [[Scale factor along x axis when animation ends]]
+            to_scale_y: double; [[Scale factor along y axis when animation ends]]
+            pivot: Efl.Canvas.Object; [[Pivot object for the center point. If the pivot object is NULL, then the object is scaled on itself.]]
+            cx: double; [[X relative coordinate of the center point. The left end is 0.0 and the right end is 1.0 (the center is 0.5).]]
+            cy: double; [[Y relative coordinate of the center point. The top end is 0.0 and the bottom end is 1.0 (the center is 0.5).]]
+         }
+      }
+      @property scale_absolute {
+         set {
+         }
+         get {
+         }
+         values {
+            from_scale_x: double; [[Scale factor along x axis when animation starts]]
+            from_scale_y: double; [[Scale factor along y axis when animation starts]]
+            to_scale_x: double; [[Scale factor along x axis when animation ends]]
+            to_scale_y: double; [[Scale factor along y axis when animation ends]]
+            cx: int; [[X absolute coordinate of the center point.]]
+            cy: int; [[Y absolute coordinate of the center point.]]
+         }
+      }
+   }
+   implements {
+      Efl.Object.constructor;
+   }
+}
diff --git a/src/lib/evas/canvas/efl_animation_scale_private.h b/src/lib/evas/canvas/efl_animation_scale_private.h
new file mode 100644 (file)
index 0000000..298097a
--- /dev/null
@@ -0,0 +1,48 @@
+#define EFL_ANIMATION_PROTECTED
+
+#include "evas_common_private.h"
+
+#define MY_CLASS EFL_ANIMATION_SCALE_CLASS
+#define MY_CLASS_NAME efl_class_name_get(MY_CLASS)
+
+#define EFL_ANIMATION_SCALE_CHECK_OR_RETURN(anim, ...) \
+   do { \
+      if (!anim) { \
+         CRI("Efl_Animation " # anim " is NULL!"); \
+         return __VA_ARGS__; \
+      } \
+      if (efl_animation_is_deleted(anim)) { \
+         ERR("Efl_Animation " # anim " has already been deleted!"); \
+         return __VA_ARGS__; \
+      } \
+   } while (0)
+
+#define EFL_ANIMATION_SCALE_DATA_GET(o, pd) \
+   Efl_Animation_Scale_Data *pd = efl_data_scope_get(o, EFL_ANIMATION_SCALE_CLASS)
+
+typedef struct _Efl_Animation_Scale_Property
+{
+   double scale_x, scale_y;
+} Efl_Animation_Scale_Property;
+
+typedef struct _Efl_Animation_Scale_Absolute_Pivot
+{
+   Evas_Coord cx, cy;
+} Efl_Animation_Scale_Absolute_Pivot;
+
+typedef struct _Efl_Animation_Scale_Relative_Pivot
+{
+   Efl_Canvas_Object *obj;
+   double             cx, cy;
+} Efl_Animation_Scale_Relative_Pivot;
+
+typedef struct _Efl_Animation_Scale_Data
+{
+   Efl_Animation_Scale_Property from;
+   Efl_Animation_Scale_Property to;
+
+   Efl_Animation_Scale_Absolute_Pivot abs_pivot;
+   Efl_Animation_Scale_Relative_Pivot rel_pivot;
+
+   Eina_Bool use_rel_pivot;
+} Efl_Animation_Scale_Data;