E (RandR): Add function to return if a specific monitor is moving. Add
authorChristopher Michael <cpmichael1@comcast.net>
Wed, 3 Oct 2012 12:03:00 +0000 (12:03 +0000)
committerChristopher Michael <cpmichael1@comcast.net>
Wed, 3 Oct 2012 12:03:00 +0000 (12:03 +0000)
function to "reposition" a monitor when move is finished. Implement
basic monitor moving (still has some issues tho).

SVN revision: 77367

src/modules/conf_randr/e_smart_monitor.c
src/modules/conf_randr/e_smart_monitor.h
src/modules/conf_randr/e_smart_randr.c

index 40ec587..4e85335 100644 (file)
@@ -13,6 +13,9 @@ struct _E_Smart_Data
    /* object geometry */
    Evas_Coord x, y, w, h;
 
+   /* object geometry before move started */
+   Evas_Coord mx, my, mw, mh;
+
    /* visible flag */
    Eina_Bool visible : 1;
 
@@ -340,6 +343,31 @@ e_smart_monitor_crtc_geometry_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y
    /*   } */
 }
 
+void 
+e_smart_monitor_move_geometry_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h)
+{
+   E_Smart_Data *sd;
+
+   if (!(sd = evas_object_smart_data_get(obj)))
+     return;
+
+   if (x) *x = sd->mx;
+   if (y) *y = sd->my;
+   if (w) *w = sd->mw;
+   if (h) *h = sd->mh;
+}
+
+Eina_Bool 
+e_smart_monitor_moving_get(Evas_Object *obj)
+{
+   E_Smart_Data *sd;
+
+   if (!(sd = evas_object_smart_data_get(obj)))
+     return EINA_FALSE;
+
+   return sd->moving;
+}
+
 /* local functions */
 static void 
 _e_smart_add(Evas_Object *obj)
@@ -858,6 +886,9 @@ _e_smart_cb_thumb_mouse_down(void *data, Evas *evas __UNUSED__, Evas_Object *obj
         man = e_manager_current_get();
         e_pointer_type_push(man->pointer, obj, "move");
 
+        /* record this monitors geometry before moving */
+        e_layout_child_geometry_get(mon, &sd->mx, &sd->my, &sd->mw, &sd->mh);
+
         /* update moving state */
         sd->moving = EINA_TRUE;
 
@@ -1131,9 +1162,10 @@ _e_smart_monitor_move(E_Smart_Data *sd, Evas_Object *mon, void *event)
 
    /* actually move the monitor */
    if ((gx != nx) || (gy != ny))
-     e_layout_child_move(mon, nx, ny);
-
-   /* evas_object_smart_callback_call(mon, "monitor_moved", NULL); */
+     {
+        e_layout_child_move(mon, nx, ny);
+        evas_object_smart_callback_call(mon, "monitor_moved", NULL);
+     }
 
    /* Hmm, this below code worked also ... and seems lighter.
     * but the above code seems more "proper".
index dc379fc..99602b3 100644 (file)
@@ -7,6 +7,8 @@ void e_smart_monitor_layout_set(Evas_Object *obj, Evas_Object *layout);
 void e_smart_monitor_crtc_set(Evas_Object *obj, E_Randr_Crtc_Info *crtc);
 E_Randr_Crtc_Info *e_smart_monitor_crtc_get(Evas_Object *obj);
 void e_smart_monitor_crtc_geometry_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h);
+void e_smart_monitor_move_geometry_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h);
+Eina_Bool e_smart_monitor_moving_get(Evas_Object *obj);
 
 #  define E_SMART_MONITOR_H
 # endif
index 6f97572..295ed3a 100644 (file)
@@ -29,6 +29,7 @@ static void _e_smart_clip_set(Evas_Object *obj, Evas_Object *clip);
 static void _e_smart_clip_unset(Evas_Object *obj);
 static void _e_smart_reconfigure(E_Smart_Data *sd);
 static void _e_smart_randr_layout_adjust(E_Smart_Data *sd, Evas_Object *obj);
+static void _e_smart_randr_layout_reposition(E_Smart_Data *sd, Evas_Object *obj);
 
 static void _e_smart_cb_monitor_resized(void *data, Evas_Object *obj, void *event __UNUSED__);
 static void _e_smart_cb_monitor_rotated(void *data, Evas_Object *obj, void *event __UNUSED__);
@@ -76,6 +77,8 @@ e_smart_randr_monitor_add(Evas_Object *obj, Evas_Object *mon)
    if (!(sd = evas_object_smart_data_get(obj)))
      return;
 
+   printf("Adding Monitor Object: %p\n", mon);
+
    /* tell monitor what layout it is in */
    e_smart_monitor_layout_set(mon, sd->o_layout);
 
@@ -252,6 +255,8 @@ _e_smart_randr_layout_adjust(E_Smart_Data *sd, Evas_Object *obj)
 
    if (!sd) return;
 
+#define RESISTANCE_THRESHOLD 5
+
    /* get the geometry of this monitor */
    e_layout_child_geometry_get(obj, &o.x, &o.y, &o.w, &o.h);
 
@@ -285,7 +290,8 @@ _e_smart_randr_layout_adjust(E_Smart_Data *sd, Evas_Object *obj)
           {
              /* they intersect, we need to move this one */
              /* NB: This can happen when monitors get moved manually */
-             if ((m.x < (o.x + o.w)))
+
+             if ((m.x <= (o.x + o.w)))
                e_layout_child_move(mon, (o.x + o.w), m.y);
              else if ((m.y <= (o.y + o.h)))
                e_layout_child_move(mon, m.x, (o.y + o.h));
@@ -296,6 +302,53 @@ _e_smart_randr_layout_adjust(E_Smart_Data *sd, Evas_Object *obj)
    e_layout_thaw(sd->o_layout);
 }
 
+static void 
+_e_smart_randr_layout_reposition(E_Smart_Data *sd, Evas_Object *obj)
+{
+   Eina_List *l = NULL;
+   Evas_Object *mon;
+   Eina_Rectangle o;
+   Evas_Coord mx, my;
+
+   if (!sd) return;
+
+   /* get this monitor geometry Before it was moved
+    * 
+    * NB: This is returned in Virtual coordinates */
+   e_smart_monitor_move_geometry_get(obj, &mx, &my, NULL, NULL);
+
+   /* get the geometry of this monitor */
+   evas_object_geometry_get(obj, &o.x, &o.y, &o.w, &o.h);
+
+   /* freeze layout */
+   e_layout_freeze(sd->o_layout);
+
+   /* find any monitors that this one intersects with */
+   EINA_LIST_FOREACH(sd->items, l, mon)
+     {
+        Eina_Rectangle m;
+
+        /* skip if it's the current monitor */
+        if ((mon == obj)) continue;
+
+        /* get the geometry of this monitor */
+        evas_object_geometry_get(mon, &m.x, &m.y, &m.w, &m.h);
+
+        if (eina_rectangles_intersect(&o, &m))
+          {
+             /* if these 2 monitors intersect, we need to move the second one 
+              * as the user is currently moving the first one
+              * 
+              * NB: Currently, this will move This monitor to the 
+              * position of the old one. This is probably not ideal */
+             e_layout_child_move(mon, mx, my);
+          }
+     }
+
+   /* thaw layout to allow redraw */
+   e_layout_thaw(sd->o_layout);
+}
+
 /* callback received from the monitor object to let us know that it was 
  * resized, and we should adjust position of any adjacent monitors */
 static void 
@@ -321,9 +374,18 @@ _e_smart_cb_monitor_rotated(void *data, Evas_Object *obj, void *event __UNUSED__
 /* callback received from the monitor object to let us know that it was 
  * moved, and we should adjust position of any adjacent monitors */
 static void 
-_e_smart_cb_monitor_moved(void *data __UNUSED__, Evas_Object *obj __UNUSED__, void *event __UNUSED__)
+_e_smart_cb_monitor_moved(void *data, Evas_Object *obj, void *event __UNUSED__)
 {
-   printf("Monitor Moved\n");
+   E_Smart_Data *sd;
+
+   if (!(sd = data)) return;
+
+//   printf("Monitor Moved: %p\n", obj);
+
+   if (e_smart_monitor_moving_get(obj)) 
+     _e_smart_randr_layout_reposition(sd, obj);
+   else 
+     _e_smart_randr_layout_adjust(sd, obj);
 }
 
 /* callback received from the monitor object to let us know that it was