[ease] [editor] Allow the user to reorder Elements.



commit bbb015bd87e2980ece6578839597461b9ce95fc9
Author: Nate Stedman <natesm gmail com>
Date:   Wed Jul 28 21:42:23 2010 -0400

    [editor] Allow the user to reorder Elements.

 data/ui/editor-window.ui                 |   39 ++++++++++++++-
 ease-core/ease-slide.vala                |   81 +++++++++++++++++++++++++++++-
 ease-core/ease-undo-actions-element.vala |   56 ++++++++++++++++++++-
 ease-core/ease-undo-controller.vala      |    2 +
 src/ease-editor-window.vala              |   28 ++++++++++
 src/ease-slide-actor.vala                |   29 ++++++++---
 6 files changed, 224 insertions(+), 11 deletions(-)
---
diff --git a/data/ui/editor-window.ui b/data/ui/editor-window.ui
index 06b27ed..57c6b9e 100644
--- a/data/ui/editor-window.ui
+++ b/data/ui/editor-window.ui
@@ -174,6 +174,43 @@
                     <signal name="activate" handler="ease_editor_window_on_delete"/>
                   </object>
                 </child>
+                <child>
+                  <object class="GtkSeparatorMenuItem" id="separatormenuitem2">
+                    <property name="visible">True</property>
+                  </object>
+                </child>
+                <child>
+                  <object class="GtkMenuItem" id="raise">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">_Raise</property>
+                    <property name="use_underline">True</property>
+                    <signal name="activate" handler="ease_editor_window_on_raise"/>
+                  </object>
+                </child>
+                <child>
+                  <object class="GtkMenuItem" id="lower">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">_Lower</property>
+                    <property name="use_underline">True</property>
+                    <signal name="activate" handler="ease_editor_window_on_lower"/>
+                  </object>
+                </child>
+                <child>
+                  <object class="GtkMenuItem" id="raise-top">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">Raise to _Top</property>
+                    <property name="use_underline">True</property>
+                    <signal name="activate" handler="ease_editor_window_on_raise_top"/>
+                  </object>
+                </child>
+                <child>
+                  <object class="GtkMenuItem" id="lower-bottom">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">Lower to _Bottom</property>
+                    <property name="use_underline">True</property>
+                    <signal name="activate" handler="ease_editor_window_on_lower_bottom"/>
+                  </object>
+                </child>
               </object>
             </child>
           </object>
@@ -199,6 +236,7 @@
                     <property name="visible">True</property>
                     <property name="label" translatable="yes">_Video</property>
                     <property name="use_underline">True</property>
+                    <signal name="activate" handler="ease_editor_window_insert_video"/>
                   </object>
                 </child>
                 <child>
@@ -244,7 +282,6 @@
             <property name="visible">True</property>
             <property name="label" translatable="yes">_View</property>
             <property name="use_underline">True</property>
-            <signal name="activate" handler="ease_editor_window_insert_video"/>
             <child type="submenu">
               <object class="GtkMenu" id="menu3">
                 <property name="visible">True</property>
diff --git a/ease-core/ease-slide.vala b/ease-core/ease-slide.vala
index 22dfb13..5a1740c 100644
--- a/ease-core/ease-slide.vala
+++ b/ease-core/ease-slide.vala
@@ -29,7 +29,7 @@ public class Ease.Slide : GLib.Object, UndoSource
 	/**
 	 * The { link Element}s contained by this Slide
 	 */
-	internal Gee.ArrayList<Element> elements = new Gee.ArrayList<Element>();
+	internal Gee.LinkedList<Element> elements = new Gee.LinkedList<Element>();
 	
 	/**
 	 * The Slide's transition
@@ -174,6 +174,11 @@ public class Ease.Slide : GLib.Object, UndoSource
 	public signal void element_removed(Slide self, Element element, int index);
 	
 	/**
+	 * Emitted when an { link Element} is repositioned.
+	 */
+	public signal void element_reordered(Slide self, Element element);
+	
+	/**
 	 * Create a new Slide.
 	 */
 	public Slide()
@@ -387,6 +392,80 @@ public class Ease.Slide : GLib.Object, UndoSource
 		return elements.get(i);
 	}
 	
+	/**
+	 * Raises the given element up one index. Automatically sends an
+	 * { link UndoItem}.
+	 */
+	public void raise(Element element)
+	{
+		if (element == elements.last()) return;
+		
+		var index = elements.index_of(element);
+		var temp = elements.get(index + 1);
+		elements.set(index + 1, element);
+		elements.set(index, temp);
+		element_reordered(this, element);
+		undo(new ElementReorderUndoAction(element, index, index + 1));
+	}
+	
+	/**
+	 * Lowers the given element down one index. Automatically sends an
+	 * { link UndoItem}.
+	 */
+	public void lower(Element element)
+	{
+		if (element == elements.first()) return;
+		
+		var index = elements.index_of(element);
+		var temp = elements.get(index - 1);
+		elements.set(index - 1, element);
+		elements.set(index, temp);
+		element_reordered(this, element);
+		undo(new ElementReorderUndoAction(element, index, index - 1));
+	}
+	
+	/**
+	 * Raises the element to the top. Automatically sends an
+	 * { link UndoItem}.
+	 */
+	public void raise_top(Element element)
+	{
+		if (element == elements.last()) return;
+		
+		var index = elements.index_of(element);
+		elements.remove(element);
+		elements.offer_tail(element);
+		element_reordered(this, element);
+		undo(new ElementReorderUndoAction(element, index,
+		                                  elements.index_of(element)));
+	}
+	
+	/**
+	 * Lowers the element to the bottom. Automatically sends an
+	 * { link UndoItem}.
+	 */
+	public void lower_bottom(Element element)
+	{
+		if (element == elements.first()) return;
+		
+		var index = elements.index_of(element);
+		elements.remove(element);
+		elements.offer_head(element);
+		element_reordered(this, element);
+		undo(new ElementReorderUndoAction(element, index,
+		                                  elements.index_of(element)));
+	}
+	
+	/**
+	 * Reorders an Element. Does not create an { link UndoItem}.
+	 */
+	internal void reorder(Element element, int current, int target)
+	{
+		elements.remove(element);
+		elements.insert(target, element);
+		element_reordered(this, element);
+	}
+	
 	/** 
 	 * Draws the { link Slide} to a Cairo.Context.
 	 *
diff --git a/ease-core/ease-undo-actions-element.vala b/ease-core/ease-undo-actions-element.vala
index 96f0061..39e7bb2 100644
--- a/ease-core/ease-undo-actions-element.vala
+++ b/ease-core/ease-undo-actions-element.vala
@@ -38,7 +38,7 @@ public class Ease.ElementAddUndoAction : UndoItem
 	/**
 	 * Applies the action, removing the { link Element}.
 	 */
-	public override UndoItem apply()
+	internal override UndoItem apply()
 	{
 		var action = new ElementRemoveUndoAction(element);
 		element.parent.remove_element(element);
@@ -83,11 +83,63 @@ public class Ease.ElementRemoveUndoAction : UndoItem
 	/**
 	 * Applies the action, restoring the { link Element}.
 	 */
-	public override UndoItem apply()
+	internal override UndoItem apply()
 	{
 		slide.add_element(index, element);
 		return new ElementAddUndoAction(element);
 	}
 }
 
+internal class Ease.ElementReorderUndoAction : UndoItem
+{
+	/**
+	 * The { link Element} that was reordered.
+	 */
+	private Element element;
+	
+	/**
+	 * The { link Slide} that the Element was reordered on.
+	 */
+	private Slide slide;
+	
+	/**
+	 * The original index of the Element.
+	 */
+	private int index_orig;
+	
+	/**
+	 * The new index of the Element.
+	 */
+	private int index_current;
+	
+	/**
+	 * Creates an ElementReorderUndoAction.
+	 *
+	 * @param e The element that was added.
+	 * @param orig The original index of the element.
+	 * @param current The new index of the element.
+	 */
+	internal ElementReorderUndoAction(Element e, int orig, int current)
+	{
+		element = e;
+		slide = e.parent;
+		index_orig = orig;
+		index_current = current;
+	}
+	
+	/**
+	 * Applies the action, restoring the { link Element}.
+	 */
+	internal override UndoItem apply()
+	{
+		slide.reorder(element, index_current, index_orig);
+		
+		// swap the indicies, return the same undoitem
+		var temp = index_current;
+		index_orig = index_current;
+		index_current = temp;
+		
+		return this;
+	}
+}
 
diff --git a/ease-core/ease-undo-controller.vala b/ease-core/ease-undo-controller.vala
index 45492bf..96fe220 100644
--- a/ease-core/ease-undo-controller.vala
+++ b/ease-core/ease-undo-controller.vala
@@ -84,6 +84,7 @@ public class Ease.UndoController : Object
 	 */
 	public void add_action(UndoItem action)
 	{
+		debug("adding an action");
 		undos.offer_head(action);
 	}
 	
@@ -94,6 +95,7 @@ public class Ease.UndoController : Object
 	 */
 	private void add_redo_action(UndoItem action)
 	{
+		debug("adding a redo action");
 		redos.offer_head(action);
 	}
 }
diff --git a/src/ease-editor-window.vala b/src/ease-editor-window.vala
index 7577ecf..4168897 100644
--- a/src/ease-editor-window.vala
+++ b/src/ease-editor-window.vala
@@ -516,6 +516,34 @@ public class Ease.EditorWindow : Gtk.Window
 	}
 	
 	[CCode (instance_pos = -1)]
+	public void on_lower(Gtk.Widget sender)
+	{
+		if (embed.selected == null) return;
+		slide.lower(embed.selected.element);
+	}
+	
+	[CCode (instance_pos = -1)]
+	public void on_raise(Gtk.Widget sender)
+	{
+		if (embed.selected == null) return;
+		slide.raise(embed.selected.element);
+	}
+	
+	[CCode (instance_pos = -1)]
+	public void on_lower_bottom(Gtk.Widget sender)
+	{
+		if (embed.selected == null) return;
+		slide.lower_bottom(embed.selected.element);
+	}
+	
+	[CCode (instance_pos = -1)]
+	public void on_raise_top(Gtk.Widget sender)
+	{
+		if (embed.selected == null) return;
+		slide.raise_top(embed.selected.element);
+	}
+	
+	[CCode (instance_pos = -1)]
 	public void inspector_clicked_handler(Gtk.Widget? sender)
 	{	
 		if (inspector.visible)
diff --git a/src/ease-slide-actor.vala b/src/ease-slide-actor.vala
index 28f4dd9..ac4de7b 100644
--- a/src/ease-slide-actor.vala
+++ b/src/ease-slide-actor.vala
@@ -197,6 +197,8 @@ public class Ease.SlideActor : Clutter.Group
 		
 		slide.element_added.connect(on_element_added);
 		slide.element_removed.connect(on_element_removed);
+		
+		slide.element_reordered.connect((s, e) => reorder());
 	}
 	
 	/**
@@ -230,13 +232,7 @@ public class Ease.SlideActor : Clutter.Group
 		contents.lower_child(actor, null);
 		
 		// raise the actor to its proper position
-		int i = 0;
-		Clutter.Actor raise;
-		foreach (var a in contents)
-		{
-			if (i >= index) break;
-			raise = a;
-		}
+		reorder();
 		
 		ease_actor_added(actor as Actor);
 	}
@@ -327,6 +323,25 @@ public class Ease.SlideActor : Clutter.Group
 		background.width = width_px;
 		background.height = height_px;
 	}
+	
+	/**
+	 * Places all { link Element}s of this SlideActor in the proper order.
+	 */
+	private void reorder()
+	{
+		// TODO: not do this in such an inefficient way
+		foreach (var e in slide)
+		{
+			foreach (var a in contents)
+			{
+				if ((a as Actor).element == e)
+				{
+					a.raise_top();
+					break;
+				}
+			}
+		}
+	}
 
 	/**
 	 * Places all child elements of this slide back into the SlideActor.



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