[ease] [editor] Undo add/remove Elements.
- From: Nate Stedman <natesm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [ease] [editor] Undo add/remove Elements.
- Date: Sun, 25 Jul 2010 08:56:32 +0000 (UTC)
commit 328287cdc8df551d780eebfd073773e7b1da0718
Author: Nate Stedman <natesm gmail com>
Date: Sun Jul 25 04:54:33 2010 -0400
[editor] Undo add/remove Elements.
- Elements can be deleted.
- Element deletion/additon can be undone
- SlideActor and EditorEmbed automatically manage
the addition and removal of Elements.
Makefile.am | 1 +
data/ui/editor-window.ui | 1 +
src/ease-editor-embed.vala | 110 +++++++++++++++++++++++++-----------
src/ease-editor-window.vala | 18 +++++-
src/ease-slide-actor.vala | 50 ++++++++++++++++
src/ease-slide.vala | 50 ++++++++++++++++-
src/ease-undo-actions-element.vala | 93 ++++++++++++++++++++++++++++++
src/ease-undo-item.vala | 2 +-
8 files changed, 285 insertions(+), 40 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index 22683b2..265fc01 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -50,6 +50,7 @@ ease_SOURCES = \
src/ease-transition-pane.vala \
src/ease-transitions.vala \
src/ease-undo-action.vala \
+ src/ease-undo-actions-element.vala \
src/ease-undo-controller.vala \
src/ease-undo-item.vala \
src/ease-undo-source.vala \
diff --git a/data/ui/editor-window.ui b/data/ui/editor-window.ui
index 9827465..8dc114c 100644
--- a/data/ui/editor-window.ui
+++ b/data/ui/editor-window.ui
@@ -154,6 +154,7 @@
<property name="visible">True</property>
<property name="use_underline">True</property>
<property name="use_stock">True</property>
+ <signal name="activate" handler="ease_editor_window_on_delete"/>
</object>
</child>
</object>
diff --git a/src/ease-editor-embed.vala b/src/ease-editor-embed.vala
index 7d8208c..da0cda4 100644
--- a/src/ease-editor-embed.vala
+++ b/src/ease-editor-embed.vala
@@ -249,26 +249,13 @@ public class Ease.EditorEmbed : ScrollableEmbed
a.button_release_event.disconnect(actor_released);
a.reactive = false;
}
+
+ slide_actor.ease_actor_added.disconnect(on_ease_actor_added);
+ slide_actor.ease_actor_removed.disconnect(on_ease_actor_removed);
}
// remove the selection rectangle
- if (selection_rectangle != null)
- {
- if (selection_rectangle.get_parent() == contents)
- {
- contents.remove_actor(selection_rectangle);
- }
- foreach (var h in handles)
- {
- if (h.get_parent() == contents)
- {
- contents.remove_actor(h);
- }
- h.button_press_event.disconnect(handle_clicked);
- h.button_release_event.disconnect(handle_released);
- }
- handles = null;
- }
+ remove_selection_rect();
// create a new SlideActor
slide_actor = new SlideActor.from_slide(document,
@@ -284,9 +271,36 @@ public class Ease.EditorEmbed : ScrollableEmbed
a.reactive = true;
}
+ slide_actor.ease_actor_added.connect(on_ease_actor_added);
+ slide_actor.ease_actor_removed.connect(on_ease_actor_removed);
+
contents.add_actor(slide_actor);
reposition_group();
}
+
+ /**
+ * Removes the selection rectangle and handles.
+ */
+ private void remove_selection_rect()
+ {
+ if (selection_rectangle != null)
+ {
+ if (selection_rectangle.get_parent() == contents)
+ {
+ contents.remove_actor(selection_rectangle);
+ }
+ foreach (var h in handles)
+ {
+ if (h.get_parent() == contents)
+ {
+ contents.remove_actor(h);
+ }
+ h.button_press_event.disconnect(handle_clicked);
+ h.button_release_event.disconnect(handle_released);
+ }
+ handles = null;
+ }
+ }
/**
* Repositions the EditorEmbed's { link SlideActor}.
@@ -314,7 +328,7 @@ public class Ease.EditorEmbed : ScrollableEmbed
? height / 2 - h / 2
: 0);
- if (selection_rectangle != null)
+ if (selection_rectangle != null && selected != null)
{
position_selection();
}
@@ -409,21 +423,8 @@ public class Ease.EditorEmbed : ScrollableEmbed
*/
private void select_actor(Actor sender)
{
- // if editing another Actor, finish that edit
- if (selected != null && is_editing)
- {
- selected.end_edit(this);
- is_editing = false;
- }
-
- // remove the selection rectangle and handles
- if (selection_rectangle != null)
- {
- if (selection_rectangle.get_parent() == contents)
- {
- contents.remove_actor(selection_rectangle);
- }
- }
+ // deselect anything that is currently selected
+ deselect_actor();
selected = sender as Actor;
@@ -453,6 +454,27 @@ public class Ease.EditorEmbed : ScrollableEmbed
}
/**
+ * Deselects the currently selected { link Actor}.
+ *
+ * This method is safe to call if nothing is selected.
+ */
+ private void deselect_actor()
+ {
+ // if editing another Actor, finish that edit
+ if (selected != null && is_editing)
+ {
+ selected.end_edit(this);
+ is_editing = false;
+ }
+
+ // deselect
+ selected = null;
+
+ // remove the selection rectangle and handles
+ remove_selection_rect();
+ }
+
+ /**
* Signal handler for releasing an { link Actor}.
*
* This handler is attached to the button_release_event of all
@@ -639,5 +661,27 @@ public class Ease.EditorEmbed : ScrollableEmbed
if (selected == null) return;
if (!selected.element.set_color(color)) return;
}
+
+ /**
+ * Handles { link SlideActor.on_ease_actor_removed}. Deselects the current
+ * { link Actor} if necessary, and disconnects handlers.
+ */
+ public void on_ease_actor_removed(Actor actor)
+ {
+ if (selected == actor) deselect_actor();
+ actor.button_press_event.disconnect(actor_clicked);
+ actor.button_release_event.disconnect(actor_released);
+ actor.reactive = false;
+ }
+
+ /**
+ * Handles { link SlideActor.on_ease_actor_added}. Connects handlers.
+ */
+ public void on_ease_actor_added(Actor actor)
+ {
+ actor.button_press_event.connect(actor_clicked);
+ actor.button_release_event.connect(actor_released);
+ actor.reactive = true;
+ }
}
diff --git a/src/ease-editor-window.vala b/src/ease-editor-window.vala
index 651b04c..ee16187 100644
--- a/src/ease-editor-window.vala
+++ b/src/ease-editor-window.vala
@@ -255,6 +255,16 @@ public class Ease.EditorWindow : Gtk.Window
{
Gtk.main_quit ();
}
+
+ [CCode (instance_pos = -1)]
+ public void on_delete(Gtk.Widget sender)
+ {
+ if (embed.selected == null) return;
+
+ var i = slide.index_of(embed.selected.element);
+ add_undo_action(new ElementRemoveUndoAction(slide.element_at(i)));
+ slide.remove_at(i);
+ }
[CCode (instance_pos = -1)]
public void new_slide_handler(Gtk.Widget? sender)
@@ -330,8 +340,8 @@ public class Ease.EditorWindow : Gtk.Window
var text = document.theme.create_custom_text();
text.x = document.width / 2 - text.width / 2;
text.y = document.height / 2 - text.height / 2;
- slide.add_element(0, text);
- embed.recreate_slide();
+ slide.add(text);
+ add_undo_action(new ElementAddUndoAction(text));
embed.select_element(text);
}
@@ -366,8 +376,8 @@ public class Ease.EditorWindow : Gtk.Window
e.filename = document.add_media_file(dialog.get_filename());
// add the element
- slide.add_element(0, e);
- embed.recreate_slide();
+ slide.add(e);
+ add_undo_action(new ElementAddUndoAction(e));
embed.select_element(e);
}
catch (Error e)
diff --git a/src/ease-slide-actor.vala b/src/ease-slide-actor.vala
index 64df96e..72e3cd4 100644
--- a/src/ease-slide-actor.vala
+++ b/src/ease-slide-actor.vala
@@ -120,6 +120,16 @@ public class Ease.SlideActor : Clutter.Group
private const int REFLECTION_OPACITY = 70;
/**
+ * Emitted when a subactor of this SlideActor is removed.
+ */
+ public signal void ease_actor_removed(Actor actor);
+
+ /**
+ * Emitted when a subactor is added to this SlideActor.
+ */
+ public signal void ease_actor_added(Actor actor);
+
+ /**
* Creates a SlideActor from a { link Slide} and a { link Document}.
* This calls the with_dimensions() constructor with the Document's
* dimensions.
@@ -174,6 +184,9 @@ public class Ease.SlideActor : Clutter.Group
add_actor(contents);
slide.background_changed.connect((s) => set_background());
+
+ slide.element_added.connect(on_element_added);
+ slide.element_removed.connect(on_element_removed);
}
/**
@@ -198,6 +211,43 @@ public class Ease.SlideActor : Clutter.Group
}
/**
+ * Handles { link Slide.element_added}.
+ */
+ public void on_element_added(Slide slide, Element element, int index)
+ {
+ var actor = element.actor(context);
+ contents.add_actor(actor);
+ 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;
+ }
+
+ ease_actor_added(actor as Actor);
+ }
+
+ /**
+ * Handles { link Slide.element_removed}.
+ */
+ public void on_element_removed(Slide slide, Element element, int index)
+ {
+ foreach (var a in contents)
+ {
+ if ((a as Actor).element == element)
+ {
+ contents.remove_actor(a);
+ ease_actor_removed(a as Actor);
+ break;
+ }
+ }
+ }
+
+ /**
* Resets all transformations on this SlideActor.
*/
public void reset(Clutter.Group container)
diff --git a/src/ease-slide.vala b/src/ease-slide.vala
index 2e85347..aefea96 100644
--- a/src/ease-slide.vala
+++ b/src/ease-slide.vala
@@ -208,6 +208,16 @@ public class Ease.Slide : GLib.Object
public signal void background_changed(Slide self);
/**
+ * Emitted when an { link Element} is added to this Slide.
+ */
+ public signal void element_added(Slide self, Element element, int index);
+
+ /**
+ * Emitted when an { link Element} is added to this Slide.
+ */
+ public signal void element_removed(Slide self, Element element, int index);
+
+ /**
* Create a new Slide.
*/
public Slide()
@@ -358,6 +368,7 @@ public class Ease.Slide : GLib.Object
{
e.parent = this;
elements.insert(index, e);
+ element_added(this, e, index);
}
/**
@@ -367,8 +378,43 @@ public class Ease.Slide : GLib.Object
*/
public void add(Element e)
{
- e.parent = this;
- elements.insert(count, e);
+ add_element(count, e);
+ }
+
+ /**
+ * Removes an { link Element} from this slide.
+ */
+ public void remove_element(Element e)
+ {
+ var index = index_of(e);
+ elements.remove(e);
+ element_removed(this, e, index);
+ }
+
+ /**
+ * Removed an { link Element} from this slide, by index.
+ */
+ public void remove_at(int index)
+ {
+ var e = elements.get(index);
+ elements.remove_at(index);
+ element_removed(this, e, index);
+ }
+
+ /**
+ * Returns the index of the specified { link Element}
+ */
+ public int index_of(Element e)
+ {
+ return elements.index_of(e);
+ }
+
+ /**
+ * Returns the { link Element} at the specified index.
+ */
+ public Element element_at(int i)
+ {
+ return elements.get(i);
}
/**
diff --git a/src/ease-undo-actions-element.vala b/src/ease-undo-actions-element.vala
new file mode 100644
index 0000000..96f0061
--- /dev/null
+++ b/src/ease-undo-actions-element.vala
@@ -0,0 +1,93 @@
+/* Ease, a GTK presentation application
+ Copyright (C) 2010 Nate Stedman
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * Undos the addition of an { link Element} to a { link Slide}.
+ */
+public class Ease.ElementAddUndoAction : UndoItem
+{
+ /**
+ * The { link Element} that was added.
+ */
+ private Element element;
+
+ /**
+ * Creates an ElementAddUndoAction.
+ *
+ * @param e The element that was added.
+ */
+ public ElementAddUndoAction(Element e)
+ {
+ element = e;
+ }
+
+ /**
+ * Applies the action, removing the { link Element}.
+ */
+ public override UndoItem apply()
+ {
+ var action = new ElementRemoveUndoAction(element);
+ element.parent.remove_element(element);
+ return action;
+ }
+}
+
+/**
+ * Undos the removal of an { link Element} from a { link Slide}.
+ */
+public class Ease.ElementRemoveUndoAction : UndoItem
+{
+ /**
+ * The { link Element} that was removed.
+ */
+ private Element element;
+
+ /**
+ * The { link Slide} that the Element was removed from.
+ */
+ private Slide slide;
+
+ /**
+ * The index of the Element in the Slide's stack.
+ */
+ int index;
+
+ /**
+ * Creates an ElementRemoveUndoAction. Note that this method references
+ * { link Element.parent}. Therefore, the action must be constructed
+ * before the Element is actually removed.
+ *
+ * @param e The element that was added.
+ */
+ public ElementRemoveUndoAction(Element e)
+ {
+ element = e;
+ slide = e.parent;
+ index = e.parent.index_of(e);
+ }
+
+ /**
+ * Applies the action, restoring the { link Element}.
+ */
+ public override UndoItem apply()
+ {
+ slide.add_element(index, element);
+ return new ElementAddUndoAction(element);
+ }
+}
+
+
diff --git a/src/ease-undo-item.vala b/src/ease-undo-item.vala
index 0b12c0c..d5faf4a 100644
--- a/src/ease-undo-item.vala
+++ b/src/ease-undo-item.vala
@@ -29,7 +29,7 @@ public abstract class Ease.UndoItem : GLib.Object
public signal void applied(UndoAction sender);
/**
- * Applies the { link Item}, restoring previous state.
+ * Applies the { link UndoItem}, restoring previous state.
*
* Returns an UndoItem that will redo the undo action.
*/
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]