You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

439 lines
15 KiB

#include "e_mod_main.h"
static E_Desk *desk_show = NULL;
static Evas_Object *dm_show = NULL;
static E_Desk *desk_hide = NULL;
static Evas_Object *dm_hide = NULL;
static DS_Type cur_type = DS_PAN;
static void
_ds_end(void *data EINA_UNUSED, Efx_Map_Data *emd EINA_UNUSED, Evas_Object *obj EINA_UNUSED)
{
/* hide/delete previous desk's mirror */
evas_object_hide(dm_hide);
E_FREE_FUNC(dm_hide, evas_object_del);
desk_hide = NULL;
/* trigger desk flip end if there's a current desk set */
if (desk_show)
{
e_desk_flip_end(desk_show);
e_comp_shape_queue_block(e_comp_get(desk_show), 0);
}
/* hide/delete current desk's mirror */
evas_object_hide(dm_show);
E_FREE_FUNC(dm_show, evas_object_del);
desk_show = NULL;
}
static Evas_Object *
dm_add(E_Desk *desk)
{
Evas_Object *o;
/* add new mirror: not a pager or taskbar */
o = e_deskmirror_add(desk, 0, 0);
/* cover desk */
evas_object_geometry_set(o, desk->zone->x, desk->zone->y, desk->zone->w, desk->zone->h);
/* don't receive events */
evas_object_pass_events_set(o, 1);
/* clip to current screen */
evas_object_clip_set(o, desk->zone->bg_clip_object);
/* above all menus/popups/clients */
evas_object_layer_set(o, E_LAYER_MENU + 100);
evas_object_show(o);
return o;
}
static void
_ds_blink2(void *data EINA_UNUSED, Efx_Map_Data *emd EINA_UNUSED, Evas_Object *obj)
{
E_FREE_FUNC(dm_hide, evas_object_del);
evas_object_show(dm_show);
efx_resize(obj, EFX_EFFECT_SPEED_DECELERATE,
EFX_POINT(desk_show->zone->x, desk_show->zone->y),
desk_show->zone->w, desk_show->zone->h,
0.45, _ds_end, NULL);
}
static void
_ds_show(E_Desk *desk, int dx, int dy)
{
E_Client *ec;
DS_Type use_type;
Eina_Bool *disabled_types = (Eina_Bool*)&ds_config->types;
/* free existing mirror */
E_FREE_FUNC(dm_show, evas_object_del);
/* iterate all clients */
E_CLIENT_FOREACH(desk->zone->comp, ec)
{
/* skip clients from other screens, iconic clients, and ignorable clients */
if (e_client_util_ignored_get(ec) || (ec->desk->zone != desk->zone) || (ec->iconic)) continue;
/* always keep user-moving clients visible */
if (ec->moving)
{
e_client_desk_set(ec, desk);
evas_object_show(ec->frame);
continue;
}
/* skip clients from other desks and clients visible on all desks */
if ((ec->desk != desk) || (ec->sticky)) continue;
e_comp_object_effect_unclip(ec->frame);
e_comp_object_effect_set(ec->frame, NULL);
/* comp unignore the client */
e_client_comp_hidden_set(ec, ec->shaded);
ec->hidden = 0;
evas_object_show(ec->frame);
}
if (ds_config->disabled_transition_count == DS_LAST)
{
e_desk_flip_end(desk);
return;
}
desk_show = desk;
e_comp_shape_queue_block(e_comp_get(desk), 1);
/* guarantee that the user gets to see each flip
* at least once
*/
if (cur_type < DS_LAST)
use_type = cur_type++;
else
use_type = rand() % DS_LAST;
while (disabled_types[use_type])
{
use_type++;
if (use_type == DS_LAST)
{
cur_type = DS_LAST;
use_type = DS_PAN;
}
}
/* pick a random flip */
switch (use_type)
{
int x, y, hx, hy, w, h;
Evas_Object *o;
case DS_PAN:
switch (dx)
{
case -1: // left -> right
x = desk->zone->x - desk->zone->w;
hx = desk->zone->x + desk->zone->w;
break;
case 0: // X
x = desk->zone->x;
hx = desk->zone->x;
break;
case 1: // left <- right
x = desk->zone->x + desk->zone->w;
hx = desk->zone->x - desk->zone->w;
break;
}
switch (dy)
{
case -1: // up -> down
y = desk->zone->y - desk->zone->h;
hy = desk->zone->y + desk->zone->h;
break;
case 0: // X
y = desk->zone->y;
hy = desk->zone->y;
break;
case 1: // up <- down
y = desk->zone->y + desk->zone->h;
hy = desk->zone->y - desk->zone->h;
break;
}
dm_show = dm_add(desk);
evas_object_move(dm_show, x, y);
efx_move(dm_hide, EFX_EFFECT_SPEED_DECELERATE, EFX_POINT(hx, hy), 0.2, NULL, NULL);
efx_move(dm_show, EFX_EFFECT_SPEED_DECELERATE, EFX_POINT(desk->zone->x, desk->zone->y), 0.2, _ds_end, NULL);
break;
case DS_FADE_OUT:
efx_fade(dm_hide, EFX_EFFECT_SPEED_LINEAR, EFX_COLOR(0, 0, 0), 0, 0.25, _ds_end, NULL);
break;
case DS_FADE_IN:
E_FREE_FUNC(dm_hide, evas_object_del);
dm_show = dm_add(desk);
efx_fade(dm_show, EFX_EFFECT_SPEED_LINEAR, EFX_COLOR(0, 0, 0), 0, 0.0, NULL, NULL);
efx_fade(dm_show, EFX_EFFECT_SPEED_LINEAR, EFX_COLOR(255, 255, 255), 255, 0.25, _ds_end, NULL);
break;
case DS_BATMAN:
evas_object_raise(dm_hide);
efx_spin_start(dm_hide, 1080.0, NULL);
efx_zoom(dm_hide, EFX_EFFECT_SPEED_LINEAR, 1.0, 0.00001, NULL, 0.4, _ds_end, NULL);
break;
case DS_ZOOM_IN:
dm_show = dm_add(desk);
efx_zoom(dm_show, EFX_EFFECT_SPEED_LINEAR, 0.000001, 1.0, NULL, 0.4, _ds_end, NULL);
break;
case DS_ZOOM_OUT:
evas_object_raise(dm_hide);
efx_zoom(dm_hide, EFX_EFFECT_SPEED_LINEAR, 1.0, 0.0000001, NULL, 0.4, _ds_end, NULL);
break;
case DS_GROW:
x = hx = desk->zone->x;
w = 1;
if (dx == 1) // grow right to left
x = desk->zone->x + desk->zone->w;
else if (!dx)
w = desk->zone->w;
y = hy = desk->zone->y;
h = 1;
if (dy == 1) // grow bottom to top
y = desk->zone->y + desk->zone->h;
else if (!dy)
h = desk->zone->h;
dm_show = dm_add(desk);
o = evas_object_rectangle_add(e_comp_get(desk)->evas);
evas_object_geometry_set(o, x, y, w, h);
evas_object_clip_set(dm_show, o);
evas_object_show(o);
e_comp_object_util_del_list_append(dm_show, o);
efx_resize(o, EFX_EFFECT_SPEED_LINEAR, EFX_POINT(hx, hy), desk->zone->w, desk->zone->h, 0.4, _ds_end, NULL);
break;
case DS_ROTATE_OUT:
efx_move_circle(dm_hide, EFX_EFFECT_SPEED_LINEAR, EFX_POINT(desk->zone->x + (desk->zone->w / 2), desk->zone->y + (desk->zone->h / 2)),
720, 0.4, NULL, NULL);
efx_resize(dm_hide, EFX_EFFECT_SPEED_LINEAR, NULL, 1, 1, 0.4, _ds_end, NULL);
break;
case DS_ROTATE_IN:
dm_show = dm_add(desk);
evas_object_resize(dm_show, 1, 1);
efx_move_circle(dm_show, EFX_EFFECT_SPEED_LINEAR, EFX_POINT(desk->zone->x + (desk->zone->w / 2), desk->zone->y + (desk->zone->h / 2)),
720, 0.4, NULL, NULL);
efx_resize(dm_show, EFX_EFFECT_SPEED_LINEAR, NULL, desk->zone->w, desk->zone->h, 0.4, _ds_end, NULL);
break;
case DS_SLIDE_SPLIT:
{
Evas_Object *dmh, *clip;
Evas_Point exy;
unsigned int i, num;
num = (rand() % 4) + 2;
dmh = dm_hide;
/* create other parts of split */
w = desk->zone->w;
h = desk->zone->h;
if (dy)
w /= num;
else
h /= num;
for (i = 0; i < num; i++)
{
if (!dmh)
{
/* create other deskmirrors where necessary */
dmh = dm_add(desk_hide);
e_comp_object_util_del_list_append(dm_hide, dmh);
}
clip = evas_object_rectangle_add(e_comp_get(desk_show)->evas);
e_comp_object_util_del_list_append(dm_hide, clip);
if (dx)
evas_object_geometry_set(clip, desk->zone->x, desk->zone->y + (i * h), w, h);
else
evas_object_geometry_set(clip, desk->zone->x + (i * w), desk->zone->y, w, h);
evas_object_clip_set(dmh, clip);
evas_object_show(clip);
exy.x = desk->zone->x;
exy.y = desk->zone->y;
if (dx)
{
if (i % 2 == 0)
exy.x = desk_show->zone->x - (dx * desk_show->zone->w);
else
exy.x = desk_show->zone->x + (dx * desk_show->zone->w);
}
if (dy)
{
if (i % 2 == 0)
exy.y = desk_show->zone->y - (dy * desk_show->zone->h);
else
exy.y = desk_show->zone->y + (dy * desk_show->zone->h);
}
efx_move(dmh, EFX_EFFECT_SPEED_ACCELERATE,
&exy, 0.5, (i == (num - 1)) ? _ds_end : NULL, NULL);
dmh = NULL;
}
}
break;
case DS_QUAD_SPLIT:
{
int i;
Evas_Object *dmh[4] = {NULL};
Evas_Object *clip[4];
/* set up quadrant position coords */
Evas_Point cxy[4] = {{desk->zone->x, desk->zone->y},
{desk->zone->x + (desk->zone->w / 2), desk->zone->y},
{desk->zone->x, desk->zone->y + (desk->zone->h / 2)},
{desk->zone->x + (desk->zone->w / 2), desk->zone->y + (desk->zone->h / 2)}
};
/* set up quadrant effect coords */
Evas_Point exy[4] = {{desk->zone->x - desk->zone->w, desk->zone->y - desk->zone->h},
{desk->zone->x + (desk->zone->w * 2), desk->zone->y - desk->zone->h},
{desk->zone->x - desk->zone->w, desk->zone->y + (desk->zone->h / 2)},
{desk->zone->x + (desk->zone->w * 2), desk->zone->y + (desk->zone->h * 2)}
};
dmh[0] = dm_hide;
for (i = 0; i < 4; i++)
{
if (!dmh[i])
{
/* create other 3 quadrants */
dmh[i] = dm_add(desk_hide);
e_comp_object_util_del_list_append(dm_hide, dmh[i]);
}
/* clip the quad */
clip[i] = evas_object_rectangle_add(e_comp_get(desk)->evas);
e_comp_object_util_del_list_append(dm_hide, clip[i]);
/* lay out 2x2 grid */
evas_object_geometry_set(clip[i], cxy[i].x, cxy[i].y, desk->zone->w / 2, desk->zone->h / 2);
evas_object_clip_set(dmh[i], clip[i]);
evas_object_show(clip[i]);
/* apply effect coords */
efx_move(clip[i], EFX_EFFECT_SPEED_ACCELERATE,
&exy[i], 0.8, (i == 3) ? _ds_end : NULL, NULL);
}
}
break;
case DS_QUAD_MERGE:
{
int i;
Evas_Object *dmh[4] = {NULL};
Evas_Object *clip[4];
/* set up quadrant position coords */
Evas_Point cxy[4] = {{desk->zone->x, desk->zone->y},
{desk->zone->x + (desk->zone->w / 2), desk->zone->y},
{desk->zone->x, desk->zone->y + (desk->zone->h / 2)},
{desk->zone->x + (desk->zone->w / 2), desk->zone->y + (desk->zone->h / 2)}
};
dmh[0] = dm_hide;
for (i = 0; i < 4; i++)
{
if (!dmh[i])
{
/* create other 3 quadrants */
dmh[i] = dm_add(desk_hide);
e_comp_object_util_del_list_append(dm_hide, dmh[i]);
}
/* clip the quad */
clip[i] = evas_object_rectangle_add(e_comp_get(desk)->evas);
e_comp_object_util_del_list_append(dm_hide, clip[i]);
/* lay out 2x2 grid */
evas_object_geometry_set(clip[i], cxy[i].x, cxy[i].y, desk->zone->w / 2, desk->zone->h / 2);
evas_object_clip_set(dmh[i], clip[i]);
evas_object_show(clip[i]);
/* resize all quads to 1x1 while moving towards center */
efx_resize(clip[i], EFX_EFFECT_SPEED_ACCELERATE,
EFX_POINT(desk->zone->x + (desk->zone->w / 2), desk->zone->y + (desk->zone->h / 2)),
1, 1 ,0.8, (i == 3) ? _ds_end : NULL, NULL);
}
}
break;
case DS_BLINK:
{
Evas_Object *clip, *bg;
dm_show = dm_add(desk);
evas_object_geometry_set(dm_show, desk->zone->x, desk->zone->y, desk->zone->w, desk->zone->h);
evas_object_hide(dm_show);
bg = evas_object_rectangle_add(e_comp_get(desk)->evas);
e_comp_object_util_del_list_append(dm_show, bg);
evas_object_color_set(bg, 0, 0, 0, 255);
evas_object_layer_set(bg, E_LAYER_MENU + 99);
evas_object_geometry_set(bg, desk->zone->x, desk->zone->y, desk->zone->w, desk->zone->h);
evas_object_show(bg);
clip = evas_object_rectangle_add(e_comp_get(desk)->evas);
e_comp_object_util_del_list_append(dm_show, clip);
/* fit clipper to zone */
evas_object_geometry_set(clip, desk->zone->x, desk->zone->y, desk->zone->w, desk->zone->h);
evas_object_clip_set(dm_hide, clip);
evas_object_clip_set(dm_show, clip);
evas_object_show(clip);
/* resize clip to 1px high while moving towards center */
efx_resize(clip, EFX_EFFECT_SPEED_ACCELERATE,
EFX_POINT(desk->zone->x, desk->zone->y + (desk->zone->h / 2)),
desk->zone->w, 1, 0.45, _ds_blink2, NULL);
}
break;
case DS_VIEWPORT:
{
Evas_Object *clip;
clip = evas_object_rectangle_add(e_comp_get(desk)->evas);
/* fit clipper to zone */
evas_object_geometry_set(clip, desk->zone->x, desk->zone->y, desk->zone->w, desk->zone->h);
evas_object_clip_set(dm_hide, clip);
e_comp_object_util_del_list_append(dm_hide, clip);
evas_object_show(clip);
/* resize clip to 1x1 while moving towards center */
efx_resize(clip, EFX_EFFECT_SPEED_DECELERATE,
EFX_POINT(desk->zone->x + (desk->zone->w / 2), desk->zone->y + (desk->zone->h / 2)),
1, 1, 0.6, _ds_end, NULL);
}
break;
default: break;
}
if (dm_show) evas_object_name_set(dm_show, "dm_show");
}
static void
_ds_hide(E_Desk *desk)
{
E_Client *ec;
E_FREE_FUNC(dm_hide, evas_object_del);
E_CLIENT_FOREACH(desk->zone->comp, ec)
{
/* same as above */
if (e_client_util_ignored_get(ec) || (ec->desk->zone != desk->zone) || (ec->iconic)) continue;
if (ec->moving) continue;
if ((ec->desk != desk) || (ec->sticky)) continue;
/* comp hide clients */
e_client_comp_hidden_set(ec, EINA_TRUE);
ec->hidden = 1;
evas_object_hide(ec->frame);
}
if (ds_config->disabled_transition_count == DS_LAST) return;
desk_hide = desk;
/* create mirror for previous desk */
dm_hide = dm_add(desk);
evas_object_name_set(dm_hide, "dm_hide");
}
static void
_ds_flip(void *data EINA_UNUSED, E_Desk *desk, int dx, int dy, Eina_Bool show)
{
/* this is called for desk hide, then for desk show. always in that order. always. */
if (show)
_ds_show(desk, dx, dy);
else
_ds_hide(desk);
}
EINTERN void
ds_init(void)
{
/* set a desk flip replacement callback */
e_desk_flip_cb_set(_ds_flip, NULL);
}
EINTERN void
ds_shutdown(void)
{
e_desk_flip_cb_set(NULL, NULL);
_ds_end(NULL, NULL, NULL);
cur_type = DS_PAN;
}