e_comp_wl: pull transformable window inside of canvas 24/47224/2
authorMinJeong Kim <minjjj.kim@samsung.com>
Tue, 1 Sep 2015 06:27:13 +0000 (15:27 +0900)
committerMinJeong Kim <minjjj.kim@samsung.com>
Wed, 2 Sep 2015 07:25:07 +0000 (16:25 +0900)
pull transformable window inside of canvas when user tried to locate window
ouside of screen.

Change-Id: I7b4f1409d5539a8b4636bb4f7fae7dc5a0a4f88b
Signed-off-by: MinJeong Kim <minjjj.kim@samsung.com>
src/bin/e_client.c
src/bin/e_comp_wl.c

index 0c073a4ae84037b44277cb23f30cbd66f8841b71..202c5c969e27def5b58616fb891e7ad935b195b5 100644 (file)
@@ -599,6 +599,9 @@ _e_client_transform_resize_handle(E_Client *ec)
           new_h = ec->moveinfo.down.h + (current.y - moveinfo.y);
      }
 
+   new_w = MIN(new_w, ec->zone->w);
+   new_h = MIN(new_h, ec->zone->h);
+
    /* step 4: move to new position */
    if ((ec->resize_mode == E_POINTER_RESIZE_TL) ||
        (ec->resize_mode == E_POINTER_RESIZE_L) ||
@@ -1736,6 +1739,11 @@ _e_client_cb_evas_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UN
      }
    if (ec->moving || (ecmove == ec))
      _e_client_hook_call(E_CLIENT_HOOK_MOVE_UPDATE, ec);
+
+   if ((!ec->moving) && (ec->transformed))
+     _e_client_transform_geometry_save(ec,
+                                       (Evas_Map *)evas_object_map_get(ec->frame));
+
    e_remember_update(ec);
    ec->pre_cb.x = x; ec->pre_cb.y = y;
 
index 3ae37d64508df95cad81663db19a09cea594a42d..15dd856258931f2f2fba23004ec058557d4de976 100644 (file)
@@ -32,6 +32,106 @@ static Eina_List *handlers = NULL;
 static double _last_event_time = 0.0;
 
 /* local functions */
+static void
+_e_comp_wl_transform_stay_within_canvas(E_Client *ec, int x, int y, int *new_x, int *new_y)
+{
+   int new_x_max, new_y_max;
+   int zw, zh;
+   Eina_Bool lw, lh;
+
+   if (!ec->zone)
+     {
+        if (new_x) *new_x = x;
+        if (new_y) *new_y = y;
+        return;
+     }
+
+   zw = ec->zone->w;
+   zh = ec->zone->h;
+
+   new_x_max = zw - ec->w;
+   new_y_max = zh - ec->h;
+   lw = ec->w > zw ? EINA_TRUE : EINA_FALSE;
+   lh = ec->h > zh ? EINA_TRUE : EINA_FALSE;
+
+   if (new_x)
+     {
+        if (lw)
+          {
+             if (x <= new_x_max)
+               *new_x = new_x_max;
+             else if (x >= 0)
+               *new_x = 0;
+          }
+        else
+          {
+             if (x >= new_x_max)
+               *new_x = new_x_max;
+             else if (x <= 0)
+               *new_x = 0;
+          }
+     }
+
+   if (new_y)
+     {
+        if (lh)
+          {
+             if (y <= new_y_max)
+               *new_y = new_y_max;
+             else if (y >= 0)
+               *new_y = 0;
+          }
+        else
+          {
+             if (y >= new_y_max)
+               *new_y = new_y_max;
+             else if (y <= 0)
+               *new_y = 0;
+          }
+     }
+}
+
+static void
+_e_comp_wl_transform_pull_del(void *data,
+                              Elm_Transit *trans EINA_UNUSED)
+{
+   E_Client *ec = data;
+   if (!ec) return;
+
+   e_object_unref(E_OBJECT(ec));
+}
+
+static void
+_e_comp_wl_transform_pull(E_Client *ec)
+{
+   Elm_Transit *trans;
+   int new_x, new_y;
+
+   new_x = ec->client.x;
+   new_y = ec->client.y;
+
+   _e_comp_wl_transform_stay_within_canvas(ec,
+                                           ec->client.x, ec->client.y,
+                                           &new_x, &new_y);
+
+   if ((ec->client.x == new_x) && (ec->client.y == new_y))
+     return;
+
+   e_object_ref(E_OBJECT(ec));
+
+   trans = elm_transit_add();
+   elm_transit_del_cb_set(trans, _e_comp_wl_transform_pull_del, ec);
+   elm_transit_tween_mode_set(trans, ELM_TRANSIT_TWEEN_MODE_DECELERATE);
+   elm_transit_effect_translation_add(trans,
+                                      0, 0,
+                                      new_x - ec->client.x,
+                                      new_y - ec->client.y);
+   elm_transit_object_add(trans, ec->frame);
+   elm_transit_objects_final_state_keep_set(trans, EINA_TRUE);
+   elm_transit_duration_set(trans, 0.4);
+   elm_transit_go(trans);
+}
+
 static void
 _e_comp_wl_transform_effect_end(Elm_Transit_Effect *context,
                                 Elm_Transit *trans)
@@ -41,6 +141,7 @@ _e_comp_wl_transform_effect_end(Elm_Transit_Effect *context,
 
    if (!ctxt) return;
    ec = ctxt->ec;
+
    if ((ec) && (!e_object_is_del(E_OBJECT(ec))))
      {
         ec->comp_data->transform.start = 0;
@@ -3198,6 +3299,16 @@ _e_comp_wl_client_cb_resize_end(void *data EINA_UNUSED, E_Client *ec)
    E_FREE_LIST(ec->pending_resize, free);
 }
 
+static void
+_e_comp_wl_client_cb_move_end(void *data EINA_UNUSED, E_Client *ec)
+{
+   if (e_object_is_del(E_OBJECT(ec))) return;
+   if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL) return;
+
+   if (ec->comp_data->transform.enabled)
+     _e_comp_wl_transform_pull(ec);
+}
+
 static void
 _e_comp_wl_cb_output_unbind(struct wl_resource *resource)
 {
@@ -3643,6 +3754,9 @@ e_comp_wl_init(void)
    e_client_hook_add(E_CLIENT_HOOK_RESIZE_END,
                      _e_comp_wl_client_cb_resize_end, NULL);
 
+   e_client_hook_add(E_CLIENT_HOOK_MOVE_END,
+                     _e_comp_wl_client_cb_move_end, NULL);
+
    _last_event_time = ecore_loop_time_get();
 
    return EINA_TRUE;