From 648d75caab1f7c45f6dcc146b50d7591b5088dd2 Mon Sep 17 00:00:00 2001 From: Viktor Kojouharov Date: Thu, 7 May 2009 18:39:55 +0000 Subject: [PATCH] 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 --- data/themes/default.edc | 22 +++ src/bin/e_bg.c | 177 ++++++++++++++++++++ src/bin/e_bg.h | 1 + src/bin/e_config.c | 12 ++ src/bin/e_config.h | 5 +- src/bin/e_desk.c | 11 +- src/bin/e_zone.c | 15 ++ src/bin/e_zone.h | 1 + src/modules/conf_desks/e_int_config_desks.c | 27 ++- 9 files changed, 267 insertions(+), 4 deletions(-) diff --git a/data/themes/default.edc b/data/themes/default.edc index 8ca18d815..8824d4a43 100644 --- a/data/themes/default.edc +++ b/data/themes/default.edc @@ -127,6 +127,28 @@ collections { /* begin the collection of edje groups that are in this file */ } } + group { name: "e/desktop/background/scrollframe"; + parts { + part { name: "clipper"; + type: RECT; + mouse_events: 0; + description { state: "default" 0.0; + } + } + part { name: "e.swallow.content"; + clip_to: "clipper"; + type: SWALLOW; + description { state: "default" 0.0; + rel1.offset: 0 0; + rel2 { + relative: 0.0 0.0; + offset: -1 -1; + } + } + } + } + } + ///////////////////////////////////////////////////////////////////////////// /*** DEFAULT WINDOW BORDER ***/ group { name: "e/widgets/border/default/border"; diff --git a/src/bin/e_bg.c b/src/bin/e_bg.c index b196e6160..ab05368b2 100644 --- a/src/bin/e_bg.c +++ b/src/bin/e_bg.c @@ -6,11 +6,27 @@ /* local subsystem functions */ static void _e_bg_signal(void *data, Evas_Object *obj, const char *emission, const char *source); static void _e_bg_event_bg_update_free(void *data, void *event); +static int _e_bg_slide_animator(void *data); /* local subsystem globals */ EAPI int E_EVENT_BG_UPDATE = 0; static E_Fm2_Mime_Handler *bg_hdl = NULL; +typedef struct _E_Bg_Anim_Params E_Bg_Anim_Params; +struct _E_Bg_Anim_Params +{ + E_Zone *zone; + double start_time; + int start_x; + int start_y; + int end_x; + int end_y; + + struct { + Eina_Bool x, y; + } freedom; +}; + /* externally accessible functions */ EAPI int e_bg_init(void) @@ -203,6 +219,7 @@ e_bg_zone_update(E_Zone *zone, E_Bg_Transition transition) else if (transition == E_BG_TRANSITION_DESK) trans = e_config->transition_desk; else if (transition == E_BG_TRANSITION_CHANGE) trans = e_config->transition_change; if ((!trans) || (!trans[0])) transition = E_BG_TRANSITION_NONE; + if (e_config->desk_flip_pan_bg) transition = E_BG_TRANSITION_NONE; desk = e_desk_current_get(zone); if (desk) @@ -265,6 +282,30 @@ e_bg_zone_update(E_Zone *zone, E_Bg_Transition transition) } evas_object_clip_set(o, zone->bg_clip_object); evas_object_show(o); + if (e_config->desk_flip_pan_bg) + { + int x = 0, y = 0; + + o = zone->bg_scrollframe; + if (!o) + { + o = e_scrollframe_add(zone->container->bg_evas); + zone->bg_scrollframe = o; + e_scrollframe_custom_theme_set(o, "base/theme/background", + "e/desktop/background/scrollframe"); + e_scrollframe_policy_set(o, E_SCROLLFRAME_POLICY_OFF, E_SCROLLFRAME_POLICY_OFF); + e_scrollframe_child_pos_set(o, 0, 0); + evas_object_show(o); + } + e_scrollframe_child_set(o, zone->bg_object); + if (desk) + { + x = desk->x; + y = desk->y; + } + e_bg_zone_slide(zone, x, y); + return; + } if (transition != E_BG_TRANSITION_NONE) { @@ -280,6 +321,71 @@ e_bg_zone_update(E_Zone *zone, E_Bg_Transition transition) } } +EAPI void +e_bg_zone_slide(E_Zone *zone, int prev_x, int prev_y) +{ + Evas_Object *o; + E_Desk *desk; + Evas_Coord w, h, maxw, maxh, step_w, step_h; + Ecore_Animator *anim; + E_Bg_Anim_Params *params; + Evas_Coord vw, vh, px, py; + int fx, fy; + const void *data; + + desk = e_desk_current_get(zone); + edje_object_size_max_get(zone->bg_object, &w, &h); + maxw = zone->w * zone->desk_x_count; + maxh = zone->h * zone->desk_y_count; + if (!w) w = maxw; + if (!h) h = maxh; + evas_object_resize(zone->bg_object, w, h); + if (zone->desk_x_count > 1) + step_w = ((double) (w - zone->w)) / (zone->desk_x_count - 1); + else step_w = 0; + if (zone->desk_y_count > 1) + step_h = ((double) (h - zone->h)) / (zone->desk_y_count - 1); + else step_h = 0; + + o = zone->bg_scrollframe; + evas_object_move(o, zone->x, zone->y); + evas_object_resize(o, zone->w, zone->h); + evas_object_layer_set(o, -1); + evas_object_clip_set(o, zone->bg_clip_object); + + data = edje_object_data_get(zone->bg_object, "directional_freedom"); + e_scrollframe_child_viewport_size_get(o, &vw, &vh); + e_scrollframe_child_pos_get(o, &px, &py); + params = evas_object_data_get(zone->bg_object, "switch_animator_params"); + if (!params) + params = E_NEW(E_Bg_Anim_Params, 1); + params->zone = zone; + params->start_x = px; + params->start_y = py; + params->end_x = desk->x * step_w * e_config->desk_flip_pan_x_axis_factor; + params->end_y = desk->y * step_h * e_config->desk_flip_pan_y_axis_factor; + params->start_time = 0.0; + if ((data) && (sscanf(data, "%d %d", &fx, &fy) == 2)) + { + if (fx) + { + params->freedom.x = EINA_TRUE; + params->start_x = prev_x * step_w * e_config->desk_flip_pan_x_axis_factor; + } + if (fy) + { + params->freedom.y = EINA_TRUE; + params->start_y = prev_y * step_h * e_config->desk_flip_pan_y_axis_factor; + } + } + + anim = evas_object_data_get(zone->bg_object, "switch_animator"); + if (anim) ecore_animator_del(anim); + anim = ecore_animator_add(_e_bg_slide_animator, params); + evas_object_data_set(zone->bg_object, "switch_animator", anim); + evas_object_data_set(zone->bg_object, "switch_animator_params", params); +} + EAPI void e_bg_default_set(char *file) { @@ -440,3 +546,74 @@ _e_bg_event_bg_update_free(void *data, void *event) { free(event); } + +static int +_e_bg_slide_animator(void *data) +{ + E_Bg_Anim_Params *params; + E_Zone *zone; + Evas_Object *o; + E_Desk *desk; + double st; + double t, dt, spd; + Evas_Coord px, py, rx, ry, bw, bh, panw, panh; + Edje_Message_Int_Set *msg; + + params = data; + zone = params->zone; + desk = e_desk_current_get(zone); + t = ecore_loop_time_get(); + dt = -1.0; + spd = e_config->desk_flip_animate_time; + + o = zone->bg_scrollframe; + if (!params->start_time) + st = params->start_time = t; + else + st = params->start_time; + + dt = (t - st) / spd; + if (dt > 1.0) dt = 1.0; + dt = 1.0 - dt; + dt *= dt; /* decelerate - could be a better hack */ + + if (params->end_x > params->start_x) + rx = params->start_x + (params->end_x - params->start_x) * (1.0 - dt); + else + rx = params->end_x + (params->start_x - params->end_x) * dt; + if (params->freedom.x) px = zone->x; + else px = rx; + + if (params->end_y > params->start_y) + ry = params->start_y + (params->end_y - params->start_y) * (1.0 - dt); + else + ry = params->end_y + (params->start_y - params->end_y) * dt; + if (params->freedom.y) py = zone->y; + else py = ry; + + e_scrollframe_child_pos_set(o, px, py); + + evas_object_geometry_get(zone->bg_object, NULL, NULL, &bw, &bh); + panw = bw - zone->w; + if (panw < 0) panw = 0; + panh = bh - zone->h; + if (panh < 0) panh = 0; + msg = alloca(sizeof(Edje_Message_Int_Set) + (5 * sizeof(int))); + msg->count = 6; + msg->val[0] = rx; + msg->val[1] = ry; + msg->val[2] = panw; + msg->val[3] = panh; + msg->val[4] = bw; + msg->val[5] = bh; + edje_object_message_send(zone->bg_object, EDJE_MESSAGE_INT_SET, 0, msg); + + if (dt <= 0.0) + { + evas_object_data_del(zone->bg_object, "switch_animator"); + evas_object_data_del(zone->bg_object, "switch_animator_params"); + E_FREE(params); + return 0; + } + return 1; +} diff --git a/src/bin/e_bg.h b/src/bin/e_bg.h index f30823bce..9323c70f3 100644 --- a/src/bin/e_bg.h +++ b/src/bin/e_bg.h @@ -32,6 +32,7 @@ EAPI int e_bg_shutdown(void); EAPI const E_Config_Desktop_Background *e_bg_config_get(int container_num, int zone_num, int desk_x, int desk_y); EAPI const char *e_bg_file_get(int container_num, int zone_num, int desk_x, int desk_y); EAPI void e_bg_zone_update(E_Zone *zone, E_Bg_Transition transition); +EAPI void e_bg_zone_slide(E_Zone *zone, int prev_x, int prev_y); EAPI void e_bg_add(int container, int zone, int desk_x, int desk_y, char *file); EAPI void e_bg_del(int container, int zone, int desk_x, int desk_y); EAPI void e_bg_default_set(char *file); diff --git a/src/bin/e_config.c b/src/bin/e_config.c index d8b87848d..b74c7d387 100644 --- a/src/bin/e_config.c +++ b/src/bin/e_config.c @@ -622,6 +622,9 @@ e_config_init(void) E_CONFIG_VAL(D, T, desk_flip_animate_mode, INT); E_CONFIG_VAL(D, T, desk_flip_animate_interpolation, INT); E_CONFIG_VAL(D, T, desk_flip_animate_time, DOUBLE); + E_CONFIG_VAL(D, T, desk_flip_pan_bg, UCHAR); + E_CONFIG_VAL(D, T, desk_flip_pan_x_axis_factor, DOUBLE); + E_CONFIG_VAL(D, T, desk_flip_pan_y_axis_factor, DOUBLE); E_CONFIG_VAL(D, T, wallpaper_import_last_dev, STR); E_CONFIG_VAL(D, T, wallpaper_import_last_path, STR); @@ -915,6 +918,12 @@ e_config_load(void) e_config->screensaver_ask_presentation_timeout = 30.0; IFCFGEND; + IFCFG(0x0133); + COPYVAL(desk_flip_pan_bg); + COPYVAL(desk_flip_pan_x_axis_factor); + COPYVAL(desk_flip_pan_y_axis_factor); + IFCFGEND; + e_config->config_version = E_CONFIG_FILE_VERSION; _e_config_free(tcfg); } @@ -1017,6 +1026,9 @@ e_config_load(void) E_CONFIG_LIMIT(e_config->desk_flip_wrap, 0, 1); E_CONFIG_LIMIT(e_config->fullscreen_flip, 0, 1); E_CONFIG_LIMIT(e_config->icon_theme_overrides, 0, 1); + E_CONFIG_LIMIT(e_config->desk_flip_pan_bg, 0, 1); + E_CONFIG_LIMIT(e_config->desk_flip_pan_x_axis_factor, 0.0, 1.0); + E_CONFIG_LIMIT(e_config->desk_flip_pan_y_axis_factor, 0.0, 1.0); E_CONFIG_LIMIT(e_config->remember_internal_windows, 0, 1); E_CONFIG_LIMIT(e_config->desk_auto_switch, 0, 1); diff --git a/src/bin/e_config.h b/src/bin/e_config.h index b7711419f..2fac4c87f 100644 --- a/src/bin/e_config.h +++ b/src/bin/e_config.h @@ -35,7 +35,7 @@ typedef struct _E_Event_Config_Icon_Theme E_Event_Config_Icon_Theme; /* increment this whenever a new set of config values are added but the users * config doesn't need to be wiped - simply new values need to be put in */ -#define E_CONFIG_FILE_GENERATION 0x0132 +#define E_CONFIG_FILE_GENERATION 0x0133 #define E_CONFIG_FILE_VERSION ((E_CONFIG_FILE_EPOCH << 16) | E_CONFIG_FILE_GENERATION) #define E_EVAS_ENGINE_DEFAULT 0 @@ -272,6 +272,9 @@ struct _E_Config int desk_flip_animate_mode; // GUI int desk_flip_animate_interpolation; // GUI double desk_flip_animate_time; // GUI + Eina_Bool desk_flip_pan_bg; + double desk_flip_pan_x_axis_factor; + double desk_flip_pan_y_axis_factor; const char *wallpaper_import_last_dev; // INTERNAL const char *wallpaper_import_last_path; // INTERNAL diff --git a/src/bin/e_desk.c b/src/bin/e_desk.c index aea955425..286a5b166 100644 --- a/src/bin/e_desk.c +++ b/src/bin/e_desk.c @@ -209,7 +209,7 @@ e_desk_show(E_Desk *desk) E_Event_Desk_Before_Show *eev; E_Event_Desk_After_Show *eeev; Eina_List *l; - int was_zone = 0, x, y, dx = 0, dy = 0; + int was_zone = 0, x, y, dx = 0, dy = 0, prev_x = 0, prev_y = 0; E_OBJECT_CHECK(desk); E_OBJECT_TYPE_CHECK(desk, E_DESK_TYPE); @@ -232,6 +232,8 @@ e_desk_show(E_Desk *desk) if (desk2->visible) { desk2->visible = 0; + prev_x = desk2->x; + prev_y = desk2->y; dx = desk->x - desk2->x; dy = desk->y - desk2->y; if (e_config->desk_flip_animate_mode > 0) @@ -272,7 +274,12 @@ e_desk_show(E_Desk *desk) e_desk_last_focused_focus(desk); if (was_zone) - e_bg_zone_update(desk->zone, E_BG_TRANSITION_DESK); + { + if (e_config->desk_flip_pan_bg) + e_bg_zone_slide(desk->zone, prev_x, prev_y); + else + e_bg_zone_update(desk->zone, E_BG_TRANSITION_DESK); + } else e_bg_zone_update(desk->zone, E_BG_TRANSITION_START); diff --git a/src/bin/e_zone.c b/src/bin/e_zone.c index 094796c52..4c0c50299 100644 --- a/src/bin/e_zone.c +++ b/src/bin/e_zone.c @@ -235,6 +235,8 @@ e_zone_move(E_Zone *zone, int x, int y) zone->x = x; zone->y = y; evas_object_move(zone->bg_object, x, y); + 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); @@ -287,6 +289,8 @@ e_zone_resize(E_Zone *zone, int w, int h) zone->w = w; zone->h = h; evas_object_resize(zone->bg_object, w, h); + 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); @@ -345,9 +349,13 @@ e_zone_move_resize(E_Zone *zone, int x, int y, int w, int h) zone->h = h; evas_object_move(zone->bg_object, x, y); + 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); + 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); @@ -939,6 +947,8 @@ _e_zone_free(E_Zone *zone) { E_Container *con; Eina_List *l; + Ecore_Animator *anim; + void *data; int x, y; /* Delete the edge windows if they exist */ @@ -988,9 +998,14 @@ _e_zone_free(E_Zone *zone) con = zone->container; if (zone->name) eina_stringshare_del(zone->name); con->zones = eina_list_remove(con->zones, zone); + 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); + 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); diff --git a/src/bin/e_zone.h b/src/bin/e_zone.h index 90f66c082..ba0f0c461 100644 --- a/src/bin/e_zone.h +++ b/src/bin/e_zone.h @@ -48,6 +48,7 @@ struct _E_Zone Evas_Object *bg_event_object; Evas_Object *bg_clip_object; Evas_Object *prev_bg_object; + Evas_Object *bg_scrollframe; Evas_Object *transition_object; int desk_x_count, desk_y_count; diff --git a/src/modules/conf_desks/e_int_config_desks.c b/src/modules/conf_desks/e_int_config_desks.c index 4fe6d547d..2177b6dc1 100644 --- a/src/modules/conf_desks/e_int_config_desks.c +++ b/src/modules/conf_desks/e_int_config_desks.c @@ -28,7 +28,10 @@ struct _E_Config_Dialog_Data int flip_wrap; int flip_mode; int flip_interp; + int flip_pan_bg; double flip_speed; + double x_axis_pan; + double y_axis_pan; /*- GUI -*/ Evas_Object *preview; @@ -73,7 +76,10 @@ _fill_data(E_Config_Dialog_Data *cfdata) cfdata->flip_wrap = e_config->desk_flip_wrap; cfdata->flip_mode = e_config->desk_flip_animate_mode; cfdata->flip_interp = e_config->desk_flip_animate_interpolation; + cfdata->flip_pan_bg = e_config->desk_flip_pan_bg; cfdata->flip_speed = e_config->desk_flip_animate_time; + cfdata->x_axis_pan = e_config->desk_flip_pan_x_axis_factor; + cfdata->y_axis_pan = e_config->desk_flip_pan_y_axis_factor; } static void * @@ -181,7 +187,10 @@ _advanced_apply_data(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata) e_config->desk_flip_animate_mode = cfdata->flip_mode; e_config->desk_flip_animate_interpolation = cfdata->flip_interp; + e_config->desk_flip_pan_bg = cfdata->flip_pan_bg; e_config->desk_flip_animate_time = cfdata->flip_speed; + e_config->desk_flip_pan_x_axis_factor = cfdata->x_axis_pan; + e_config->desk_flip_pan_y_axis_factor = cfdata->y_axis_pan; e_config->edge_flip_dragging = cfdata->edge_flip_dragging; e_config->desk_flip_wrap = cfdata->flip_wrap; @@ -210,7 +219,10 @@ _advanced_check_changed(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata) return ((e_config->desk_flip_animate_mode != cfdata->flip_mode) || (e_config->desk_flip_animate_interpolation != cfdata->flip_interp) || + (e_config->desk_flip_pan_bg != cfdata->flip_pan_bg) || (e_config->desk_flip_animate_time != cfdata->flip_speed) || + (e_config->desk_flip_pan_x_axis_factor != cfdata->x_axis_pan) || + (e_config->desk_flip_pan_y_axis_factor != cfdata->y_axis_pan) || (e_config->edge_flip_dragging != cfdata->edge_flip_dragging) || (e_config->desk_flip_wrap != cfdata->flip_wrap)); } @@ -300,8 +312,21 @@ _advanced_create_widgets(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data e_widget_on_change_hook_set(ob, _cb_disable_flip_anim, cfdata); ob = e_widget_slider_add(evas, 1, 0, _("%1.1f sec"), 0.0, 5.0, 0.05, 0, &(cfdata->flip_speed), NULL, 200); e_widget_disabled_set(ob, !cfdata->flip_mode); - e_widget_framelist_object_append(of, ob); cfdata->flip_anim_list = eina_list_append(cfdata->flip_anim_list, ob); + e_widget_framelist_object_append(of, ob); + ob = e_widget_check_add(evas, _("Background panning"), &(cfdata->flip_pan_bg)); + e_widget_disabled_set(ob, !cfdata->flip_mode); + cfdata->flip_anim_list = eina_list_append(cfdata->flip_anim_list, ob); + e_widget_framelist_object_append(of, ob); + ob = e_widget_slider_add(evas, 1, 0, _("%.2f X-axis pan factor"), 0.0, 1.0, 0.01, 0, &(cfdata->x_axis_pan), NULL, 200); + e_widget_disabled_set(ob, !cfdata->flip_mode); + cfdata->flip_anim_list = eina_list_append(cfdata->flip_anim_list, ob); + e_widget_framelist_object_append(of, ob); + ob = e_widget_slider_add(evas, 1, 0, _("%.2f Y-axis pan factor"), 0.0, 1.0, 0.01, 0, &(cfdata->y_axis_pan), NULL, 200); + e_widget_disabled_set(ob, !cfdata->flip_mode); + cfdata->flip_anim_list = eina_list_append(cfdata->flip_anim_list, ob); + e_widget_framelist_object_append(of, ob); + e_widget_table_object_append(ott, of, 1, 1, 1, 1, 1, 1, 1, 1); e_widget_list_object_append(o, ott, 1, 1, 0.5);