[ease] [editor] Add Slide Sorter



commit 5b301df2cb2820b09b2af750a8829f2df6a26ec9
Author: Nate Stedman <natesm gmail com>
Date:   Thu Jul 29 03:11:30 2010 -0400

    [editor] Add Slide Sorter
    
    SlideSorter is an icon view that can be used to rearrange, add,
    and remove slides. Double clicking on a slide will open that
    slide for editing.

 Makefile.am                  |    1 +
 data/ui/editor-window.ui     |   90 ++++++++++++++++++++++++++++--------------
 ease-core/ease-document.vala |   16 ++++++-
 src/ease-editor-window.vala  |   66 ++++++++++++++++++++++++++++++
 src/ease-slide-sorter.vala   |   72 +++++++++++++++++++++++++++++++++
 5 files changed, 213 insertions(+), 32 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index b046f22..b9a0aa3 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -22,6 +22,7 @@ ease_SOURCES = \
 	src/ease-selection-rectangle.vala \
 	src/ease-slide-actor.vala \
 	src/ease-slide-button-panel.vala \
+	src/ease-slide-sorter.vala \
 	src/ease-welcome-actor.vala \
 	src/ease-welcome-window.vala
 
diff --git a/data/ui/editor-window.ui b/data/ui/editor-window.ui
index 57c6b9e..5cb7053 100644
--- a/data/ui/editor-window.ui
+++ b/data/ui/editor-window.ui
@@ -286,6 +286,31 @@
               <object class="GtkMenu" id="menu3">
                 <property name="visible">True</property>
                 <child>
+                  <object class="GtkRadioMenuItem" id="editor-radio">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">Editor</property>
+                    <property name="use_underline">True</property>
+                    <property name="active">True</property>
+                    <property name="draw_as_radio">True</property>
+                    <signal name="activate" handler="ease_editor_window_set_view"/>
+                  </object>
+                </child>
+                <child>
+                  <object class="GtkRadioMenuItem" id="slide-sorter-radio">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">Slide Sorter</property>
+                    <property name="use_underline">True</property>
+                    <property name="draw_as_radio">True</property>
+                    <property name="group">editor-radio</property>
+                    <signal name="activate" handler="ease_editor_window_set_view"/>
+                  </object>
+                </child>
+                <child>
+                  <object class="GtkSeparatorMenuItem" id="menuitem5">
+                    <property name="visible">True</property>
+                  </object>
+                </child>
+                <child>
                   <object class="GtkImageMenuItem" id="Zoom In">
                     <property name="label">gtk-zoom-in</property>
                     <property name="visible">True</property>
@@ -494,46 +519,51 @@
       </packing>
     </child>
     <child>
-      <object class="GtkHBox" id="HBox">
+      <object class="GtkAlignment" id="main-align">
         <property name="visible">True</property>
         <child>
-          <object class="GtkAlignment" id="Slides Align">
+          <object class="GtkHBox" id="editor">
             <property name="visible">True</property>
-            <property name="right_padding">4</property>
             <child>
-              <placeholder/>
+              <object class="GtkAlignment" id="Slides Align">
+                <property name="visible">True</property>
+                <property name="right_padding">4</property>
+                <child>
+                  <placeholder/>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">0</property>
+              </packing>
             </child>
-          </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">False</property>
-            <property name="position">0</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkAlignment" id="Embed Align">
-            <property name="visible">True</property>
             <child>
-              <placeholder/>
+              <object class="GtkAlignment" id="Embed Align">
+                <property name="visible">True</property>
+                <child>
+                  <placeholder/>
+                </child>
+              </object>
+              <packing>
+                <property name="position">1</property>
+              </packing>
             </child>
-          </object>
-          <packing>
-            <property name="position">1</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkAlignment" id="Inspector Align">
-            <property name="visible">True</property>
-            <property name="left_padding">4</property>
             <child>
-              <placeholder/>
+              <object class="GtkAlignment" id="Inspector Align">
+                <property name="visible">True</property>
+                <property name="left_padding">4</property>
+                <child>
+                  <placeholder/>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">2</property>
+              </packing>
             </child>
           </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">False</property>
-            <property name="position">2</property>
-          </packing>
         </child>
       </object>
       <packing>
diff --git a/ease-core/ease-document.vala b/ease-core/ease-document.vala
index d8aea79..d7e2aa1 100644
--- a/ease-core/ease-document.vala
+++ b/ease-core/ease-document.vala
@@ -48,7 +48,7 @@ public class Ease.Document : GLib.Object, UndoSource
 	/**
 	 * Model column count.
 	 */
-	private const int MODEL_COLS = 2;
+	private const int MODEL_COLS = 3;
 	
 	/**
 	 * Model Slide column.
@@ -59,6 +59,16 @@ public class Ease.Document : GLib.Object, UndoSource
 	 * Model pixbuf column.
 	 */
 	public const int COL_PIXBUF = 1;
+	
+	/**
+	 * Model title column.
+	 */
+	public const int COL_TITLE = 2;
+	
+	/**
+	 * Default slide title.
+	 */
+	private const string DEFAULT_TITLE = _("Slide %i");
 
 	/**
 	 * The { link Theme} linked to this Document.
@@ -96,7 +106,8 @@ public class Ease.Document : GLib.Object, UndoSource
 	 */
 	public IterableListStore slides = new IterableListStore(
 		{ typeof(Slide),
-		  typeof(Gdk.Pixbuf) });
+		  typeof(Gdk.Pixbuf),
+		  typeof(string) });
 	
 	/**
 	 * The number of { link Slide}s in the Document.
@@ -235,6 +246,7 @@ public class Ease.Document : GLib.Object, UndoSource
 		Gtk.TreeIter itr;
 		slides.insert(out itr, index);
 		slides.set(itr, COL_SLIDE, slide);
+		slides.set(itr, COL_TITLE, DEFAULT_TITLE.printf(index));
 		slide_added(slide, index);
 		listen(slide);
 		
diff --git a/src/ease-editor-window.vala b/src/ease-editor-window.vala
index 4438e56..d43b199 100644
--- a/src/ease-editor-window.vala
+++ b/src/ease-editor-window.vala
@@ -62,6 +62,21 @@ public class Ease.EditorWindow : Gtk.Window
 	private Inspector inspector;
 	
 	/**
+	 * The main editor widget (embed, inspector, and slide thumbnails)
+	 */
+	private Gtk.Widget editor;
+	
+	/**
+	 * The { link SlideSorter} for this window.
+	 */
+	private SlideSorter sorter;
+	
+	/**
+	 * The container for the editor or the SlideSorter.
+	 */
+	private Gtk.Bin main_bin;
+	
+	/**
 	 * The { link UndoController} for this window.
 	 */
 	private UndoController undo;
@@ -97,6 +112,16 @@ public class Ease.EditorWindow : Gtk.Window
 	private Gtk.ColorSelection color_selection;
 	
 	/**
+	 * The Editor radio button.
+	 */
+	private Gtk.RadioMenuItem show_editor;
+	
+	/**
+	 * The Editor radio button.
+	 */
+	private Gtk.RadioMenuItem show_sorter;
+	
+	/**
 	 * The time the document was last saved.
 	 */
 	long last_saved = 0;
@@ -139,6 +164,12 @@ public class Ease.EditorWindow : Gtk.Window
 		
 		builder.connect_signals(this);
 		add(builder.get_object("Editor Widget") as Gtk.VBox);
+		main_bin = builder.get_object("main-align") as Gtk.Bin;
+		editor = builder.get_object("editor") as Gtk.Widget;
+		show_sorter =
+			builder.get_object("slide-sorter-radio") as Gtk.RadioMenuItem;
+		show_editor =
+			builder.get_object("editor-radio") as Gtk.RadioMenuItem;
 				
 		// slide display
 		slide_button_panel = new SlideButtonPanel(document, this);
@@ -289,6 +320,7 @@ public class Ease.EditorWindow : Gtk.Window
 		document.add_slide(index, s);
 	}
 	
+	[CCode (instance_pos = -1)]
 	public void on_new_slide_menu(Gtk.Widget? sender)
 	{
 		var item = sender as Gtk.MenuItem;
@@ -307,6 +339,14 @@ public class Ease.EditorWindow : Gtk.Window
 		// don't remove the last slide in a document
 		if (document.length < 2) return;
 		
+		// if the sorter isn't set to null, it must be active
+		if (sorter != null)
+		{
+			var s = sorter.delete_slide();
+			if (s != null) slide_button_panel.select_slide(s);
+			return;
+		}
+		
 		// set the slide to something safe
 		slide_button_panel.select_slide(document.remove_slide(slide));
 	}
@@ -428,6 +468,32 @@ public class Ease.EditorWindow : Gtk.Window
 	}
 	
 	[CCode (instance_pos = -1)]
+	public void set_view(Gtk.Widget sender)
+	{
+		if (show_editor == sender)
+		{
+			if (main_bin.get_child() == editor) return;
+			main_bin.remove(sorter);
+			main_bin.add(editor);
+			sorter = null;
+		}
+		else if (show_sorter == sender)
+		{
+			if (sorter == null) sorter = new SlideSorter(document);
+			if (main_bin.get_child() == sorter) return;
+			main_bin.remove(editor);
+			main_bin.add(sorter);
+			sorter.show_all();
+			
+			// when a slide is clicked in the sorter, switch back here
+			sorter.display_slide.connect((s) => {
+				set_slide(document.index_of(s));
+				show_editor.active = true;
+			});
+		}
+	}
+	
+	[CCode (instance_pos = -1)]
 	public void zoom_in(Gtk.Widget sender)
 	{
 		zoom_slider.zoom_in();
diff --git a/src/ease-slide-sorter.vala b/src/ease-slide-sorter.vala
new file mode 100644
index 0000000..30404ed
--- /dev/null
+++ b/src/ease-slide-sorter.vala
@@ -0,0 +1,72 @@
+/*  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/>.
+*/
+
+/**
+ * A widget displaying an icon view the user can use to sort and delete slides.
+ */
+public class Ease.SlideSorter : Gtk.ScrolledWindow
+{
+	private Gtk.IconView view;
+	private Document document;
+	
+	private const int WIDTH = 100;
+	
+	public signal void display_slide(Slide s);
+	
+	public SlideSorter(Document doc)
+	{
+		document = doc;
+		view = new Gtk.IconView.with_model(document.slides);
+		view.pixbuf_column = Document.COL_PIXBUF;
+		view.markup_column = Document.COL_TITLE;
+		view.reorderable = true;
+		view.item_width = WIDTH;
+		
+		// add and show the iconview
+		add(view);
+		view.show();
+		
+		// when a slide is clicked, show it in the editor
+		view.item_activated.connect((v, path) => {
+			Gtk.TreeIter itr;
+			Slide slide;
+			view.model.get_iter(out itr, path);
+			view.model.get(itr, Document.COL_SLIDE, out slide);
+			display_slide(slide);
+		});
+	}
+	
+	public Slide? delete_slide()
+	{
+		Slide slide = null, ret_slide = null;
+		GLib.List<Slide> slides_to_remove = null;
+		
+		view.selected_foreach((v, path) => {
+			Gtk.TreeIter itr;
+			view.model.get_iter(out itr, path);
+			view.model.get(itr, Document.COL_SLIDE, out slide);
+			slides_to_remove.append(slide);
+		});
+		
+		slides_to_remove.foreach(() => {
+			if (document.length < 2) return;
+			ret_slide = document.remove_slide(slide);
+		});
+		
+		return ret_slide;
+	}
+}



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