quickpanel: Support rotation for handler of quickpanel. 10/67310/2
authorSeunghun Lee <shiin.lee@samsung.com>
Thu, 21 Apr 2016 05:10:27 +0000 (14:10 +0900)
committerGwanglim Lee <gl77.lee@samsung.com>
Tue, 26 Apr 2016 12:52:04 +0000 (05:52 -0700)
Change-Id: I265dc67310a21e438d4edd2c88f810ecabe7526b

src/Makefile.am
src/e_mod_gesture.c
src/e_mod_gesture.h
src/e_mod_indicator.c [deleted file]
src/e_mod_indicator.h [deleted file]
src/e_mod_quickpanel.c
src/e_mod_region.c [new file with mode: 0644]
src/e_mod_region.h [new file with mode: 0644]
src/e_mod_wl.c

index 6d73298..b971bd7 100644 (file)
@@ -29,8 +29,6 @@ WL_SRC   += e_mod_wl.c \
             tizen_policy_ext-server-protocol.h \
             e_mod_quickpanel.c \
             e_mod_quickpanel.h \
-            e_mod_indicator.c \
-            e_mod_indicator.h \
             e_mod_volume.c \
             e_mod_volume.h \
             e_mod_lockscreen.c \
@@ -56,6 +54,8 @@ module_la_SOURCES      = e_mod_config.c \
                          e_mod_transit.h \
                          e_mod_transform_mode.c \
                          e_mod_transform_mode.h \
+                         e_mod_region.c \
+                         e_mod_region.h \
                          $(WL_SRC) \
                          $(ROT_SRC)
 
index 39c89a7..b2dbebb 100644 (file)
@@ -10,6 +10,7 @@ struct _Pol_Gesture
 
    struct
    {
+      int x;
       int y;
       int timestamp;
       Eina_Bool pressed; /* to avoid processing that happened mouse move right after mouse up */
@@ -44,11 +45,13 @@ _gesture_obj_cb_mouse_up(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj, v
 static Eina_Bool
 _gesture_line_check(Pol_Gesture *gesture, int x, int y)
 {
-   int dy;
+   int dx, dy;
    const int sensitivity = 50; /* FIXME: hard coded, it sould be configurable. */
 
+   dx = x - gesture->mouse_info.x;
    dy = y - gesture->mouse_info.y;
-   if (abs(dy) < sensitivity)
+   if ((abs(dy) < sensitivity) &&
+       (abs(dx) < sensitivity))
      return EINA_FALSE;
 
    return EINA_TRUE;
@@ -86,6 +89,9 @@ _gesture_check(Pol_Gesture *gesture, Evas_Object *obj, int x, int y, unsigned in
 
    switch (gesture->type)
      {
+      case POL_GESTURE_TYPE_NONE:
+         ret = EINA_TRUE;
+         break;
       case POL_GESTURE_TYPE_LINE:
          ret = _gesture_line_check(gesture, x, y);
          break;
@@ -131,15 +137,23 @@ _gesture_obj_cb_mouse_move(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj,
 }
 
 static void
-_gesture_obj_cb_mouse_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event)
+_gesture_obj_cb_mouse_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj, void *event)
 {
    Pol_Gesture *gesture = data;
    Evas_Event_Mouse_Down *ev = event;
 
    gesture->active = EINA_FALSE;
    gesture->mouse_info.pressed = EINA_TRUE;
+   gesture->mouse_info.x = ev->canvas.x;
    gesture->mouse_info.y = ev->canvas.y;
    gesture->mouse_info.timestamp = ev->timestamp;
+
+   gesture->active = _gesture_check(gesture, obj, ev->canvas.x, ev->canvas.y, ev->timestamp);
+   if (gesture->active)
+     {
+        if (gesture->cb.start)
+          gesture->cb.start(gesture->cb.data, obj, ev->canvas.x, ev->canvas.y, ev->timestamp);
+     }
 }
 
 EINTERN Pol_Gesture *
index 92d4c66..89c5c83 100644 (file)
@@ -5,6 +5,7 @@ typedef struct _Pol_Gesture Pol_Gesture;
 
 typedef enum
 {
+   POL_GESTURE_TYPE_NONE,
    POL_GESTURE_TYPE_LINE,
    POL_GESTURE_TYPE_FLICK,
 } Pol_Gesture_Type;
diff --git a/src/e_mod_indicator.c b/src/e_mod_indicator.c
deleted file mode 100644 (file)
index af55c5d..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-#include "e_mod_main.h"
-#include "e_mod_quickpanel.h"
-
-typedef struct _Pol_Indicator Pol_Indicator;
-
-struct _Pol_Indicator
-{
-   Evas_Object *handler;
-   E_Client *qp_ec;
-};
-
-static Eina_List *indicator_hooks = NULL;
-
-static void
-_indicator_hook_client_del(void *d, E_Client *ec)
-{
-   Pol_Indicator *pi = d;
-
-   if (pi->qp_ec != ec) return;
-
-   DBG("DEL Indicator Handler: obj %p", pi->handler);
-
-   evas_object_del(pi->handler);
-   free(pi);
-
-   E_FREE_LIST(indicator_hooks, e_client_hook_del);
-}
-
-static void
-_quickpanel_client_evas_cb_show(void *data, Evas *evas, Evas_Object *qp_obj, void *event)
-{
-   evas_object_hide(((Pol_Indicator*)data)->handler);
-}
-
-static void
-_quickpanel_client_evas_cb_hide(void *data, Evas *evas, Evas_Object *qp_obj, void *event)
-{
-   evas_object_show(((Pol_Indicator*)data)->handler);
-}
-
-#undef E_CLIENT_HOOK_APPEND
-#define E_CLIENT_HOOK_APPEND(l, t, cb, d) \
-  do                                      \
-    {                                     \
-       E_Client_Hook *_h;                 \
-       _h = e_client_hook_add(t, cb, d);  \
-       assert(_h);                        \
-       l = eina_list_append(l, _h);       \
-    }                                     \
-  while (0)
-
-EINTERN void
-e_mod_indicator_create(int w, int h)
-{
-   E_Client *qp_ec;
-   Pol_Indicator *pi;
-
-   DBG("Create Indicator Region: w %d, h %d", w, h);
-
-   qp_ec = e_mod_quickpanel_client_get(/* passing zone? */);
-   if (!qp_ec)
-     return;
-
-   pi = E_NEW(Pol_Indicator, 1);
-   pi->qp_ec = qp_ec;
-   pi->handler = e_mod_quickpanel_handler_object_add(qp_ec, 0, 0, w, h);
-
-   /* FIXME set stacking as a max temporally. */
-   evas_object_layer_set(pi->handler, EVAS_LAYER_MAX);
-
-   /* show handler object */
-   if (!evas_object_visible_get(qp_ec->frame))
-     evas_object_show(pi->handler);
-
-   evas_object_event_callback_add(qp_ec->frame, EVAS_CALLBACK_SHOW,
-                                  _quickpanel_client_evas_cb_show, pi);
-
-   evas_object_event_callback_add(qp_ec->frame, EVAS_CALLBACK_HIDE,
-                                  _quickpanel_client_evas_cb_hide, pi);
-
-   E_CLIENT_HOOK_APPEND(indicator_hooks, E_CLIENT_HOOK_DEL,
-                        _indicator_hook_client_del, pi);
-}
diff --git a/src/e_mod_indicator.h b/src/e_mod_indicator.h
deleted file mode 100644 (file)
index 3eea4d0..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef E_MOD_INDICATOR_H
-#define E_MOD_INDICATOR_H
-
-EINTERN void   e_mod_indicator_create(int w, int h);
-
-#endif
index 810858b..1033e84 100644 (file)
@@ -1,15 +1,15 @@
 #include "e_mod_private_data.h"
 #include "e_mod_main.h"
 #include "e_mod_quickpanel.h"
-#include "e_mod_indicator.h"
 #include "e_mod_gesture.h"
+#include "e_mod_region.h"
 #include "e_mod_transit.h"
 #include "e_mod_rotation.h"
 
 #define SMART_NAME            "quickpanel_object"
 #define INTERNAL_ENTRY                    \
    Mover_Data *md;                        \
-   md = evas_object_smart_data_get(obj);
+   md = evas_object_smart_data_get(obj)
 
 #define QP_SHOW(EC)              \
 do                               \
@@ -34,19 +34,19 @@ do                               \
 
 typedef struct _Pol_Quickpanel Pol_Quickpanel;
 typedef struct _Mover_Data Mover_Data;
-typedef struct _Handler_Data Handler_Data;
 typedef struct _Mover_Effect_Data Mover_Effect_Data;
 
 struct _Pol_Quickpanel
 {
    E_Client *ec;
    Evas_Object *mover;
+   Evas_Object *indi_obj;
+   Evas_Object *handler_obj;
 
-   struct
-   {
-      Evas_Object *obj;
-      Eina_Rectangle rect;
-   } handler;
+   Eina_List *hooks;
+   Eina_List *events;
+
+   Rot_Idx rotation;
 
    Eina_Bool show_block;
 };
@@ -54,6 +54,7 @@ struct _Pol_Quickpanel
 struct _Mover_Data
 {
    Pol_Quickpanel *qp;
+   E_Client *ec;
 
    Evas_Object *smart_obj; //smart object
    Evas_Object *qp_layout_obj; // quickpanel's e_layout_object
@@ -61,68 +62,49 @@ struct _Mover_Data
    Evas_Object *base_clip; // clipper for quickapnel base object
    Evas_Object *handler_clip; // clipper for quickpanel handler object
 
-   struct
-   {
-      Handler_Data *data;
-      Eina_Rectangle rect;
-   } handler;
+   Eina_Rectangle handler_rect;
+   Rot_Idx rotation;
 
    struct
    {
       Pol_Transit *transit;
       Mover_Effect_Data *data;
-      int y;
+      int x, y;
       unsigned int timestamp;
       float accel;
       Eina_Bool visible;
    } effect_info;
 };
 
-struct _Handler_Data
-{
-   Pol_Quickpanel *qp;
-   Pol_Gesture *gesture;
-   Evas_Object *handler;
-   Evas_Object *mover;
-};
-
 struct _Mover_Effect_Data
 {
    Pol_Transit *transit;
    Evas_Object *mover;
-   int from_dy;
-   int to_dy;
+   int from;
+   int to;
    Eina_Bool visible : 1;
 };
 
 static Pol_Quickpanel *_pol_quickpanel = NULL;
-static Eina_List *_quickpanel_events = NULL;
-static Eina_List *_quickpanel_hooks = NULL;
 static Evas_Smart *_mover_smart = NULL;
 
 static Pol_Quickpanel *
-_quickpanel_find(E_Client *ec)
+_quickpanel_get()
 {
-   if (!_pol_quickpanel)
-     return NULL;
-
-   if (_pol_quickpanel->ec == ec)
-     return _pol_quickpanel;
-
-   return NULL;
+   return _pol_quickpanel;
 }
 
 static void
 _mover_intercept_show(void *data, Evas_Object *obj)
 {
-   Mover_Data *md = data;
-   E_Client *ec = md->qp->ec;
+   Mover_Data *md;
+   E_Client *ec;
    Evas *e;
 
+   md = data;
    md->qp->show_block = EINA_FALSE;
 
-   e = evas_object_evas_get(obj);
-
+   ec = md->ec;
    QP_SHOW(ec);
 
    /* force update */
@@ -130,7 +112,8 @@ _mover_intercept_show(void *data, Evas_Object *obj)
    e_comp_object_dirty(ec->frame);
    e_comp_object_render(ec->frame);
 
-   // create base_clip
+  // create base_clip
+   e = evas_object_evas_get(obj);
    md->base_clip = evas_object_rectangle_add(e);
    e_layout_pack(md->qp_layout_obj, md->base_clip);
    e_layout_child_move(md->base_clip, 0, 0);
@@ -142,15 +125,15 @@ _mover_intercept_show(void *data, Evas_Object *obj)
    // create handler_mirror_obj
    md->handler_mirror_obj =  e_comp_object_util_mirror_add(ec->frame);
    e_layout_pack(md->qp_layout_obj, md->handler_mirror_obj);
-   e_layout_child_move(md->handler_mirror_obj, md->handler.rect.x, md->handler.rect.y);
+   e_layout_child_move(md->handler_mirror_obj, ec->x, ec->y);
    e_layout_child_resize(md->handler_mirror_obj, ec->w, ec->h);
    evas_object_show(md->handler_mirror_obj);
 
    // create handler_clip
    md->handler_clip = evas_object_rectangle_add(e);
    e_layout_pack(md->qp_layout_obj, md->handler_clip);
-   e_layout_child_move(md->handler_clip, md->handler.rect.x, md->handler.rect.y);
-   e_layout_child_resize(md->handler_clip, md->handler.rect.w, md->handler.rect.h);
+   e_layout_child_move(md->handler_clip, md->handler_rect.x, md->handler_rect.y);
+   e_layout_child_resize(md->handler_clip, md->handler_rect.w, md->handler_rect.h);
    evas_object_color_set(md->handler_clip, 255, 255, 255, 255);
    evas_object_show(md->handler_clip);
    evas_object_clip_set(md->handler_mirror_obj, md->handler_clip);
@@ -283,17 +266,47 @@ _mover_smart_init(void)
 static Eina_Bool
 _mover_obj_handler_move(Mover_Data *md, int x, int y)
 {
-   // angle 0 case
-   // do not move handler out of screen.
-   if ((y + md->handler.rect.h) > md->qp->ec->zone->h) return EINA_FALSE;
-
-   // angle 0 case
-   md->handler.rect.y = y;
-
-   e_layout_child_resize(md->base_clip, md->qp->ec->w, md->handler.rect.y); // base clip resize
+   E_Zone *zone;
+   E_Client *ec;
 
-   e_layout_child_move(md->handler_mirror_obj, md->handler.rect.x, md->handler.rect.y - md->qp->ec->h + md->handler.rect.h); // handler mirror object move
-   e_layout_child_move(md->handler_clip, md->handler.rect.x, md->handler.rect.y); // handler mirror object move
+   ec = md->ec;
+   zone = ec->zone;
+   switch (md->rotation)
+     {
+      case ROT_IDX_90:
+         if ((x + md->handler_rect.w) > zone->w) return EINA_FALSE;
+
+         md->handler_rect.x = x;
+         e_layout_child_resize(md->base_clip, md->handler_rect.x, ec->h);
+         e_layout_child_move(md->handler_mirror_obj, md->handler_rect.x - ec->w + md->handler_rect.w, md->handler_rect.y);
+         e_layout_child_move(md->handler_clip, md->handler_rect.x, md->handler_rect.y);
+         break;
+      case ROT_IDX_180:
+         if ((y - md->handler_rect.h) < 0) return EINA_FALSE;
+
+         md->handler_rect.y = y;
+         e_layout_child_move(md->base_clip, md->handler_rect.x, md->handler_rect.y);
+         e_layout_child_resize(md->base_clip, ec->w, ec->h - md->handler_rect.y);
+         e_layout_child_move(md->handler_mirror_obj, md->handler_rect.x, md->handler_rect.y - md->handler_rect.h);
+         e_layout_child_move(md->handler_clip, md->handler_rect.x, md->handler_rect.y - md->handler_rect.h);
+         break;
+      case ROT_IDX_270:
+         if ((x - md->handler_rect.w) < 0) return EINA_FALSE;
+
+         md->handler_rect.x = x;
+         e_layout_child_move(md->base_clip, md->handler_rect.x, md->handler_rect.y);
+         e_layout_child_resize(md->base_clip, ec->w - md->handler_rect.x, ec->h);
+         e_layout_child_move(md->handler_mirror_obj, md->handler_rect.x - md->handler_rect.w, md->handler_rect.y);
+         e_layout_child_move(md->handler_clip, md->handler_rect.x - md->handler_rect.w, md->handler_rect.y);
+         break;
+      default:
+        if ((y + md->handler_rect.h) > zone->h) return EINA_FALSE;
+
+        md->handler_rect.y = y;
+        e_layout_child_resize(md->base_clip, ec->w, md->handler_rect.y);
+        e_layout_child_move(md->handler_mirror_obj, md->handler_rect.x, md->handler_rect.y - ec->h + md->handler_rect.h);
+        e_layout_child_move(md->handler_clip, md->handler_rect.x, md->handler_rect.y);
+     }
 
    return EINA_TRUE;
 }
@@ -303,28 +316,28 @@ _mover_obj_new(Pol_Quickpanel *qp)
 {
    Evas_Object *mover;
    Mover_Data *md;
+   int x, y, w, h;
 
-   if (!qp->ec) return NULL;
-   if (!qp->ec->frame) return NULL;
-
-   if (qp->mover)
-     return qp->mover;
+   /* Pause WM Rotation during mover object is working. */
+   e_zone_rotation_block_set(qp->ec->zone, "quickpanel-mover", EINA_TRUE);
 
    _mover_smart_init();
    mover = evas_object_smart_add(evas_object_evas_get(qp->ec->frame), _mover_smart);
 
+   /* Should setup 'md' before call evas_object_show() */
    md = evas_object_smart_data_get(mover);
    md->qp = qp;
-   md->handler.rect.w = qp->handler.rect.w;
-   md->handler.rect.h = qp->handler.rect.h;
+   md->ec = qp->ec;
+   md->rotation = qp->rotation;
+
+   e_mod_region_rectangle_get(qp->handler_obj, qp->rotation, &x, &y, &w, &h);
+   EINA_RECTANGLE_SET(&md->handler_rect, x, y, w, h);
 
-   evas_object_move(mover, 0, 0); // 0 angle case
+   evas_object_move(mover, 0, 0);
    evas_object_resize(mover, qp->ec->w, qp->ec->h);
    evas_object_show(mover);
 
-   qp->mover = mover;
-
-   e_zone_rotation_block_set(qp->ec->zone, "quickpanel-mover", EINA_TRUE);
+   qp->show_block = EINA_FALSE;
 
    return mover;
 }
@@ -340,7 +353,7 @@ _mover_obj_new_with_move(Pol_Quickpanel *qp, int x, int y, unsigned int timestam
      return NULL;
 
    md = evas_object_smart_data_get(mover);
-
+   md->effect_info.x = x;
    md->effect_info.y = y;
    md->effect_info.timestamp = timestamp;
 
@@ -349,11 +362,40 @@ _mover_obj_new_with_move(Pol_Quickpanel *qp, int x, int y, unsigned int timestam
    return mover;
 }
 
+static void
+_mover_obj_visible_set(Evas_Object *mover, Eina_Bool visible)
+{
+   Mover_Data *md;
+   E_Client *ec;
+   int x = 0, y = 0;
+
+   md = evas_object_smart_data_get(mover);
+   ec = md->ec;
+
+   switch (md->rotation)
+     {
+      case ROT_IDX_90:
+         x = visible ? ec->zone->w : 0;
+         break;
+      case ROT_IDX_180:
+         y = visible ? 0 : ec->zone->h;
+         break;
+      case ROT_IDX_270:
+         x = visible ? 0 : ec->zone->w;
+         break;
+      default:
+         y = visible ? ec->zone->h : 0;
+         break;
+     }
+
+   _mover_obj_handler_move(md, x, y);
+}
+
 static Eina_Bool
 _mover_obj_move(Evas_Object *mover, int x, int y, unsigned int timestamp)
 {
    Mover_Data *md;
-   int dy;
+   int dp;
    unsigned int dt;
 
    if (!mover) return EINA_FALSE;
@@ -363,11 +405,26 @@ _mover_obj_move(Evas_Object *mover, int x, int y, unsigned int timestamp)
 
    /* Calculate the acceleration of movement,
     * determine the visibility of quickpanel based on the result. */
-   dy = y - md->effect_info.y;
    dt = timestamp - md->effect_info.timestamp;
-   if (dt) md->effect_info.accel = (float)dy / (float)dt;
+   switch (md->rotation)
+     {
+      case ROT_IDX_90:
+         dp = x - md->effect_info.x;
+         break;
+      case ROT_IDX_180:
+         dp = md->effect_info.y - y;
+         break;
+      case ROT_IDX_270:
+         dp = md->effect_info.x - x;
+         break;
+      default:
+         dp = y - md->effect_info.y;
+         break;
+     }
+   if (dt) md->effect_info.accel = (float)dp / (float)dt;
 
    /* Store current information to next calculation */
+   md->effect_info.x = x;
    md->effect_info.y = y;
    md->effect_info.timestamp = timestamp;
 
@@ -375,7 +432,7 @@ _mover_obj_move(Evas_Object *mover, int x, int y, unsigned int timestamp)
 }
 
 static Pol_Transit_Effect *
-_mover_obj_effect_data_new(Pol_Transit *transit, Evas_Object *mover, int from_y, int to_y, Eina_Bool visible)
+_mover_obj_effect_data_new(Pol_Transit *transit, Evas_Object *mover, int from, int to, Eina_Bool visible)
 {
    Mover_Effect_Data *ed;
 
@@ -385,8 +442,8 @@ _mover_obj_effect_data_new(Pol_Transit *transit, Evas_Object *mover, int from_y,
    ed->transit = transit;
    ed->mover = mover;
    ed->visible = visible;
-   ed->from_dy = from_y;
-   ed->to_dy = to_y;
+   ed->from = from;
+   ed->to = to;
 
    return ed;
 }
@@ -396,11 +453,23 @@ _mover_obj_effect_op(Pol_Transit_Effect *effect, Pol_Transit *transit, double pr
 {
    Mover_Effect_Data *ed = effect;
    Mover_Data *md;
-   int new_y;
+   int new_x = 0, new_y = 0;
 
    md = evas_object_smart_data_get(ed->mover);
-   new_y = ed->from_dy + (ed->to_dy * progress);
-   _mover_obj_handler_move(md, 0, new_y);
+
+   switch (md->rotation)
+     {
+      case ROT_IDX_90:
+      case ROT_IDX_270:
+         new_x = ed->from + (ed->to * progress);
+         break;
+      default:
+      case ROT_IDX_180:
+         new_y = ed->from + (ed->to * progress);
+         break;
+     }
+
+   _mover_obj_handler_move(md, new_x, new_y);
 }
 
 static void
@@ -438,32 +507,52 @@ _mover_obj_effect_data_free(Pol_Transit_Effect *effect, Pol_Transit *transit)
 }
 
 static void
-_mover_obj_effect_start(Evas_Object *mover, int from_y, Eina_Bool visible)
+_mover_obj_effect_start(Evas_Object *mover, Eina_Bool visible)
 {
    Mover_Data *md;
    E_Client *ec;
    Pol_Transit *transit;
    Pol_Transit_Effect *effect;
-   int to_y;
+   int from;
+   int to;
    double duration;
    const double ref = 0.1;
 
    md = evas_object_smart_data_get(mover);
    ec = md->qp->ec;
 
+   switch (md->rotation)
+     {
+      case ROT_IDX_90:
+         from = md->handler_rect.x;
+         to = (visible) ? (ec->zone->w - from) : (-from);
+         duration = ((double)abs(to) / (ec->zone->w / 2)) * ref;
+         break;
+      case ROT_IDX_180:
+         from = md->handler_rect.y;
+         to = (visible) ? (-from) : (ec->zone->h - from);
+         duration = ((double)abs(to) / (ec->zone->h / 2)) * ref;
+         break;
+      case ROT_IDX_270:
+         from = md->handler_rect.x;
+         to = (visible) ? (-from) : (ec->zone->w - from);
+         duration = ((double)abs(to) / (ec->zone->w / 2)) * ref;
+         break;
+      default:
+         from = md->handler_rect.y;
+         to = (visible) ? (ec->zone->h - from) : (-from);
+         duration = ((double)abs(to) / (ec->zone->h / 2)) * ref;
+         break;
+     }
+
    transit = pol_transit_add();
    pol_transit_object_add(transit, mover);
    pol_transit_tween_mode_set(transit, POL_TRANSIT_TWEEN_MODE_DECELERATE);
 
-   /* determine the position as a destination */
-   to_y = (visible) ? (ec->zone->h - from_y) : (-from_y);
-
-   /* determine the transit's duration */
-   duration = ((double)abs(to_y) / (ec->zone->h / 2)) * ref;
    pol_transit_duration_set(transit, duration);
 
    /* create and add effect to transit */
-   effect = _mover_obj_effect_data_new(transit, mover, from_y, to_y, visible);
+   effect = _mover_obj_effect_data_new(transit, mover, from, to, visible);
    pol_transit_effect_add(transit, _mover_obj_effect_op, effect, _mover_obj_effect_data_free);
 
    /* start transit */
@@ -490,17 +579,34 @@ _mover_obj_effect_stop(Evas_Object *mover)
 }
 
 static Eina_Bool
-_mover_obj_visibility_eval(Evas_Object *mover, int x, int y, unsigned int timestamp)
+_mover_obj_visibility_eval(Evas_Object *mover)
 {
    E_Client *ec;
    Mover_Data *md;
+   Eina_Bool threshold;
    const float sensitivity = 1.5; /* hard coded. (arbitrary) */
 
    md = evas_object_smart_data_get(mover);
-   ec = md->qp->ec;
+   ec = md->ec;
+
+   switch (md->rotation)
+     {
+        case ROT_IDX_90:
+           threshold = (md->handler_rect.x > (ec->zone->w / 2));
+           break;
+        case ROT_IDX_180:
+           threshold = (md->handler_rect.y < (ec->zone->h / 2));
+           break;
+        case ROT_IDX_270:
+           threshold = (md->handler_rect.x < (ec->zone->w / 2));
+           break;
+        default:
+           threshold = (md->handler_rect.y > (ec->zone->h / 2));
+           break;
+     }
 
    if ((md->effect_info.accel > sensitivity) ||
-       ((md->effect_info.accel > -sensitivity) && (y > ec->zone->h / 2)))
+       ((md->effect_info.accel > -sensitivity) && threshold))
      return EINA_TRUE;
 
    return EINA_FALSE;
@@ -527,184 +633,209 @@ _mover_obj_effect_visible_get(Evas_Object *mover)
 }
 
 static void
-_handler_obj_cb_mover_obj_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED)
+_region_obj_cb_gesture_start(void *data, Evas_Object *handler, int x, int y, unsigned int timestamp)
 {
-   Handler_Data *hd;
+   Pol_Quickpanel *qp;
 
-   hd = data;
-   hd->mover = NULL;
-}
+   qp = data;
+   if (EINA_UNLIKELY(!qp))
+     return;
 
-static void
-_handler_obj_cb_gesture_start(void *data, Evas_Object *handler, int x, int y, unsigned int timestamp)
-{
-   Handler_Data *hd;
+   if (EINA_UNLIKELY(!qp->ec))
+     return;
 
-   hd = data;
-   if (hd->mover)
+   if (e_object_is_del(E_OBJECT(qp->ec)))
+     return;
+
+   if (qp->mover)
      {
-        if (_mover_obj_is_animating(hd->mover))
+        if (_mover_obj_is_animating(qp->mover))
           return;
 
         DBG("Mover object already existed");
-        evas_object_del(hd->mover);
+        evas_object_del(qp->mover);
      }
 
    e_comp_wl_touch_cancel();
 
-   hd->mover = _mover_obj_new_with_move(hd->qp, 0, y, timestamp);
-   evas_object_event_callback_add(hd->mover, EVAS_CALLBACK_DEL, _handler_obj_cb_mover_obj_del, hd);
+   qp->mover = _mover_obj_new_with_move(qp, x, y, timestamp);
 }
 
 static void
-_handler_obj_cb_gesture_move(void *data, Evas_Object *handler, int x, int y, unsigned int timestamp)
+_region_obj_cb_gesture_move(void *data, Evas_Object *handler, int x, int y, unsigned int timestamp)
 {
-   Handler_Data *hd;
+   Pol_Quickpanel *qp;
 
-   hd = data;
-   if (!hd->mover)
+   qp = data;
+   if (!qp->mover)
      return;
 
-   if (_mover_obj_is_animating(hd->mover))
+   if (_mover_obj_is_animating(qp->mover))
      return;
 
-   _mover_obj_move(hd->mover, 0, y, timestamp);
+   _mover_obj_move(qp->mover, x, y, timestamp);
 }
 
 static void
-_handler_obj_cb_gesture_end(void *data EINA_UNUSED, Evas_Object *handler, int x, int y, unsigned int timestamp)
+_region_obj_cb_gesture_end(void *data EINA_UNUSED, Evas_Object *handler, int x, int y, unsigned int timestamp)
 {
-   Handler_Data *hd;
+   Pol_Quickpanel *qp;
    Eina_Bool v;
 
-   hd = data;
-   if (!hd->mover)
+   qp = data;
+   if (!qp->mover)
      {
         DBG("Could not find quickpanel mover object");
         return;
      }
 
-   if (_mover_obj_is_animating(hd->mover))
+   if (_mover_obj_is_animating(qp->mover))
      return;
 
-   v = _mover_obj_visibility_eval(hd->mover, 0, y, timestamp);
-   _mover_obj_effect_start(hd->mover, y, v);
+   v = _mover_obj_visibility_eval(qp->mover);
+   _mover_obj_effect_start(qp->mover, v);
 }
 
 static void
-_handler_obj_cb_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
+_quickpanel_free(Pol_Quickpanel *qp)
 {
-   Handler_Data *hd;
-
-   hd = data;
-
-   E_FREE_FUNC(hd->mover, evas_object_del);
-   E_FREE_FUNC(hd->gesture, e_mod_gesture_del);
-
-   free(hd);
-}
-
-static void
-_quickpanel_free(Pol_Quickpanel *pol_qp)
-{
-   if (pol_qp->mover)
-     evas_object_del(pol_qp->mover);
-
-   E_FREE_FUNC(pol_qp->handler.obj, evas_object_del);
-   E_FREE_LIST(_quickpanel_hooks, e_client_hook_del);
+   E_FREE_FUNC(qp->mover, evas_object_del);
+   E_FREE_FUNC(qp->indi_obj, evas_object_del);
+   E_FREE_FUNC(qp->handler_obj, evas_object_del);
+   E_FREE_LIST(qp->events, ecore_event_handler_del);
+   E_FREE_LIST(qp->hooks, e_client_hook_del);
    E_FREE(_pol_quickpanel);
 }
 
 static void
-_quickpanel_hook_client_del(void *d EINA_UNUSED, E_Client *ec)
+_quickpanel_hook_client_del(void *d, E_Client *ec)
 {
-   Pol_Quickpanel *pol_qp;
+   Pol_Quickpanel *qp;
+
+   qp = d;
+   if (EINA_UNLIKELY(!qp))
+     return;
 
    if (!ec) return;
 
-   pol_qp = _quickpanel_find(ec);
-   if (!pol_qp)
+   if (qp->ec != ec)
      return;
 
-   _quickpanel_free(pol_qp);
+   _quickpanel_free(qp);
 }
 
 static void
-_quickpanel_client_evas_cb_show(void *data, Evas *evas, Evas_Object *qp_obj, void *event)
+_quickpanel_client_evas_cb_show(void *data, Evas *evas, Evas_Object *obj, void *event)
 {
-   Evas_Object *handler = data;
+   Pol_Quickpanel *qp;
+
+   qp = data;
+   if (EINA_UNLIKELY(!qp))
+     return;
 
-   evas_object_show(handler);
-   evas_object_raise(handler);
+   if (qp->show_block)
+     {
+        QP_HIDE(qp->ec);
+        evas_object_show(qp->indi_obj);
+        return;
+     }
+
+   evas_object_show(qp->handler_obj);
+   evas_object_raise(qp->handler_obj);
+
+   evas_object_hide(qp->indi_obj);
 }
 
 static void
-_quickpanel_client_evas_cb_hide(void *data, Evas *evas, Evas_Object *qp_obj, void *event)
+_quickpanel_client_evas_cb_hide(void *data, Evas *evas, Evas_Object *obj, void *event)
 {
-   evas_object_hide((Evas_Object *)data);
+   Pol_Quickpanel *qp;
+
+   qp = data;
+   if (EINA_UNLIKELY(!qp))
+     return;
+
+   evas_object_hide(qp->handler_obj);
+   evas_object_show(qp->indi_obj);
 }
 
 static void
-_quickpanel_client_evas_cb_move(void *data, Evas *evas, Evas_Object *qp_obj, void *event)
+_quickpanel_client_evas_cb_move(void *data, Evas *evas, Evas_Object *obj, void *event)
 {
-   Evas_Object *handler = data;
+   Pol_Quickpanel *qp;
    int x, y, hx, hy;
 
-   hx = _pol_quickpanel->handler.rect.x;
-   hy = _pol_quickpanel->handler.rect.y;
+   qp = data;
+   if (EINA_UNLIKELY(!qp))
+     return;
 
-   evas_object_geometry_get(qp_obj, &x, &y, NULL, NULL);
-   evas_object_move(handler, x + hx, y + hy);
+   e_mod_region_rectangle_get(qp->handler_obj, qp->rotation, &hx, &hy, NULL, NULL);
+   evas_object_geometry_get(obj, &x, &y, NULL, NULL);
+   evas_object_move(qp->handler_obj, x + hx, y + hy);
 }
 
 static void
-_quickpanel_handler_rect_add(Pol_Quickpanel *qp, int angle, int x, int y, int w, int h)
+_quickpanel_handler_rect_add(Pol_Quickpanel *qp, Rot_Idx ridx, int x, int y, int w, int h)
 {
    E_Client *ec;
-   Evas_Object *handler;
+   Evas_Object *obj;
 
    ec = qp->ec;
 
    ELOGF("QUICKPANEL", "Handler Geo Set | x %d, y %d, w %d, h %d",
          NULL, NULL, x, y, w, h);
 
-   handler =
-      e_mod_quickpanel_handler_object_add(ec,
-                                          ec->client.x + x,
-                                          ec->client.y + y,
-                                          w, h);
+   if (qp->handler_obj)
+     goto end;
+
+   obj = e_mod_region_object_new();
+   if (!obj)
+     return;
+
+   e_mod_region_cb_set(obj,
+                       _region_obj_cb_gesture_start,
+                       _region_obj_cb_gesture_move,
+                       _region_obj_cb_gesture_end, qp);
 
    /* Add handler object to smart member to follow the client's stack */
-   evas_object_smart_member_add(handler, ec->frame);
-   evas_object_propagate_events_set(handler, 0);
-
+   evas_object_smart_member_add(obj, ec->frame);
+   evas_object_propagate_events_set(obj, 0);
    if (evas_object_visible_get(ec->frame))
-     evas_object_show(handler);
+     evas_object_show(obj);
 
-   evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_SHOW,
-                                  _quickpanel_client_evas_cb_show, handler);
-   evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_HIDE,
-                                  _quickpanel_client_evas_cb_hide, handler);
-   evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_MOVE,
-                                  _quickpanel_client_evas_cb_move, handler);
+   qp->handler_obj = obj;
 
-   EINA_RECTANGLE_SET(&qp->handler.rect, x, y, w, h);
-   qp->handler.obj = handler;
+end:
+   e_mod_region_rectangle_set(qp->handler_obj, ridx, x, y, w, h);
 }
 
 static void
-_quickpanel_handler_region_set(Pol_Quickpanel *qp, int angle, Eina_Tiler *tiler)
+_quickpanel_handler_region_set(Pol_Quickpanel *qp, Rot_Idx ridx, Eina_Tiler *tiler)
 {
    Eina_Iterator *it;
    Eina_Rectangle *r;
+   int x = 0, y = 0;
 
-   /* NOTE: supported single rectangle, not tiler */
+   /* FIXME supported single rectangle, not tiler */
 
    it = eina_tiler_iterator_new(tiler);
    EINA_ITERATOR_FOREACH(it, r)
      {
-        _quickpanel_handler_rect_add(qp, angle, r->x, r->y, r->w, r->h);
-        e_mod_indicator_create(r->w, r->h);
+        _quickpanel_handler_rect_add(qp, ridx, r->x, r->y, r->w, r->h);
+
+        /* FIXME: this should be set by another way like indicator */
+        if (ridx == ROT_IDX_180)
+          {
+             x = 0;
+             y = qp->ec->zone->h - r->h;
+          }
+        else if (ridx == ROT_IDX_270)
+          {
+             x = qp->ec->zone->w - r->w;
+             y = 0;
+          }
+        e_mod_region_rectangle_set(qp->indi_obj, ridx, x, y, r->w, r->h);
+
         break;
      }
    eina_iterator_free(it);
@@ -715,9 +846,7 @@ _quickpanel_visibility_change(Pol_Quickpanel *qp, Eina_Bool vis, Eina_Bool with_
 {
    E_Client *ec;
    Evas_Object *mover;
-   Mover_Data *md;
    Eina_Bool cur_vis = EINA_FALSE;
-   int from_y;
    int x, y, w, h;
 
    ec = qp->ec;
@@ -743,17 +872,14 @@ _quickpanel_visibility_change(Pol_Quickpanel *qp, Eina_Bool vis, Eina_Bool with_
 
                   _mover_obj_effect_stop(mover);
                }
-
-             md = evas_object_smart_data_get(mover);
-             from_y = md->handler.rect.y;
           }
         else
           {
-             from_y = vis ? 0 : ec->zone->h;
-             mover = _mover_obj_new_with_move(qp, 0, from_y, 0);
+             mover = _mover_obj_new(qp);
+             _mover_obj_visible_set(mover, !vis);
           }
 
-        _mover_obj_effect_start(mover, from_y, vis);
+        _mover_obj_effect_start(mover, vis);
      }
    else
      {
@@ -768,23 +894,6 @@ _quickpanel_visibility_change(Pol_Quickpanel *qp, Eina_Bool vis, Eina_Bool with_
      }
 }
 
-static void
-_quickpanel_client_evas_cb_show_block(void *data, Evas *evas, Evas_Object *qp_obj, void *event)
-{
-   Pol_Quickpanel *pol_qp = data;
-   E_Client *ec = pol_qp->ec;
-
-   if (pol_qp->show_block)
-     QP_HIDE(ec);
-   else
-     {
-        evas_object_event_callback_del_full(ec->frame,
-                                            EVAS_CALLBACK_SHOW,
-                                            _quickpanel_client_evas_cb_show_block,
-                                            pol_qp);
-     }
-}
-
 static Eina_Bool
 _quickpanel_cb_buffer_change(void *data, int type, void *event)
 {
@@ -805,26 +914,109 @@ end:
 }
 
 static Eina_Bool
+_quickpanel_cb_rotation_begin(void *data, int type, void *event)
+{
+   Pol_Quickpanel *qp;
+   E_Event_Client *ev = event;
+   E_Client *ec;
+
+   qp = data;
+   if (EINA_UNLIKELY(!qp))
+     goto end;
+
+   ec = ev->ec;
+   if (EINA_UNLIKELY(!ec))
+     goto end;
+
+   if (qp->ec != ec)
+     goto end;
+
+   E_FREE_FUNC(qp->mover, evas_object_del);
+
+   evas_object_hide(qp->indi_obj);
+   evas_object_hide(qp->handler_obj);
+
+end:
+   return ECORE_CALLBACK_PASS_ON;
+}
+
+static Eina_Bool
+_quickpanel_cb_rotation_cancel(void *data, int type, void *event)
+{
+   Pol_Quickpanel *qp;
+   E_Event_Client *ev = event;
+   E_Client *ec;
+
+   qp = data;
+   if (EINA_UNLIKELY(!qp))
+     goto end;
+
+   ec = ev->ec;
+   if (EINA_UNLIKELY(!ec))
+     goto end;
+
+   if (qp->ec != ec)
+     goto end;
+
+   if (evas_object_visible_get(ec->frame))
+     evas_object_show(qp->handler_obj);
+   else
+     evas_object_show(qp->indi_obj);
+
+end:
+   return ECORE_CALLBACK_PASS_ON;
+}
+
+static Eina_Bool
 _quickpanel_cb_rotation_done(void *data, int type, void *event)
 {
+   Pol_Quickpanel *qp;
    E_Event_Client *ev = event;
    E_Client *ec;
 
+   qp = data;
+   if (EINA_UNLIKELY(!qp))
+     goto end;
+
    ec = ev->ec;
-   if (ec != e_mod_quickpanel_client_get())
+   if (EINA_UNLIKELY(!ec))
      goto end;
 
-   if (!ec->visible)
+   if (qp->ec != ec)
      goto end;
 
-   /* force update */
-   e_comp_object_damage(ec->frame, 0, 0, ec->w, ec->h);
-   e_comp_object_dirty(ec->frame);
+   qp->rotation = e_mod_rotation_angle_to_idx(ec->e.state.rot.ang.curr);
+
+   if (evas_object_visible_get(ec->frame))
+     evas_object_show(qp->handler_obj);
+   else
+     evas_object_show(qp->indi_obj);
 
 end:
    return ECORE_CALLBACK_PASS_ON;
 }
 
+static Evas_Object *
+_quickpanel_indicator_object_new(Pol_Quickpanel *qp)
+{
+   Evas_Object *indi_obj;
+
+   indi_obj = e_mod_region_object_new();
+   if (!indi_obj)
+     return NULL;
+
+   evas_object_repeat_events_set(indi_obj, EINA_TRUE);
+   /* FIXME: make me move to explicit layer something like POL_LAYER */
+   evas_object_layer_set(indi_obj, EVAS_LAYER_MAX - 1);
+
+   e_mod_region_cb_set(indi_obj,
+                       _region_obj_cb_gesture_start,
+                       _region_obj_cb_gesture_move,
+                       _region_obj_cb_gesture_end, qp);
+
+   return indi_obj;
+}
+
 #undef E_CLIENT_HOOK_APPEND
 #define E_CLIENT_HOOK_APPEND(l, t, cb, d) \
   do                                      \
@@ -840,12 +1032,13 @@ end:
 EINTERN void
 e_mod_quickpanel_client_set(E_Client *ec)
 {
-   Pol_Quickpanel *pol_qp = NULL;
+   Pol_Quickpanel *qp;
 
    if (EINA_UNLIKELY(!ec))
      {
-        pol_qp = _quickpanel_find(e_mod_quickpanel_client_get());
-        _quickpanel_free(pol_qp);
+        qp = _quickpanel_get();
+        if (qp)
+          _quickpanel_free(qp);
         return;
      }
 
@@ -858,13 +1051,22 @@ e_mod_quickpanel_client_set(E_Client *ec)
    /* if we have not setup evas callbacks for this client, do it */
    if (_pol_quickpanel) return;
 
-   pol_qp = E_NEW(Pol_Quickpanel, 1);
-   if (!pol_qp) return;
+   ELOGF("QUICKPANEL", "Set Client | ec %p", NULL, NULL, ec);
 
-   pol_qp->ec = ec;
-   pol_qp->show_block = EINA_TRUE;
+   qp = calloc(1, sizeof(*qp));
+   if (!qp)
+     return;
 
-   ELOGF("QUICKPANEL", "Set Client | ec %p", NULL, NULL, ec);
+   _pol_quickpanel = qp;
+
+   qp->ec = ec;
+   qp->show_block = EINA_TRUE;
+   qp->indi_obj = _quickpanel_indicator_object_new(qp);
+   if (!qp->indi_obj)
+     {
+        free(qp);
+        return;
+     }
 
    eina_stringshare_replace(&ec->icccm.window_role, "quickpanel");
 
@@ -877,23 +1079,22 @@ e_mod_quickpanel_client_set(E_Client *ec)
 
    // set skip iconify
    ec->exp_iconify.skip_iconify = 1;
-
    ec->e.state.rot.type = E_CLIENT_ROTATION_TYPE_DEPENDENT;
+
+   /* force update rotation for quickpanel */
    e_mod_pol_rotation_force_update_add(ec);
 
    QP_HIDE(ec);
 
-   // to avoid that quickpanel is shawn, when it's first launched. */
-   evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_SHOW,
-                                  _quickpanel_client_evas_cb_show_block, pol_qp);
-
-   E_CLIENT_HOOK_APPEND(_quickpanel_hooks, E_CLIENT_HOOK_DEL,
-                        _quickpanel_hook_client_del, NULL);
-
-   E_LIST_HANDLER_APPEND(_quickpanel_events, E_EVENT_CLIENT_BUFFER_CHANGE,       _quickpanel_cb_buffer_change, NULL);
-   E_LIST_HANDLER_APPEND(_quickpanel_events, E_EVENT_CLIENT_ROTATION_CHANGE_END, _quickpanel_cb_rotation_done, NULL);
+   evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_SHOW, _quickpanel_client_evas_cb_show, qp);
+   evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_HIDE, _quickpanel_client_evas_cb_hide, qp);
+   evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_MOVE, _quickpanel_client_evas_cb_move, qp);
 
-   _pol_quickpanel = pol_qp;
+   E_CLIENT_HOOK_APPEND(qp->hooks,   E_CLIENT_HOOK_DEL,                       _quickpanel_hook_client_del,  qp);
+   E_LIST_HANDLER_APPEND(qp->events, E_EVENT_CLIENT_BUFFER_CHANGE,            _quickpanel_cb_buffer_change, qp);
+   E_LIST_HANDLER_APPEND(qp->events, E_EVENT_CLIENT_ROTATION_CHANGE_BEGIN,    _quickpanel_cb_rotation_begin, qp);
+   E_LIST_HANDLER_APPEND(qp->events, E_EVENT_CLIENT_ROTATION_CHANGE_CANCEL,   _quickpanel_cb_rotation_cancel, qp);
+   E_LIST_HANDLER_APPEND(qp->events, E_EVENT_CLIENT_ROTATION_CHANGE_END,      _quickpanel_cb_rotation_done, qp);
 }
 
 EINTERN E_Client *
@@ -908,84 +1109,41 @@ EINTERN Eina_Bool
 e_mod_quickpanel_region_set(int type, int angle, Eina_Tiler *tiler)
 {
    Pol_Quickpanel *qp;
-   E_Client *ec;
+   Rot_Idx ridx;
 
-   ec = e_mod_quickpanel_client_get();
-   if (EINA_UNLIKELY(!ec))
+   qp = _quickpanel_get();
+   if (EINA_UNLIKELY(!qp))
      return EINA_FALSE;
 
-   qp = _quickpanel_find(ec);
-   if (EINA_UNLIKELY(!qp))
+   if (EINA_UNLIKELY(!qp->ec))
      return EINA_FALSE;
 
-   // FIXME should consider rotation.
-   if (angle != 0)
+   if (e_object_is_del(E_OBJECT(qp->ec)))
      return EINA_FALSE;
 
    // FIXME: region type
    if (type != 0)
      return EINA_FALSE;
 
-   _quickpanel_handler_region_set(qp, angle, tiler);
+   ridx = e_mod_rotation_angle_to_idx(angle);
+   _quickpanel_handler_region_set(qp, ridx, tiler);
 
    return EINA_TRUE;
 }
 
-EINTERN Evas_Object *
-e_mod_quickpanel_handler_object_add(E_Client *ec, int x, int y, int w, int h)
-{
-   Pol_Quickpanel *qp;
-   Pol_Gesture *gesture;
-   Evas_Object *handler;
-   Handler_Data *hd;
-
-   qp = _quickpanel_find(ec);
-   if (!qp)
-     return NULL;
-
-   hd = E_NEW(Handler_Data, 1);
-   if (EINA_UNLIKELY(!hd))
-     return NULL;
-
-   handler = evas_object_rectangle_add(evas_object_evas_get(ec->frame));
-
-   /* make it transparent */
-   evas_object_color_set(handler, 0, 0, 0, 0);
-
-   evas_object_repeat_events_set(handler, EINA_TRUE);
-
-   evas_object_move(handler, x, y);
-   evas_object_resize(handler, w, h);
-
-   evas_object_event_callback_add(handler, EVAS_CALLBACK_DEL, _handler_obj_cb_del, hd);
-
-   gesture = e_mod_gesture_add(handler, POL_GESTURE_TYPE_LINE);
-   e_mod_gesture_cb_set(gesture,
-                        _handler_obj_cb_gesture_start,
-                        _handler_obj_cb_gesture_move,
-                        _handler_obj_cb_gesture_end,
-                        hd);
-
-   hd->qp = qp;
-   hd->gesture = gesture;
-   hd->handler = handler;
-   hd->mover = NULL;
-
-   return handler;
-}
-
 EINTERN void
 e_mod_quickpanel_show(void)
 {
    Pol_Quickpanel *qp;
-   E_Client *ec;
 
-   ec = e_mod_quickpanel_client_get();
-   if (!ec)
+   qp = _quickpanel_get();
+   if (EINA_UNLIKELY(!qp))
      return;
 
-   qp = _quickpanel_find(ec);
-   if (!qp)
+   if (EINA_UNLIKELY(!qp->ec))
+     return;
+
+   if (e_object_is_del(E_OBJECT(qp->ec)))
      return;
 
    _quickpanel_visibility_change(qp, EINA_TRUE, EINA_TRUE);
@@ -995,14 +1153,15 @@ EINTERN void
 e_mod_quickpanel_hide(void)
 {
    Pol_Quickpanel *qp;
-   E_Client *ec;
 
-   ec = e_mod_quickpanel_client_get();
-   if (!ec)
+   qp = _quickpanel_get();
+   if (EINA_UNLIKELY(!qp))
      return;
 
-   qp = _quickpanel_find(ec);
-   if (!qp)
+   if (EINA_UNLIKELY(!qp->ec))
+     return;
+
+   if (e_object_is_del(E_OBJECT(qp->ec)))
      return;
 
    _quickpanel_visibility_change(qp, EINA_FALSE, EINA_TRUE);
diff --git a/src/e_mod_region.c b/src/e_mod_region.c
new file mode 100644 (file)
index 0000000..989d090
--- /dev/null
@@ -0,0 +1,203 @@
+#include "e_mod_main.h"
+#include "e_mod_rotation.h"
+#include "e_mod_gesture.h"
+#include "e_mod_region.h"
+
+/* FIXME: temporary use quickpanel to find out ui orientation */
+#include "e_mod_quickpanel.h"
+
+#define ENTRY(...)                                 \
+   Pol_Region *region;                             \
+   EINA_SAFETY_ON_NULL_RETURN_VAL(ro, EINA_FALSE); \
+   region = evas_object_data_get(ro, EO_DATA_KEY); \
+   if (EINA_UNLIKELY(!region))                     \
+     return __VA_ARGS__
+
+/* FIXME: Implementation for log that can access commonly */
+#ifdef INF
+#undef INF
+#endif
+
+#define INF(f, x...) NULL
+
+#define EO_DATA_KEY  "pol-region"
+
+struct _Pol_Region
+{
+   Evas_Object       *obj;
+   Pol_Gesture       *gesture;
+   Eina_List         *event_list;
+   Eina_Rectangle     geom[ROT_IDX_NUM];
+   Rot_Idx            rotation;
+};
+
+static void
+_region_rotation_set(Pol_Region *region, int angle)
+{
+   if (!e_mod_rotation_angle_valid_check(angle))
+     return;
+
+   region->rotation = e_mod_rotation_angle_to_idx(angle);
+}
+
+static void
+_region_obj_geometry_update(Pol_Region *region)
+{
+   Rot_Idx r;
+
+   r = region->rotation;
+
+   INF("Update Geometry: rotation %d x %d y %d w %d h %d",
+       e_mod_rotation_idx_to_angle(r), region->geom[r].x, region->geom[r].y, region->geom[r].w, region->geom[r].h);
+
+   evas_object_geometry_set(region->obj,
+                            region->geom[r].x, region->geom[r].y,
+                            region->geom[r].w, region->geom[r].h);
+}
+
+static Eina_Bool
+_region_rotation_cb_change_end(void *data, int type, void *event)
+{
+   Pol_Region *region;
+   E_Event_Client *ev;
+   E_Client *ec;
+
+   region = data;
+   if (EINA_UNLIKELY(!region))
+     goto end;
+
+   ev = event;
+   if (EINA_UNLIKELY(!ev))
+     goto end;
+
+   ec = ev->ec;
+   if (EINA_UNLIKELY(!ec))
+     goto end;
+
+   if (e_mod_quickpanel_client_get() != ec)
+     goto end;
+
+   _region_rotation_set(region, ec->e.state.rot.ang.curr);
+   _region_obj_geometry_update(region);
+
+end:
+   return ECORE_CALLBACK_PASS_ON;
+}
+
+static Eina_Bool
+_region_rotation_init(Pol_Region *region)
+{
+   E_Client *ec;
+
+   /* FIXME: temporary use quickpanel to find out ui orientation */
+   ec = e_mod_quickpanel_client_get();
+   if (ec)
+     _region_rotation_set(region, ec->e.state.rot.ang.curr);
+
+   E_LIST_HANDLER_APPEND(region->event_list, E_EVENT_CLIENT_ROTATION_CHANGE_END, _region_rotation_cb_change_end, region);
+
+   return EINA_TRUE;
+}
+
+static void
+_region_free(Pol_Region *region)
+{
+   INF("Free Instant");
+   E_FREE_LIST(region->event_list, ecore_event_del);
+   E_FREE_FUNC(region->gesture, e_mod_gesture_del);
+   E_FREE_FUNC(region->obj, evas_object_del);
+   free(region);
+}
+
+static void
+_region_object_cb_del(void *data, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED)
+{
+   Pol_Region *region;
+
+   region = data;
+   if (EINA_UNLIKELY(!region))
+     return;
+
+   _region_free(region);
+}
+
+EINTERN Evas_Object *
+e_mod_region_object_new(void)
+{
+   Pol_Region *region;
+   Evas_Object *o;
+
+   INF("New Instant");
+
+   region = calloc(1, sizeof(*region));
+   if (!region)
+     return NULL;
+
+   o = evas_object_rectangle_add(e_comp->evas);
+   evas_object_color_set(o, 0, 0, 0, 0);
+   region->obj = o;
+
+   if (!_region_rotation_init(region))
+     goto err_event;
+
+   evas_object_data_set(o, EO_DATA_KEY, region);
+   evas_object_event_callback_add(o, EVAS_CALLBACK_DEL, _region_object_cb_del, region);
+
+   return o;
+err_event:
+   evas_object_del(o);
+   free(region);
+
+   return NULL;
+}
+
+EINTERN Eina_Bool
+e_mod_region_cb_set(Evas_Object *ro, Pol_Gesture_Start_Cb cb_start, Pol_Gesture_Move_Cb cb_move, Pol_Gesture_End_Cb cb_end, void *data)
+{
+   Pol_Gesture *gesture;
+
+   ENTRY(EINA_FALSE);
+
+   INF("Set Callback function");
+   if (!region->gesture)
+     {
+        gesture = e_mod_gesture_add(ro, POL_GESTURE_TYPE_NONE);
+        if (!gesture)
+          return EINA_FALSE;
+
+        region->gesture = gesture;
+     }
+
+   e_mod_gesture_cb_set(region->gesture, cb_start, cb_move, cb_end, data);
+
+   return EINA_TRUE;
+}
+
+EINTERN Eina_Bool
+e_mod_region_rectangle_set(Evas_Object *ro, Rot_Idx ridx, int x, int y, int w, int h)
+{
+   ENTRY(EINA_FALSE);
+
+   INF("Add Rectangle: a %d x %d y %d w %d h %d",
+       e_mod_rotation_idx_to_angle(ridx), x, y, w, h);
+
+   EINA_RECTANGLE_SET(&region->geom[ridx], x, y, w, h);
+
+   if (ridx == region->rotation)
+     _region_obj_geometry_update(region);
+
+   return EINA_TRUE;
+}
+
+EINTERN Eina_Bool
+e_mod_region_rectangle_get(Evas_Object *ro, Rot_Idx ridx, int *x, int *y, int *w, int *h)
+{
+   ENTRY(EINA_FALSE);
+
+   if (x) *x = region->geom[ridx].x;
+   if (y) *y = region->geom[ridx].y;
+   if (w) *w = region->geom[ridx].w;
+   if (h) *h = region->geom[ridx].h;
+
+   return EINA_TRUE;
+}
diff --git a/src/e_mod_region.h b/src/e_mod_region.h
new file mode 100644 (file)
index 0000000..68fa1c5
--- /dev/null
@@ -0,0 +1,14 @@
+#ifndef E_MOD_POL_GESTURE_REGION
+#define E_MOD_POL_GESTURE_REGION
+
+#include "e_mod_rotation.h"
+#include "e_mod_gesture.h"
+
+typedef struct _Pol_Region Pol_Region;
+
+EINTERN Evas_Object        *e_mod_region_object_new(void);
+EINTERN Eina_Bool           e_mod_region_rectangle_set(Evas_Object *ro, Rot_Idx ridx, int x, int y, int w, int h);
+EINTERN Eina_Bool           e_mod_region_rectangle_get(Evas_Object *ro, Rot_Idx ridx, int *x, int *y, int *w, int *h);
+EINTERN Eina_Bool           e_mod_region_cb_set(Evas_Object *ro, Pol_Gesture_Start_Cb cb_start, Pol_Gesture_Move_Cb cb_move, Pol_Gesture_End_Cb cb_end, void *data);
+
+#endif
index 4ba2c90..7b9e949 100644 (file)
@@ -1,7 +1,6 @@
 #include "e_mod_wl.h"
 #include "e_mod_main.h"
 #include "e_mod_quickpanel.h"
-#include "e_mod_indicator.h"
 #include "e_mod_volume.h"
 #include "e_mod_lockscreen.h"