Hi,

I've been playing around with the making the bg_object pan on desk
switch, instead of using transitions. To illustrate what I'm talking
about, I made a rather crappy screencast (istanbul only seems to make
10fps screencasts, anyone have an alternative program?):

http://www.youtube.com/watch?v=glYLH3GSikE

The idea is that the background slides depending on its size relative to
the geometry of all desks, as well as a user specified factor. E.g.: if
you have 2 horizontal desks of size 640x480, and a bg of size 1280x480,
the background will slide at most by a half of its size. If the user
specifies a factor below 1.0, the offset of the bg is smaller, creating
a parallax effect. If the bg size is smaller, the total offset will be
smaller, thus not causing the bg to scroll off boundary. 

I've currently implemented it with this patch. It is toggable by an
option in the virtual desks settings dialog, which will override any
preselected transition (since it doesn't use the same function). Speed
is not blazing fast, but I'm not sure if it can be faster with just
using the software engine (using the gl engine for the container is
flicker free though).

So what do you guys think of this idea?
Index: src/bin/e_zone.c
===================================================================
--- src/bin/e_zone.c	(revision 40414)
+++ src/bin/e_zone.c	(working copy)
@@ -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
    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);
 
Index: src/bin/e_zone.h
===================================================================
--- src/bin/e_zone.h	(revision 40414)
+++ src/bin/e_zone.h	(working copy)
@@ -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;
Index: src/bin/e_config.c
===================================================================
--- src/bin/e_config.c	(revision 40414)
+++ src/bin/e_config.c	(working copy)
@@ -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);
 
Index: src/bin/e_config.h
===================================================================
--- src/bin/e_config.h	(revision 40414)
+++ src/bin/e_config.h	(working copy)
@@ -35,7 +35,7 @@ typedef struct _E_Event_Config_Icon_Theme   E_Even
 /* 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
Index: src/bin/e_bg.c
===================================================================
--- src/bin/e_bg.c	(revision 40414)
+++ src/bin/e_bg.c	(working copy)
@@ -6,11 +6,23 @@
 /* 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;
+};
+
 /* externally accessible functions */
 EAPI int 
 e_bg_init(void)
@@ -263,6 +275,17 @@ e_bg_zone_update(E_Zone *zone, E_Bg_Transition tra
 	evas_object_resize(o, zone->w, zone->h);
 	evas_object_layer_set(o, -1);
      }
+   if (e_config->desk_flip_pan_bg)
+     {
+	Evas_Coord w, h, maxw, maxh;
+
+	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);
+     }
    evas_object_clip_set(o, zone->bg_clip_object);
    evas_object_show(o);
    
@@ -281,6 +304,60 @@ e_bg_zone_update(E_Zone *zone, E_Bg_Transition tra
 }
 
 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;
+   
+   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);
+   step_w = ((double) (w - zone->w)) / (zone->desk_x_count - 1);
+   step_h = ((double) (h - zone->h)) / (zone->desk_y_count - 1);
+
+   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_set(o, zone->bg_object);
+	e_scrollframe_child_pos_set(o, 0, 0);
+	evas_object_show(o);
+     }
+   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);
+
+   e_scrollframe_child_viewport_size_get(o, &vw, &vh);
+   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 = prev_x * step_w * e_config->desk_flip_pan_x_axis_factor;
+   params->start_y = prev_y * step_h * e_config->desk_flip_pan_y_axis_factor;
+   params->end_x = params->start_x + ((desk->x - prev_x) * step_w * e_config->desk_flip_pan_x_axis_factor);
+   params->end_y = params->start_y + ((desk->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)
 {
    E_Event_Bg_Update *ev;
@@ -440,3 +517,54 @@ _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;
+
+   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)
+     px = params->start_x + (params->end_x - params->start_x) * (1.0 - dt);
+   else
+     px = params->end_x + (params->start_x - params->end_x) * dt;
+
+   if (params->end_y > params->start_y)
+     py = params->start_y + (params->end_y - params->start_y) * (1.0 - dt);
+   else
+     py = params->end_y + (params->start_y - params->end_y) * dt;
+
+   e_scrollframe_child_pos_set(o, px, py);
+
+   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;
+}
Index: src/bin/e_bg.h
===================================================================
--- src/bin/e_bg.h	(revision 40414)
+++ src/bin/e_bg.h	(working copy)
@@ -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);
Index: src/bin/e_desk.c
===================================================================
--- src/bin/e_desk.c	(revision 40414)
+++ src/bin/e_desk.c	(working copy)
@@ -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);
 
Index: src/modules/conf_desks/e_int_config_desks.c
===================================================================
--- src/modules/conf_desks/e_int_config_desks.c	(revision 40455)
+++ src/modules/conf_desks/e_int_config_desks.c	(working copy)
@@ -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_Confi
 
    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_Co
 
    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, Eva
    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);
+   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);
Index: data/themes/default.edc
===================================================================
--- data/themes/default.edc	(revision 40414)
+++ data/themes/default.edc	(working copy)
@@ -127,6 +127,28 @@ collections { /* begin the collection of edje grou
       }
    }
 
+   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";
------------------------------------------------------------------------------
Register Now & Save for Velocity, the Web Performance & Operations 
Conference from O'Reilly Media. Velocity features a full day of 
expert-led, hands-on workshops and two days of sessions from industry 
leaders in dedicated Performance & Operations tracks. Use code vel09scf 
and Save an extra 15% before 5/3. http://p.sf.net/sfu/velocityconf
_______________________________________________
enlightenment-devel mailing list
enlightenment-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to