enlightenment/src/bin/e_zone.c

1314 lines
38 KiB
C
Raw Normal View History

/*
* vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
*/
#include "e.h"
/* E_Zone is a child object of E_Container. There is one zone per screen
* in a xinerama setup. Each zone has one or more desktops.
*/
static void _e_zone_free(E_Zone *zone);
static void _e_zone_cb_bg_mouse_down(void *data, Evas *evas, Evas_Object *obj, void *event_info);
static void _e_zone_cb_bg_mouse_up(void *data, Evas *evas, Evas_Object *obj, void *event_info);
static void _e_zone_event_zone_desk_count_set_free(void *data, void *ev);
2005-04-22 01:19:39 -07:00
static int _e_zone_cb_mouse_in(void *data, int type, void *event);
static int _e_zone_cb_mouse_out(void *data, int type, void *event);
static int _e_zone_cb_mouse_move(void *data, int type, void *event);
static int _e_zone_cb_desk_after_show(void *data, int type, void *event);
static int _e_zone_cb_edge_timer(void *data);
static void _e_zone_event_move_resize_free(void *data, void *ev);
static void _e_zone_event_add_free(void *data, void *ev);
static void _e_zone_event_del_free(void *data, void *ev);
static void _e_zone_object_del_attach(void *o);
2006-01-07 02:39:46 -08:00
EAPI int E_EVENT_ZONE_DESK_COUNT_SET = 0;
EAPI int E_EVENT_POINTER_WARP = 0;
EAPI int E_EVENT_ZONE_MOVE_RESIZE = 0;
EAPI int E_EVENT_ZONE_ADD = 0;
EAPI int E_EVENT_ZONE_DEL = 0;
2007-11-22 12:08:07 -08:00
EAPI int E_EVENT_ZONE_EDGE_IN = 0;
EAPI int E_EVENT_ZONE_EDGE_OUT = 0;
EAPI int E_EVENT_ZONE_EDGE_MOVE = 0;
#define E_ZONE_FLIP_LEFT(zone) ((e_config->desk_flip_wrap && ((zone)->desk_x_count > 1)) || ((zone)->desk_x_current > 0))
#define E_ZONE_FLIP_RIGHT(zone) ((e_config->desk_flip_wrap && ((zone)->desk_x_count > 1)) || (((zone)->desk_x_current + 1) < (zone)->desk_x_count))
#define E_ZONE_FLIP_UP(zone) ((e_config->desk_flip_wrap && ((zone)->desk_y_count > 1)) || ((zone)->desk_y_current > 0))
#define E_ZONE_FLIP_DOWN(zone) ((e_config->desk_flip_wrap && ((zone)->desk_y_count > 1)) || (((zone)->desk_y_current + 1) < (zone)->desk_y_count))
2005-04-24 09:04:20 -07:00
#define E_ZONE_CORNER_RATIO 0.025;
2006-01-07 02:39:46 -08:00
EAPI int
e_zone_init(void)
{
E_EVENT_ZONE_DESK_COUNT_SET = ecore_event_type_new();
E_EVENT_POINTER_WARP = ecore_event_type_new();
E_EVENT_ZONE_MOVE_RESIZE = ecore_event_type_new();
E_EVENT_ZONE_ADD = ecore_event_type_new();
E_EVENT_ZONE_DEL = ecore_event_type_new();
2007-11-22 12:08:07 -08:00
E_EVENT_ZONE_EDGE_IN = ecore_event_type_new();
E_EVENT_ZONE_EDGE_OUT = ecore_event_type_new();
E_EVENT_ZONE_EDGE_MOVE = ecore_event_type_new();
return 1;
}
2006-01-07 02:39:46 -08:00
EAPI int
e_zone_shutdown(void)
{
return 1;
}
2006-01-07 02:39:46 -08:00
EAPI E_Zone *
e_zone_new(E_Container *con, int num, int id, int x, int y, int w, int h)
{
E_Zone *zone;
char name[40];
Evas_Object *o;
E_Event_Zone_Add *ev;
int cw, ch;
zone = E_OBJECT_ALLOC(E_Zone, E_ZONE_TYPE, _e_zone_free);
if (!zone) return NULL;
zone->container = con;
zone->x = x;
zone->y = y;
zone->w = w;
zone->h = h;
zone->num = num;
zone->id = id;
e_zone_useful_geometry_dirty(zone);
cw = w * E_ZONE_CORNER_RATIO;
ch = h * E_ZONE_CORNER_RATIO;
zone->corner.left_bottom = ecore_x_window_input_new(con->win,
zone->x, zone->y + zone->h - ch, 1, ch);
zone->edge.left = ecore_x_window_input_new(con->win,
zone->x, zone->y + ch, 1, zone->h - 2 * ch);
zone->corner.left_top = ecore_x_window_input_new(con->win,
zone->x, zone->y, 1, ch);
zone->corner.top_left = ecore_x_window_input_new(con->win,
zone->x + 1, zone->y, cw, 1);
zone->edge.top = ecore_x_window_input_new(con->win,
zone->x + 1 + cw, zone->y, zone->w - 2 * cw - 2, 1);
zone->corner.top_right = ecore_x_window_input_new(con->win,
zone->x + zone->w - cw - 2, zone->y, cw, 1);
zone->corner.right_top = ecore_x_window_input_new(con->win,
zone->x + zone->w - 1, zone->y, 1, ch);
zone->edge.right = ecore_x_window_input_new(con->win,
zone->x + zone->w - 1, zone->y + ch, 1, zone->h - 2 * ch);
zone->corner.right_bottom = ecore_x_window_input_new(con->win,
zone->x + zone->w - 1, zone->y + zone->h - ch, 1, ch);
zone->corner.bottom_right = ecore_x_window_input_new(con->win,
zone->x + 1, zone->y + zone->h - 1, cw, 1);
zone->edge.bottom = ecore_x_window_input_new(con->win,
zone->x + 1 + cw, zone->y + zone->h - 1, zone->w - 2 - 2 * cw, 1);
zone->corner.bottom_left = ecore_x_window_input_new(con->win,
zone->x + zone->w - cw - 2, zone->y + zone->h - 1, cw, 1);
e_container_window_raise(zone->container, zone->corner.left_bottom, 999);
e_container_window_raise(zone->container, zone->corner.left_top, 999);
e_container_window_raise(zone->container, zone->corner.top_left, 999);
e_container_window_raise(zone->container, zone->corner.top_right, 999);
e_container_window_raise(zone->container, zone->corner.right_top, 999);
e_container_window_raise(zone->container, zone->corner.right_bottom, 999);
e_container_window_raise(zone->container, zone->corner.bottom_right, 999);
e_container_window_raise(zone->container, zone->corner.bottom_left, 999);
e_container_window_raise(zone->container, zone->edge.left, 999);
e_container_window_raise(zone->container, zone->edge.right, 999);
e_container_window_raise(zone->container, zone->edge.top, 999);
e_container_window_raise(zone->container, zone->edge.bottom, 999);
2005-04-22 01:19:39 -07:00
ecore_x_window_show(zone->edge.left);
ecore_x_window_show(zone->edge.right);
ecore_x_window_show(zone->edge.top);
ecore_x_window_show(zone->edge.bottom);
ecore_x_window_show(zone->corner.left_bottom);
ecore_x_window_show(zone->corner.left_top);
ecore_x_window_show(zone->corner.top_left);
ecore_x_window_show(zone->corner.top_right);
ecore_x_window_show(zone->corner.right_top);
ecore_x_window_show(zone->corner.right_bottom);
ecore_x_window_show(zone->corner.bottom_right);
ecore_x_window_show(zone->corner.bottom_left);
zone->handlers =
eina_list_append(zone->handlers,
ecore_event_handler_add(ECORE_X_EVENT_MOUSE_IN,
_e_zone_cb_mouse_in, zone));
zone->handlers =
eina_list_append(zone->handlers,
ecore_event_handler_add(ECORE_X_EVENT_MOUSE_OUT,
_e_zone_cb_mouse_out, zone));
zone->handlers =
eina_list_append(zone->handlers,
ecore_event_handler_add(ECORE_EVENT_MOUSE_MOVE,
_e_zone_cb_mouse_move, zone));
zone->handlers =
eina_list_append(zone->handlers,
ecore_event_handler_add(E_EVENT_DESK_AFTER_SHOW,
_e_zone_cb_desk_after_show, zone));
2005-04-22 01:19:39 -07:00
snprintf(name, sizeof(name), "Zone %d", zone->num);
zone->name = eina_stringshare_add(name);
con->zones = eina_list_append(con->zones, zone);
o = evas_object_rectangle_add(con->bg_evas);
zone->bg_clip_object = o;
evas_object_move(o, x, y);
evas_object_resize(o, w, h);
evas_object_color_set(o, 255, 255, 255, 255);
evas_object_show(o);
o = evas_object_rectangle_add(con->bg_evas);
zone->bg_event_object = o;
evas_object_clip_set(o, zone->bg_clip_object);
evas_object_move(o, x, y);
evas_object_resize(o, w, h);
evas_object_color_set(o, 0, 0, 0, 0);
evas_object_repeat_events_set(o, 1);
evas_object_show(o);
evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_DOWN, _e_zone_cb_bg_mouse_down, zone);
evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_UP, _e_zone_cb_bg_mouse_up, zone);
/* TODO: config the ecore_evas type. */
zone->black_ecore_evas =
e_canvas_new(e_config->evas_engine_zone, zone->container->win,
0, 0, zone->w, zone->h, 1, 1, &(zone->black_win));
e_canvas_add(zone->black_ecore_evas);
ecore_evas_layer_set(zone->black_ecore_evas, 6);
zone->black_evas = ecore_evas_get(zone->black_ecore_evas);
o = evas_object_rectangle_add(zone->black_evas);
evas_object_move(o, 0, 0);
evas_object_resize(o, zone->w, zone->h);
evas_object_color_set(o, 0, 0, 0, 255);
evas_object_show(o);
ecore_evas_name_class_set(zone->black_ecore_evas, "E", "Black_Window");
snprintf(name, sizeof(name), "Enlightenment Black Zone (%d)", zone->num);
ecore_evas_title_set(zone->black_ecore_evas, name);
zone->desk_x_count = 0;
zone->desk_y_count = 0;
zone->desk_x_current = 0;
zone->desk_y_current = 0;
e_zone_desk_count_set(zone, e_config->zone_desks_x_count,
e_config->zone_desks_y_count);
2005-04-22 01:19:39 -07:00
e_object_del_attach_func_set(E_OBJECT(zone), _e_zone_object_del_attach);
ev = E_NEW(E_Event_Zone_Add, 1);
ev->zone = zone;
e_object_ref(E_OBJECT(ev->zone));
ecore_event_add(E_EVENT_ZONE_ADD, ev, _e_zone_event_add_free, NULL);
return zone;
}
2006-01-07 02:39:46 -08:00
EAPI void
e_zone_name_set(E_Zone *zone, const char *name)
{
E_OBJECT_CHECK(zone);
E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
if (zone->name) eina_stringshare_del(zone->name);
zone->name = eina_stringshare_add(name);
}
2006-01-07 02:39:46 -08:00
EAPI void
e_zone_move(E_Zone *zone, int x, int y)
{
E_Event_Zone_Move_Resize *ev;
int cw, ch;
E_OBJECT_CHECK(zone);
E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
if ((x == zone->x) && (y == zone->y)) return;
zone->x = x;
zone->y = y;
evas_object_move(zone->bg_object, x, y);
Larger backgrounds can now be set to scroll whenever a E changes between desks. Kind of like a transition, but uses only one (the first desk's), larger wallpaper instead of several wallpapers for all desks, and it overrides the transition settings if activated. The option can currently be activated from Virtual Desktops Settings -> Advanced. A better home and preview would be better for these settings. In more detail, this option can make a wallpaper, larger than the geometry of the zone, scroll appropriately with each desk change. Consider a nice panorama picture, which is as wide as the total desks' width. Then, at most, E will scroll the background by 1 / (number of desks) for each desk change. The direction of the scrolling is dependent on the desk change itself. Also, the user can specify a coefficient of maximum scrolling for each axis. If the coefficient is 0, the wallpaper will not move. More advanced animations can be constructed with edje. The data item "directional_freedom" "(1|0) (1|0)" can toggle the actual wallpaper scrolling done by E for each axis. A message with the current x/y position, panning w|h, and zone w|h is sent to the background edje with each desk change animation tick. An example embryo script that handles the message, and changes a hypothetical "a1" part in the "e/desktop/background" group is shown below: public message(Msg_Type:type, id, ...) { if (type == MSG_INT_SET) { new x = getarg(2); new y = getarg(3); // new max_x = getarg(4); // new max_y = getarg(5); // new w = getarg(6); // new h = getarg(7); custom_state(PART:"a1", "default", 0.0); set_state_val(PART:"a1", STATE_FILL_POS, 0.0, 0.0, -x / 4, -y / 4); set_state(PART:"a1", "custom", 0.0); } } SVN revision: 40543
2009-05-07 11:39:55 -07:00
if (zone->bg_scrollframe)
evas_object_move(zone->bg_scrollframe, x, y);
evas_object_move(zone->bg_event_object, x, y);
evas_object_move(zone->bg_clip_object, x, y);
ev = E_NEW(E_Event_Zone_Move_Resize, 1);
ev->zone = zone;
e_object_ref(E_OBJECT(ev->zone));
ecore_event_add(E_EVENT_ZONE_MOVE_RESIZE, ev, _e_zone_event_move_resize_free, NULL);
cw = zone->w * E_ZONE_CORNER_RATIO;
ch = zone->h * E_ZONE_CORNER_RATIO;
ecore_x_window_move_resize(zone->corner.left_bottom,
zone->x, zone->y + zone->h - ch, 1, ch);
ecore_x_window_move_resize(zone->edge.left,
zone->x, zone->y + ch, 1, zone->h - 2 * ch);
ecore_x_window_move_resize(zone->corner.left_top,
zone->x, zone->y, 1, ch);
ecore_x_window_move_resize(zone->corner.top_left,
zone->x + 1, zone->y, cw, 1);
ecore_x_window_move_resize(zone->edge.top,
zone->x + 1 + cw, zone->y, zone->w - 2 * cw - 2, 1);
ecore_x_window_move_resize(zone->corner.top_right,
zone->x + zone->w - cw - 2, zone->y, cw, 1);
ecore_x_window_move_resize(zone->corner.right_top,
zone->x + zone->w - 1, zone->y, 1, ch);
ecore_x_window_move_resize(zone->edge.right,
zone->x + zone->w - 1, zone->y + ch, 1, zone->h - 2 * ch);
ecore_x_window_move_resize(zone->corner.right_bottom,
zone->x + zone->w - 1, zone->y + zone->h - ch, 1, ch);
ecore_x_window_move_resize(zone->corner.bottom_right,
zone->x + 1, zone->y + zone->h - 1, cw, 1);
ecore_x_window_move_resize(zone->edge.bottom,
zone->x + 1 + cw, zone->y + zone->h - 1, zone->w - 2 - 2 * cw, 1);
ecore_x_window_move_resize(zone->corner.bottom_left,
zone->x + zone->w - cw - 2, zone->y + zone->h - 1, cw, 1);
}
2006-01-07 02:39:46 -08:00
EAPI void
e_zone_resize(E_Zone *zone, int w, int h)
{
E_Event_Zone_Move_Resize *ev;
int cw, ch;
E_OBJECT_CHECK(zone);
E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
if ((w == zone->w) && (h == zone->h)) return;
zone->w = w;
zone->h = h;
evas_object_resize(zone->bg_object, w, h);
Larger backgrounds can now be set to scroll whenever a E changes between desks. Kind of like a transition, but uses only one (the first desk's), larger wallpaper instead of several wallpapers for all desks, and it overrides the transition settings if activated. The option can currently be activated from Virtual Desktops Settings -> Advanced. A better home and preview would be better for these settings. In more detail, this option can make a wallpaper, larger than the geometry of the zone, scroll appropriately with each desk change. Consider a nice panorama picture, which is as wide as the total desks' width. Then, at most, E will scroll the background by 1 / (number of desks) for each desk change. The direction of the scrolling is dependent on the desk change itself. Also, the user can specify a coefficient of maximum scrolling for each axis. If the coefficient is 0, the wallpaper will not move. More advanced animations can be constructed with edje. The data item "directional_freedom" "(1|0) (1|0)" can toggle the actual wallpaper scrolling done by E for each axis. A message with the current x/y position, panning w|h, and zone w|h is sent to the background edje with each desk change animation tick. An example embryo script that handles the message, and changes a hypothetical "a1" part in the "e/desktop/background" group is shown below: public message(Msg_Type:type, id, ...) { if (type == MSG_INT_SET) { new x = getarg(2); new y = getarg(3); // new max_x = getarg(4); // new max_y = getarg(5); // new w = getarg(6); // new h = getarg(7); custom_state(PART:"a1", "default", 0.0); set_state_val(PART:"a1", STATE_FILL_POS, 0.0, 0.0, -x / 4, -y / 4); set_state(PART:"a1", "custom", 0.0); } } SVN revision: 40543
2009-05-07 11:39:55 -07:00
if (zone->bg_scrollframe)
evas_object_resize(zone->bg_scrollframe, w, h);
evas_object_resize(zone->bg_event_object, w, h);
evas_object_resize(zone->bg_clip_object, w, h);
ev = E_NEW(E_Event_Zone_Move_Resize, 1);
ev->zone = zone;
e_object_ref(E_OBJECT(ev->zone));
ecore_event_add(E_EVENT_ZONE_MOVE_RESIZE, ev,
_e_zone_event_move_resize_free, NULL);
cw = zone->w * E_ZONE_CORNER_RATIO;
ch = zone->h * E_ZONE_CORNER_RATIO;
ecore_x_window_move_resize(zone->corner.left_bottom,
zone->x, zone->y + zone->h - ch, 1, ch);
ecore_x_window_move_resize(zone->edge.left,
zone->x, zone->y + ch, 1, zone->h - 2 * ch);
ecore_x_window_move_resize(zone->corner.left_top,
zone->x, zone->y, 1, ch);
ecore_x_window_move_resize(zone->corner.top_left,
zone->x + 1, zone->y, cw, 1);
ecore_x_window_move_resize(zone->edge.top,
zone->x + 1 + cw, zone->y, zone->w - 2 * cw - 2, 1);
ecore_x_window_move_resize(zone->corner.top_right,
zone->x + zone->w - cw - 2, zone->y, cw, 1);
ecore_x_window_move_resize(zone->corner.right_top,
zone->x + zone->w - 1, zone->y, 1, ch);
ecore_x_window_move_resize(zone->edge.right,
zone->x + zone->w - 1, zone->y + ch, 1, zone->h - 2 * ch);
ecore_x_window_move_resize(zone->corner.right_bottom,
zone->x + zone->w - 1, zone->y + zone->h - ch, 1, ch);
ecore_x_window_move_resize(zone->corner.bottom_right,
zone->x + 1, zone->y + zone->h - 1, cw, 1);
ecore_x_window_move_resize(zone->edge.bottom,
zone->x + 1 + cw, zone->y + zone->h - 1, zone->w - 2 - 2 * cw, 1);
ecore_x_window_move_resize(zone->corner.bottom_left,
zone->x + zone->w - cw - 2, zone->y + zone->h - 1, cw, 1);
}
2006-01-07 02:39:46 -08:00
EAPI void
e_zone_move_resize(E_Zone *zone, int x, int y, int w, int h)
{
E_Event_Zone_Move_Resize *ev;
int cw, ch;
E_OBJECT_CHECK(zone);
E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
if ((x == zone->x) && (y == zone->y) && (w == zone->w) && (h == zone->h))
return;
zone->x = x;
zone->y = y;
zone->w = w;
zone->h = h;
evas_object_move(zone->bg_object, x, y);
Larger backgrounds can now be set to scroll whenever a E changes between desks. Kind of like a transition, but uses only one (the first desk's), larger wallpaper instead of several wallpapers for all desks, and it overrides the transition settings if activated. The option can currently be activated from Virtual Desktops Settings -> Advanced. A better home and preview would be better for these settings. In more detail, this option can make a wallpaper, larger than the geometry of the zone, scroll appropriately with each desk change. Consider a nice panorama picture, which is as wide as the total desks' width. Then, at most, E will scroll the background by 1 / (number of desks) for each desk change. The direction of the scrolling is dependent on the desk change itself. Also, the user can specify a coefficient of maximum scrolling for each axis. If the coefficient is 0, the wallpaper will not move. More advanced animations can be constructed with edje. The data item "directional_freedom" "(1|0) (1|0)" can toggle the actual wallpaper scrolling done by E for each axis. A message with the current x/y position, panning w|h, and zone w|h is sent to the background edje with each desk change animation tick. An example embryo script that handles the message, and changes a hypothetical "a1" part in the "e/desktop/background" group is shown below: public message(Msg_Type:type, id, ...) { if (type == MSG_INT_SET) { new x = getarg(2); new y = getarg(3); // new max_x = getarg(4); // new max_y = getarg(5); // new w = getarg(6); // new h = getarg(7); custom_state(PART:"a1", "default", 0.0); set_state_val(PART:"a1", STATE_FILL_POS, 0.0, 0.0, -x / 4, -y / 4); set_state(PART:"a1", "custom", 0.0); } } SVN revision: 40543
2009-05-07 11:39:55 -07:00
if (zone->bg_scrollframe)
evas_object_move(zone->bg_scrollframe, x, y);
evas_object_move(zone->bg_event_object, x, y);
evas_object_move(zone->bg_clip_object, x, y);
evas_object_resize(zone->bg_object, w, h);
Larger backgrounds can now be set to scroll whenever a E changes between desks. Kind of like a transition, but uses only one (the first desk's), larger wallpaper instead of several wallpapers for all desks, and it overrides the transition settings if activated. The option can currently be activated from Virtual Desktops Settings -> Advanced. A better home and preview would be better for these settings. In more detail, this option can make a wallpaper, larger than the geometry of the zone, scroll appropriately with each desk change. Consider a nice panorama picture, which is as wide as the total desks' width. Then, at most, E will scroll the background by 1 / (number of desks) for each desk change. The direction of the scrolling is dependent on the desk change itself. Also, the user can specify a coefficient of maximum scrolling for each axis. If the coefficient is 0, the wallpaper will not move. More advanced animations can be constructed with edje. The data item "directional_freedom" "(1|0) (1|0)" can toggle the actual wallpaper scrolling done by E for each axis. A message with the current x/y position, panning w|h, and zone w|h is sent to the background edje with each desk change animation tick. An example embryo script that handles the message, and changes a hypothetical "a1" part in the "e/desktop/background" group is shown below: public message(Msg_Type:type, id, ...) { if (type == MSG_INT_SET) { new x = getarg(2); new y = getarg(3); // new max_x = getarg(4); // new max_y = getarg(5); // new w = getarg(6); // new h = getarg(7); custom_state(PART:"a1", "default", 0.0); set_state_val(PART:"a1", STATE_FILL_POS, 0.0, 0.0, -x / 4, -y / 4); set_state(PART:"a1", "custom", 0.0); } } SVN revision: 40543
2009-05-07 11:39:55 -07:00
if (zone->bg_scrollframe)
evas_object_resize(zone->bg_scrollframe, w, h);
evas_object_resize(zone->bg_event_object, w, h);
evas_object_resize(zone->bg_clip_object, w, h);
ev = E_NEW(E_Event_Zone_Move_Resize, 1);
ev->zone = zone;
e_object_ref(E_OBJECT(ev->zone));
ecore_event_add(E_EVENT_ZONE_MOVE_RESIZE, ev,
_e_zone_event_move_resize_free, NULL);
cw = zone->w * E_ZONE_CORNER_RATIO;
ch = zone->h * E_ZONE_CORNER_RATIO;
ecore_x_window_move_resize(zone->corner.left_bottom,
zone->x, zone->y + zone->h - ch, 1, ch);
ecore_x_window_move_resize(zone->edge.left,
zone->x, zone->y + ch, 1, zone->h - 2 * ch);
ecore_x_window_move_resize(zone->corner.left_top,
zone->x, zone->y, 1, ch);
ecore_x_window_move_resize(zone->corner.top_left,
zone->x + 1, zone->y, cw, 1);
ecore_x_window_move_resize(zone->edge.top,
zone->x + 1 + cw, zone->y, zone->w - 2 * cw - 2, 1);
ecore_x_window_move_resize(zone->corner.top_right,
zone->x + zone->w - cw - 2, zone->y, cw, 1);
ecore_x_window_move_resize(zone->corner.right_top,
zone->x + zone->w - 1, zone->y, 1, ch);
ecore_x_window_move_resize(zone->edge.right,
zone->x + zone->w - 1, zone->y + ch, 1, zone->h - 2 * ch);
ecore_x_window_move_resize(zone->corner.right_bottom,
zone->x + zone->w - 1, zone->y + zone->h - ch, 1, ch);
ecore_x_window_move_resize(zone->corner.bottom_right,
zone->x + 1, zone->y + zone->h - 1, cw, 1);
ecore_x_window_move_resize(zone->edge.bottom,
zone->x + 1 + cw, zone->y + zone->h - 1, zone->w - 2 - 2 * cw, 1);
ecore_x_window_move_resize(zone->corner.bottom_left,
zone->x + zone->w - cw - 2, zone->y + zone->h - 1, cw, 1);
}
2006-01-07 02:39:46 -08:00
EAPI void
e_zone_fullscreen_set(E_Zone *zone, int on)
{
E_OBJECT_CHECK(zone);
E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
if ((!zone->fullscreen) && (on))
{
ecore_evas_show(zone->black_ecore_evas);
e_container_window_raise(zone->container, zone->black_win, 150);
zone->fullscreen = 1;
}
else if ((zone->fullscreen) && (!on))
{
ecore_evas_hide(zone->black_ecore_evas);
zone->fullscreen = 0;
}
}
2006-01-07 02:39:46 -08:00
EAPI E_Zone *
e_zone_current_get(E_Container *con)
{
Eina_List *l = NULL;
E_OBJECT_CHECK_RETURN(con, NULL);
E_OBJECT_TYPE_CHECK_RETURN(con, E_CONTAINER_TYPE, NULL);
if (!starting)
{
int x, y;
ecore_x_pointer_xy_get(con->win, &x, &y);
for (l = con->zones; l; l = l->next)
{
E_Zone *zone;
zone = l->data;
if (E_INSIDE(x, y, zone->x, zone->y, zone->w, zone->h))
return zone;
}
}
if (!con->zones) return NULL;
l = con->zones;
return (E_Zone *)l->data;
}
2006-01-07 02:39:46 -08:00
EAPI void
e_zone_bg_reconfigure(E_Zone *zone)
{
E_OBJECT_CHECK(zone);
E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
e_bg_zone_update(zone, E_BG_TRANSITION_CHANGE);
}
2006-01-07 02:39:46 -08:00
EAPI void
e_zone_flip_coords_handle(E_Zone *zone, int x, int y)
{
E_Event_Zone_Edge *zev;
E_Binding_Edge *bind;
E_Zone_Edge edge;
Eina_List *l;
E_Shelf *es;
int ok = 0;
int one_row = 1;
int one_col = 1;
E_OBJECT_CHECK(zone);
E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
if (!e_config->edge_flip_dragging || zone->flip.switching) return;
/* if we have only 1 row we can flip up/down even if we have xinerama */
if (eina_list_count(zone->container->zones) > 1)
{
Eina_List *zones;
E_Zone *next_zone;
int cx, cy;
zones = zone->container->zones;
next_zone = (E_Zone *)eina_list_data_get(zones);
cx = next_zone->x;
cy = next_zone->y;
zones = eina_list_next(zones);
while (zones)
{
next_zone = (E_Zone *)zones->data;
if (next_zone->x != cx) one_col = 0;
if (next_zone->y != cy) one_row = 0;
zones = zones->next;
}
}
if (eina_list_count(zone->container->manager->containers) > 1)
goto noflip;
if (!E_INSIDE(x, y, zone->x, zone->y, zone->w, zone->h))
goto noflip;
if ((one_row) && (y == 0))
edge = E_ZONE_EDGE_TOP;
else if ((one_col) && (x == (zone->w - 1)))
edge = E_ZONE_EDGE_RIGHT;
else if ((one_row) && (y == (zone->h - 1)))
edge = E_ZONE_EDGE_BOTTOM;
else if ((one_col) && (x == 0))
edge = E_ZONE_EDGE_LEFT;
else
{
noflip:
if (zone->flip.es)
e_shelf_toggle(zone->flip.es, 0);
zone->flip.es = NULL;
return;
}
EINA_LIST_FOREACH(e_shelf_list(), l, es)
{
ok = 0;
if (es->zone != zone) continue;
switch(es->gadcon->orient)
{
case E_GADCON_ORIENT_TOP:
case E_GADCON_ORIENT_CORNER_TL:
case E_GADCON_ORIENT_CORNER_TR:
if (edge == E_ZONE_EDGE_TOP) ok = 1;
break;
case E_GADCON_ORIENT_BOTTOM:
case E_GADCON_ORIENT_CORNER_BL:
case E_GADCON_ORIENT_CORNER_BR:
if (edge == E_ZONE_EDGE_BOTTOM) ok = 1;
break;
case E_GADCON_ORIENT_LEFT:
case E_GADCON_ORIENT_CORNER_LT:
case E_GADCON_ORIENT_CORNER_LB:
if (edge == E_ZONE_EDGE_LEFT) ok = 1;
break;
case E_GADCON_ORIENT_RIGHT:
case E_GADCON_ORIENT_CORNER_RT:
case E_GADCON_ORIENT_CORNER_RB:
if (edge == E_ZONE_EDGE_RIGHT) ok = 1;
break;
}
if (!ok) continue;
if (!E_INSIDE(x, y, es->x, es->y, es->w, es->h))
continue;
if (zone->flip.es)
e_shelf_toggle(zone->flip.es, 0);
zone->flip.es = es;
e_shelf_toggle(es, 1);
}
ok = 0;
switch(edge)
{
case E_ZONE_EDGE_LEFT:
if (E_ZONE_FLIP_LEFT(zone)) ok = 1;
break;
case E_ZONE_EDGE_TOP:
if (E_ZONE_FLIP_UP(zone)) ok = 1;
break;
case E_ZONE_EDGE_RIGHT:
if (E_ZONE_FLIP_RIGHT(zone)) ok = 1;
break;
case E_ZONE_EDGE_BOTTOM:
if (E_ZONE_FLIP_DOWN(zone)) ok = 1;
break;
}
if (!ok) return;
bind = e_bindings_edge_get("desk_flip_in_direction", edge);
if (bind)
{
zev = E_NEW(E_Event_Zone_Edge, 1);
zev->zone = zone;
zev->x = x;
zev->y = y;
zev->edge = edge;
zone->flip.ev = zev;
zone->flip.bind = bind;
zone->flip.switching = 1;
bind->timer = ecore_timer_add(((double) bind->delay), _e_zone_cb_edge_timer, zone);
}
}
2006-01-07 02:39:46 -08:00
EAPI void
e_zone_desk_count_set(E_Zone *zone, int x_count, int y_count)
{
E_Desk **new_desks;
E_Desk *desk, *new_desk;
E_Border *bd;
E_Event_Zone_Desk_Count_Set *ev;
E_Border_List *bl;
int x, y, xx, yy, moved, nx, ny;
E_OBJECT_CHECK(zone);
E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
xx = x_count;
if (xx < 1) xx = 1;
yy = y_count;
if (yy < 1) yy = 1;
/* Orphaned window catcher; in case desk count gets reset */
moved = 0;
if (zone->desk_x_current >= xx) moved = 1;
if (zone->desk_y_current >= yy) moved = 1;
if (moved)
{
nx = zone->desk_x_current;
ny = zone->desk_y_current;
if (zone->desk_x_current >= xx) nx = xx - 1;
if (zone->desk_y_current >= yy) ny = yy - 1;
e_desk_show(e_desk_at_xy_get(zone, nx, ny));
}
new_desks = malloc(xx * yy * sizeof(E_Desk *));
for (x = 0; x < xx; x++)
{
for (y = 0; y < yy; y++)
{
if ((x < zone->desk_x_count) && (y < zone->desk_y_count))
desk = zone->desks[x + (y * zone->desk_x_count)];
else
desk = e_desk_new(zone, x, y);
new_desks[x + (y * xx)] = desk;
}
}
/* catch windoes that have fallen off the end if we got smaller */
if (xx < zone->desk_x_count)
{
for (y = 0; y < zone->desk_y_count; y++)
{
new_desk = zone->desks[xx - 1 + (y * zone->desk_x_count)];
for (x = xx; x < zone->desk_x_count; x++)
{
desk = zone->desks[x + (y * zone->desk_x_count)];
bl = e_container_border_list_first(zone->container);
while ((bd = e_container_border_list_next(bl)))
{
if (bd->desk == desk)
e_border_desk_set(bd, new_desk);
}
e_container_border_list_free(bl);
e_object_del(E_OBJECT(desk));
}
}
}
if (yy < zone->desk_y_count)
{
for (x = 0; x < zone->desk_x_count; x++)
{
new_desk = zone->desks[x + ((yy - 1) * zone->desk_x_count)];
for (y = yy; y < zone->desk_y_count; y++)
{
desk = zone->desks[x + (y * zone->desk_x_count)];
bl = e_container_border_list_first(zone->container);
while ((bd = e_container_border_list_next(bl)))
{
if (bd->desk == desk)
e_border_desk_set(bd, new_desk);
}
e_container_border_list_free(bl);
e_object_del(E_OBJECT(desk));
}
}
}
if (zone->desks) free(zone->desks);
zone->desks = new_desks;
zone->desk_x_count = xx;
zone->desk_y_count = yy;
e_config->zone_desks_x_count = xx;
e_config->zone_desks_y_count = yy;
e_config_save_queue();
/* Cannot call desk_current_get until the zone desk counts have been set
* or else we end up with a "white background" because desk_current_get will
* return NULL.
*/
desk = e_desk_current_get(zone);
if (desk)
{
desk->visible = 0;
e_desk_show(desk);
}
ev = E_NEW(E_Event_Zone_Desk_Count_Set, 1);
if (!ev) return;
ev->zone = zone;
e_object_ref(E_OBJECT(ev->zone));
ecore_event_add(E_EVENT_ZONE_DESK_COUNT_SET, ev,
_e_zone_event_zone_desk_count_set_free, NULL);
}
2006-01-07 02:39:46 -08:00
EAPI void
e_zone_desk_count_get(E_Zone *zone, int *x_count, int *y_count)
{
E_OBJECT_CHECK(zone);
E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
if (x_count) *x_count = zone->desk_x_count;
if (y_count) *y_count = zone->desk_y_count;
}
2006-01-07 02:39:46 -08:00
EAPI void
e_zone_desk_flip_by(E_Zone *zone, int dx, int dy)
{
E_OBJECT_CHECK(zone);
E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
dx = zone->desk_x_current + dx;
dy = zone->desk_y_current + dy;
e_zone_desk_flip_to(zone, dx, dy);
}
2006-01-07 02:39:46 -08:00
EAPI void
e_zone_desk_flip_to(E_Zone *zone, int x, int y)
{
E_Desk *desk;
E_OBJECT_CHECK(zone);
E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
if (e_config->desk_flip_wrap)
{
x = x % zone->desk_x_count;
y = y % zone->desk_y_count;
if (x < 0) x += zone->desk_x_count;
if (y < 0) y += zone->desk_y_count;
}
else
{
if (x < 0) x = 0;
else if (x >= zone->desk_x_count) x = zone->desk_x_count - 1;
if (y < 0) y = 0;
else if (y >= zone->desk_y_count) y = zone->desk_y_count - 1;
}
desk = e_desk_at_xy_get(zone, x, y);
if (desk) e_desk_show(desk);
}
2006-01-07 02:39:46 -08:00
EAPI void
e_zone_desk_linear_flip_by(E_Zone *zone, int dx)
{
E_OBJECT_CHECK(zone);
E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
dx = zone->desk_x_current +
(zone->desk_y_current * zone->desk_x_count) + dx;
dx = dx % (zone->desk_x_count * zone->desk_y_count);
while (dx < 0)
dx += (zone->desk_x_count * zone->desk_y_count);
e_zone_desk_linear_flip_to(zone, dx);
}
2006-01-07 02:39:46 -08:00
EAPI void
e_zone_desk_linear_flip_to(E_Zone *zone, int x)
{
int y;
E_OBJECT_CHECK(zone);
E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
y = x / zone->desk_x_count;
x = x - (y * zone->desk_x_count);
e_zone_desk_flip_to(zone, x, y);
}
2006-01-07 02:39:46 -08:00
EAPI void
2005-07-26 21:51:42 -07:00
e_zone_flip_win_disable(void)
{
Eina_List *l, *ll, *lll;
2005-07-26 21:51:42 -07:00
E_Manager *man;
E_Container *con;
2005-07-26 21:51:42 -07:00
for (l = e_manager_list(); l; l = l->next)
{
man = l->data;
for (ll = man->containers; ll; ll = ll->next)
{
con = ll->data;
for (lll = con->zones; lll; lll = lll->next)
{
E_Zone *zone;
2005-07-26 21:51:42 -07:00
zone = lll->data;
ecore_x_window_hide(zone->edge.left);
ecore_x_window_hide(zone->edge.right);
ecore_x_window_hide(zone->edge.top);
ecore_x_window_hide(zone->edge.bottom);
ecore_x_window_hide(zone->corner.left_bottom);
ecore_x_window_hide(zone->corner.left_top);
ecore_x_window_hide(zone->corner.top_left);
ecore_x_window_hide(zone->corner.top_right);
ecore_x_window_hide(zone->corner.right_top);
ecore_x_window_hide(zone->corner.right_bottom);
ecore_x_window_hide(zone->corner.bottom_right);
ecore_x_window_hide(zone->corner.bottom_left);
2005-07-26 21:51:42 -07:00
}
}
}
}
2006-01-07 02:39:46 -08:00
EAPI void
2005-07-26 21:51:42 -07:00
e_zone_flip_win_restore(void)
{
Eina_List *l, *ll, *lll;
2005-07-26 21:51:42 -07:00
E_Manager *man;
E_Container *con;
2005-07-26 21:51:42 -07:00
for (l = e_manager_list(); l; l = l->next)
{
man = l->data;
for (ll = man->containers; ll; ll = ll->next)
{
con = ll->data;
for (lll = con->zones; lll; lll = lll->next)
{
E_Zone *zone;
2005-07-26 21:51:42 -07:00
zone = lll->data;
ecore_x_window_show(zone->edge.left);
ecore_x_window_show(zone->edge.right);
ecore_x_window_show(zone->edge.top);
ecore_x_window_show(zone->edge.bottom);
ecore_x_window_show(zone->corner.left_bottom);
ecore_x_window_show(zone->corner.left_top);
ecore_x_window_show(zone->corner.top_left);
ecore_x_window_show(zone->corner.top_right);
ecore_x_window_show(zone->corner.right_top);
ecore_x_window_show(zone->corner.right_bottom);
ecore_x_window_show(zone->corner.bottom_right);
ecore_x_window_show(zone->corner.bottom_left);
2005-07-26 21:51:42 -07:00
}
}
}
}
static void
_e_zone_useful_geometry_calc(E_Zone *zone)
{
const Eina_List *l;
const E_Shelf *shelf;
int x0, x1, y0, y1;
x0 = 0;
y0 = 0;
x1 = zone->w;
y1 = zone->h;
EINA_LIST_FOREACH(e_shelf_list(), l, shelf)
{
E_Gadcon_Orient orient;
if (shelf->zone != zone)
continue;
if (shelf->cfg)
{
if (shelf->cfg->autohide)
continue;
orient = shelf->cfg->orient;
}
else
orient = shelf->gadcon->orient;
switch (orient)
{
/* these are non-edje orientations */
case E_GADCON_ORIENT_FLOAT:
case E_GADCON_ORIENT_HORIZ:
case E_GADCON_ORIENT_VERT:
break;
case E_GADCON_ORIENT_TOP:
case E_GADCON_ORIENT_CORNER_TL:
case E_GADCON_ORIENT_CORNER_TR:
if (y0 < shelf->h)
y0 = shelf->h;
break;
case E_GADCON_ORIENT_BOTTOM:
case E_GADCON_ORIENT_CORNER_BL:
case E_GADCON_ORIENT_CORNER_BR:
if (y1 > zone->h - shelf->h)
y1 = zone->h - shelf->h;
break;
break;
case E_GADCON_ORIENT_LEFT:
case E_GADCON_ORIENT_CORNER_LT:
case E_GADCON_ORIENT_CORNER_LB:
if (x0 < shelf->w)
x0 = shelf->w;
break;
case E_GADCON_ORIENT_RIGHT:
case E_GADCON_ORIENT_CORNER_RT:
case E_GADCON_ORIENT_CORNER_RB:
if (y1 > zone->w - shelf->w)
y1 = zone->w - shelf->w;
break;
}
}
zone->useful_geometry.x = zone->x + x0;
zone->useful_geometry.y = zone->y + y0;
zone->useful_geometry.w = x1 - x0;
zone->useful_geometry.h = y1 - y0;
zone->useful_geometry.dirty = 0;
}
/**
* Get (or calculate) the useful (or free, without any shelves) area.
*/
EAPI void
e_zone_useful_geometry_get(E_Zone *zone, int *x, int *y, int *w, int *h)
{
E_OBJECT_CHECK(zone);
E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
if (zone->useful_geometry.dirty)
_e_zone_useful_geometry_calc(zone);
if (x) *x = zone->useful_geometry.x;
if (y) *y = zone->useful_geometry.y;
if (w) *w = zone->useful_geometry.w;
if (h) *h = zone->useful_geometry.h;
}
/**
* Mark as dirty so e_zone_useful_geometry_get() will need to recalculate.
*
* Call this function when shelves are added or important properties changed.
*/
EAPI void
e_zone_useful_geometry_dirty(E_Zone *zone)
{
E_OBJECT_CHECK(zone);
E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE);
zone->useful_geometry.dirty = 1;
zone->useful_geometry.x = -1;
zone->useful_geometry.y = -1;
zone->useful_geometry.w = -1;
zone->useful_geometry.h = -1;
}
/* local subsystem functions */
static void
_e_zone_free(E_Zone *zone)
{
E_Container *con;
Eina_List *l;
Larger backgrounds can now be set to scroll whenever a E changes between desks. Kind of like a transition, but uses only one (the first desk's), larger wallpaper instead of several wallpapers for all desks, and it overrides the transition settings if activated. The option can currently be activated from Virtual Desktops Settings -> Advanced. A better home and preview would be better for these settings. In more detail, this option can make a wallpaper, larger than the geometry of the zone, scroll appropriately with each desk change. Consider a nice panorama picture, which is as wide as the total desks' width. Then, at most, E will scroll the background by 1 / (number of desks) for each desk change. The direction of the scrolling is dependent on the desk change itself. Also, the user can specify a coefficient of maximum scrolling for each axis. If the coefficient is 0, the wallpaper will not move. More advanced animations can be constructed with edje. The data item "directional_freedom" "(1|0) (1|0)" can toggle the actual wallpaper scrolling done by E for each axis. A message with the current x/y position, panning w|h, and zone w|h is sent to the background edje with each desk change animation tick. An example embryo script that handles the message, and changes a hypothetical "a1" part in the "e/desktop/background" group is shown below: public message(Msg_Type:type, id, ...) { if (type == MSG_INT_SET) { new x = getarg(2); new y = getarg(3); // new max_x = getarg(4); // new max_y = getarg(5); // new w = getarg(6); // new h = getarg(7); custom_state(PART:"a1", "default", 0.0); set_state_val(PART:"a1", STATE_FILL_POS, 0.0, 0.0, -x / 4, -y / 4); set_state(PART:"a1", "custom", 0.0); } } SVN revision: 40543
2009-05-07 11:39:55 -07:00
Ecore_Animator *anim;
void *data;
int x, y;
/* Delete the edge windows if they exist */
if (zone->edge.top) ecore_x_window_free(zone->edge.top);
if (zone->edge.bottom) ecore_x_window_free(zone->edge.bottom);
if (zone->edge.left) ecore_x_window_free(zone->edge.left);
if (zone->edge.right) ecore_x_window_free(zone->edge.right);
if (zone->corner.left_bottom) ecore_x_window_free(zone->corner.left_bottom);
if (zone->corner.left_top) ecore_x_window_free(zone->corner.left_top);
if (zone->corner.top_left) ecore_x_window_free(zone->corner.top_left);
if (zone->corner.top_right) ecore_x_window_free(zone->corner.top_right);
if (zone->corner.right_top) ecore_x_window_free(zone->corner.right_top);
if (zone->corner.right_bottom) ecore_x_window_free(zone->corner.right_bottom);
if (zone->corner.bottom_right) ecore_x_window_free(zone->corner.bottom_right);
if (zone->corner.bottom_left) ecore_x_window_free(zone->corner.bottom_left);
/* Delete the object event callbacks */
evas_object_event_callback_del(zone->bg_event_object,
EVAS_CALLBACK_MOUSE_DOWN,
_e_zone_cb_bg_mouse_down);
evas_object_event_callback_del(zone->bg_event_object,
EVAS_CALLBACK_MOUSE_UP,
_e_zone_cb_bg_mouse_up);
if (zone->black_ecore_evas)
{
e_canvas_del(zone->black_ecore_evas);
ecore_evas_free(zone->black_ecore_evas);
}
2005-06-27 21:00:17 -07:00
if (zone->cur_mouse_action)
{
e_object_unref(E_OBJECT(zone->cur_mouse_action));
zone->cur_mouse_action = NULL;
}
/* remove handlers */
for (l = zone->handlers; l; l = l->next)
{
Ecore_Event_Handler *h;
h = l->data;
ecore_event_handler_del(h);
}
eina_list_free(zone->handlers);
zone->handlers = NULL;
con = zone->container;
if (zone->name) eina_stringshare_del(zone->name);
con->zones = eina_list_remove(con->zones, zone);
Larger backgrounds can now be set to scroll whenever a E changes between desks. Kind of like a transition, but uses only one (the first desk's), larger wallpaper instead of several wallpapers for all desks, and it overrides the transition settings if activated. The option can currently be activated from Virtual Desktops Settings -> Advanced. A better home and preview would be better for these settings. In more detail, this option can make a wallpaper, larger than the geometry of the zone, scroll appropriately with each desk change. Consider a nice panorama picture, which is as wide as the total desks' width. Then, at most, E will scroll the background by 1 / (number of desks) for each desk change. The direction of the scrolling is dependent on the desk change itself. Also, the user can specify a coefficient of maximum scrolling for each axis. If the coefficient is 0, the wallpaper will not move. More advanced animations can be constructed with edje. The data item "directional_freedom" "(1|0) (1|0)" can toggle the actual wallpaper scrolling done by E for each axis. A message with the current x/y position, panning w|h, and zone w|h is sent to the background edje with each desk change animation tick. An example embryo script that handles the message, and changes a hypothetical "a1" part in the "e/desktop/background" group is shown below: public message(Msg_Type:type, id, ...) { if (type == MSG_INT_SET) { new x = getarg(2); new y = getarg(3); // new max_x = getarg(4); // new max_y = getarg(5); // new w = getarg(6); // new h = getarg(7); custom_state(PART:"a1", "default", 0.0); set_state_val(PART:"a1", STATE_FILL_POS, 0.0, 0.0, -x / 4, -y / 4); set_state(PART:"a1", "custom", 0.0); } } SVN revision: 40543
2009-05-07 11:39:55 -07:00
anim = evas_object_data_get(zone->bg_object, "switch_animator");
if (anim) ecore_animator_del(anim);
data = evas_object_data_get(zone->bg_object, "switch_animator_params");
if (data) E_FREE(data);
evas_object_del(zone->bg_event_object);
evas_object_del(zone->bg_clip_object);
evas_object_del(zone->bg_object);
Larger backgrounds can now be set to scroll whenever a E changes between desks. Kind of like a transition, but uses only one (the first desk's), larger wallpaper instead of several wallpapers for all desks, and it overrides the transition settings if activated. The option can currently be activated from Virtual Desktops Settings -> Advanced. A better home and preview would be better for these settings. In more detail, this option can make a wallpaper, larger than the geometry of the zone, scroll appropriately with each desk change. Consider a nice panorama picture, which is as wide as the total desks' width. Then, at most, E will scroll the background by 1 / (number of desks) for each desk change. The direction of the scrolling is dependent on the desk change itself. Also, the user can specify a coefficient of maximum scrolling for each axis. If the coefficient is 0, the wallpaper will not move. More advanced animations can be constructed with edje. The data item "directional_freedom" "(1|0) (1|0)" can toggle the actual wallpaper scrolling done by E for each axis. A message with the current x/y position, panning w|h, and zone w|h is sent to the background edje with each desk change animation tick. An example embryo script that handles the message, and changes a hypothetical "a1" part in the "e/desktop/background" group is shown below: public message(Msg_Type:type, id, ...) { if (type == MSG_INT_SET) { new x = getarg(2); new y = getarg(3); // new max_x = getarg(4); // new max_y = getarg(5); // new w = getarg(6); // new h = getarg(7); custom_state(PART:"a1", "default", 0.0); set_state_val(PART:"a1", STATE_FILL_POS, 0.0, 0.0, -x / 4, -y / 4); set_state(PART:"a1", "custom", 0.0); } } SVN revision: 40543
2009-05-07 11:39:55 -07:00
evas_object_del(zone->bg_scrollframe);
if (zone->prev_bg_object) evas_object_del(zone->prev_bg_object);
if (zone->transition_object) evas_object_del(zone->transition_object);
/* free desks */
for (x = 0; x < zone->desk_x_count; x++)
2005-06-27 21:00:17 -07:00
{
2007-04-08 14:00:30 -07:00
for (y = 0; y < zone->desk_y_count; y++)
2005-06-27 21:00:17 -07:00
e_object_del(E_OBJECT(zone->desks[x + (y * zone->desk_x_count)]));
}
free(zone->desks);
free(zone);
}
static void
_e_zone_cb_bg_mouse_down(void *data, Evas *evas, Evas_Object *obj, void *event_info)
{
E_Zone *zone;
Evas_Event_Mouse_Down *ev;
ev = (Evas_Event_Mouse_Down *)event_info;
zone = data;
if (e_menu_grab_window_get()) return;
if (!zone->cur_mouse_action)
{
if (ecore_event_current_type_get() == ECORE_EVENT_MOUSE_BUTTON_DOWN)
{
Ecore_Event_Mouse_Button *ev2;
ev2 = ecore_event_current_event_get();
zone->cur_mouse_action =
e_bindings_mouse_down_event_handle(E_BINDING_CONTEXT_ZONE,
E_OBJECT(zone), ev2);
2005-06-27 21:00:17 -07:00
if (zone->cur_mouse_action)
{
if ((!zone->cur_mouse_action->func.end_mouse) &&
(!zone->cur_mouse_action->func.end))
zone->cur_mouse_action = NULL;
if (zone->cur_mouse_action)
e_object_ref(E_OBJECT(zone->cur_mouse_action));
}
}
}
}
static void
_e_zone_cb_bg_mouse_up(void *data, Evas *evas, Evas_Object *obj, void *event_info)
{
E_Zone *zone;
Evas_Event_Mouse_Up *ev;
ev = (Evas_Event_Mouse_Up *)event_info;
zone = data;
if (zone->cur_mouse_action)
{
if (ecore_event_current_type_get() == ECORE_EVENT_MOUSE_BUTTON_UP)
{
Ecore_Event_Mouse_Button *ev2;
ev2 = ecore_event_current_event_get();
if (zone->cur_mouse_action->func.end_mouse)
zone->cur_mouse_action->func.end_mouse(E_OBJECT(zone), "", ev2);
else if (zone->cur_mouse_action->func.end)
zone->cur_mouse_action->func.end(E_OBJECT(zone), "");
}
2005-06-27 21:00:17 -07:00
e_object_unref(E_OBJECT(zone->cur_mouse_action));
zone->cur_mouse_action = NULL;
}
else
{
if (ecore_event_current_type_get() == ECORE_EVENT_MOUSE_BUTTON_UP)
{
Ecore_Event_Mouse_Button *ev2;
ev2 = ecore_event_current_event_get();
e_bindings_mouse_up_event_handle(E_BINDING_CONTEXT_ZONE,
E_OBJECT(zone), ev2);
}
}
}
static void
_e_zone_event_zone_desk_count_set_free(void *data, void *ev)
{
E_Event_Zone_Desk_Count_Set *e;
e = ev;
e_object_unref(E_OBJECT(e->zone));
free(e);
}
2005-04-22 01:19:39 -07:00
static int
_e_zone_cb_mouse_in(void *data, int type, void *event)
{
Ecore_X_Event_Mouse_In *ev;
E_Event_Zone_Edge *zev;
E_Zone_Edge edge;
2005-04-22 01:19:39 -07:00
E_Zone *zone;
ev = event;
zone = data;
if (ev->win == zone->edge.left)
edge = E_ZONE_EDGE_LEFT;
else if (ev->win == zone->edge.top)
edge = E_ZONE_EDGE_TOP;
2007-11-22 12:08:07 -08:00
else if (ev->win == zone->edge.right)
edge = E_ZONE_EDGE_RIGHT;
2007-11-22 12:08:07 -08:00
else if (ev->win == zone->edge.bottom)
edge = E_ZONE_EDGE_BOTTOM;
else if ((ev->win == zone->corner.left_top) ||
(ev->win == zone->corner.top_left))
edge = E_ZONE_EDGE_TOP_LEFT;
else if ((ev->win == zone->corner.right_top) ||
(ev->win == zone->corner.top_right))
edge = E_ZONE_EDGE_TOP_RIGHT;
else if ((ev->win == zone->corner.right_bottom) ||
(ev->win == zone->corner.bottom_right))
edge = E_ZONE_EDGE_BOTTOM_RIGHT;
else if ((ev->win == zone->corner.left_bottom) ||
(ev->win == zone->corner.bottom_left))
edge = E_ZONE_EDGE_BOTTOM_LEFT;
else return 1;
zev = E_NEW(E_Event_Zone_Edge, 1);
zev->zone = zone;
zev->edge = edge;
zev->x = ev->x;
zev->y = ev->y;
zev->modifiers = ev->modifiers;
ecore_event_add(E_EVENT_ZONE_EDGE_IN, zev, NULL, NULL);
e_bindings_edge_in_event_handle(E_BINDING_CONTEXT_ZONE, E_OBJECT(zone), zev);
2007-11-22 12:08:07 -08:00
2005-04-22 01:19:39 -07:00
return 1;
}
static int
_e_zone_cb_mouse_out(void *data, int type, void *event)
{
Ecore_X_Event_Mouse_Out *ev;
E_Event_Zone_Edge *zev;
E_Zone_Edge edge;
2005-04-22 01:19:39 -07:00
E_Zone *zone;
ev = event;
zone = data;
if (ev->win == zone->edge.left)
edge = E_ZONE_EDGE_LEFT;
else if (ev->win == zone->edge.top)
edge = E_ZONE_EDGE_TOP;
else if (ev->win == zone->edge.right)
edge = E_ZONE_EDGE_RIGHT;
else if (ev->win == zone->edge.bottom)
edge = E_ZONE_EDGE_BOTTOM;
else if ((ev->win == zone->corner.left_top) ||
(ev->win == zone->corner.top_left))
edge = E_ZONE_EDGE_TOP_LEFT;
else if ((ev->win == zone->corner.right_top) ||
(ev->win == zone->corner.top_right))
edge = E_ZONE_EDGE_TOP_RIGHT;
else if ((ev->win == zone->corner.right_bottom) ||
(ev->win == zone->corner.bottom_right))
edge = E_ZONE_EDGE_BOTTOM_RIGHT;
else if ((ev->win == zone->corner.left_bottom) ||
(ev->win == zone->corner.bottom_left))
edge = E_ZONE_EDGE_BOTTOM_LEFT;
else return 1;
zev = E_NEW(E_Event_Zone_Edge, 1);
zev->zone = zone;
zev->edge = edge;
zev->x = ev->x;
zev->y = ev->y;
zev->modifiers = ev->modifiers;
ecore_event_add(E_EVENT_ZONE_EDGE_OUT, zev, NULL, NULL);
e_bindings_edge_out_event_handle(E_BINDING_CONTEXT_ZONE, E_OBJECT(zone), zev);
2005-04-22 01:19:39 -07:00
return 1;
}
static int
_e_zone_cb_mouse_move(void *data, int type, void *event)
{
Ecore_Event_Mouse_Move *ev;
E_Event_Zone_Edge *zev;
E_Zone_Edge edge;
E_Zone *zone;
ev = event;
zone = data;
if (ev->window == zone->edge.left)
edge = E_ZONE_EDGE_LEFT;
else if (ev->window == zone->edge.top)
edge = E_ZONE_EDGE_TOP;
else if (ev->window == zone->edge.right)
edge = E_ZONE_EDGE_RIGHT;
else if (ev->window == zone->edge.bottom)
edge = E_ZONE_EDGE_BOTTOM;
else if ((ev->window == zone->corner.left_top) ||
(ev->window == zone->corner.top_left))
edge = E_ZONE_EDGE_TOP_LEFT;
else if ((ev->window == zone->corner.right_top) ||
(ev->window == zone->corner.top_right))
edge = E_ZONE_EDGE_TOP_RIGHT;
else if ((ev->window == zone->corner.right_bottom) ||
(ev->window == zone->corner.bottom_right))
edge = E_ZONE_EDGE_BOTTOM_RIGHT;
else if ((ev->window == zone->corner.left_bottom) ||
(ev->window == zone->corner.bottom_left))
edge = E_ZONE_EDGE_BOTTOM_LEFT;
else return 1;
zev = E_NEW(E_Event_Zone_Edge, 1);
zev->zone = zone;
zev->edge = edge;
zev->x = ev->x;
zev->y = ev->y;
zev->modifiers = ev->modifiers;
ecore_event_add(E_EVENT_ZONE_EDGE_MOVE, zev, NULL, NULL);
return 1;
}
2005-04-22 01:19:39 -07:00
static int
_e_zone_cb_desk_after_show(void *data, int type, void *event)
{
E_Event_Desk_Show *ev;
E_Zone *zone;
ev = event;
zone = data;
if (ev->desk->zone != zone) return 1;
zone->flip.switching = 0;
return 1;
}
static int
_e_zone_cb_edge_timer(void *data)
2005-04-22 01:19:39 -07:00
{
E_Zone *zone;
E_Action *act;
zone = data;
act = e_action_find(zone->flip.bind->action);
if (!act)
{
E_FREE(zone->flip.ev);
return 0;
}
if (act->func.go_edge)
act->func.go_edge(E_OBJECT(zone), zone->flip.bind->params, zone->flip.ev);
else if (act->func.go)
act->func.go(E_OBJECT(zone), zone->flip.bind->params);
zone->flip.bind->timer = NULL;
E_FREE(zone->flip.ev);
return 0;
}
static void
_e_zone_event_move_resize_free(void *data, void *ev)
{
E_Event_Zone_Move_Resize *e;
e = ev;
e_object_unref(E_OBJECT(e->zone));
free(e);
}
static void
_e_zone_event_add_free(void *data, void *ev)
{
E_Event_Zone_Add *e;
e = ev;
e_object_unref(E_OBJECT(e->zone));
free(e);
}
static void
_e_zone_event_del_free(void *data, void *ev)
{
E_Event_Zone_Del *e;
e = ev;
e_object_unref(E_OBJECT(e->zone));
free(e);
}
static void
_e_zone_object_del_attach(void *o)
{
E_Zone *zone;
E_Event_Zone_Del *ev;
if (e_object_is_del(E_OBJECT(o))) return;
zone = o;
ev = E_NEW(E_Event_Zone_Del, 1);
ev->zone = zone;
e_object_ref(E_OBJECT(ev->zone));
ecore_event_add(E_EVENT_ZONE_DEL, ev, _e_zone_event_del_free, NULL);
}