[ease] Transition previews in the inspector.
- From: Nate Stedman <natesm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [ease] Transition previews in the inspector.
- Date: Wed, 2 Jun 2010 21:37:05 +0000 (UTC)
commit 54bcaf2318a89027a0cd1b2e884b9278800c90f8
Author: Nate Stedman <natesm gmail com>
Date: Wed Jun 2 17:36:57 2010 -0400
Transition previews in the inspector.
src/Document.vala | 18 ++++++++
src/Slide.vala | 45 +++++++++++++++++++++
src/SlideActor.vala | 54 ++++++++++++++++++++++++-
src/TransitionPane.vala | 102 ++++++++++++++++++++++++++++++++++++++++++-----
4 files changed, 207 insertions(+), 12 deletions(-)
---
diff --git a/src/Document.vala b/src/Document.vala
index 87eaec9..101c5f4 100644
--- a/src/Document.vala
+++ b/src/Document.vala
@@ -74,6 +74,24 @@ public class Ease.Document : GLib.Object
slides.insert(index, s);
}
+ /**
+ * Returns whether or not the Document has a { link Slide} after the
+ * passed in { link Slide}.
+ *
+ * @param slide
+ */
+ public bool has_next_slide(Slide slide)
+ {
+ for (int i = 0; i < slides.size - 1; i++)
+ {
+ if (slides.get(i) == slide)
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
public void export_to_html(Gtk.Window window)
{
// make an HTMLExporter
diff --git a/src/Slide.vala b/src/Slide.vala
index 5a3350a..ae72741 100644
--- a/src/Slide.vala
+++ b/src/Slide.vala
@@ -45,6 +45,15 @@ public class Ease.Slide
public double transition_time { get; set; }
/**
+ * The duration of this Slide's transition, in milliseconds
+ */
+ public uint transition_msecs
+ {
+ get { return (uint)(transition_time * 1000); }
+ set { transition_time = value / 1000f; }
+ }
+
+ /**
* If the slide advances automatically or on key press
*/
public bool automatically_advance { get; set; }
@@ -83,6 +92,42 @@ public class Ease.Slide
public int count { get { return elements.size; } }
/**
+ * The next Slide in this Slide's { link Document}.
+ */
+ public Slide? next
+ {
+ owned get
+ {
+ for (int i = 0; i < parent.slides.size - 1; i++)
+ {
+ if (parent.slides.get(i) == this)
+ {
+ return parent.slides.get(i + 1);
+ }
+ }
+ return null;
+ }
+ }
+
+ /**
+ * The previous Slide in this Slide's { link Document}.
+ */
+ public Slide? previous
+ {
+ owned get
+ {
+ for (int i = 1; i < parent.slides.size; i++)
+ {
+ if (parent.slides.get(i) == this)
+ {
+ return parent.slides.get(i - 1);
+ }
+ }
+ return null;
+ }
+ }
+
+ /**
* Create a new Slide.
*/
public Slide() {}
diff --git a/src/SlideActor.vala b/src/SlideActor.vala
index a476367..e9b9565 100644
--- a/src/SlideActor.vala
+++ b/src/SlideActor.vala
@@ -63,7 +63,7 @@ public class Ease.SlideActor : Clutter.Group
private const int REFLECTION_OPACITY = 70;
public SlideActor.from_slide(Document document, Slide s, bool clip,
- ActorContext ctx)
+ ActorContext ctx)
{
slide = s;
context = ctx;
@@ -98,7 +98,53 @@ public class Ease.SlideActor : Clutter.Group
add_actor(contents);
}
-
+
+ /**
+ * Instantiates a SlideActor of a single color. Used for transition previews
+ * with no "next" slide.
+ *
+ * @param document The { link Document} this slide is "part of", to make it
+ * the proper size.
+ * @param color The background color.
+ */
+ public SlideActor.blank(Document document, Clutter.Color color)
+ {
+ // create the background
+ background = new Clutter.Rectangle();
+ ((Clutter.Rectangle)background).color = color;
+
+ // create a blank contents actor
+ contents = new Clutter.Group();
+
+ // set the background size
+ background.width = document.width;
+ background.height = document.height;
+ }
+
+ /**
+ * Resets all transformations on this SlideActor.
+ */
+ public void reset(Clutter.Group container)
+ {
+ reset_actor(this);
+ reset_actor(background);
+ reset_actor(contents);
+ stack(container);
+ }
+
+ private void reset_actor(Clutter.Actor actor)
+ {
+ actor.depth = 0;
+ actor.opacity = 255;
+ actor.rotation_angle_x = 0;
+ actor.rotation_angle_y = 0;
+ actor.rotation_angle_z = 0;
+ actor.scale_x = 1;
+ actor.scale_y = 1;
+ actor.x = 0;
+ actor.y = 0;
+ }
+
public void relayout()
{
set_background();
@@ -159,6 +205,10 @@ public class Ease.SlideActor : Clutter.Group
{
contents.reparent(this);
}
+ if (get_parent() != container)
+ {
+ reparent(container);
+ }
}
// unstack the actor, layering it with another actor
diff --git a/src/TransitionPane.vala b/src/TransitionPane.vala
index 9729879..a503d41 100644
--- a/src/TransitionPane.vala
+++ b/src/TransitionPane.vala
@@ -29,12 +29,16 @@ public class Ease.TransitionPane : InspectorPane
private Gtk.SpinButton delay;
// transition preview
- private Gtk.AspectFrame aspect;
private GtkClutter.Embed preview;
+ private Clutter.Group preview_group;
private Gtk.Alignment preview_align;
private SlideActor current_slide;
private SlideActor new_slide;
+ private Clutter.Timeline preview_alarm;
+
+ // constants
private const int PREVIEW_HEIGHT = 150;
+ private const uint PREVIEW_DELAY = 500;
public TransitionPane()
{
@@ -42,12 +46,17 @@ public class Ease.TransitionPane : InspectorPane
// preview
preview = new GtkClutter.Embed();
- preview.set_size_request(0, PREVIEW_HEIGHT);
((Clutter.Stage)(preview.get_stage())).color = {0, 0, 0, 255};
- aspect = new Gtk.AspectFrame("", 0.5f, 0.5f, 0.5f, false);
- aspect.add(preview);
- aspect.shadow_type = Gtk.ShadowType.IN;
- pack_start(aspect, false, false, 5);
+
+ preview_align = new Gtk.Alignment(0.5f, 0.5f, 1, 1);
+ var frame = new Gtk.Frame(null);
+ frame.shadow_type = Gtk.ShadowType.IN;
+ preview_align.add(preview);
+ frame.add(preview_align);
+
+ pack_start(frame, false, false, 5);
+ preview_group = new Clutter.Group();
+ ((Clutter.Stage)preview.get_stage()).add_actor(preview_group);
// transition selection
var vbox = new Gtk.VBox(false, 0);
@@ -66,7 +75,7 @@ public class Ease.TransitionPane : InspectorPane
vbox.pack_start(align, false, false, 0);
hbox.pack_start(vbox, true, true, 5);
- // transition transition_time
+ // transition time
vbox = new Gtk.VBox(false, 0);
align = new Gtk.Alignment(0, 0, 0, 0);
align.add(new Gtk.Label(_("Duration")));
@@ -177,13 +186,59 @@ public class Ease.TransitionPane : InspectorPane
delay.value_changed.connect(() => {
slide.advance_delay = delay.get_value();
});
+
+ // automatically scale the preview to fit in the embed
+ preview.get_stage().allocation_changed.connect((box, flags) => {
+ preview_group.scale_x = (box.x2 - box.x1) / slide.parent.width;
+ preview_group.scale_y = (box.y2 - box.y1) / slide.parent.height;
+ });
+
+ // automatically set the correct aspect ratio for the preview
+ preview_align.size_allocate.connect((widget, allocation) => {
+ if (slide == null) return;
+
+ preview_align.height_request =
+ (int)(allocation.width / slide.parent.aspect);
+ });
}
- protected override void slide_updated()
+ private void animate_preview()
+ {
+ current_slide.reset(preview_group);
+ new_slide.reset(preview_group);
+ new_slide.opacity = 0;
+
+ preview_alarm = new Clutter.Timeline(PREVIEW_DELAY);
+ preview_alarm.completed.connect(() => {
+ animate_preview_start();
+ });
+ preview_alarm.start();
+ }
+
+ private void animate_preview_start()
+ {
+ new_slide.opacity = 255;
+
+ current_slide.transition(new_slide, preview_group);
+
+ preview_alarm = new Clutter.Timeline(slide.transition_msecs);
+ preview_alarm.completed.connect(() => {
+ animate_preview_delay();
+ });
+ preview_alarm.start();
+ }
+
+ private void animate_preview_delay()
{
- // set preview aspect ratio
- aspect.ratio = (float)slide.parent.width / (float)slide.parent.height;
+ preview_alarm = new Clutter.Timeline(PREVIEW_DELAY);
+ preview_alarm.completed.connect(() => {
+ animate_preview();
+ });
+ preview_alarm.start();
+ }
+ protected override void slide_updated()
+ {
// set transition time box
transition_time.set_value(slide.transition_time);
@@ -195,6 +250,33 @@ public class Ease.TransitionPane : InspectorPane
start_transition.set_active(slide.automatically_advance ? 1 : 0);
delay.set_value(slide.advance_delay);
delay.sensitive = slide.automatically_advance;
+
+ // size the preview box
+ Gtk.Allocation alloc = Gtk.Allocation();
+ preview_align.get_allocation(alloc);
+ preview_align.height_request = (int)(alloc.width / slide.parent.aspect);
+
+ // remove the old preview slide actors
+ preview_group.remove_all();
+
+ // add new slide previews
+ current_slide = new SlideActor.from_slide(slide.parent, slide, true,
+ ActorContext.PRESENTATION);
+
+ new_slide = slide.parent.has_next_slide(slide) ?
+ new SlideActor.from_slide(slide.parent, slide.next, true,
+ ActorContext.PRESENTATION) :
+ new SlideActor.blank(slide.parent, { 0, 0, 0, 255 });
+
+ preview_group.add_actor(current_slide);
+ preview_group.add_actor(new_slide);
+
+ // start the preview animation
+ if (preview_alarm != null)
+ {
+ preview_alarm.stop();
+ }
+ animate_preview();
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]