[ease/text] Switched build systems to waf. Using newest valac vapis as well.



commit c01756090de5495a7147df881cdc7576f93f6931
Author: Nate Stedman <natesm gmail com>
Date:   Thu Dec 2 07:37:25 2010 -0500

    Switched build systems to waf. Using newest valac vapis as well.

 configure.ac                                  |   97 +++++++++
 ease-core/ease-archiver.vala                  |    4 +-
 ease-core/ease-background-widget.vala         |    2 +-
 ease-core/ease-dialogs.vala                   |   12 +-
 ease-core/ease-layout.vala                    |  175 ++++++++++++++++
 ease-core/ease-pdf-actor.vala                 |   12 +-
 ease-core/ease-pdf-element.vala               |   59 +++++-
 ease-core/ease-plugin-import-service.vala     |   11 +-
 ease-core/ease-text-actor.vala                |  126 ++++++------
 ease-core/ease-text-element.vala              |    2 +-
 ease-core/ease-text.vala                      |  264 +++++++++++++++++++++----
 ease-core/ease-theme.vala                     |    2 +-
 ease-core/ease-video-actor.vala               |    4 +-
 ease-core/sourcelist/source-item.vala         |   16 +--
 ease-core/sourcelist/source-number-item.vala  |   14 ++-
 ease-core/sourcelist/source-spinner-item.vala |    4 +-
 ease-core/wscript                             |  127 ++++++++-----
 ease/Makefile.am                              |   57 ------
 ease/wscript                                  |    9 +-
 wscript                                       |  157 ++++++++-------
 20 files changed, 827 insertions(+), 327 deletions(-)
---
diff --git a/configure.ac b/configure.ac
new file mode 100644
index 0000000..6de07a1
--- /dev/null
+++ b/configure.ac
@@ -0,0 +1,97 @@
+AC_PREREQ([2.59])
+
+m4_define(ease_version, 0.5)
+m4_define(ease_core_version, 0.5)
+m4_define(flutter_version, 0.5)
+
+AC_INIT([Ease],
+        [ease_version],
+        [https://bugzilla.gnome.org/enter_bug.cgi?product=ease],
+        [ease],
+        [http://live.gnome.org/Ease])
+
+AC_CONFIG_FILES([
+	Makefile
+	po/Makefile.in
+	data/Makefile
+	ease-core/Makefile
+	flutter/Makefile
+	ease/Makefile
+	pkgconfig/ease-core-0.5.pc
+	pkgconfig/flutter-0.5.pc])
+
+AC_CONFIG_SRCDIR([Makefile.am])
+AC_CONFIG_HEADERS([config.h])
+
+AM_INIT_AUTOMAKE([no-dist-gzip dist-bzip2 subdir-objects -Wno-portability])
+AM_MAINTAINER_MODE()
+
+# Enable silent rules is available
+m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
+
+AC_PROG_CC
+AC_PROG_CC_STDC
+
+if test "x$USE_MAINTAINER_MODE" = "xyes" ; then
+  AM_PROG_VALAC([0.11.0])
+fi
+
+AM_PROG_CC_C_O
+AC_PROG_INSTALL
+AC_PROG_INTLTOOL([0.35])
+AM_PROG_LIBTOOL
+
+# GObject introspection
+AC_CONFIG_MACRO_DIR([m4])
+GOBJECT_INTROSPECTION_CHECK([0.6.7])
+
+dnl this is preferred, but doesn't work for me :
+dnl LT_PREREQ([2.2.6])
+
+GNOME_COMPILE_WARNINGS([maximum])
+GNOME_MAINTAINER_MODE_DEFINES
+
+dnl packages
+pkg_modules="\
+ clutter-gst-1.0\
+ clutter-gtk-0.10 >= 0.10\
+ gee-1.0\
+ gmodule-2.0\
+ json-glib-1.0 >= 0.7.6\
+ libarchive\
+ poppler-glib\
+ rest-0.6 \
+ rest-extras-0.6\
+ unique-1.0"
+ 
+PKG_CHECK_MODULES(EASE, [$pkg_modules])
+
+EASE_PACKAGES="\
+ --pkg clutter-gst-1.0\
+ --pkg clutter-gtk-0.10\
+ --pkg gee-1.0\
+ --pkg gmodule-2.0\
+ --pkg json-glib-1.0\
+ --pkg libarchive\
+ --pkg poppler-glib\
+ --pkg rest-extras-0.6\
+ --pkg unique-1.0"
+
+AC_SUBST(EASE_CFLAGS)
+AC_SUBST(EASE_LIBS)
+AC_SUBST(EASE_PACKAGES)
+
+AC_DEFINE(EASE_VERSION, ease_version, [Ease Version])
+AC_SUBST(EASE_VERSION, ease_version)
+AC_DEFINE(EASE_CORE_VERSION, ease_core_version, [Ease Core Version])
+AC_SUBST(EASE_CORE_VERSION, ease_core_version)
+AC_DEFINE(FLUTTER_VERSION, flutter_version, [Flutter Version])
+AC_SUBST(FLUTTER_VERSION, flutter_version)
+
+dnl internationalization
+GETTEXT_PACKAGE=ease
+AC_DEFINE_UNQUOTED([GETTEXT_PACKAGE], ["$GETTEXT_PACKAGE"], [Gettext Package])
+AC_SUBST(GETTEXT_PACKAGE)
+AM_GLIB_GNU_GETTEXT
+
+AC_OUTPUT
diff --git a/ease-core/ease-archiver.vala b/ease-core/ease-archiver.vala
index 3ab150a..9f5c6aa 100644
--- a/ease-core/ease-archiver.vala
+++ b/ease-core/ease-archiver.vala
@@ -67,13 +67,13 @@ private class Ease.Archiver.Archiver : GLib.Object
 		dialog.show();
 		
 		// archive in a thread
-		thread = Thread.create(archive_real, true);
+		thread = Thread.create<string>(archive_real, true);
 	}
 	
 	/**
 	 * Does the actual archiving of a directory.
 	 */
-	private void* archive_real()
+	private string archive_real()
 	{
 		// create a writable archive
 		var archive = new Archive.Write();
diff --git a/ease-core/ease-background-widget.vala b/ease-core/ease-background-widget.vala
index 8dad770..bdcb5f4 100644
--- a/ease-core/ease-background-widget.vala
+++ b/ease-core/ease-background-widget.vala
@@ -229,7 +229,7 @@ public class Ease.BackgroundWidget : Gtk.Alignment
 		// ease doesn't provide a default for images, so one must be requested
 		if (type == BackgroundType.IMAGE && background.image.filename == null)
 		{
-			var filename = Dialog.open_ext(BG_DIALOG_TITLE,
+			var filename = Dialog.open_ext(_("Select Background Image"),
 			                               widget_window(this),
 			                               (dialog) => {
 				// add a filter for image files
diff --git a/ease-core/ease-dialogs.vala b/ease-core/ease-dialogs.vala
index e6ef51c..9be796d 100644
--- a/ease-core/ease-dialogs.vala
+++ b/ease-core/ease-dialogs.vala
@@ -282,9 +282,9 @@ namespace Ease.Dialog
 				if (!has_suffix)
 				{
 					// ask the user if they'd like to append .ease
-					var code = question(VERIFY_EASE_PRIMARY,
-					                    VERIFY_EASE_PRIMARY,
-						                VERIFY_EASE_SECONDARY,
+					var code = question(_("Append .ease?"),
+					                    _("Append .ease?"),
+						                _("The specified filename does not end with a \".ease\" extension. Would you like to append one?"),
 							            modal,
 							            Gtk.ResponseType.YES,
 							            _("Don't append .ease"),
@@ -319,9 +319,9 @@ namespace Ease.Dialog
 					// ask the user if they'd like to overwrite
 					var code = message(
 						Gtk.MessageType.WARNING,
-						VERIFY_OVERWRITE_TITLE.printf(bname),
-						VERIFY_OVERWRITE_FMT.printf(bname),
-						VERIFY_OVERWRITE_SECONDARY_FMT.printf(folder),
+						_("Replace %s?").printf(bname),
+						_("A file named %s already exists. Do you want to replace it?").printf(bname),
+						_("This file already exists in the directory \"%s\". Overwriting it will replace its contents.").printf(folder),
 						modal,
 						Gtk.ResponseType.YES,
 						_("Don't overwrite %s").printf(bname),
diff --git a/ease-core/ease-layout.vala b/ease-core/ease-layout.vala
new file mode 100644
index 0000000..d5b869e
--- /dev/null
+++ b/ease-core/ease-layout.vala
@@ -0,0 +1,175 @@
+/*  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/>.
+*/
+
+/**
+ * Provides several additions to PangoLayout in a GObject wrapper.
+ *
+ * If additional functionality is required, in general, it should be added to
+ * Layout (or { link Text}), rather than accessing the PangoLayout member
+ * directly, so that Layout appears to be a subclass of PangoLayout (which is
+ * not subclassable).
+ */
+public class Ease.Layout : GLib.Object
+{
+	/**
+	 * Default filler text, which can be rendered if the text is empty.
+	 */
+	private const string DEFAULT_TEXT = _("Double click to edit.");
+	
+	/**
+	 * The PangoLayout that this EaseLayout is wrapping.
+	 */
+	public Pango.Layout layout { get; private set; }
+	
+	/**
+	 * The context, which the layout requires.
+	 */
+	private Pango.Context context;
+	
+	/**
+	 * The text of the PangoLayout.
+	 */
+	public string text
+	{
+		get { return layout.get_text(); }
+		set { layout.set_text(value, (int)value.length); }
+	}
+	
+	/**
+	 * The height of the layout.
+	 */
+	public int width
+	{
+		get { return layout.get_width(); }
+		set { layout.set_width(value); }
+	}
+	
+	/**
+	 * The height of the layout.
+	 */
+	public int height
+	{
+		get { return layout.get_height(); }
+		set { layout.set_height(value); }
+	}
+	
+	/**
+	 * The size of the layout as a two item array. Arrays not of length 2 will
+	 * be ignored.
+	 */
+	public int[] size
+	{
+		owned get { return { width, height }; }
+		set
+		{
+			if (value.length != 2)
+			{
+				critical("Layout size must be a two item array, not %i",
+				         value.length);
+				return;
+			}
+			width = value[0];
+			height = value[1];
+		}
+	}
+	
+	/**
+	 * The actual rendered width of the layout, in pixels. This cannot be set.
+	 */
+	public int width_px
+	{
+		get
+		{
+			int width, height;
+			layout.get_pixel_size(out width, out height);
+			return width;
+		}
+	}
+	
+	/**
+	 * The actual rendered height of the layout, in pixels. This cannot be set.
+	 */
+	public int height_px
+	{
+		get
+		{
+			int width, height;
+			layout.get_pixel_size(out width, out height);
+			return height;
+		}
+	}
+	
+	/**
+	 * The actual rendered size of the layout, in pixels. This cannot be set.
+	 */
+	public int[] size_px
+	{
+		owned get
+		{
+			int width, height;
+			layout.get_pixel_size(out width, out height);
+			return { width, height };
+		}
+	}
+	
+	/**
+	 * The attribute list of the layout. In { link TextElement}, this is
+	 * controlled by a master list of attributes that operates across the
+	 * entire set of layouts.
+	 */
+	public Pango.AttrList attrs
+	{
+		get { return layout.get_attributes(); }
+		set { layout.set_attributes(value); }
+	}
+	
+	construct
+	{
+		// create context and layout
+		context = Gdk.pango_context_get_for_screen(Gdk.Screen.get_default());
+		layout = new Pango.Layout(context);
+		
+		// set layout properties
+		layout.set_ellipsize(Pango.EllipsizeMode.END);
+		
+		// create attribute list
+		attrs = new Pango.AttrList();
+	}
+	
+	/**
+	 * Renders the layout to a Cairo context.
+	 *
+	 * @param use_default If the default filler text should be used if the
+	 * layout is empty.
+	 */
+	public void render(Cairo.Context cr, bool use_default)
+	{
+		// display default text if there is no text in the element
+		string text = layout.get_text();
+		if (text.length == 0 && use_default)
+		{
+			layout.set_text(DEFAULT_TEXT, (int)DEFAULT_TEXT.length);
+		}
+		
+		// render
+		Pango.cairo_show_layout(cr, layout);
+		
+		// restore empty text if necessary
+		layout.set_text(text, (int)text.length);
+	}
+}
+
diff --git a/ease-core/ease-pdf-actor.vala b/ease-core/ease-pdf-actor.vala
index 4888f57..442e457 100644
--- a/ease-core/ease-pdf-actor.vala
+++ b/ease-core/ease-pdf-actor.vala
@@ -53,6 +53,9 @@ public class Ease.PdfActor : Actor
 			current_page = e.displayed_page;
 			draw_page();
 		});
+		
+		// provide proper resolution renders
+		notify["zoom"].connect(() => draw_page());
 	}
 	
 	private void draw_page()
@@ -65,7 +68,8 @@ public class Ease.PdfActor : Actor
 		// create a texture
 		if (texture == null)
 		{
-			texture = new Clutter.CairoTexture((int)width, (int)height);
+			texture = new Clutter.CairoTexture((int)(width * zoom),
+			                                   (int)(height * zoom));
 			(contents as Clutter.Group).add_actor(texture);
 			
 			texture.width = contents.width;
@@ -83,13 +87,15 @@ public class Ease.PdfActor : Actor
 		// otherwise, set the size
 		else
 		{
-			texture.set_surface_size((int)width, (int)height);
+			texture.set_surface_size((int)(width * zoom),
+			                         (int)(height * zoom));
 		}
 		
 		// draw the texture
 		texture.clear();
 		var cr = texture.create();
-		pdf_element.background.cairo_render(cr, (int)width, (int)height,
+		pdf_element.background.cairo_render(cr, (int)(width * zoom),
+			                                    (int)(height * zoom),
 		                                    element.parent.parent.path, false);
 		page.render(cr);
 	}
diff --git a/ease-core/ease-pdf-element.vala b/ease-core/ease-pdf-element.vala
index d61f56a..7351504 100644
--- a/ease-core/ease-pdf-element.vala
+++ b/ease-core/ease-pdf-element.vala
@@ -22,6 +22,7 @@ public class Ease.PdfElement : MediaElement
 {
 	private const string UI_FILE = "inspector-element-pdf.ui";
 	private const int DEFAULT_PAGE = 0;
+	private const double CACHE_SIZE = 76.0;
 	
 	/**
 	 * The page of the PDF file that is initially displayed.
@@ -45,6 +46,12 @@ public class Ease.PdfElement : MediaElement
 	
 	internal Poppler.Document pdf_doc;
 	
+	// invalidate the cache when the displayed page changes
+	construct
+	{
+		notify["displayed-page"].connect(() => small_cache = null);
+	}
+	
 	public PdfElement(string filename)
 	{
 		pdf_doc = new Poppler.Document.from_file(Filename.to_uri(filename),
@@ -121,18 +128,54 @@ public class Ease.PdfElement : MediaElement
 		background.cairo_render(context, (int)width, (int)height,
 		                        parent.parent.path, use_small);
 		
-		// get the current page
-		var page = pdf_doc.get_page(displayed_page);
+		// if rendering at a small size, use the small cache
+		if (use_small)
+		{
+			// create the cache if necessary
+			if (small_cache == null)
+			{
+				// get the current page and page size
+				var page = pdf_doc.get_page(displayed_page);
+				double w = 0, h = 0;
+				page.get_size(out w, out h);
+				
+				// create a cache pixbuf
+				small_cache = new Gdk.Pixbuf(Gdk.Colorspace.RGB, true, 8,
+				                             (int)CACHE_SIZE,
+				                             (int)(h * (CACHE_SIZE / w)));
+				
+				// render to the cache
+				page.render_to_pixbuf(0, 0, (int)w, (int)h, CACHE_SIZE / w,
+				                      0, small_cache);
+			}
+			
+			// render the cached thumbnail
+			Gdk.cairo_set_source_pixbuf(context, small_cache, 0, 0);
+			context.scale(small_cache.width / width,
+			              small_cache.height / height);
+			context.rectangle(0, 0, width, height);
+			context.fill();
+		}
+		
+		// otherwise, render the full PDF
+		else
+		{
+			// get the current page
+			var page = pdf_doc.get_page(displayed_page);
 		
-		// scale the context
-		double w = 0, h = 0;
-		page.get_size(out w, out h);
-		context.scale(width / w, height / h);
+			// scale the context
+			double w = 0, h = 0;
+			page.get_size(out w, out h);
+			context.scale(width / w, height / h);
 		
-		// render the PDF
-		page.render(context);
+			// render the PDF
+			page.render(context);
+		}
 	}
 	
+	// a small version to cache so that thumbnail redraws aren't absurdly slow
+	private Gdk.Pixbuf small_cache;
+	
 	public override Gtk.Widget inspector_widget()
 	{
 		bool silence_undo = false;
diff --git a/ease-core/ease-plugin-import-service.vala b/ease-core/ease-plugin-import-service.vala
index 90a3d45..d8ca3a2 100644
--- a/ease-core/ease-plugin-import-service.vala
+++ b/ease-core/ease-plugin-import-service.vala
@@ -188,12 +188,15 @@ public abstract class Ease.Plugin.ImportService : GLib.Object
 			// if threads are supported, get the pixbufs in a thread
 			if (Thread.supported())
 			{
-				try { Thread.create(threaded_get_pixbufs, false); }
-				catch { threaded_get_pixbufs(); }
+				try
+				{
+					Thread.create<ImportService>(threaded_get_pixbufs, false);
+				}
+				catch { threaded_get_pixbufs<weak void*>(); }
 			}
 			else
 			{
-				threaded_get_pixbufs();
+				threaded_get_pixbufs<void*>();
 			}
 		}
 		else
@@ -212,7 +215,7 @@ public abstract class Ease.Plugin.ImportService : GLib.Object
 	 * this will lock up the user interface and be a bad experience for the
 	 * user.
 	 */
-	private void* threaded_get_pixbufs()
+	private ImportService threaded_get_pixbufs()
 	{
 		// get the next image
 		ImportMedia image;
diff --git a/ease-core/ease-text-actor.vala b/ease-core/ease-text-actor.vala
index 28ef196..396c733 100644
--- a/ease-core/ease-text-actor.vala
+++ b/ease-core/ease-text-actor.vala
@@ -58,6 +58,22 @@ public class Ease.TextActor : Actor
 	 * The other end of the selection (the first one being { link cursor_index}.
 	 */
 	private int selection_index = 0;
+	
+	/**
+	 * The index of the cursor, in terms of layouts.
+	 */
+	private int cursor_layout = 0;
+	
+	/**
+	 * The other end of the selection, in terms of layouts ,the first one being
+	 * { link cursor_layout}.
+	 */
+	private int selection_layout = 0;
+	
+	/**
+	 * Convenience property for grabbing the { link Text}.
+	 */
+	private Text text { get { return (element as TextElement).text; } }
 
 	/**
 	 * Instantiates a new TextActor from an Element.
@@ -100,17 +116,13 @@ public class Ease.TextActor : Actor
 	
 	public override void edit(Gtk.Widget sender, float mouse_x, float mouse_y)
 	{
-		int trailing = 0;
-		var layout = (element as TextElement).text.layout;
-		if (!layout.xy_to_index((int)mouse_x * Pango.SCALE,
-		                        (int)mouse_y * Pango.SCALE,
-		                        out cursor_index, out trailing))
+		if (!text.xy_to_index((int)mouse_x, (int)mouse_y,
+		                       ref cursor_index, ref cursor_layout))
 		{
 			debug("Click was not inside element (%f, %f)", mouse_x, mouse_y);
-			cursor_index =
-				(int)(element as TextElement).text.layout.get_text().length;
+			cursor_index = 0;
+			cursor_layout = 0;
 		}
-		cursor_index += trailing;
 		selection_index = cursor_index;
 		
 		debug("Editing text, cursor index is %i", cursor_index);
@@ -128,7 +140,7 @@ public class Ease.TextActor : Actor
 		render_text();
 	}
 	
-	private override void end_edit(Gtk.Widget sender)
+	public override void end_edit(Gtk.Widget sender)
 	{
 		// remove the cursor and stop its animation
 		remove_actor(cursor);
@@ -145,62 +157,56 @@ public class Ease.TextActor : Actor
 			switch (event.keyval)
 			{
 				case Key.BACKSPACE:
-					if (cursor_index > 0)
-					{
-						text.delete(cursor_index - 1);
-						cursor_index--;
-						selection_index = cursor_index;
-						cursor.opacity = 255;
-						cursor_timeline.rewind();
-					}
-					break;
-				
-				case Key.DELETE:
-					if (cursor_index < text.layout.get_text().length)
-					{
-						text.delete(cursor_index);
-						cursor.opacity = 255;
-						cursor_timeline.rewind();
-					}
+					text.delete(cursor_index - 1, cursor_layout);
+					text.retreat_cursor(ref cursor_index,
+					                    ref cursor_layout, 1);
+					selection_index = cursor_index;
+					cursor.opacity = 255;
+					cursor_timeline.rewind();
 					break;
 				
 				case Key.DELETE:
-					if (cursor_index < text.layout.get_text().length)
-					{
-						text.delete(cursor_index);
-						cursor.opacity = 255;
-						cursor_timeline.rewind();
-					}
+					text.delete(cursor_index, cursor_layout);
+					cursor.opacity = 255;
+					cursor_timeline.rewind();
 					break;
 				
 				case Key.LEFT:
-					cursor_index = int.max(cursor_index - 1, 0);
+					// move the cursor back
+					text.retreat_cursor(ref cursor_index, ref cursor_layout, 1);
 					selection_index = cursor_index;
+					selection_layout = cursor_layout;
+					
+					// reset cursor blink
 					cursor.opacity = 255;
 					cursor_timeline.rewind();
 					break;
 				
 				case Key.RIGHT:
-					cursor_index = int.min(cursor_index + 1,
-					                       (int)text.layout.get_text().length);
+					// advance the cursor
+					text.advance_cursor(ref cursor_index, ref cursor_layout, 1);
 					selection_index = cursor_index;
+					selection_layout = cursor_layout;
+					
+					// reset cursor blink
 					cursor.opacity = 255;
 					cursor_timeline.rewind();
 					break;
 				
 				case Key.ENTER:
-					text.insert("\n", cursor_index);
+					/*text.insert("\n", cursor_index);
 					cursor_index++;
 					selection_index = cursor_index;
 					cursor.opacity = 255;
-					cursor_timeline.rewind();
+					cursor_timeline.rewind();*/
 					break;
 				
 				default: {
 					unichar key = Gdk.keyval_to_unicode(event.keyval);
 					if (key != 0)
 					{
-						text.insert(key.to_string(), cursor_index);
+						text.insert(key.to_string(),
+						            cursor_index, cursor_layout);
 						cursor_index++;
 						selection_index = cursor_index;
 						cursor.opacity = 255;
@@ -212,27 +218,25 @@ public class Ease.TextActor : Actor
 			
 			render_text();
 			position_cursor();
-			debug("Cursor index is %i", cursor_index);
+			debug("Cursor index is %i %i", cursor_index, cursor_layout);
 		}
 		
 		return true;
 	}
 	
-	private override bool clicked_event(Clutter.Actor self,
-	                                    Clutter.ButtonEvent event,
-	                                    float mouse_x, float mouse_y)
+	public override bool clicked_event(Clutter.Actor self,
+	                                   Clutter.ButtonEvent event,
+	                                   float mouse_x, float mouse_y)
 	{
-		int trailing = 0;
-		var layout = (element as TextElement).text.layout;
-		if (!layout.xy_to_index((int)mouse_x * Pango.SCALE,
-		                        (int)mouse_y * Pango.SCALE,
-		                        out cursor_index, out trailing))
+		if (!text.xy_to_index((int)mouse_x, (int)mouse_y,
+		                       ref cursor_index, ref cursor_layout))
 		{
 			debug("Edit click not inside element (%f, %f)", mouse_x, mouse_y);
-			return true;
+			cursor_index = 0;
+			cursor_layout = 0;
 		}
-		cursor_index += trailing;
 		selection_index = cursor_index;
+		
 		position_cursor();
 		cursor.opacity = 255;
 		cursor_timeline.rewind();
@@ -245,9 +249,9 @@ public class Ease.TextActor : Actor
 		return true;
 	}
 	
-	private bool on_motion_event(Clutter.Actor self, Clutter.MotionEvent event)
+	public bool on_motion_event(Clutter.Actor self, Clutter.MotionEvent event)
 	{
-		float mouse_x, mouse_y;
+		/*float mouse_x, mouse_y;
 		transform_stage_point(event.x, event.y, out mouse_x, out mouse_y);
 		
 		int trailing, index;
@@ -265,11 +269,12 @@ public class Ease.TextActor : Actor
 		debug("Selection index: %i    Cursor index: %i",
 		      selection_index, cursor_index);
 		
+		return true;*/
 		return true;
 	}
 	
-	private bool on_button_release_event(Clutter.Actor self,
-	                                     Clutter.ButtonEvent event)
+	public bool on_button_release_event(Clutter.Actor self,
+	                                    Clutter.ButtonEvent event)
 	{
 		debug("Pointer released");
 		button_release_event.disconnect(on_button_release_event);
@@ -284,9 +289,8 @@ public class Ease.TextActor : Actor
 	private void position_cursor()
 	{
 		// get the position
-		Pango.Rectangle rect;
-		(element as TextElement).text.layout.index_to_pos(cursor_index,
-		                                                  out rect);
+		var rect = (element as TextElement).text.index_to_pos(cursor_index,
+		                                                      cursor_layout);
 		
 		// move the cursor
 		cursor.x = rect.x / Pango.SCALE + 3;
@@ -317,7 +321,7 @@ public class Ease.TextActor : Actor
 		cr.save();
 		
 		// render the selection if applicable
-		if (selection_index != cursor_index)
+		/*if (selection_index != cursor_index)
 		{
 			// get the layout and set its size
 			var layout = (element as TextElement).text.layout;
@@ -391,7 +395,7 @@ public class Ease.TextActor : Actor
 			cr.move_to(x / Pango.SCALE, logical.y);
 			cr.move_to(x / Pango.SCALE, logical.y + logical.height);*/
 			
-			int start_index, end_index;
+			/*int start_index, end_index;
 			if (selection_index < cursor_index)
 			{
 				start_index = selection_index;
@@ -433,13 +437,11 @@ public class Ease.TextActor : Actor
 			// fill and stroke
 			cr.stroke_preserve();
 			cr.fill();
-		}
+		}*/
 		
 		// render the text
 		cr.restore();
-		(element as TextElement).text.render(cr, !editing,
-		                                     (int)texture.width,
-		                                     (int)texture.height);
+		(element as TextElement).text.render(cr, !editing);
 	}
 }
 
diff --git a/ease-core/ease-text-element.vala b/ease-core/ease-text-element.vala
index 0c6bc58..ee2238f 100644
--- a/ease-core/ease-text-element.vala
+++ b/ease-core/ease-text-element.vala
@@ -171,7 +171,7 @@ public class Ease.TextElement : Element
 	public override void cairo_render(Cairo.Context context,
 	                                  bool use_small) throws Error
 	{
-		text.render(context, true, (int)width, (int)height);
+		text.render(context, true);
 	}
 	
 	/**
diff --git a/ease-core/ease-text.vala b/ease-core/ease-text.vala
index 0d31c7b..f09b2d5 100644
--- a/ease-core/ease-text.vala
+++ b/ease-core/ease-text.vala
@@ -23,12 +23,10 @@
  */
 public class Ease.Text : GLib.Object
 {
-	private const string DEFAULT_TEXT = _("Double click to edit.");
-	
 	/**
 	 * The layout, which controls the text and formatting.
 	 */
-	internal Pango.Layout layout;
+	internal Gee.LinkedList<Layout> layouts;
 	
 	/**
 	 * The context, which the layout requires.
@@ -36,22 +34,54 @@ public class Ease.Text : GLib.Object
 	private Pango.Context context;
 	
 	/**
-	 * The layout's attributes, which control text formatting.
+	 * The master list of attributes. When this is altered, layouts will be
+	 * updated with attributes for their local lengths and indices.
 	 */
 	private Pango.AttrList attrs;
 	
+	/**
+	 * The width of the text layout.
+	 */
+	public int width { get; set; default = 640; }
+	
+	/**
+	 * The height of the text layout. Text after this height will be ellipsized.
+	 */
+	public int height { get; set; default = 480; }
+	
+	/**
+	 * The size of the Text as a two item array. Arrays not of length 2 will
+	 * be ignored.
+	 */
+	public int[] size
+	{
+		owned get { return { width, height }; }
+		set
+		{
+			if (value.length != 2)
+			{
+				critical("Text size must be a two item array, not %i",
+				         value.length);
+				return;
+			}
+			width = value[0];
+			height = value[1];
+		}
+	}
+	
 	construct
 	{
-		// create context and layout
-		context = Gdk.pango_context_get_for_screen(Gdk.Screen.get_default());
-		layout = new Pango.Layout(context);
+		// create layout set
+		layouts = new Gee.LinkedList<Layout>();
+		
+		// create the first layout
+		layouts.add(new Layout());
 		
 		// set layout properties
-		layout.set_ellipsize(Pango.EllipsizeMode.END);
+		layouts.first().layout.set_ellipsize(Pango.EllipsizeMode.END);
 		
 		// create attribute list
 		attrs = new Pango.AttrList();
-		layout.set_attributes(attrs);
 	}
 	
 	/**
@@ -62,45 +92,107 @@ public class Ease.Text : GLib.Object
 	 */
 	public Text.with_text(string text, Pango.FontDescription font_description)
 	{
-		layout.set_text(text, (int)text.length);
-		layout.set_font_description(font_description);
+		layouts.first().layout.set_text(text, (int)text.length);
+		layouts.first().layout.set_font_description(font_description);
+	}
+	
+	/**
+	 * Advances the cursor by a specified number of characters. If the cursor
+	 * cannot be moved forward, it will not be moved.
+	 *
+	 * @param index The index of the cursor, this value is set on out.
+	 * @param layout_index The layout index, this value is set on out.
+	 * @param chars The number of characters to advance.
+	 */
+	public void advance_cursor(ref int index, ref int layout_index, uint chars)
+	{
+		
+	}
+	
+	/**
+	 * Moves the the cursor back by a specified number of characters. If the
+	 * cursor cannot move back, it will not be moved.
+	 *
+	 * @param index The index of the cursor, this value is set on out.
+	 * @param layout_index The layout index, this value is set on out.
+	 * @param chars The number of characters to advance.
+	 */
+	public void retreat_cursor(ref int index, ref int layout_index, uint chars)
+	{
+		
+	}
+	
+	/**
+	 * Iterates over each { link Layout} in a text object.
+	 *
+	 * @param function The function to call for each iteration. Returning false
+	 * will break the iteration.
+	 */
+	public void @foreach(TextForeachFunc function)
+	{
+		foreach (var layout in layouts)
+		{
+			if (!function(layout)) return;
+		}
 	}
 	
 	/**
+	 * Called for each iteration of { link foreach}. Returning false will break
+	 * the iteration.
+	 */
+	public delegate bool TextForeachFunc(Layout layout);
+	
+	/**
 	 * Renders the Text to a Cairo Context.
 	 *
 	 * @param cr The context to render to.
 	 * @param use_default If the text is empty, the default string will be
 	 * rendered instead of an empty string.
-	 * @param width The width to render at.
-	 * @param height The height to render at.
 	 */
-	public void render(Cairo.Context cr, bool use_default,
-	                   int width, int height)
+	public void render(Cairo.Context cr, bool use_default)
 	{
-		// display default text if there is no text in the element
-		string text = layout.get_text();
-		if (text.length == 0 && use_default)
-		{
-			layout.set_text(DEFAULT_TEXT, (int)DEFAULT_TEXT.length);
-		}
+		int y = 0;
+		cr.save();
+		
+		// render each layout, if it's within the bounds of the rectangle
+		@foreach((layout) => {
+			// render the layout
+			layout.render(cr, use_default);
+			
+			// translate for the next render
+			cr.translate(0, layout.height_px);
+			
+			// stop once we've rendered all visible layouts
+			y += layout.height_px;
+			return y < height;
+		});
+		
+		cr.restore();
+	}
+	
+	/**
+	 * Adds a paragraph to the layout.
+	 */
+	public void add_layout()
+	{
+		// create the first layout
+		var layout = new Layout();
 		
-		// set size and render
-		layout.set_width(width * Pango.SCALE);
-		layout.set_height(height * Pango.SCALE);
-		Pango.cairo_show_layout(cr, layout);
+		// set layout properties
+		layouts.first().layout.set_ellipsize(Pango.EllipsizeMode.END);
 		
-		// restore empty text if necessary
-		layout.set_text(text, (int)text.length);
+		// add layout
+		layouts.insert(layouts.size, layout);
 	}
 	
 	/**
 	 * Inserts a string at a given index.
 	 */
-	public void insert(string text, int index)
+	public void insert(string text, int index, int layout_index)
 	{
-		debug("Insert at %i", index);
-		string result, current = layout.get_text();
+		var layout = layouts.get(layout_index);
+		
+		string result, current = layout.text;
 		if (index == 0)
 		{
 			result = text + current;
@@ -115,18 +207,21 @@ public class Ease.Text : GLib.Object
 			         current.substring(index, current.length - index);
 		}
 		
-		layout.set_text(result, (int)result.length);
+		layout.text = result;
 	}
 	
 	/**
 	 * Deletes the character as a given index.
 	 */
-	public void @delete(int index)
+	public void @delete(int index, int layout_index)
 	{
-		debug("Delete at %i", index);
+		debug("Delete at %i %i", layout_index, index);
+		
+		// get the layout
+		var layout = layouts.get(layout_index);
 		
 		// get current string
-		var current = layout.get_text();
+		var current = layout.text;
 		
 		// don't do bad things
 		if (index >= current.length)
@@ -143,7 +238,7 @@ public class Ease.Text : GLib.Object
 		// delete the character
 		var str = current.substring(0, index) +
 		          current.substring(index + 1, current.length - index - 1);
-		layout.set_text(str, (int)str.length);
+		layout.text = str;
 	}
 	
 	/**
@@ -156,14 +251,109 @@ public class Ease.Text : GLib.Object
 	 */
 	public void clear_set(string text, Pango.FontDescription? font_description)
 	{
-		layout.set_text(text, (int)text.length);
+		while (layouts.size > 1) layouts.remove_at(1);
+		layouts.first().text = text;
 		if (font_description != null)
 		{
-			layout.set_font_description(font_description);
+			layouts.first().layout.set_font_description(font_description);
 		}
 	}
 	
 	/**
+	 * Adds an attribute.
+	 *
+	 * @param attr The attribute to add.
+	 */
+	public void add_attr(Pango.Attribute attr)
+	{
+	}
+	
+	/**
+	 * Converts from an index within a PangoLayout to the onscreen position
+	 * corresponding to the grapheme at that index, which is represented as
+	 * rectangle. Note that pos->x is always the leading edge of the grapheme
+	 * and pos->x + pos->width the trailing edge of the grapheme. If the
+	 * directionality of the grapheme is right-to-left, then pos->width will be
+	 * negative.
+	 *
+	 * The implementation of this function in Text checks across multiple
+	 * layouts (as indicated by the second index parameter) for the result.
+	 *
+	 * @param index The character index.
+	 * @param layout_index The layout index.
+	 */
+	public Pango.Rectangle index_to_pos(int index, int layout_index)
+	{
+		Pango.Rectangle pos = Pango.Rectangle();
+		int i = 0, y = 0;
+		@foreach((layout) => {
+			if (i < index)
+			{
+				y += layout.height_px;
+				return true;
+			}
+			else
+			{
+				layout.layout.index_to_pos(index, out pos);
+				pos.y += y * Pango.SCALE;
+				return false;
+			}
+		});
+		
+		return pos;
+	}
+	
+	/**
+	 * Converts from X and Y position within a layout to the byte index to the
+	 * character at that logical position. If the Y position is not inside the
+	 * layout, the closest position is chosen (the position will be clamped
+	 * inside the layout). If the X position is not within the layout, then the
+	 * start or the end of the line is chosen as described for
+	 * pango_layout_x_to_index(). If either the X or Y positions were not inside
+	 * the layout, then the function returns false; on an exact hit, it returns
+	 * true.
+	 *
+	 * @param x The x position, in pixels.
+	 * @param y The y position, in pixels.
+	 * @param index A return value for the cursor index.
+	 * @param layout_index A return value for the layout index.
+	 */
+	public bool xy_to_index(int x, int y, ref int index, ref int layout_index)
+	{
+		// clamp the x position
+		if (x > width) x = width;
+		if (x < 0) x = 0;
+		
+		// clamp the y position
+		if (y > height) y = height;
+		if (y < 0) y = 0;
+		
+		// convert to pango units
+		width *= Pango.SCALE;
+		height *= Pango.SCALE;
+		
+		// find the indices
+		layout_index = 0;
+		foreach (var layout in layouts)
+		{
+			if (y > layout.height_px)
+			{
+				y -= layout.height_px;
+				layout_index++;
+			}
+			else
+			{
+				int trailing = 0;
+				layout.layout.xy_to_index(x, y, out index, out trailing);
+				index += trailing;
+				break;
+			}
+		}
+		
+		return true;
+	}
+	
+	/**
 	 * Creates a PangoStyle from a string.
 	 */
 	public static Pango.Style style_from_string(string str)
diff --git a/ease-core/ease-theme.vala b/ease-core/ease-theme.vala
index 97762a1..f5ca1d1 100644
--- a/ease-core/ease-theme.vala
+++ b/ease-core/ease-theme.vala
@@ -491,7 +491,7 @@ public class Ease.Theme : GLib.Object
 		
 		// create the text element
 		var text = new TextElement("", font);
-		text.text.layout.get_attributes().insert(color_attr.copy());
+		text.text.add_attr(color_attr.copy());
 		
 		// set size properties
 		text.x = x;
diff --git a/ease-core/ease-video-actor.vala b/ease-core/ease-video-actor.vala
index 0b02f7f..cebfba8 100644
--- a/ease-core/ease-video-actor.vala
+++ b/ease-core/ease-video-actor.vala
@@ -208,7 +208,9 @@ public class Ease.VideoActor : Actor, Clutter.Media
 		cr.fill();
 		
 		// create the action button
-		action_button = new Clutter.Texture.from_file(data_path(PLAY_PATH));
+		action_button =
+			new Clutter.Texture.from_file(
+				data_path(Path.build_filename("svg", "video-play-button.svg")));
 		
 		// set the position of the button
 		action_button.anchor_gravity = Clutter.Gravity.CENTER;
diff --git a/ease-core/sourcelist/source-item.vala b/ease-core/sourcelist/source-item.vala
index 1b5fa7a..afd419c 100644
--- a/ease-core/sourcelist/source-item.vala
+++ b/ease-core/sourcelist/source-item.vala
@@ -71,17 +71,7 @@ public class Source.Item : Gtk.HBox
 	/**
 	 * Format string for deselected items.
 	 */
-	private const string FORMAT_DESELECTED = "%s";
-	
-	/**
-	 * Format string for right notification number when new.
-	 */
-	private const string FORMAT_RIGHT_NEW = "<small><b>%i</b></small>";
-	
-	/**
-	 * Format string for right notification number once viewed.
-	 */
-	private const string FORMAT_RIGHT_OLD = "<small><b>%i</b></small>";
+	protected const string FORMAT_DESELECTED = "%s";
 	
 	/**
 	 * Padding to the sides of the label and image. Not used on the right of
@@ -216,7 +206,7 @@ public class Source.Item : Gtk.HBox
 	public Item.from_stock_text(string item, Gtk.Image img, Gtk.Widget? widg)
 	{
 		Gtk.StockItem stock = Gtk.StockItem();
-		if (Gtk.stock_lookup(item, stock))
+		if (Gtk.Stock.lookup(item, out stock))
 		{
 			this(stock.label.replace("_", ""), img, widg);
 		}
@@ -233,7 +223,7 @@ public class Source.Item : Gtk.HBox
 	public Item.from_stock(string item, Gtk.Widget? widg)
 	{
 		Gtk.StockItem stock = Gtk.StockItem();
-		if (Gtk.stock_lookup(item, stock))
+		if (Gtk.Stock.lookup(item, out stock))
 		{
 			this(stock.label.replace("_", ""),
 			     new Gtk.Image.from_stock(item, ICON_SIZE),
diff --git a/ease-core/sourcelist/source-number-item.vala b/ease-core/sourcelist/source-number-item.vala
index 1db0d4b..f621c96 100644
--- a/ease-core/sourcelist/source-number-item.vala
+++ b/ease-core/sourcelist/source-number-item.vala
@@ -20,6 +20,16 @@
 public class Source.NumberItem : Source.Item
 {
 	/**
+	 * Format string for right notification number when new.
+	 */
+	protected const string FORMAT_RIGHT_NEW = "<small><b>%i</b></small>";
+	
+	/**
+	 * Format string for right notification number once viewed.
+	 */
+	protected const string FORMAT_RIGHT_OLD = "<small><b>%i</b></small>";
+	
+	/**
 	 * The right label widget, which can display a number if desired.
 	 */
 	private Gtk.Label right_label;
@@ -116,7 +126,7 @@ public class Source.NumberItem : Source.Item
 	                                  Gtk.Widget? widg)
 	{
 		Gtk.StockItem stock = Gtk.StockItem();
-		if (Gtk.stock_lookup(item, stock))
+		if (Gtk.Stock.lookup(item, out stock))
 		{
 			this(stock.label.replace("_", ""), img, widg);
 		}
@@ -133,7 +143,7 @@ public class Source.NumberItem : Source.Item
 	public NumberItem.from_stock(string item, Gtk.Widget? widg)
 	{
 		Gtk.StockItem stock = Gtk.StockItem();
-		if (Gtk.stock_lookup(item, stock))
+		if (Gtk.Stock.lookup(item, out stock))
 		{
 			this(stock.label.replace("_", ""),
 			     new Gtk.Image.from_stock(item, ICON_SIZE),
diff --git a/ease-core/sourcelist/source-spinner-item.vala b/ease-core/sourcelist/source-spinner-item.vala
index d0b83f6..fd85cd4 100644
--- a/ease-core/sourcelist/source-spinner-item.vala
+++ b/ease-core/sourcelist/source-spinner-item.vala
@@ -102,7 +102,7 @@ public class Source.SpinnerItem : Source.Item
 	                                   Gtk.Widget? widg)
 	{
 		Gtk.StockItem stock = Gtk.StockItem();
-		if (Gtk.stock_lookup(item, stock))
+		if (Gtk.Stock.lookup(item, out stock))
 		{
 			this(stock.label.replace("_", ""), img, widg);
 		}
@@ -119,7 +119,7 @@ public class Source.SpinnerItem : Source.Item
 	public SpinnerItem.from_stock(string item, Gtk.Widget? widg)
 	{
 		Gtk.StockItem stock = Gtk.StockItem();
-		if (Gtk.stock_lookup(item, stock))
+		if (Gtk.Stock.lookup(item, out stock))
 		{
 			this(stock.label.replace("_", ""),
 			     new Gtk.Image.from_stock(item, ICON_SIZE),
diff --git a/ease-core/wscript b/ease-core/wscript
index 754f6db..56d42a0 100644
--- a/ease-core/wscript
+++ b/ease-core/wscript
@@ -1,58 +1,93 @@
 #!/usr/bin/env python
 
 ease_core_files = ["ease-actor.vala",
-		   "ease-animated-zoom-slider.vala", "ease-archiver.vala",
-		   "ease-background.vala", "ease-background-widget.vala",
-		   "ease-cairo-actor.vala", "ease-cairo-element.vala",
-		   "ease-color.vala", "ease-dialog-progress.vala",
-		   "ease-dialogs.vala", "ease-document.vala",
-		   "ease-element.vala", "ease-enums.vala",
-		   "ease-gradient.vala", "ease-html-exporter.vala",
-		   "ease-icon-view.vala", "ease-image-actor.vala",
-		   "ease-image-element.vala", "ease-image.vala",
-		   "ease-iterable-models.vala", "ease-media-element.vala",
-		   "ease-plugin-import-media.vala", "ease-plugin-import-service.vala",
-		   "ease-pdf-actor.vala", "ease-pdf-element.vala",
-		   "ease-scrolled-embed.vala", "ease-scrolled-embed-window.vala",
-		   "ease-shape-element.vala", "ease-slide.vala",
-		   "ease-temp.vala", "ease-text-actor.vala",
-		   "ease-text-element.vala", "ease-theme.vala",
-		   "ease-transformations.vala", "ease-transitions.vala",
-		   "ease-undo-actions-element.vala", "ease-undo-actions-slide.vala",
-		   "ease-undo-action.vala", "ease-undo-controller.vala",
-		   "ease-undo-item.vala", "ease-undo-source.vala",
-		   "ease-utilities.vala", "ease-video-actor.vala",
-		   "ease-video-element.vala", "ease-zoom-slider.vala",
-		   "sourcelist/source-base-group.vala", "sourcelist/source-base-view.vala",
-		   "sourcelist/source-expandable-group.vala", "sourcelist/source-group.vala",
-		   "sourcelist/source-item.vala", "sourcelist/source-list.vala",
-		   "sourcelist/source-number-item.vala", "sourcelist/source-pane-view.vala",
-		   "sourcelist/source-spinner-item.vala", "sourcelist/source-view.vala"]
-
-ease_core_packages = ["clutter-gst-1.0", "clutter-gtk-0.10", "gee-1.0", "gmodule-2.0", "json-glib-1.0", "libarchive", "poppler-glib", "rest-extras-0.6", "unique-1.0"]
+                   "ease-animated-zoom-slider.vala",
+                   "ease-archiver.vala",
+                   "ease-background.vala",
+                   "ease-background-widget.vala",
+                   "ease-cairo-actor.vala",
+                   "ease-cairo-element.vala",
+                   "ease-color.vala",
+                   "ease-dialog-progress.vala",
+                   "ease-dialogs.vala",
+                   "ease-document.vala",
+                   "ease-element.vala",
+                   "ease-enums.vala",
+                   "ease-gradient.vala",
+                   "ease-html-exporter.vala",
+                   "ease-icon-view.vala",
+                   "ease-image-actor.vala",
+                   "ease-image-element.vala",
+                   "ease-image.vala",
+                   "ease-iterable-models.vala",
+                   "ease-layout.vala",
+                   "ease-media-element.vala",
+                   "ease-plugin-import-media.vala",
+                   "ease-plugin-import-service.vala",
+                   "ease-pdf-actor.vala",
+                   "ease-pdf-element.vala",
+                   "ease-scrolled-embed.vala",
+                   "ease-scrolled-embed-window.vala",
+                   "ease-shape-element.vala",
+                   "ease-slide.vala",
+                   "ease-temp.vala",
+                   "ease-text.vala",
+                   "ease-text-actor.vala",
+                   "ease-text-element.vala",
+                   "ease-theme.vala",
+                   "ease-transitions.vala",
+                   "ease-undo-actions-element.vala",
+                   "ease-undo-actions-slide.vala",
+                   "ease-undo-action.vala",
+                   "ease-undo-controller.vala",
+                   "ease-undo-item.vala",
+                   "ease-undo-source.vala",
+                   "ease-utilities.vala",
+                   "ease-video-actor.vala",
+                   "ease-video-element.vala",
+                   "ease-zoom-slider.vala",
+                   "sourcelist/source-base-group.vala",
+                   "sourcelist/source-base-view.vala",
+                   "sourcelist/source-expandable-group.vala",
+                   "sourcelist/source-group.vala",
+                   "sourcelist/source-item.vala",
+                   "sourcelist/source-list.vala",
+                   "sourcelist/source-number-item.vala",
+                   "sourcelist/source-pane-view.vala",
+                   "sourcelist/source-spinner-item.vala",
+                   "sourcelist/source-view.vala"]
 
 def build(bld):
-	version = bld.env["EASE_CORE_VERSION"][0]
-	print version
-	library_name = 'ease-core-' + version
+  ease_core_packages = ["clutter-gst-1.0",
+                        "clutter-gtk-0.10",
+                        "gee-1.0",
+                        "gmodule-2.0",
+                        "json-glib-1.0",
+                        "libarchive",
+                        "poppler-glib",
+                        "rest-extras-0.6",
+                        "unique-1.0",
+                        'flutter-' + bld.env["FLUTTER_VERSION"][0]]
 
-	lib = bld(features='c cshlib', after='flutter')
+  version = bld.env["EASE_CORE_VERSION"][0]
+  library_name = 'ease-core-' + version
 
-	lib.name = "ease-core"
-	lib.target = library_name
-	
-	lib.source = " ".join(ease_core_files)
+  lib = bld(features='c cshlib', after='flutter')
 
-	lib.cflags = ['-include', 'config.h']
-	lib.uselib = 'GOBJECT CLUTTER GEE CLUTTERGST GMODULE LIBARCHIVE POPPLERGLIB RESTEXTRAS CLUTTERGTK JSONGLIB'
-	lib.packages = 'flutter-' + bld.env["FLUTTER_VERSION"][0] + " "
-	lib.packages += " ".join(ease_core_packages)
-	
-	lib.vapi_dirs = "../build/flutter"
-	
-	lib.gir = "EaseCore-" + version
+  lib.name = "ease-core"
+  lib.target = library_name
+  
+  lib.source = " ".join(ease_core_files)
 
+  lib.cflags = ['-include', 'config.h', '-w']
+  lib.uselib = 'GOBJECT CLUTTER GEE CLUTTERGST GMODULE LIBARCHIVE POPPLERGLIB RESTEXTRAS CLUTTERGTK JSONGLIB'
+  lib.packages = " ".join(ease_core_packages)
+  
+  lib.vapi_dirs = "../build/flutter ../vapi"
+  
+  lib.gir = "EaseCore-" + version
 
 
-	
+
+  
 
diff --git a/ease/wscript b/ease/wscript
index 8dfda7c..6f9f81d 100644
--- a/ease/wscript
+++ b/ease/wscript
@@ -16,14 +16,13 @@ ease_files = ["ease-about-dialog.vala",
               "ease-inspector-slide-pane.vala", 
               "ease-inspector-transition-pane.vala", 
               "ease-inspector.vala", 
-              "ease-main.vala", 
+              "ease-main.vala",
+              "ease-new-presentation-window.vala",
               "ease-player.vala", 
               "ease-selection-rectangle.vala", 
               "ease-slide-actor.vala", 
               "ease-slide-button-panel.vala", 
-              "ease-slide-sorter.vala", 
-              "ease-welcome-actor.vala", 
-              "ease-welcome-window.vala"]
+              "ease-slide-sorter.vala"]
 
 def build(bld):
   ease_packages = ["flutter-" + bld.env["FLUTTER_VERSION"][0],
@@ -48,7 +47,7 @@ def build(bld):
   
   prog.includes = "../build/ease-core ../build/flutter"
   
-  prog.cflags = ['-include', 'config.h']
+  prog.cflags = ['-include', 'config.h', '-w']
   prog.uselib = 'GTK+ GOBJECT CLUTTER GEE CLUTTERGST GMODULE LIBARCHIVE POPPLERGLIB RESTEXTRAS CLUTTERGTK JSONGLIB UNIQUE' 
   prog.packages = " ".join(ease_packages)
 
diff --git a/wscript b/wscript
index 6452c8a..2beee0d 100644
--- a/wscript
+++ b/wscript
@@ -1,6 +1,7 @@
 #!/usr/bin/env python
 
 from waflib import TaskGen
+from os import system
 
 PACKAGE_VERSION = "ease-0.5"
 VERSION = "0.5"
@@ -13,94 +14,98 @@ top = '.'
 out = ''
 
 def options(opt):
-    opt.tool_options('compiler_c')
-    opt.tool_options('gnu_dirs')
+  opt.tool_options('compiler_c')
+  opt.tool_options('gnu_dirs')
 
 def library_check(conf):
-    libraries =  (
-        ("clutter-1.0", "CLUTTER", None),
-        ("clutter-gst-1.0", "CLUTTERGST", None),
-        ("gee-1.0", "GEE", None),
-        ("gmodule-2.0", "GMODULE", None),
-        ("libarchive", "LIBARCHIVE", None),
-        ("poppler-glib", "POPPLERGLIB", None),
-        ("rest-0.6", "REST", None),
-        ("rest-extras-0.6", "RESTEXTRAS",None),
-        ("unique-1.0", "UNIQUE", None),
-        ("clutter-gtk-0.10", "CLUTTERGTK", "0.10"),
-        ("json-glib-1.0", "JSONGLIB", "0.7.6")
-     )
-    for (package, uselib, version) in libraries:
-        conf.check_cfg(package=package, uselib_store=uselib, 
-                       mandatory=True, version=version, 
-                       args='--cflags --libs')
+  libraries =  (
+    ("clutter-1.0", "CLUTTER", None),
+    ("clutter-gst-1.0", "CLUTTERGST", None),
+    ("gee-1.0", "GEE", None),
+    ("gmodule-2.0", "GMODULE", None),
+    ("libarchive", "LIBARCHIVE", None),
+    ("poppler-glib", "POPPLERGLIB", None),
+    ("rest-0.6", "REST", None),
+    ("rest-extras-0.6", "RESTEXTRAS",None),
+    ("unique-1.0", "UNIQUE", None),
+    ("clutter-gtk-0.10", "CLUTTERGTK", "0.10"),
+    ("json-glib-1.0", "JSONGLIB", "0.7.6")
+   )
+  for (package, uselib, version) in libraries:
+    conf.check_cfg(package=package, uselib_store=uselib, 
+                   mandatory=True, version=version, 
+                   args='--cflags --libs')
 
 def write_config_header(conf):
-    conf.define('PACKAGE', APPNAME)
-    conf.define('PACKAGE_NAME', APPNAME)
-    conf.define('PACKAGE_STRING', APPNAME + '-' + VERSION)
-    conf.define('PACKAGE_VERSION', APPNAME + '-' + VERSION)
+  conf.define('PACKAGE', APPNAME)
+  conf.define('PACKAGE_NAME', APPNAME)
+  conf.define('PACKAGE_STRING', APPNAME + '-' + VERSION)
+  conf.define('PACKAGE_VERSION', APPNAME + '-' + VERSION)
 
-    conf.define('EASE_VERSION', EASE_VERSION)
-    conf.define('FLUTTER_VERSION', FLUTTER_VERSION)
-    conf.define('EASE_CORE_VERSION', EASE_CORE_VERSION)
-    
-    conf.define('EASE_DATA_DIR', '%{DATADIR}')
-    
-    conf.define('GETTEXT_PACKAGE', 'ease')
+  conf.define('EASE_VERSION', EASE_VERSION)
+  conf.define('FLUTTER_VERSION', FLUTTER_VERSION)
+  conf.define('EASE_CORE_VERSION', EASE_CORE_VERSION)
+  
+  conf.define('EASE_DATA_DIR', '%{DATADIR}')
+  
+  conf.define('GETTEXT_PACKAGE', 'ease')
 
-    conf.write_config_header('config.h')
+  conf.write_config_header('config.h')
 
 def configure(conf):
-    conf.load('intltool')
-    conf.check_tool('compiler_c vala gnu_dirs')
-    
-
-    # For pkgconfig substitution.
-    conf.env.append_value('FLUTTER_VERSION', FLUTTER_VERSION)
-    conf.env.append_value('EASE_CORE_VERSION', EASE_CORE_VERSION)
-    conf.env.append_value('EASE_VERSION', EASE_VERSION)
-    conf.env.append_value('PACKAGE_VERSION', PACKAGE_VERSION)
-    
-    write_config_header(conf)
-    
-    library_check(conf)
-
-
+  conf.load('intltool')
+  conf.check_tool('compiler_c vala gnu_dirs')
+  
+  # For pkgconfig substitution.
+  conf.env.append_value('FLUTTER_VERSION', FLUTTER_VERSION)
+  conf.env.append_value('EASE_CORE_VERSION', EASE_CORE_VERSION)
+  conf.env.append_value('EASE_VERSION', EASE_VERSION)
+  conf.env.append_value('PACKAGE_VERSION', PACKAGE_VERSION)
+  
+  # disable vala warnings because the unused function ones are really annoying
+  conf.env.append_value('VALAFLAGS', '--disable-warnings')
+  
+  write_config_header(conf)
+  
+  library_check(conf)
 
 def build_pkgconfig_file(bld, name):
-    obj = bld(features = "subst_pc",
-              source = name,
-              install_path = "${LIBDIR}/pkgconfig")
+  obj = bld(features = "subst_pc",
+            source = name,
+            install_path = "${LIBDIR}/pkgconfig")
 
 def build_po(bld):
-    bld(features='intltool_po', 
-        appname=APPNAME, 
-        podir='po', install_path="${LOCALEDIR}")
+  bld(features='intltool_po', 
+      appname=APPNAME, 
+      podir='po', install_path="${LOCALEDIR}")
 
 
 def build(bld):
-    bld.EASE_VERSION = EASE_VERSION
-    bld.EASE_CORE_VERSION = EASE_CORE_VERSION
-    bld.FLUTTER_VERSION = FLUTTER_VERSION
-    bld.srcdir = top 
-    bld.builddir = out
-    
-    bld.add_subdirs('flutter')
-    bld.add_group()
-
-    bld.add_subdirs('ease-core')
-    bld.add_subdirs('data')
-    bld.add_group()
-
-    bld.add_subdirs('ease')
-    bld.add_group()
-    
-    build_pkgconfig_file(bld, "pkgconfig/ease-core-0.5.pc.in")
-    build_pkgconfig_file(bld, "pkgconfig/flutter-0.5.pc.in")
-    
-    build_po(bld)
-    
-
-
-
+  bld.EASE_VERSION = EASE_VERSION
+  bld.EASE_CORE_VERSION = EASE_CORE_VERSION
+  bld.FLUTTER_VERSION = FLUTTER_VERSION
+  bld.srcdir = top 
+  bld.builddir = out
+  
+  bld.add_subdirs('flutter')
+  bld.add_group()
+
+  bld.add_subdirs('ease-core')
+  bld.add_subdirs('data')
+  bld.add_group()
+
+  bld.add_subdirs('ease')
+  bld.add_group()
+  
+  build_pkgconfig_file(bld, "pkgconfig/ease-core-0.5.pc.in")
+  build_pkgconfig_file(bld, "pkgconfig/flutter-0.5.pc.in")
+  
+  build_po(bld)
+
+def run(ctx):
+  system("./waf build")
+  system("LD_LIBRARY_PATH=./build/ease-core:./build/flutter ./build/ease/ease")
+
+def db(ctx):
+  system("./waf build")
+  system("LD_LIBRARY_PATH=./build/ease-core:./build/flutter gdb ./build/ease/ease")



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