E (RandR): Add function to return if a specific monitor is moving. Add

function to "reposition" a monitor when move is finished. Implement
basic monitor moving (still has some issues tho).



SVN revision: 77367
This commit is contained in:
Christopher Michael 2012-10-03 12:03:00 +00:00
parent 3a6943ce26
commit 0f5cd63f5a
3 changed files with 102 additions and 6 deletions

View 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".

View 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

View 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