[ease/themes] [editor] Use Gtk.TreeView for the slide panel.



commit ce04820dce1867021a028bbd63fb05025dc2c9a6
Author: Nate Stedman <natesm gmail com>
Date:   Thu Jul 22 14:30:56 2010 -0400

    [editor] Use Gtk.TreeView for the slide panel.

 Makefile.am                      |    1 -
 src/ease-document.vala           |   20 +++++
 src/ease-editor-window.vala      |    1 -
 src/ease-scrollable-embed.vala   |    4 +-
 src/ease-slide-button-panel.vala |  142 +++++++++++++++++++++++++++++++-------
 src/ease-slide-set.vala          |    2 +-
 6 files changed, 139 insertions(+), 31 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index e62d567..639a7f5 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -39,7 +39,6 @@ ease_SOURCES = \
 	src/ease-scrollable-embed.vala \
 	src/ease-slide-actor.vala \
 	src/ease-slide-button-panel.vala \
-	src/ease-slide-button.vala \
 	src/ease-slide-pane.vala \
 	src/ease-slide-set.vala \
 	src/ease-slide.vala \
diff --git a/src/ease-document.vala b/src/ease-document.vala
index d9580c7..5262575 100644
--- a/src/ease-document.vala
+++ b/src/ease-document.vala
@@ -52,6 +52,16 @@ public class Ease.Document : SlideSet
 	 * The aspect ratio of the Document.
 	 */
 	public float aspect { get { return (float)width / (float)height; } }
+	
+	/**
+	 * Emitted when a { link Slide} is deleted from the Document.
+	 */
+	public signal void slide_deleted(Slide slide, int index);
+	
+	/**
+	 * Emitted when a { link Slide} is added to the Document.
+	 */
+	public signal void slide_added(Slide slide, int index);
 
 	/**
 	 * Default constructor, creates an empty Document.
@@ -98,6 +108,16 @@ public class Ease.Document : SlideSet
 	{
 		s.parent = this;
 		base.add_slide(index, s);
+		slide_added(s, index);
+	}
+	
+	/**
+	 * { inheritDoc}
+	 */
+	public override void append_slide(Slide s)
+	{
+		base.append_slide(s);
+		slide_added(s, slides.size - 1);
 	}
 	
 	/**
diff --git a/src/ease-editor-window.vala b/src/ease-editor-window.vala
index 6368ede..30db27a 100644
--- a/src/ease-editor-window.vala
+++ b/src/ease-editor-window.vala
@@ -248,7 +248,6 @@ public class Ease.EditorWindow : Gtk.Window
 		var index = document.index_of(slide) + 1;
 		
 		document.add_slide(index, slide);
-		slide_button_panel.add_slide(index, slide);
 	}
 	
 	[CCode (instance_pos = -1)]
diff --git a/src/ease-scrollable-embed.vala b/src/ease-scrollable-embed.vala
index 5582879..a9d81f4 100644
--- a/src/ease-scrollable-embed.vala
+++ b/src/ease-scrollable-embed.vala
@@ -114,8 +114,8 @@ public class Ease.ScrollableEmbed : Gtk.HBox
 			hscroll_box.pack_start(h_padder, false, false, 0);
 			vbox.pack_start(hscroll_box, false, false, 0);
 			
-			// so that the vertical scrollbar doesn't extend to the bottom
-			// of the horizontal scrollbar, a padding widget is added
+			/* so that the vertical scrollbar doesn't extend to the bottom
+			   of the horizontal scrollbar, a padding widget is added */
 			v_padder = new Gtk.Alignment(0, 0, 0, 0);
 			
 			var vscroll_box = new Gtk.VBox(false, 0);
diff --git a/src/ease-slide-button-panel.vala b/src/ease-slide-button-panel.vala
index 9297d00..4126ef7 100644
--- a/src/ease-slide-button-panel.vala
+++ b/src/ease-slide-button-panel.vala
@@ -25,8 +25,32 @@ public class Ease.SlideButtonPanel : Gtk.ScrolledWindow
 {
 	private Document document;
 	private EditorWindow owner;
-	public Gtk.VButtonBox slides_box;
-	private Gtk.Alignment align;
+	
+	// tree view
+	private Gtk.TreeView slides;
+	private Gtk.ListStore list_store;
+	private Gtk.CellRendererPixbuf renderer;
+	
+	// thumbnails on disk
+	private static string m_temp_dir;
+	private static string? temp_dir
+	{
+		get
+		{
+			if (m_temp_dir != null) return m_temp_dir;
+			try { return m_temp_dir = Temp.request(); }
+			catch (GLib.Error e)
+			{
+				critical("Could not create temporary directory for thumbnails");
+			}
+			return null;
+		}
+	}
+	private static int temp_count = 0;
+	
+	private const int WIDTH_REQUEST = 100;
+	private const int PREV_WIDTH = 76;
+	private const int PADDING = 4;
 	
 	/**
 	 * Creates a SlideButtonPanel
@@ -41,51 +65,117 @@ public class Ease.SlideButtonPanel : Gtk.ScrolledWindow
 	{			
 		document = d;
 		owner = win;
+		width_request = WIDTH_REQUEST;
 
 		// set the scrollbar policy
 		vscrollbar_policy = Gtk.PolicyType.AUTOMATIC;
 		hscrollbar_policy = Gtk.PolicyType.NEVER;
+		shadow_type = Gtk.ShadowType.IN;
 		
-		slides_box = new Gtk.VButtonBox();
-		for (int i = 0; i < document.slides.size; i++)
+		// create the list store and add all current slides
+		list_store = new Gtk.ListStore(3, typeof(Gdk.Pixbuf), typeof(Slide),
+		                                  typeof(string));
+		Gtk.TreeIter iter;
+		foreach (var slide in document.slides)
 		{
-			var button = new SlideButton(i, document.slides.get(i), owner, this);
-			slides_box.pack_start(button, false, false, 0);
+			list_store.append(out iter);
+			string path = "";
+			var pb = pixbuf(slide, PREV_WIDTH, out path);
+			list_store.set(iter, 0, pb, 1, slide, 2, path);
 		}
-		align = new Gtk.Alignment(0, 0, 1, 0);
-		align.add(slides_box);
+		
+		// create the tree view
+		slides = new Gtk.TreeView();
+		slides.headers_visible = false;
+		renderer = new Gtk.CellRendererPixbuf();
+		renderer.set_padding(PADDING, PADDING);
+		slides.insert_column_with_attributes(-1, "Slides", renderer,
+		                                     "pixbuf", 0);
+		slides.set_model(list_store);
+		
+		// add the tree view with a viewport
 		var viewport = new Gtk.Viewport(null, null);
 		viewport.set_shadow_type(Gtk.ShadowType.NONE);
-		viewport.add(align);
+		viewport.add(slides);
 		add(viewport);
+		
+		// switch slides when the selection changes
+		slides.get_selection().changed.connect((sender) => {
+			slides.get_selection().selected_foreach((m, p, itr) => {
+				Slide s = new Slide();
+				m.get(itr, 1, ref s);
+				owner.load_slide(document.slides.index_of(s));
+			});
+		});
+		
+		// handle the document's slide_added signal
+		document.slide_added.connect((slide, index) => {
+			Gtk.TreeIter itr;
+			list_store.insert(out itr, index);
+			string path = "";
+			var pb = pixbuf(slide, PREV_WIDTH, out path);
+			list_store.set(itr, 0, pb, 1, slide, 2, path);
+		});
+		
+		// redraw all slides when the size allocation changes
+		/*viewport.size_allocate.connect((sender, alloc) => {
+			var width = alloc.width - 2 * PADDING;
+			
+			Gtk.TreeIter itr;
+			if (!list_store.get_iter_first(out itr)) return;
+			for (; list_store.iter_next(ref itr);)
+			{
+				Slide s = new Slide();
+				list_store.get(itr, 1, ref s);
+				list_store.set(itr, 0, pixbuf(s, width));
+			}
+		});*/
 	}
 	
 	/**
-	 * Adds a new { link Slide} to the SlideButtonPanel.
+	 * Creates a Gdk.Pixbuf for a given slide.
 	 *
-	 * @param index The index of the new { link Slide} in the { link Document}.
-	 * @param slide The { link Slide} to add.
+	 * @param slide The slide to create a pixbuf of.
 	 */
-	public void add_slide(int index, Slide slide)
+	private Gdk.Pixbuf? pixbuf(Slide slide, int width, out string path)
 	{
-		// create a new button
-		var button = new SlideButton(index, slide, owner, this);
+		var height = (int)((float)width * slide.parent.height /
+		                                  slide.parent.width);
+		var surface = new Cairo.ImageSurface(Cairo.Format.RGB24, width, height);
 		
-		// add the new button to the box
-		slides_box.pack_start(button, false, false, 0);
+		var context = new Cairo.Context(surface);
+		context.save();
+		context.scale((float)width / slide.parent.width,
+		              (float)height / slide.parent.height);
 		
-		// put the button in the proper position
-		slides_box.reorder_child(button, index);
-		
-		int i = 0;
-		for (unowned GLib.List<Gtk.Widget>* itr = slides_box.get_children();
-		     itr != null; itr = itr->next)
+		try
 		{
-			((SlideButton*)(itr->data))->slide_id = i;
-			i++;
+			slide.cairo_render_sized(context, width, height);
 		}
+		catch (GLib.Error e)
+		{
+			critical(_("Error drawing slide preview: %s"), e.message);
+		}
+		
+		// render a black rectangle around the slide
+		/*context.rectangle(0, 0, width, height);
+		context.set_source_rgb(0, 0, 0);
+		context.stroke();*/
+		
+		context.restore();
+		
+		// HACK: write it to a PNG, load it and return
+		path = Path.build_filename(temp_dir,
+		                           (temp_count++).to_string() + ".png");
+		surface.write_to_png(path);
 		
-		button.show_all();
+		/*return new Gdk.Pixbuf.from_data(surface.get_data(), Gdk.Colorspace.RGB,
+		                                true, 8,
+		                                surface.get_width(),
+		                                surface.get_height(),
+		                                surface.get_stride(), null);*/
+		try { return new Gdk.Pixbuf.from_file(path); }
+		catch (GLib.Error e) { error(e.message); return null; }
 	}
 }
 
diff --git a/src/ease-slide-set.vala b/src/ease-slide-set.vala
index 1aa5593..cff61ff 100644
--- a/src/ease-slide-set.vala
+++ b/src/ease-slide-set.vala
@@ -59,7 +59,7 @@ public abstract class Ease.SlideSet : Object
 	 *
 	 * @param s The { link Slide} to append.
 	 */
-	public void append_slide(Slide s)
+	public virtual void append_slide(Slide s)
 	{
 		slides.insert(length, s);
 	}



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