[ease/plugins] Re-add sourcelist files.



commit 7c4831852c44485753da6dbd58b38182d8681179
Author: Nate Stedman <natesm gmail com>
Date:   Sun Aug 22 07:12:42 2010 -0400

    Re-add sourcelist files.

 Makefile.am                                       |   10 +-
 ease-core/Makefile.am                             |    8 +
 ease-core/sourcelist/source-base-group.vala       |  120 ++++++++
 ease-core/sourcelist/source-base-view.vala        |   70 +++++
 ease-core/sourcelist/source-expandable-group.vala |   57 ++++
 ease-core/sourcelist/source-group.vala            |   45 +++
 ease-core/sourcelist/source-item.vala             |  301 +++++++++++++++++++++
 ease-core/sourcelist/source-list.vala             |  148 ++++++++++
 ease-core/sourcelist/source-pane-view.vala        |   59 ++++
 ease-core/sourcelist/source-view.vala             |   41 +++
 ease-core/sourcelist/sourcelist-0.1.deps          |    1 +
 11 files changed, 858 insertions(+), 2 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index 4ef6c9e..55f605e 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -27,7 +27,10 @@ doc: ease-core/*.vala
 	
 	valadoc \
 		$(EASE_PACKAGES) \
-		--directory=./doc ./ease-core/*.vala ./flutter/*.vala
+		--directory=./doc \
+		./ease-core/*.vala \
+		ease-core/sourcelist/*.vala \
+		./flutter/*.vala
 	
 	gnome-open doc/doc/Ease.html
 
@@ -38,7 +41,10 @@ doc-internal:
 		--private \
 		--internal \
 		$(EASE_PACKAGES) \
-		--directory=./doc ./ease-core/*.vala ./flutter/*.vala
+		--directory=./doc \
+		./ease-core/*.vala \
+		ease-core/sourcelist/*.vala \
+		./flutter/*.vala
 	
 	gnome-open doc/doc/Ease.html
 
diff --git a/ease-core/Makefile.am b/ease-core/Makefile.am
index db72680..d3e5f43 100644
--- a/ease-core/Makefile.am
+++ b/ease-core/Makefile.am
@@ -45,6 +45,14 @@ libease_core_ EASE_CORE_VERSION@_la_SOURCES = \
 	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-pane-view.vala \
+	sourcelist/source-view.vala \
 	$(NULL)
 
 # compiler flags
diff --git a/ease-core/sourcelist/source-base-group.vala b/ease-core/sourcelist/source-base-group.vala
new file mode 100644
index 0000000..df18486
--- /dev/null
+++ b/ease-core/sourcelist/source-base-group.vala
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2010, Nate Stedman <natesm gmail com>
+ * 
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * Abstract base class for a group in a { link Source.List}.
+ *
+ * Source.BaseGroup can contain any amount of { link Source.Item}s. Above
+ * these items, a header is shown in order to categorize a { link Source.List}.
+ */
+public abstract class Source.BaseGroup : Gtk.Alignment
+{
+	/**
+	 * The group header, displayed on top of the { link Source.Item}s.
+	 */
+	private Gtk.Label header;
+	
+	/**
+	 * The Gtk.VBox containing all { link Source.Item}s.
+	 */
+	private Gtk.VBox items_box;
+	
+	/**
+	 * Alignment containing header. This widget should be packed in subclasses,
+	 * not header itself.
+	 */
+	protected Gtk.Alignment header_align;
+	
+	/**
+	 * Alignment containing items_box. This widget should be packed in
+	 * subclasses, not items_box itself.
+	 */
+	protected Gtk.Alignment items_align;
+	
+	/**
+	 * Format string for the group header.
+	 */
+	private const string HEADER_FORMAT = "<b>%s</b>";
+	
+	/**
+	 * Padding between each { link Source.Item}.
+	 */
+	private const int ITEM_PADDING = 2;
+	
+	/**
+	 * Padding to the left of all items.
+	 */
+	private const int ITEMS_PADDING_LEFT = 5;
+	
+	/**
+	 * Padding to the right of all items.
+	 */
+	private const int ITEMS_PADDING_RIGHT = 5;
+	
+	/**
+	 * Padding above the set of items.
+	 */
+	private const int ITEMS_PADDING_TOP = 5;
+	
+	/**
+	 * Padding below the set of all items.
+	 */
+	private const int ITEMS_PADDING_BOTTOM = 10;
+	
+	/**
+	 * Emitted when a child { link Source.Item} of this group is clicked.
+	 *
+	 * @param sender The { link Source.Item} that was clicked.
+	 */
+	public signal void clicked(Item sender);
+	
+	/**
+	 * Base constructor for subclasses of Source.BaseGroup.
+	 *
+	 * @param title The header of the Source.BaseGroup.
+	 */
+	public BaseGroup(string title)
+	{
+		// create subwidgets
+		items_box = new Gtk.VBox(true, ITEM_PADDING);
+		items_align = new Gtk.Alignment(0, 0, 1, 0);
+		items_align.set_padding(ITEMS_PADDING_TOP,
+		                        ITEMS_PADDING_BOTTOM,
+		                        ITEMS_PADDING_LEFT,
+		                        ITEMS_PADDING_RIGHT);
+		header = new Gtk.Label(HEADER_FORMAT.printf(title));
+		header.use_markup = true;
+		header_align = new Gtk.Alignment(0, 0, 0, 0);
+		
+		set(0, 0, 1, 0);
+		
+		// assemble contents
+		items_align.add(items_box);
+		header_align.add(header);
+	}
+	
+	/**
+	 * Adds a { link Source.Item} to the end of this group.
+	 *
+	 * @param item The { link Source.Item} to add.
+	 */
+	public void add_item(Item item)
+	{
+		items_box.pack_start(item, false, false, 0);
+		item.clicked.connect((sender) => clicked(sender));
+	}
+}
+
diff --git a/ease-core/sourcelist/source-base-view.vala b/ease-core/sourcelist/source-base-view.vala
new file mode 100644
index 0000000..8da23e1
--- /dev/null
+++ b/ease-core/sourcelist/source-base-view.vala
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2010, Nate Stedman <natesm gmail com>
+ * 
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * Abstract base for a simple implementation of a widget using
+ * { link Source.List}.
+ *
+ * Source.BaseView creates a { link Source.List} and a Gtk.Bin. These can be
+ * placed into container widgets by subclasses.
+ */
+public abstract class Source.BaseView : Gtk.Alignment
+{
+	/**
+	 * The content view.
+	 */
+	protected Gtk.Alignment bin;
+	
+	/**
+	 * The { link Source.List} for this Source.BaseView.
+	 */
+	protected Source.List list;
+	
+	/**
+	 * The width request of this Source.BaseView's { link Source.List}.
+	 */
+	public int list_width_request
+	{
+		get { return list.width_request; }
+		set { list.width_request = value; }
+	}
+	
+	/**
+	 * Creates the list and bin widgets. Should be called by subclass
+	 * constructors.
+	 */
+	public BaseView()
+	{
+		// create widgets
+		bin = new Gtk.Alignment(0, 0, 1, 1);
+		list = new Source.List(bin);
+		
+		// set properties
+		set(0, 0, 1, 1);
+	}
+	
+	/**
+	 * Adds a { link Source.BaseGroup} subclass to this
+	 * Source.BaseView's { link Source.List}.
+	 *
+	 * @param group The group to add.
+	 */
+	public void add_group(Source.BaseGroup group)
+	{
+		list.add_group(group);
+	}
+}
+
diff --git a/ease-core/sourcelist/source-expandable-group.vala b/ease-core/sourcelist/source-expandable-group.vala
new file mode 100644
index 0000000..adc179a
--- /dev/null
+++ b/ease-core/sourcelist/source-expandable-group.vala
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2010, Nate Stedman <natesm gmail com>
+ * 
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * An expandable group in a { link Source.List}.
+ *
+ * Source.ExpandableGroup can contain any amount of { link Source.Item}s.
+ * Above these items, a header is shown in order to categorize a
+ * { link Source.List}. Unlike { link Source.Group}, which is VBox based,
+ * ExpandableGroup can be expanded and contracted.
+ */
+public class Source.ExpandableGroup : BaseGroup
+{
+	/**
+	 * The Gtk.Expander containing the header and items_box.
+	 */
+	private Gtk.Expander expander = new Gtk.Expander("");
+	
+	/**
+	 * If the ExpandableGroup's expander is expanded.
+	 */
+	public bool expanded
+	{
+		get { return expander.expanded; }
+		set { expander.expanded = value; }
+	}
+	
+	/**
+	 * Create a new, empty, Source.ExpandableGroup.
+	 *
+	 * @param title The header of the Source.Group.
+	 * @param expanded If the group should be expanded by default.
+	 */
+	public ExpandableGroup(string title, bool expanded)
+	{
+		base(title);
+		
+		expander.label_widget = header_align;
+		expander.can_focus = false;
+		expander.set_expanded(expanded);
+		expander.add(items_align);
+		add(expander);
+	}
+}
diff --git a/ease-core/sourcelist/source-group.vala b/ease-core/sourcelist/source-group.vala
new file mode 100644
index 0000000..c47830a
--- /dev/null
+++ b/ease-core/sourcelist/source-group.vala
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2010, Nate Stedman <natesm gmail com>
+ * 
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * A group in a { link Source.List}.
+ *
+ * Source.Group can contain any amount of { link Source.Item}s. Above these items,
+ * a header is shown in order to categorize a { link Source.List}.
+ */
+public class Source.Group : BaseGroup
+{
+	/**
+	 * The Gtk.VBox containing the header and items_box.
+	 */
+	private Gtk.VBox all_box;
+	
+	/**
+	 * Create a new, empty, Source.Group.
+	 *
+	 * @param title The header of the Source.Group.
+	 */
+	public Group(string title)
+	{
+		base(title);
+		
+		all_box = new Gtk.VBox(false, 0);
+		all_box.pack_start(header_align, false, false, 0);
+		all_box.pack_start(items_align, false, false, 0);
+		add(all_box);
+	}
+}
+
diff --git a/ease-core/sourcelist/source-item.vala b/ease-core/sourcelist/source-item.vala
new file mode 100644
index 0000000..20e9f56
--- /dev/null
+++ b/ease-core/sourcelist/source-item.vala
@@ -0,0 +1,301 @@
+/*
+ * Copyright (c) 2010, Nate Stedman <natesm gmail com>
+ * 
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * An individual item in a { link Source.Group}.
+ *
+ * Source.Item contains a Gtk.Button, which in turn contains an image and a
+ * label. When added to a { link Source.Group}, signals are automatically set
+ * up to manage the { link Source.View} this item is a part of.
+ */
+public class Source.Item : Gtk.HBox
+{
+	/**
+	 * The Source.Item's image widget, displayed on the left.
+	 */
+	private Gtk.Image image;
+	
+	/**
+	 * The Source.Item's label widget, displayed to the right of the image.
+	 */
+	private Gtk.Label label;
+	
+	/**
+	 * The right label widget, which can display a number if desired.
+	 */
+	private Gtk.Label right_label;
+	
+	/**
+	 * The alignment for the right label.
+	 */
+	private Gtk.Alignment right_align;
+	
+	/**
+	 * A number, displayed on the righthand side of the Source.Item. If
+	 * notification is 0, the label is not displayed.
+	 */
+	public int notification
+	{
+		get { return notification_priv; }
+		set
+		{
+			if (value == notification_priv) return;
+			
+			// if value is 0, notification_priv can't be
+			if (value == 0)
+			{
+				// therefore, the widget has been added, so remove it
+				right_align.remove(right_label);
+			}
+			
+			// update the label
+			right_label.label = (selected ?
+			                     FORMAT_RIGHT_OLD : 
+			                     FORMAT_RIGHT_NEW).printf(value);
+			
+			// if necessary, add the label
+			if (notification_priv == 0)
+			{
+				right_align.add(right_label);
+			}
+			
+			// store the value
+			notification_priv = value;
+		}
+	}
+	
+	/**
+	 * Private store for notification value
+	 */
+	private int notification_priv = 0;
+	
+	/**
+	 * The Source.Item's button widget, containing the image and label.
+	 */
+	private Gtk.Button button;
+	
+	/**
+	 * The widget this Source.Item is linked with in its { link Source.View}.
+	 */
+	public Gtk.Widget widget;
+	
+	/**
+	 * The text displayed in the label widget.
+	 */
+	private string label_text;
+	
+	/**
+	 * The size of lefthand side icons.
+	 */
+	public const Gtk.IconSize ICON_SIZE = Gtk.IconSize.MENU;
+	
+	/**
+	 * The padding of the internal button elements.
+	 */
+	private const int HBOX_PADDING = 2;
+	
+	/**
+	 * Format string for selected items.
+	 */
+	private const string FORMAT_SELECTED = "<b>%s</b>";
+	
+	/**
+	 * 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>";
+	
+	/**
+	 * Padding to the sides of the label and image. Not used on the right of
+	 * the image, as the label left padding covers this space.
+	 */
+	private const int ITEM_PADDING = 5;
+	
+	/**
+	 * Alignment of label.
+	 */
+	private const float LABEL_VERT_ALIGN = 0.6f;
+	
+	/**
+	 * Relief style for selected items.
+	 */
+	private const Gtk.ReliefStyle RELIEF_SELECTED = Gtk.ReliefStyle.NORMAL;
+	
+	/**
+	 * Relief style for deselected items.
+	 */
+	private const Gtk.ReliefStyle RELIEF_DESELECTED = Gtk.ReliefStyle.NONE;
+	
+	/**
+	 * If this Source.Item is the selected item in its { link Source.List}.
+	 */
+	public bool selected
+	{
+		get { return button.relief == RELIEF_SELECTED; }
+		set
+		{
+			// don't emit any signals or change anything if it's redundant
+			if (selected == value) return;
+			
+			// otherwise, go ahead
+			button.relief = value ? RELIEF_SELECTED : RELIEF_DESELECTED;
+			label.label = (value ?
+			               FORMAT_SELECTED :
+			               FORMAT_DESELECTED).printf(label_text);
+			
+			// if "selected" is being set to true, emit a signal
+			if (value)
+			{
+				clicked(this);
+				
+				// remove bold from notification text
+				right_label.label = FORMAT_RIGHT_OLD.printf(notification);
+			}
+		}
+	}
+	
+	/**
+	 * Emitted when the Source.Item's Gtk.Button is clicked. Generally used
+	 * internally to change { link Source.List} selection.
+	 *
+	 * @param sender The Source.Item that emitted the signal (generally, "this").
+	 */
+	public signal void clicked(Source.Item sender);
+	
+	/**
+	 * Creates a Source.Item with a customizable icon and text.
+	 *
+	 * @param text The text to display in the source item.
+	 * @param img The image widget to use (note that this icon should use
+	 * the Gtk.IconSize constant ICON_SIZE to fit in with other items).
+	 * @param widg The widget that this Source.Item should be linked with.
+	 * If null, this Source.Item will only emit the clicked signal when 
+	 * clicked, without any automatic UI changes.
+	 */
+	public Item(string text, Gtk.Image img, Gtk.Widget? widg)
+	{
+		// set properties
+		homogeneous = false;
+		label_text = text;
+		widget = widg;
+		
+		// build subwidgets
+		image = img;
+		label = new Gtk.Label(FORMAT_DESELECTED.printf(text));
+		label.use_markup = true;
+		button = new Gtk.Button();
+		button.can_focus = false;
+		selected = false;
+		var label_align = new Gtk.Alignment(0, LABEL_VERT_ALIGN, 0, 0);
+		label_align.set_padding(0, 0, ITEM_PADDING, ITEM_PADDING);
+		right_label = new Gtk.Label("");
+		right_label.use_markup = true;
+		right_align = new Gtk.Alignment(1, LABEL_VERT_ALIGN, 1, 1);
+		var image_align = new Gtk.Alignment(0.5f, 0.5f, 0, 1);
+		image_align.set_padding(0, 0, ITEM_PADDING, 0);
+		
+		// build the source item
+		label_align.add(label);
+		image_align.add(image);
+		var hbox = new Gtk.HBox(false, HBOX_PADDING);
+		hbox.pack_start(image_align, false, false, 0);
+		hbox.pack_start(label_align, true, true, 0);
+		button.add(hbox);
+		
+		pack_start(button, false, false, 0);
+		pack_start(new Gtk.Alignment(1, 1, 0, 0), true, true, 0);
+		pack_end(right_align, false, false, 0);
+		
+		// send the clicked signal when the button is clicked
+		button.clicked.connect(() => {
+			if (!selected)
+			{
+				clicked(this);
+			}
+		});
+	}
+	
+	/**
+	 * Creates a Source.Item with a stock icon and customizable text.
+	 *
+	 * @param text The text to display in the source item.
+	 * @param item The stock item to take the icon from.
+	 * @param widg The widget that this Source.Item should be linked with.
+	 * If null, this Source.Item will only emit the clicked signal when 
+	 * clicked, without any automatic UI changes.
+	 */
+	public Item.from_stock_icon(string text, string item, Gtk.Widget? widg)
+	{
+		this(text, new Gtk.Image.from_stock(item, ICON_SIZE), widg);
+	}
+	
+	/**
+	 * Creates a Source.Item with a stock icon and customizable text.
+	 *
+	 * @param text The text to display in the source item.
+	 * @param item The stock item to take the label from.
+	 * @param img The image widget to use (note that this icon should use
+	 * the Gtk.IconSize constant ICON_SIZE to fit in with other items).
+	 * @param widg The widget that this Source.Item should be linked with.
+	 * If null, this Source.Item will only emit the clicked signal when 
+	 * clicked, without any automatic UI changes.
+	 */
+	public Item.from_stock_text(string item, Gtk.Image img, Gtk.Widget? widg)
+	{
+		Gtk.StockItem stock = Gtk.StockItem();
+		if (Gtk.stock_lookup(item, stock))
+		{
+			this(stock.label.replace("_", ""), img, widg);
+		}
+	}
+	
+	/**
+	 * Creates a Source.Item with a stock icon and text.
+	 *
+	 * @param item The stock item to take the icon and text from.
+	 * @param widg The widget that this Source.Item should be linked with.
+	 * If null, this Source.Item will only emit the clicked signal when 
+	 * clicked, without any automatic UI changes.
+	 */
+	public Item.from_stock(string item, Gtk.Widget? widg)
+	{
+		Gtk.StockItem stock = Gtk.StockItem();
+		if (Gtk.stock_lookup(item, stock))
+		{
+			this(stock.label.replace("_", ""),
+			     new Gtk.Image.from_stock(item, ICON_SIZE),
+			     widg);
+		}
+	}
+	
+	/**
+	 * Selects this Source.Item, emitting a "clicked" signal.
+	 */
+	public void select()
+	{
+		selected = true;
+	}
+}
+
diff --git a/ease-core/sourcelist/source-list.vala b/ease-core/sourcelist/source-list.vala
new file mode 100644
index 0000000..63d5b25
--- /dev/null
+++ b/ease-core/sourcelist/source-list.vala
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2010, Nate Stedman <natesm gmail com>
+ * 
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * A widget for switching between multiple data sources.
+ *
+ * Source.List contains { link Source.Group}s, which in turn contain
+ * { link Source.Item}s. Each Source.Item is linked to a Gtk.Widget, which
+ * is displayed in the Source.List's linked Gtk.Bin when clicked.
+ *
+ * For a simple Source.List next to bin implementation, use { link Source.View}.
+ */
+public class Source.List : Gtk.Alignment
+{
+	/**
+	 * The child of this widget, provides scrollbars if necessary.
+	 */
+	private Gtk.ScrolledWindow scroll;
+	
+	/**
+	 * Gtk.VBox to contain this Source.List's { link Source.Group}s.
+	 */
+	private Gtk.VBox box;
+	
+	/**
+	 * The bin used by this widget's { link Source.Item}s to display their
+	 * linked widgets.
+	 */
+	private Gtk.Bin bin;
+	
+	/**
+	 * The currently selected { link Source.Item}.
+	 */
+	private Source.Item selected;
+	
+	/**
+	 * The Gtk.ShadowType of the scrolled window.
+	 */
+	private const Gtk.ShadowType SHADOW = Gtk.ShadowType.NONE;
+	
+	/**
+	 * The behaviour of the horizontal scroll bar.
+	 */
+	private const Gtk.PolicyType H_POLICY = Gtk.PolicyType.NEVER;
+	
+	/**
+	 * The behaviour of the vertical scroll bar.
+	 */
+	private const Gtk.PolicyType V_POLICY = Gtk.PolicyType.AUTOMATIC;
+	
+	/**
+	 * Padding around the Source.List
+	 */
+	public const int PADDING = 5;
+	
+	/**
+	 * Padding between groups.
+	 */
+	public const int GROUP_PADDING = 5;
+	
+	/**
+	 * Emitted when a { link Source.Item} in this Source.List is clicked.
+	 *
+	 * @param sender The Source.Item that was clicked.
+	 */
+	public signal void clicked(Source.Item sender);
+
+	/**
+	 * Creates a Source.List and links it to a Gtk.Bin
+	 *
+	 * @param linked_bin The Gtk.Bin to link this Source.View with.
+	 */
+	public List(Gtk.Bin linked_bin)
+	{
+		// create widgets
+		scroll = new Gtk.ScrolledWindow(null, null);
+		box = new Gtk.VBox(false, GROUP_PADDING);
+		var viewport = new Gtk.Viewport(null, null);
+		
+		// set properties
+		bin = linked_bin;
+		scroll.shadow_type = SHADOW;
+		viewport.shadow_type = SHADOW;
+		scroll.hscrollbar_policy = H_POLICY;
+		scroll.vscrollbar_policy = V_POLICY;
+		set(0, 0, 1, 1);
+		set_padding(PADDING, PADDING, PADDING, PADDING);
+		
+		// assemble
+		viewport.add(box);
+		scroll.add(viewport);
+		add(scroll);
+	}
+	
+	/**
+	 * Adds a group to the { link Source.List}, automatically setting up click
+	 * signals.
+	 *
+	 * @param group The group to add.
+	 */
+	public void add_group(Source.BaseGroup group)
+	{
+		box.pack_start(group, false, false, 0);
+		
+		group.clicked.connect((sender) => {
+			// deselect the old selected widget, if any
+			if (selected != null && selected != sender)
+			{
+				selected.selected = false;
+			}
+			
+			if (sender.widget != null)
+			{
+				// remove the bin's old child, if any
+				var child = bin.get_child();
+				if (child != null)
+				{
+					bin.remove(child);
+				}
+			
+				// add the new child
+				bin.add(sender.widget);
+				bin.show_all();
+			}
+			
+			// select the sender
+			sender.selected = true;
+			selected = sender;
+		
+			// emit a clicked event
+			clicked(sender);
+		});
+	}
+}
+
diff --git a/ease-core/sourcelist/source-pane-view.vala b/ease-core/sourcelist/source-pane-view.vala
new file mode 100644
index 0000000..9ce91cf
--- /dev/null
+++ b/ease-core/sourcelist/source-pane-view.vala
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2010, Nate Stedman <natesm gmail com>
+ * 
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * An implementation of { link Source.BaseView} with a Gtk.HPaned
+ *
+ * Source.View consists of a { link Source.List}, a separator, and a Gtk.Bin
+ * packed into a Gtk.HBox.
+ */
+public class Source.PaneView : BaseView
+{	
+	/**
+	 * Creates an empty Source.View. Add groups with add_group().
+	 *
+	 * @param with_separator If true, a Gtk.Separator is included to the right
+	 * of the drag handle.
+	 */
+	public PaneView(bool with_separator)
+	{
+		// create base widgets
+		base();
+		
+		// create pane widgets and build the view
+		var hpane = new Gtk.HPaned();
+		hpane.pack1(list, false, false);
+		
+		// if a separator is requested, build an hbox with it and the bin
+		if (with_separator)
+		{
+			var hbox = new Gtk.HBox(false, 0);
+			hbox.pack_start(new Gtk.VSeparator(), false, false, 0);
+			hbox.pack_start(bin, true, true, 0);
+			hpane.pack2(hbox, true, false);
+		}
+		
+		// otherwise, just pack the bin in
+		else
+		{
+			hpane.pack2(bin, true, false);
+		}
+		
+		// add the hpaned to the view
+		add(hpane);
+	}
+}
+
diff --git a/ease-core/sourcelist/source-view.vala b/ease-core/sourcelist/source-view.vala
new file mode 100644
index 0000000..11bbab7
--- /dev/null
+++ b/ease-core/sourcelist/source-view.vala
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2010, Nate Stedman <natesm gmail com>
+ * 
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/**
+ * A simple implementation of a widget using { link Source.List}.
+ *
+ * Source.View consists of a { link Source.List}, a separator, and a Gtk.Bin
+ * packed into a Gtk.HBox.
+ */
+public class Source.View : BaseView
+{	
+	/**
+	 * Creates an empty Source.View. Add groups with add_group().
+	 */
+	public View()
+	{
+		// create the bin and list widgets
+		base();
+		
+		// create the hbox widget and build the full view
+		var hbox = new Gtk.HBox(false, 0);
+		hbox.pack_start(list, false, false, 0);
+		hbox.pack_start(new Gtk.VSeparator(), false, false, 0);
+		hbox.pack_start(bin, true, true, 0);
+		add(hbox);
+	}
+}
+
diff --git a/ease-core/sourcelist/sourcelist-0.1.deps b/ease-core/sourcelist/sourcelist-0.1.deps
new file mode 100644
index 0000000..24a2237
--- /dev/null
+++ b/ease-core/sourcelist/sourcelist-0.1.deps
@@ -0,0 +1 @@
+gtk+-2.0



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