[ease] Create individual functions for each transition instead of giant switch statement.



commit 7fa578961a240cd71a889dd17a17f8171de2e5f4
Author: Nate Stedman <natesm gmail com>
Date:   Fri May 21 02:54:24 2010 -0400

    Create individual functions for each transition instead of giant switch statement.

 src/SlideActor.vala | 1245 ++++++++++++++++++++++++++++++---------------------
 1 files changed, 724 insertions(+), 521 deletions(-)
---
diff --git a/src/SlideActor.vala b/src/SlideActor.vala
index db7aa4f..5da99cb 100644
--- a/src/SlideActor.vala
+++ b/src/SlideActor.vala
@@ -35,10 +35,10 @@ public class Ease.SlideActor : Clutter.Group
 
 	// the group of the slide's contents
 	public Clutter.Group contents;
-	
+
 	// the context of the actor (presentation, etc.)
 	public ActorContext context;
-	
+
 	// timelines
 	public Clutter.Timeline animation_time { get; set; }
 	private Clutter.Alpha animation_alpha { get; set; }
@@ -46,30 +46,30 @@ public class Ease.SlideActor : Clutter.Group
 	private Clutter.Timeline time2;
 	private Clutter.Alpha alpha1;
 	private Clutter.Alpha alpha2;
-	
+
 	// constants
 	public const Clutter.AnimationMode EASE_SLIDE =
 		Clutter.AnimationMode.EASE_IN_OUT_SINE;
-		
+
 	public const Clutter.AnimationMode EASE_DROP =
 		Clutter.AnimationMode.EASE_OUT_BOUNCE;
-	
+
 	public const Clutter.AnimationMode EASE_PIVOT =
 		Clutter.AnimationMode.EASE_OUT_SINE;
-		
+
 	public const float FLIP_DEPTH = -400;
 	public const float ZOOM_OUT_SCALE = 0.75f;
 	private const float OPEN_DEPTH = -3000;
 	private const float OPEN_MOVE = 0.15f;
 	private const float OPEN_TIME = 0.8f;
 	private const int SLAT_COUNT = 8;
-	
+
 	public SlideActor.from_slide(Document document, Slide s, bool clip,
 	                              ActorContext ctx)
 	{
 		slide = s;
 		context = ctx;
-		
+
 		// clip the actor's bounds
 		if (clip)
 		{
@@ -80,7 +80,7 @@ public class Ease.SlideActor : Clutter.Group
 		set_background();
 
 		contents = new Clutter.Group();
-		
+
 		foreach (var e in slide.elements)
 		{
 			// load the proper type of actor
@@ -100,11 +100,11 @@ public class Ease.SlideActor : Clutter.Group
 
 		add_actor(contents);
 	}
-	
+
 	public void relayout()
 	{
 		set_background();
-		
+
 		for (unowned List<Clutter.Actor>* itr = contents.get_children();
 		     itr != null;
 		     itr = itr->next)
@@ -112,10 +112,10 @@ public class Ease.SlideActor : Clutter.Group
 			((Actor)(itr->data)).reposition();
 		}
 	}
-	
+
 	/**
 	 * Builds the background actor for this SlideActor.
-	 */	
+	 */
 	private void set_background()
 	{
 		if (background != null)
@@ -125,7 +125,7 @@ public class Ease.SlideActor : Clutter.Group
 				remove_actor(background);
 			}
 		}
-		
+
 		if (slide.background_image != null)
 		{
 			try
@@ -145,7 +145,7 @@ public class Ease.SlideActor : Clutter.Group
 		}
 		background.width = slide.parent.width;
 		background.height = slide.parent.height;
-		
+
 		add_actor(background);
 		lower_child(background, null);
 	}
@@ -163,7 +163,7 @@ public class Ease.SlideActor : Clutter.Group
 		}
 	}
 
-	// unstack the actor, layering it with another actor 
+	// unstack the actor, layering it with another actor
 	public void unstack(SlideActor other, Clutter.Actor container)
 	{
 		if (other.background.get_parent() != container)
@@ -183,579 +183,782 @@ public class Ease.SlideActor : Clutter.Group
 			other.contents.reparent(container);
 		}
 	}
-	
+
 	private void prepare_slide_transition(SlideActor new_slide,
 	                                      Clutter.Group stack_container)
 	{
 		new_slide.stack(stack_container);
 		stack(stack_container);
 	}
-	
+
 	private void prepare_stack_transition(bool current_on_top,
 	                                      SlideActor new_slide,
 	                                      Clutter.Group stack_container)
 	{
 		unstack(new_slide, stack_container);
 	}
-	
+
 	public void transition(SlideActor new_slide,
 	                       Clutter.Group stack_container)
 	{
-		uint length = (uint)max(10, slide.transition_time * 1000);
-		float xpos = 0, ypos = 0, angle = 90;
-		var property = "";
-		
+		uint length = (uint)max(1, slide.transition_time * 1000);
+
 		animation_time = new Clutter.Timeline(length);
-		animation_time.start();
-	
+
 		switch (slide.transition)
 		{
 			case "Fade":
-				prepare_slide_transition(new_slide, stack_container);
-				new_slide.opacity = 0;
-				new_slide.animate(Clutter.AnimationMode.LINEAR,
-				                  length, "opacity", 255);
+				fade_transition(new_slide, stack_container, length);
 				break;
-			
+
 			case "Slide":
-				switch (slide.variant)
-				{
-					case "Up":
-						new_slide.y = slide.parent.height;
-						new_slide.animate(EASE_SLIDE, length, "y", 0);
-						animate(EASE_SLIDE, length, "y", -new_slide.y);
-						break;
-					case "Down":
-						new_slide.y = -slide.parent.height;
-						new_slide.animate(EASE_SLIDE, length, "y", 0);
-						animate(EASE_SLIDE, length, "y", -new_slide.y);
-						break;
-					case "Left":
-						new_slide.x = slide.parent.width;
-						new_slide.animate(EASE_SLIDE, length, "x", 0);
-						animate(EASE_SLIDE, length, "x", -new_slide.x);
-						break;
-					case "Right":
-						new_slide.x = -slide.parent.width;
-						new_slide.animate(EASE_SLIDE, length, "x", 0);
-						animate(EASE_SLIDE, length, "x", -new_slide.x);
-						break;
-				}
+				slide_transition(new_slide, stack_container, length);
 				break;
-			
+
 			case "Drop":
-				new_slide.y = -slide.parent.height;
-				new_slide.animate(EASE_DROP, length, "y", 0);
+				drop_transition(new_slide, stack_container, length);
 				break;
-			
+
 			case "Pivot":
-				switch (slide.variant)
-				{
-					case "Top Right":
-						xpos = slide.parent.width;
-						angle = -90;
-						break;
-					case "Bottom Left":
-						ypos = slide.parent.height;
-						angle = -90;
-						break;
-					case "Bottom Right":
-						xpos = slide.parent.width;
-						ypos = slide.parent.height;
-						break;
-				}
-				new_slide.set_rotation(Clutter.RotateAxis.Z_AXIS,
-				                       angle, xpos, ypos, 0);
-				animation_alpha = new Clutter.Alpha.full(animation_time,
-				                                         EASE_PIVOT);
-				animation_time.new_frame.connect((m) => {
-					new_slide.set_rotation(Clutter.RotateAxis.Z_AXIS,
-					                       angle * (1 - animation_alpha.alpha),
-					                       xpos, ypos, 0);
-				});
+				pivot_transition(new_slide, stack_container, length);
 				break;
-				
+
 			case "Open Door":
-			{
-				// zoom the new slide in
-				new_slide.depth = OPEN_DEPTH;
-				new_slide.animate(Clutter.AnimationMode.EASE_OUT_SINE,
-				                  length, "depth", 0);
-				
-				animate(Clutter.AnimationMode.LINEAR, length, "opacity", 0);
-				reparent(stack_container);
-				x = slide.parent.width;
-				
-				// create left and right half clone actors
-				float width = slide.parent.width / 2f;
-				Clutter.Clone left = new Clutter.Clone(this),
-				              right = new Clutter.Clone(this);
-				              
-				left.set_clip(0, 0, width, slide.parent.height);
-				right.set_clip(width, 0, width, slide.parent.height);
-				
-				// add the left and right actors
-				stack_container.add_actor(left);
-				stack_container.add_actor(right);
-				
-				// move the left and right sides outwards
-				left.animate(Clutter.AnimationMode.EASE_IN_OUT_SINE,
-				             length / 2, "x", left.x - width * OPEN_MOVE);
-				
-				right.animate(Clutter.AnimationMode.EASE_IN_OUT_SINE,
-				              length / 2, "x", right.x + width * OPEN_MOVE);
-				
-				// animate the angles of the left and right sides
-				time1 = new Clutter.Timeline((int)(OPEN_TIME * length));
-				animation_alpha = new Clutter.Alpha.full(time1,
-				                            Clutter.AnimationMode.EASE_IN_SINE);
-				
-				time1.new_frame.connect((m) => {
-					left.set_rotation(Clutter.RotateAxis.Y_AXIS,
-					                  180 * animation_alpha.alpha,
-					                  0, 0, 0);
-					                  
-					right.set_rotation(Clutter.RotateAxis.Y_AXIS,
-					                   -180 * animation_alpha.alpha,
-					                   width * 2, 0, 0);
-				});
-				
-				// clean up
-				time1.completed.connect(() => {
-					stack_container.remove_actor(left);
-					stack_container.remove_actor(right);
-				});
-				
-				time1.start();
-				
+				open_door_transition(new_slide, stack_container, length);
 				break;
-			}
-			
+
 			case "Reveal":
-				// TODO: make this transition not a total hack
-				((Clutter.Container)get_parent()).raise_child(this, new_slide);
-				
-				switch (slide.variant)
-				{
-					case "Top":
-						new_slide.y = slide.parent.height;
-						animate(EASE_SLIDE, length, "y", -new_slide.y);
-						new_slide.y = 0;
-						break;
-					case "Bottom":
-						new_slide.y = -slide.parent.height;
-						animate(EASE_SLIDE, length, "y", -new_slide.y);
-						new_slide.y = 0;
-						break;
-					case "Left":
-						new_slide.x = slide.parent.width;
-						this.animate(EASE_SLIDE, length, "x", -new_slide.x);
-						new_slide.x = 0;
-						break;
-					case "Right":
-						new_slide.x = -slide.parent.width;
-						animate(EASE_SLIDE, length, "x", -new_slide.x);
-						new_slide.x = 0;
-						break;
-				}
-				break;
-				
+				reveal_transition(new_slide, stack_container, length);
+				break;
+
 			case "Slats":
-			{
-				// hide the real SlideActors
-				reparent(stack_container);
-				new_slide.reparent(stack_container);
-				x = slide.parent.width;
-				new_slide.x = slide.parent.width;
-				
-				// make arrays for the slats
-				var this_slats = new Clutter.Clone[SLAT_COUNT];
-				var new_slats = new Clutter.Clone[SLAT_COUNT];
-				var groups = new Clutter.Group[SLAT_COUNT];
-				
-				// calculate the width of each slat
-				float width = (float)slide.parent.width / SLAT_COUNT;
-				
-				// make the slats
-				for (int i = 0; i < SLAT_COUNT; i++)
-				{
-					// create groups
-					groups[i] = new Clutter.Group();
-					stack_container.add_actor(groups[i]);
-					
-					// create clones
-					this_slats[i] = new Clutter.Clone(this);
-					groups[i].add_actor(this_slats[i]);
-					new_slats[i] = new Clutter.Clone(new_slide);
-					groups[i].add_actor(new_slats[i]);
-					
-					// clip clones
-					this_slats[i].set_clip(width * i, 0,
-					                       width, slide.parent.height);
-					new_slats[i].set_clip(width * i, 0,
-					                      width, slide.parent.height);
-					                      
-					// flip the back slats
-					new_slats[i].set_rotation(Clutter.RotateAxis.Y_AXIS,
-					                          180, width / 2, 0, 0);
-					
-					// place the new slats behind the current ones
-					new_slats[i].depth = 5;
-				}
-				
-				// make an alpha for easing
-				animation_alpha = new Clutter.Alpha.full(animation_time,
-				                        Clutter.AnimationMode.EASE_IN_OUT_BACK);
-				
-				// animate
-				animation_time.new_frame.connect((m) => {
-					for (int i = 0; i < SLAT_COUNT; i++)
-					{
-						groups[i].set_rotation(Clutter.RotateAxis.Y_AXIS,
-							              180 * animation_alpha.alpha,
-							              (i + 0.5f) * width, 0, 0);
-					}
-				});
-				
-				animation_time.completed.connect(() => {
-					// clean up the slats
-					for (int i = 0; i < SLAT_COUNT; i++)
-					{
-						stack_container.remove_actor(groups[i]);
-					}
-					
-					// put the new slide in place
-					new_slide.x = 0;
-				});
-				
+				slats_transition(new_slide, stack_container, length);
 				break;
-			}
-			
+
 			case "Flip":
-				new_slide.opacity = 0;				
-				time1 = new Clutter.Timeline(length / 2);
-				time2 = new Clutter.Timeline(length / 2);
-				alpha1 = new Clutter.Alpha.full(time1,
-				                       Clutter.AnimationMode.EASE_IN_SINE);
-				alpha2 = new Clutter.Alpha.full(time2,
-				                       Clutter.AnimationMode.EASE_OUT_SINE);
-				switch (slide.variant)
-				{
-					case "Bottom to Top":
-						time1.new_frame.connect((m) => {
-							set_rotation(Clutter.RotateAxis.X_AXIS, 90 * alpha1.alpha, 0, slide.parent.height / 2, 0);
-							depth = (float)(FLIP_DEPTH * alpha1.alpha);
-						});
-						time2.new_frame.connect((m) => {
-							new_slide.opacity = 255;
-							new_slide.depth = FLIP_DEPTH * (float)(1 - alpha2.alpha);
-							new_slide.set_rotation(Clutter.RotateAxis.X_AXIS, -90 * (1 - alpha2.alpha), 0, slide.parent.height / 2, 0);
-						});
-						break;
-					case "Top to Bottom":
-						time1.new_frame.connect((m) => {
-							set_rotation(Clutter.RotateAxis.X_AXIS, -90 * alpha1.alpha, 0, slide.parent.height / 2, 0);
-							depth = (float)(FLIP_DEPTH * alpha1.alpha);
-						});
-						time2.new_frame.connect((m) => {
-							new_slide.opacity = 255;
-							new_slide.depth = FLIP_DEPTH * (float)(1 - alpha2.alpha);
-							new_slide.set_rotation(Clutter.RotateAxis.X_AXIS, 90 * (1 - alpha2.alpha), 0, slide.parent.height / 2, 0);
-						});
-						break;
-					case "Left to Right":
-						time1.new_frame.connect((m) => {
-							set_rotation(Clutter.RotateAxis.Y_AXIS, 90 * alpha1.alpha, slide.parent.width / 2, 0, 0);
-							depth = (float)(FLIP_DEPTH * alpha1.alpha);
-						});
-						time2.new_frame.connect((m) => {
-							new_slide.opacity = 255;
-							new_slide.depth = FLIP_DEPTH * (float)(1 - alpha2.alpha);
-							new_slide.set_rotation(Clutter.RotateAxis.Y_AXIS, -90 * (1 - alpha2.alpha), slide.parent.width / 2, 0, 0);
-						});
-						break;
-					case "Right to Left":
-						time1.new_frame.connect((m) => {
-							set_rotation(Clutter.RotateAxis.Y_AXIS, -90 * alpha1.alpha, slide.parent.width / 2, 0, 0);
-							depth = (float)(FLIP_DEPTH * alpha1.alpha);
-						});
-						time2.new_frame.connect((m) => {
-							new_slide.opacity = 255;
-							new_slide.depth = FLIP_DEPTH * (float)(1 - alpha2.alpha);
-							new_slide.set_rotation(Clutter.RotateAxis.Y_AXIS, 90 * (1 - alpha2.alpha), slide.parent.width / 2, 0, 0);
-						});
-						break;
-				}
-				time1.completed.connect(() => {
-					opacity = 0;
-					new_slide.depth = FLIP_DEPTH;
-					time2.start();
-				});
-				time1.start();
+				flip_transition(new_slide, stack_container, length);
 				break;
-			
+
 			case "Revolving Door":
-				depth = 1; //ugly, but works
-				animation_alpha = new Clutter.Alpha.full(animation_time, Clutter.AnimationMode.EASE_IN_OUT_SINE);
-				switch (slide.variant)
-				{
-					case "Left":
-						new_slide.set_rotation(Clutter.RotateAxis.Y_AXIS, 90, 0, 0, 0);
-						animation_time.new_frame.connect((m) => {
-							new_slide.set_rotation(Clutter.RotateAxis.Y_AXIS, 90 * (1 - animation_alpha.alpha), 0, 0, 0);
-							set_rotation(Clutter.RotateAxis.Y_AXIS, -110 * animation_alpha.alpha, 0, 0, 0);
-						});
-						break;
-					case "Right":
-						new_slide.set_rotation(Clutter.RotateAxis.Y_AXIS, 90, slide.parent.width, 0, 0);
-						animation_time.new_frame.connect((m) => {
-							new_slide.set_rotation(Clutter.RotateAxis.Y_AXIS, -90 * (1 - animation_alpha.alpha), slide.parent.width, 0, 0);
-							set_rotation(Clutter.RotateAxis.Y_AXIS, 110 * animation_alpha.alpha, slide.parent.width, 0, 0);
-						});
-						break;
-					case "Top":
-						new_slide.set_rotation(Clutter.RotateAxis.X_AXIS, -90, 0, 0, 0);
-						animation_time.new_frame.connect((m) => {
-							new_slide.set_rotation(Clutter.RotateAxis.X_AXIS, -90 * (1 - animation_alpha.alpha), 0, 0, 0);
-							set_rotation(Clutter.RotateAxis.X_AXIS, 110 * animation_alpha.alpha, 0, 0, 0);
-						});
-						break;
-					case "Bottom":
-						new_slide.set_rotation(Clutter.RotateAxis.X_AXIS, 90, 0, slide.parent.height, 0);
-						animation_time.new_frame.connect((m) => {
-							new_slide.set_rotation(Clutter.RotateAxis.X_AXIS, 90 * (1 - animation_alpha.alpha), 0, slide.parent.height, 0);
-							set_rotation(Clutter.RotateAxis.X_AXIS, -110 * animation_alpha.alpha, 0, slide.parent.height, 0);
-						});
-						break;
-				}
+				revolving_door_transition(new_slide, stack_container, length);
 				break;
-			
+
 			case "Fall":
-				depth = 1; //ugly, but works
-				animation_alpha = new Clutter.Alpha.full(animation_time, Clutter.AnimationMode.EASE_IN_QUART);
-				animation_time.new_frame.connect((m) => {
-					set_rotation(Clutter.RotateAxis.X_AXIS, -90 * animation_alpha.alpha, 0, slide.parent.height, 0);
-				});
+				fall_transition(new_slide, stack_container, length);
 				break;
-			
+
 			case "Spin Contents":
-				prepare_stack_transition(false, new_slide, stack_container);
-			
-				new_slide.contents.opacity = 0;	
-				background.animate(Clutter.AnimationMode.EASE_IN_OUT_SINE, length, "opacity", 0);			
-				time1 = new Clutter.Timeline(length / 2);
-				time2 = new Clutter.Timeline(length / 2);
-				alpha1 = new Clutter.Alpha.full(time1, Clutter.AnimationMode.EASE_IN_SINE);
-				alpha2 = new Clutter.Alpha.full(time2, Clutter.AnimationMode.EASE_OUT_SINE);
-				angle = slide.variant == "Left" ? -90 : 90;
-				time1.completed.connect(() => {
-					contents.opacity = 0;
-					time2.start();
+				spin_contents_transition(new_slide, stack_container, length);
+				break;
+
+			case "Swing Contents":
+				swing_contents_transition(new_slide, stack_container, length);
+				break;
+
+			case "Zoom":
+				zoom_transition(new_slide, stack_container, length);
+				break;
+
+			case "Slide Contents":
+				slide_contents_transition(new_slide, stack_container, length);
+				break;
+
+			case "Spring Contents":
+				spring_contents_transition(new_slide, stack_container, length);
+				break;
+
+			case "Zoom Contents":
+				zoom_contents_transition(new_slide, stack_container, length);
+				break;
+
+			case "Panel":
+				panel_transition(new_slide, stack_container, length);
+				break;
+		}
+		
+		animation_time.start();
+	}
+
+	private void fade_transition(SlideActor new_slide,
+	                             Clutter.Group stack_container, uint length)
+	{
+		prepare_slide_transition(new_slide, stack_container);
+		new_slide.opacity = 0;
+		new_slide.animate(Clutter.AnimationMode.LINEAR,
+		                  length, "opacity", 255);
+	}
+
+	private void slide_transition(SlideActor new_slide,
+	                              Clutter.Group stack_container, uint length)
+	{
+		switch (slide.variant)
+		{
+			case "Up":
+				new_slide.y = slide.parent.height;
+				new_slide.animate(EASE_SLIDE, length, "y", 0);
+				animate(EASE_SLIDE, length, "y", -new_slide.y);
+				break;
+			case "Down":
+				new_slide.y = -slide.parent.height;
+				new_slide.animate(EASE_SLIDE, length, "y", 0);
+				animate(EASE_SLIDE, length, "y", -new_slide.y);
+				break;
+			case "Left":
+				new_slide.x = slide.parent.width;
+				new_slide.animate(EASE_SLIDE, length, "x", 0);
+				animate(EASE_SLIDE, length, "x", -new_slide.x);
+				break;
+			case "Right":
+				new_slide.x = -slide.parent.width;
+				new_slide.animate(EASE_SLIDE, length, "x", 0);
+				animate(EASE_SLIDE, length, "x", -new_slide.x);
+				break;
+		}
+	}
+
+	private void drop_transition(SlideActor new_slide,
+	                             Clutter.Group stack_container, uint length)
+	{
+		new_slide.y = -slide.parent.height;
+		new_slide.animate(EASE_DROP, length, "y", 0);
+	}
+
+	private void pivot_transition(SlideActor new_slide,
+	                              Clutter.Group stack_container, uint length)
+	{
+		float xpos = 0, ypos = 0, angle = 90;
+		switch (slide.variant)
+		{
+			case "Top Right":
+				xpos = slide.parent.width;
+				angle = -90;
+				break;
+			case "Bottom Left":
+				ypos = slide.parent.height;
+				angle = -90;
+				break;
+			case "Bottom Right":
+				xpos = slide.parent.width;
+				ypos = slide.parent.height;
+				break;
+		}
+		new_slide.set_rotation(Clutter.RotateAxis.Z_AXIS,
+		                       angle, xpos, ypos, 0);
+		animation_alpha = new Clutter.Alpha.full(animation_time,
+		                                         EASE_PIVOT);
+		animation_time.new_frame.connect((m) => {
+			new_slide.set_rotation(Clutter.RotateAxis.Z_AXIS,
+			                       angle * (1 - animation_alpha.alpha),
+			                       xpos, ypos, 0);
+		});
+	}
+
+	private void flip_transition(SlideActor new_slide,
+	                             Clutter.Group stack_container, uint length)
+	{
+		new_slide.opacity = 0;
+		time1 = new Clutter.Timeline(length / 2);
+		time2 = new Clutter.Timeline(length / 2);
+		alpha1 = new Clutter.Alpha.full(time1,
+		                                Clutter.AnimationMode.EASE_IN_SINE);
+		alpha2 = new Clutter.Alpha.full(time2,
+		                                Clutter.AnimationMode.EASE_OUT_SINE);
+		switch (slide.variant)
+		{
+			case "Bottom to Top":
+				time1.new_frame.connect((m) => {
+					set_rotation(Clutter.RotateAxis.X_AXIS, 90 * alpha1.alpha,
+					             0, slide.parent.height / 2, 0);
+					depth = (float)(FLIP_DEPTH * alpha1.alpha);
 				});
+
+				time2.new_frame.connect((m) => {
+					new_slide.opacity = 255;
+					new_slide.depth = FLIP_DEPTH * (float)(1 - alpha2.alpha);
+					new_slide.set_rotation(Clutter.RotateAxis.X_AXIS,
+					                       -90 * (1 - alpha2.alpha), 0,
+					                       slide.parent.height / 2, 0);
+				});
+				break;
+
+			case "Top to Bottom":
 				time1.new_frame.connect((m) => {
-					contents.set_rotation(Clutter.RotateAxis.Y_AXIS, angle * alpha1.alpha, slide.parent.width / 2, 0, 0);
+					set_rotation(Clutter.RotateAxis.X_AXIS, -90 * alpha1.alpha,
+					             0, slide.parent.height / 2, 0);
+					depth = (float)(FLIP_DEPTH * alpha1.alpha);
 				});
+
 				time2.new_frame.connect((m) => {
-					new_slide.contents.opacity = 255;
-					new_slide.contents.set_rotation(Clutter.RotateAxis.Y_AXIS, -angle * (1 - alpha2.alpha), slide.parent.width / 2, 0, 0);
+					new_slide.opacity = 255;
+					new_slide.depth = FLIP_DEPTH * (float)(1 - alpha2.alpha);
+					new_slide.set_rotation(Clutter.RotateAxis.X_AXIS,
+					                       90 * (1 - alpha2.alpha), 0,
+					                       slide.parent.height / 2, 0);
 				});
-				time1.start();
 				break;
-			
-			case "Swing Contents":
-				prepare_stack_transition(false, new_slide, stack_container);
-			
-				new_slide.contents.opacity = 0;	
-				background.animate(Clutter.AnimationMode.EASE_IN_OUT_SINE, length, "opacity", 0);
-				alpha1 = new Clutter.Alpha.full(animation_time, Clutter.AnimationMode.EASE_IN_SINE);
-				alpha2 = new Clutter.Alpha.full(animation_time, Clutter.AnimationMode.EASE_OUT_SINE);
-				animation_alpha = new Clutter.Alpha.full(animation_time, Clutter.AnimationMode.LINEAR);
+
+			case "Left to Right":
+				time1.new_frame.connect((m) => {
+					set_rotation(Clutter.RotateAxis.Y_AXIS,
+					             90 * alpha1.alpha,
+					             slide.parent.width / 2, 0,0);
+
+					depth = (float)(FLIP_DEPTH * alpha1.alpha);
+				});
+
+				time2.new_frame.connect((m) => {
+					new_slide.opacity = 255;
+					new_slide.depth = FLIP_DEPTH * (float)(1 - alpha2.alpha);
+					new_slide.set_rotation(Clutter.RotateAxis.Y_AXIS,
+					                       -90 * (1 - alpha2.alpha),
+					                       slide.parent.width / 2, 0, 0);
+				});
+				break;
+
+			case "Right to Left":
+				time1.new_frame.connect((m) => {
+					set_rotation(Clutter.RotateAxis.Y_AXIS, -90 * alpha1.alpha,
+					             slide.parent.width / 2, 0, 0);
+					depth = (float)(FLIP_DEPTH * alpha1.alpha);
+				});
+
+				time2.new_frame.connect((m) => {
+					new_slide.opacity = 255;
+					new_slide.depth = FLIP_DEPTH * (float)(1 - alpha2.alpha);
+					new_slide.set_rotation(Clutter.RotateAxis.Y_AXIS,
+					                       90 * (1 - alpha2.alpha),
+					                       slide.parent.width / 2, 0, 0);
+				});
+				break;
+		}
+		time1.completed.connect(() => {
+			opacity = 0;
+			new_slide.depth = FLIP_DEPTH;
+			time2.start();
+		});
+		time1.start();
+	}
+
+	private void revolving_door_transition(SlideActor new_slide,
+	                                       Clutter.Group stack_container,
+	                                       uint length)
+	{
+		depth = 1; //ugly, but works
+
+		animation_alpha = new Clutter.Alpha.full(animation_time,
+		                                Clutter.AnimationMode.EASE_IN_OUT_SINE);
+		switch (slide.variant)
+		{
+			case "Left":
+				new_slide.set_rotation(Clutter.RotateAxis.Y_AXIS, 90, 0, 0, 0);
 				animation_time.new_frame.connect((m) => {
-					unowned GLib.List<Clutter.Actor>* itr;
-					contents.opacity = clamp_opacity(455 - 555 * alpha1.alpha);
-					new_slide.contents.opacity = clamp_opacity(-100 + 400 * alpha2.alpha);
-					for (itr = contents.get_children(); itr != null; itr = itr->next)
-					{
-						((Clutter.Actor*)itr->data)->set_rotation(Clutter.RotateAxis.X_AXIS, 540 * alpha1.alpha, 0, 0, 0);
-					}
-					for (itr = new_slide.contents.get_children(); itr != null; itr = itr->next)
-					{
-						((Clutter.Actor*)itr->data)->set_rotation(Clutter.RotateAxis.X_AXIS, -540 * (1 - alpha2.alpha), 0, 0, 0);
-					}
+					new_slide.set_rotation(Clutter.RotateAxis.Y_AXIS, 90 * (1 - animation_alpha.alpha), 0, 0, 0);
+					set_rotation(Clutter.RotateAxis.Y_AXIS, -110 * animation_alpha.alpha, 0, 0, 0);
 				});
 				break;
-			
-			case "Zoom":
-				switch (slide.variant)
-				{
-					case "Center":
-						new_slide.set_scale_full(0, 0, slide.parent.width / 2, slide.parent.height / 2);
-						break;
-					case "Top Left":
-						new_slide.set_scale_full(0, 0, 0, 0);
-						break;
-					case "Top Right":
-						new_slide.set_scale_full(0, 0, slide.parent.width, 0);
-						break;
-					case "Bottom Left":
-						new_slide.set_scale_full(0, 0, 0, slide.parent.height);
-						break;
-					case "Bottom Right":
-						new_slide.set_scale_full(0, 0, slide.parent.width, slide.parent.height);
-						break;
-				}
-				animation_alpha = new Clutter.Alpha.full(animation_time, Clutter.AnimationMode.EASE_OUT_SINE);
+			case "Right":
+				new_slide.set_rotation(Clutter.RotateAxis.Y_AXIS, 90, slide.parent.width, 0, 0);
 				animation_time.new_frame.connect((m) => {
-					new_slide.set_scale(animation_alpha.alpha, animation_alpha.alpha);
+					new_slide.set_rotation(Clutter.RotateAxis.Y_AXIS, -90 * (1 - animation_alpha.alpha), slide.parent.width, 0, 0);
+					set_rotation(Clutter.RotateAxis.Y_AXIS, 110 * animation_alpha.alpha, slide.parent.width, 0, 0);
 				});
-				//new_slide.animate(Clutter.AnimationMode.EASE_OUT_SINE, length, "scale_x", 1);
-				//new_slide.animate(Clutter.AnimationMode.EASE_OUT_SINE, length, "scale_y", 1);
 				break;
-			
-			case "Slide Contents":
-				prepare_stack_transition(false, new_slide, stack_container);
-			
-				background.animate(Clutter.AnimationMode.EASE_IN_OUT_SINE, length, "opacity", 0);
-				switch (slide.variant)
-				{
-					case "Right":
-						new_slide.contents.x = -slide.parent.width;
-						new_slide.contents.animate(Clutter.AnimationMode.EASE_IN_OUT_SINE, length, "x", 0);
-						contents.animate(Clutter.AnimationMode.EASE_IN_OUT_SINE, length, "x", -new_slide.contents.x);
-						break;
-					case "Left":
-						new_slide.contents.x = slide.parent.width;
-						new_slide.contents.animate(Clutter.AnimationMode.EASE_IN_OUT_SINE, length, "x", 0);
-						contents.animate(Clutter.AnimationMode.EASE_IN_OUT_SINE, length, "x", -new_slide.contents.x);
-						break;
-					case "Up":
-						new_slide.contents.y = slide.parent.height;
-						new_slide.contents.animate(Clutter.AnimationMode.EASE_IN_OUT_SINE, length, "y", 0);
-						contents.animate(Clutter.AnimationMode.EASE_IN_OUT_SINE, length, "y", -new_slide.contents.y);
-						break;
-					case "Down":
-						new_slide.contents.y = -slide.parent.height;
-						new_slide.contents.animate(Clutter.AnimationMode.EASE_IN_OUT_SINE, length, "y", 0);
-						contents.animate(Clutter.AnimationMode.EASE_IN_OUT_SINE, length, "y", -new_slide.contents.y);
-						break;
-				}
+			case "Top":
+				new_slide.set_rotation(Clutter.RotateAxis.X_AXIS, -90, 0, 0, 0);
+				animation_time.new_frame.connect((m) => {
+					new_slide.set_rotation(Clutter.RotateAxis.X_AXIS, -90 * (1 - animation_alpha.alpha), 0, 0, 0);
+					set_rotation(Clutter.RotateAxis.X_AXIS, 110 * animation_alpha.alpha, 0, 0, 0);
+				});
 				break;
-			
-			case "Spring Contents":
-				prepare_stack_transition(false, new_slide, stack_container);
-			
-				background.animate(Clutter.AnimationMode.EASE_IN_OUT_SINE, length, "opacity", 0);
-				switch (slide.variant)
-				{
-					case "Up":
-						new_slide.contents.y = slide.parent.height * 1.2f;
-						new_slide.contents.animate(Clutter.AnimationMode.EASE_IN_OUT_ELASTIC, length, "y", 0);
-						contents.animate(Clutter.AnimationMode.EASE_IN_OUT_ELASTIC, length, "y", -slide.parent.height * 1.2);
-						break;
-					case "Down":
-						new_slide.contents.y = -slide.parent.height * 1.2f;
-						new_slide.contents.animate(Clutter.AnimationMode.EASE_IN_OUT_ELASTIC, length, "y", 0);
-						contents.animate(Clutter.AnimationMode.EASE_IN_OUT_ELASTIC, length, "y", slide.parent.height * 1.2);
-						break;
-				}
+			case "Bottom":
+				new_slide.set_rotation(Clutter.RotateAxis.X_AXIS, 90, 0, slide.parent.height, 0);
+				animation_time.new_frame.connect((m) => {
+					new_slide.set_rotation(Clutter.RotateAxis.X_AXIS, 90 * (1 - animation_alpha.alpha), 0, slide.parent.height, 0);
+					set_rotation(Clutter.RotateAxis.X_AXIS, -110 * animation_alpha.alpha, 0, slide.parent.height, 0);
+				});
 				break;
-			
-			case "Zoom Contents":
-				prepare_stack_transition(slide.variant == "Out",
-				                         new_slide, stack_container);
-				                         
-				animation_alpha = new Clutter.Alpha.full(animation_time, Clutter.AnimationMode.EASE_IN_OUT_SINE);
-				background.animate(Clutter.AnimationMode.LINEAR, length, "opacity", 0);
-				switch (slide.variant)
-				{
-					case "In":
-						new_slide.contents.set_scale_full(0, 0, slide.parent.width / 2, slide.parent.height / 2);
-						contents.set_scale_full(1, 1, slide.parent.width / 2, slide.parent.height / 2);
-						contents.animate(Clutter.AnimationMode.LINEAR, length / 2, "opacity", 0);
-						animation_time.new_frame.connect((m) => {
-							new_slide.contents.set_scale(animation_alpha.alpha,
-								                            animation_alpha.alpha);
-							contents.set_scale(1.0 + 2 * animation_alpha.alpha,
-							   	                        1.0 + 2 * animation_alpha.alpha);
-						});
-						break;
-					case "Out":
-						new_slide.contents.set_scale_full(0, 0, slide.parent.width / 2, slide.parent.height / 2);
-						contents.set_scale_full(1, 1, slide.parent.width / 2, slide.parent.height / 2);
-						new_slide.contents.opacity = 0;
-						new_slide.contents.animate(Clutter.AnimationMode.EASE_IN_SINE, length / 2, "opacity", 255);
-						animation_time.new_frame.connect((m) => {
-							new_slide.contents.set_scale(1.0 + 2 * (1 - animation_alpha.alpha),
-								                            1.0 + 2 * (1 - animation_alpha.alpha));
-							contents.set_scale(1 - animation_alpha.alpha,
-							   	                         1 - animation_alpha.alpha);
-						});
-						break;
-				}
+		}
+	}
+
+	private void reveal_transition(SlideActor new_slide,
+	                               Clutter.Group stack_container, uint length)
+	{
+		// TODO: make this transition not a total hack
+		((Clutter.Container)get_parent()).raise_child(this, new_slide);
+
+		switch (slide.variant)
+		{
+			case "Top":
+				new_slide.y = slide.parent.height;
+				animate(EASE_SLIDE, length, "y", -new_slide.y);
+				new_slide.y = 0;
 				break;
+			case "Bottom":
+				new_slide.y = -slide.parent.height;
+				animate(EASE_SLIDE, length, "y", -new_slide.y);
+				new_slide.y = 0;
+				break;
+			case "Left":
+				new_slide.x = slide.parent.width;
+				this.animate(EASE_SLIDE, length, "x", -new_slide.x);
+				new_slide.x = 0;
+				break;
+			case "Right":
+				new_slide.x = -slide.parent.width;
+				animate(EASE_SLIDE, length, "x", -new_slide.x);
+				new_slide.x = 0;
+				break;
+		}
+	}
+
+	private void fall_transition(SlideActor new_slide,
+	                             Clutter.Group stack_container, uint length)
+	{
+		depth = 1;
+
+		animation_alpha = new Clutter.Alpha.full(animation_time,
+		                                   Clutter.AnimationMode.EASE_IN_QUART);
+		animation_time.new_frame.connect((m) => {
+			set_rotation(Clutter.RotateAxis.X_AXIS,
+			             -90 * animation_alpha.alpha,
+			             0, slide.parent.height, 0);
+		});
+	}
+
+	private void slats_transition(SlideActor new_slide,
+	                              Clutter.Group stack_container, uint length)
+	{
+		// hide the real SlideActors
+		reparent(stack_container);
+		new_slide.reparent(stack_container);
+		x = slide.parent.width;
+		new_slide.x = slide.parent.width;
+
+		// make arrays for the slats
+		var this_slats = new Clutter.Clone[SLAT_COUNT];
+		var new_slats = new Clutter.Clone[SLAT_COUNT];
+		var groups = new Clutter.Group[SLAT_COUNT];
+
+		// calculate the width of each slat
+		float width = (float)slide.parent.width / SLAT_COUNT;
+
+		// make the slats
+		for (int i = 0; i < SLAT_COUNT; i++)
+		{
+			// create groups
+			groups[i] = new Clutter.Group();
+			stack_container.add_actor(groups[i]);
+
+			// create clones
+			this_slats[i] = new Clutter.Clone(this);
+			groups[i].add_actor(this_slats[i]);
+			new_slats[i] = new Clutter.Clone(new_slide);
+			groups[i].add_actor(new_slats[i]);
+
+			// clip clones
+			this_slats[i].set_clip(width * i, 0,
+			                       width, slide.parent.height);
+			new_slats[i].set_clip(width * i, 0,
+			                      width, slide.parent.height);
+
+			// flip the back slats
+			new_slats[i].set_rotation(Clutter.RotateAxis.Y_AXIS,
+			                          180, width / 2, 0, 0);
+
+			// place the new slats behind the current ones
+			new_slats[i].depth = 5;
+		}
+
+		// make an alpha for easing
+		animation_alpha = new Clutter.Alpha.full(animation_time,
+		                        Clutter.AnimationMode.EASE_IN_OUT_BACK);
+
+		// animate
+		animation_time.new_frame.connect((m) => {
+			for (int i = 0; i < SLAT_COUNT; i++)
+			{
+				groups[i].set_rotation(Clutter.RotateAxis.Y_AXIS,
+					              180 * animation_alpha.alpha,
+					              (i + 0.5f) * width, 0, 0);
+			}
+		});
+
+		animation_time.completed.connect(() => {
+			// clean up the slats
+			for (int i = 0; i < SLAT_COUNT; i++)
+			{
+				stack_container.remove_actor(groups[i]);
+			}
+
+			// put the new slide in place
+			new_slide.x = 0;
+		});
+	}
+
+	private void open_door_transition(SlideActor new_slide,
+	                                  Clutter.Group stack_container,
+	                                  uint length)
+	{
+		// zoom the new slide in
+		new_slide.depth = OPEN_DEPTH;
+		new_slide.animate(Clutter.AnimationMode.EASE_OUT_SINE,
+		                  length, "depth", 0);
+
+		animate(Clutter.AnimationMode.LINEAR, length, "opacity", 0);
+		reparent(stack_container);
+		x = slide.parent.width;
+
+		// create left and right half clone actors
+		float width = slide.parent.width / 2f;
+		Clutter.Clone left = new Clutter.Clone(this),
+		              right = new Clutter.Clone(this);
+
+		left.set_clip(0, 0, width, slide.parent.height);
+		right.set_clip(width, 0, width, slide.parent.height);
+
+		// add the left and right actors
+		stack_container.add_actor(left);
+		stack_container.add_actor(right);
+
+		// move the left and right sides outwards
+		left.animate(Clutter.AnimationMode.EASE_IN_OUT_SINE,
+		             length / 2, "x", left.x - width * OPEN_MOVE);
+
+		right.animate(Clutter.AnimationMode.EASE_IN_OUT_SINE,
+		              length / 2, "x", right.x + width * OPEN_MOVE);
+
+		// animate the angles of the left and right sides
+		time1 = new Clutter.Timeline((int)(OPEN_TIME * length));
+		animation_alpha = new Clutter.Alpha.full(time1,
+		                            Clutter.AnimationMode.EASE_IN_SINE);
+
+		time1.new_frame.connect((m) => {
+			left.set_rotation(Clutter.RotateAxis.Y_AXIS,
+			                  180 * animation_alpha.alpha,
+			                  0, 0, 0);
+
+			right.set_rotation(Clutter.RotateAxis.Y_AXIS,
+			                   -180 * animation_alpha.alpha,
+			                   width * 2, 0, 0);
+		});
+
+		// clean up
+		time1.completed.connect(() => {
+			stack_container.remove_actor(left);
+			stack_container.remove_actor(right);
+		});
+
+		time1.start();
+	}
+
+	private void zoom_transition(SlideActor new_slide,
+	                             Clutter.Group stack_container, uint length)
+	{
+		switch (slide.variant)
+		{
+			case "Center":
+				new_slide.set_scale_full(0, 0,
+				                         slide.parent.width / 2,
+				                         slide.parent.height / 2);
+				break;
+			case "Top Left":
+				new_slide.set_scale_full(0, 0, 0, 0);
+				break;
+			case "Top Right":
+				new_slide.set_scale_full(0, 0, slide.parent.width, 0);
+				break;
+			case "Bottom Left":
+				new_slide.set_scale_full(0, 0, 0, slide.parent.height);
+				break;
+			case "Bottom Right":
+				new_slide.set_scale_full(0, 0,
+				                         slide.parent.width,
+				                         slide.parent.height);
+				break;
+		}
+		animation_alpha = new Clutter.Alpha.full(animation_time,
+		                                   Clutter.AnimationMode.EASE_OUT_SINE);
+		animation_time.new_frame.connect((m) => {
+			new_slide.set_scale(animation_alpha.alpha, animation_alpha.alpha);
+		});
+		//new_slide.animate(Clutter.AnimationMode.EASE_OUT_SINE, length, "scale_x", 1);
+		//new_slide.animate(Clutter.AnimationMode.EASE_OUT_SINE, length, "scale_y", 1);
+	}
+
+	private void panel_transition(SlideActor new_slide,
+	                              Clutter.Group stack_container, uint length)
+	{
+		float pos = 0;
+		string property="";
+		
+		switch (slide.variant)
+		{
+			case "Up":
+				pos = slide.parent.height;
+				property = "y";
+				break;
+			case "Down":
+				pos = -slide.parent.height;
+				property = "y";
+				break;
+			case "Left":
+				pos = slide.parent.width;
+				property = "x";
+				break;
+			default:
+				pos = -slide.parent.width;
+				property = "x";
+				break;
+		}
+
+		time1 = new Clutter.Timeline(length / 4);
+		time2 = new Clutter.Timeline(3 * length / 4);
+		new_slide.set_scale_full(ZOOM_OUT_SCALE, ZOOM_OUT_SCALE,
+		                         slide.parent.width / 2,
+		                         slide.parent.height / 2);
+
+		new_slide.set_property(property, pos);
+		alpha1 = new Clutter.Alpha.full(time1,
+		                                Clutter.AnimationMode.EASE_IN_OUT_SINE);
+
+		time1.new_frame.connect((m) => {
+			set_scale_full(ZOOM_OUT_SCALE + (1 - ZOOM_OUT_SCALE) *
+			                                (1 - alpha1.alpha),
+			               ZOOM_OUT_SCALE + (1 - ZOOM_OUT_SCALE) *
+			                                (1 - alpha1.alpha),
+				           slide.parent.width / 2, slide.parent.height / 2);
+		});
+		time1.completed.connect(() => {
+			animate(Clutter.AnimationMode.EASE_IN_OUT_SINE, length / 2,
+			        property, -pos);
 			
-			case "Panel":
-				switch (slide.variant)
-				{
-					case "Up":
-						xpos = slide.parent.height;
-						property = "y";
-						break;
-					case "Down":
-						xpos = -slide.parent.height;
-						property = "y";
-						break;
-					case "Left":
-						xpos = slide.parent.width;
-						property = "x";
-						break;
-					case "Right":
-						xpos = -slide.parent.width;
-						property = "x";
-						break;
-				}
-			
-				time1 = new Clutter.Timeline(length / 4);
-				time2 = new Clutter.Timeline(3 * length / 4);
-				new_slide.set_scale_full(ZOOM_OUT_SCALE, ZOOM_OUT_SCALE, slide.parent.width / 2, slide.parent.height / 2);
-				new_slide.set_property(property, xpos);
-				alpha1 = new Clutter.Alpha.full(time1, Clutter.AnimationMode.EASE_IN_OUT_SINE);
+			new_slide.animate(Clutter.AnimationMode.EASE_IN_OUT_SINE,
+			                  length / 2, property, 0.0f);
+		});
+		time2.completed.connect(() => {
+			time1.new_frame.connect((m) => {
+				new_slide.set_scale_full(ZOOM_OUT_SCALE + (1 - ZOOM_OUT_SCALE) * alpha1.alpha,
+					                         ZOOM_OUT_SCALE + (1 - ZOOM_OUT_SCALE) * alpha1.alpha,
+					                         slide.parent.width / 2,
+					                         slide.parent.height / 2);
+			});
+			time1.start();
+		});
+		time1.start();
+		time2.start();
+	}
+
+	private void spin_contents_transition(SlideActor new_slide,
+	                                      Clutter.Group stack_container,
+	                                      uint length)
+	{
+		prepare_stack_transition(false, new_slide, stack_container);
+
+		new_slide.contents.opacity = 0;
+		background.animate(Clutter.AnimationMode.EASE_IN_OUT_SINE, length,
+		                   "opacity", 0);
+		time1 = new Clutter.Timeline(length / 2);
+		time2 = new Clutter.Timeline(length / 2);
+		alpha1 = new Clutter.Alpha.full(time1,
+		                                Clutter.AnimationMode.EASE_IN_SINE);
+
+		alpha2 = new Clutter.Alpha.full(time2,
+		                                Clutter.AnimationMode.EASE_OUT_SINE);
+
+		float angle = slide.variant == "Left" ? -90 : 90;
+		time1.completed.connect(() => {
+			contents.opacity = 0;
+			time2.start();
+		});
+		time1.new_frame.connect((m) => {
+			contents.set_rotation(Clutter.RotateAxis.Y_AXIS,
+			                      angle * alpha1.alpha,
+			                      slide.parent.width / 2, 0, 0);
+		});
+		time2.new_frame.connect((m) => {
+			new_slide.contents.opacity = 255;
+			new_slide.contents.set_rotation(Clutter.RotateAxis.Y_AXIS,
+			                                -angle * (1 - alpha2.alpha),
+			                                 slide.parent.width / 2, 0, 0);
+		});
+		time1.start();
+	}
+
+	private void swing_contents_transition(SlideActor new_slide,
+	                                       Clutter.Group stack_container,
+	                                       uint length)
+	{
+		prepare_stack_transition(false, new_slide, stack_container);
+
+		new_slide.contents.opacity = 0;
+		background.animate(Clutter.AnimationMode.EASE_IN_OUT_SINE,
+		                   length, "opacity", 0);
+		alpha1 = new Clutter.Alpha.full(animation_time,
+		                                Clutter.AnimationMode.EASE_IN_SINE);
+		                                
+		alpha2 = new Clutter.Alpha.full(animation_time,
+		                                Clutter.AnimationMode.EASE_OUT_SINE);
+		                                
+		animation_alpha = new Clutter.Alpha.full(animation_time,
+		                                         Clutter.AnimationMode.LINEAR);
+		
+		animation_time.new_frame.connect((m) => {
+			unowned GLib.List<Clutter.Actor>* itr;
+			contents.opacity = clamp_opacity(455 - 555 * alpha1.alpha);
+			new_slide.contents.opacity = clamp_opacity(-100 + 400 * alpha2.alpha);
 			
-				time1.new_frame.connect((m) => {
-					set_scale_full(ZOOM_OUT_SCALE + (1 - ZOOM_OUT_SCALE) * (1 - alpha1.alpha),
-						                     ZOOM_OUT_SCALE + (1 - ZOOM_OUT_SCALE) * (1 - alpha1.alpha),
-						                     slide.parent.width / 2,
-						                     slide.parent.height / 2);
-				});
-				time1.completed.connect(() => {
-					animate(Clutter.AnimationMode.EASE_IN_OUT_SINE, length / 2, property, -xpos);
-					new_slide.animate(Clutter.AnimationMode.EASE_IN_OUT_SINE, length / 2, property, 0.0f);
+			for (itr = contents.get_children(); itr != null; itr = itr->next)
+			{
+				((Actor*)itr->data)->set_rotation(Clutter.RotateAxis.X_AXIS,
+				                                  540 * alpha1.alpha,
+				                                  0, 0, 0);
+			}
+			for (itr = new_slide.contents.get_children(); itr != null; itr = itr->next)
+			{
+				((Actor*)itr->data)->set_rotation(Clutter.RotateAxis.X_AXIS,
+				                                  -540 * (1 - alpha2.alpha),
+				                                  0, 0, 0);
+			}
+		});
+	}
+
+	private void slide_contents_transition(SlideActor new_slide,
+	                                       Clutter.Group stack_container,
+	                                       uint length)
+	{
+		prepare_stack_transition(false, new_slide, stack_container);
+
+		background.animate(Clutter.AnimationMode.EASE_IN_OUT_SINE,
+		                   length, "opacity", 0);
+		
+		switch (slide.variant)
+		{
+			case "Right":
+				new_slide.contents.x = -slide.parent.width;
+				new_slide.contents.animate(Clutter.AnimationMode.EASE_IN_OUT_SINE,
+				                           length, "x", 0);
+
+				contents.animate(Clutter.AnimationMode.EASE_IN_OUT_SINE,
+				                 length, "x", -new_slide.contents.x);
+				break;
+			case "Left":
+				new_slide.contents.x = slide.parent.width;
+				new_slide.contents.animate(Clutter.AnimationMode.EASE_IN_OUT_SINE,
+				                           length, "x", 0);
+
+				contents.animate(Clutter.AnimationMode.EASE_IN_OUT_SINE,
+				                 length, "x", -new_slide.contents.x);
+				break;
+			case "Up":
+				new_slide.contents.y = slide.parent.height;
+				new_slide.contents.animate(Clutter.AnimationMode.EASE_IN_OUT_SINE,
+				                           length, "y", 0);
+
+				contents.animate(Clutter.AnimationMode.EASE_IN_OUT_SINE,
+				                 length, "y", -new_slide.contents.y);
+				break;
+			case "Down":
+				new_slide.contents.y = -slide.parent.height;
+				new_slide.contents.animate(Clutter.AnimationMode.EASE_IN_OUT_SINE,
+				                           length, "y", 0);
+
+				contents.animate(Clutter.AnimationMode.EASE_IN_OUT_SINE, length,
+				                 "y", -new_slide.contents.y);
+				break;
+		}
+	}
+
+	private void spring_contents_transition(SlideActor new_slide,
+	                                        Clutter.Group stack_container,
+	                                        uint length)
+	{
+		prepare_stack_transition(false, new_slide, stack_container);
+
+		background.animate(Clutter.AnimationMode.EASE_IN_OUT_SINE, length,
+		                   "opacity", 0);
+
+		switch (slide.variant)
+		{
+			case "Up":
+				new_slide.contents.y = slide.parent.height * 1.2f;
+				new_slide.contents.animate(Clutter.AnimationMode.EASE_IN_OUT_ELASTIC,
+				                           length, "y", 0);
+				contents.animate(Clutter.AnimationMode.EASE_IN_OUT_ELASTIC,
+				                 length, "y", -slide.parent.height * 1.2);
+				break;
+			case "Down":
+				new_slide.contents.y = -slide.parent.height * 1.2f;
+				new_slide.contents.animate(Clutter.AnimationMode.EASE_IN_OUT_ELASTIC,
+				                           length, "y", 0);
+				contents.animate(Clutter.AnimationMode.EASE_IN_OUT_ELASTIC,
+				                 length, "y", slide.parent.height * 1.2);
+				break;
+		}
+	}
+
+	private void zoom_contents_transition(SlideActor new_slide,
+	                                      Clutter.Group stack_container,
+	                                      uint length)
+	{
+		prepare_stack_transition(slide.variant == "Out",
+		                         new_slide, stack_container);
+
+		animation_alpha = new Clutter.Alpha.full(animation_time,
+		                                Clutter.AnimationMode.EASE_IN_OUT_SINE);
+
+		background.animate(Clutter.AnimationMode.LINEAR, length, "opacity", 0);
+		switch (slide.variant)
+		{
+			case "In":
+				new_slide.contents.set_scale_full(0, 0,
+				                                  slide.parent.width / 2,
+				                                  slide.parent.height / 2);
+
+				contents.set_scale_full(1, 1,
+				                        slide.parent.width / 2,
+				                        slide.parent.height / 2);
+
+				contents.animate(Clutter.AnimationMode.LINEAR, length / 2, "opacity", 0);
+				animation_time.new_frame.connect((m) => {
+					new_slide.contents.set_scale(animation_alpha.alpha,
+					                             animation_alpha.alpha);
+
+					contents.set_scale(1.0 + 2 * animation_alpha.alpha,
+					   	               1.0 + 2 * animation_alpha.alpha);
 				});
-				time2.completed.connect(() => {
-					time1.new_frame.connect((m) => {
-						new_slide.set_scale_full(ZOOM_OUT_SCALE + (1 - ZOOM_OUT_SCALE) * alpha1.alpha,
-							                         ZOOM_OUT_SCALE + (1 - ZOOM_OUT_SCALE) * alpha1.alpha,
-							                         slide.parent.width / 2,
-							                         slide.parent.height / 2);
-					});
-					time1.start();
+				break;
+			case "Out":
+				new_slide.contents.set_scale_full(0, 0,
+				                                  slide.parent.width / 2,
+				                                  slide.parent.height / 2);
+
+				contents.set_scale_full(1, 1,
+				                        slide.parent.width / 2,
+				                        slide.parent.height / 2);
+
+				new_slide.contents.opacity = 0;
+				new_slide.contents.animate(Clutter.AnimationMode.EASE_IN_SINE,
+				                           length / 2, "opacity", 255);
+				animation_time.new_frame.connect((m) => {
+					new_slide.contents.set_scale(1.0 + 2 * (1 - animation_alpha.alpha),
+						                         1.0 + 2 * (1 - animation_alpha.alpha));
+					contents.set_scale(1 - animation_alpha.alpha,
+					   	               1 - animation_alpha.alpha);
 				});
-				time1.start();
-				time2.start();
 				break;
 		}
 	}
-	
+
 	private double min(double a, double b)
 	{
 		return a > b ? b : a;
 	}
-	
+
 	private double max(double a, double b)
 	{
 		return a > b ? a : b;
 	}
-	
+
 	private uint8 clamp_opacity(double o)
 	{
 		return (uint8)(max(0, min(255, o)));



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]