[ease/sourceview] Added a "SourceView" widget and corresponding components.



commit 28309260edba62b3864fe3646bb7a1ab772e2e99
Author: Nate Stedman <natesm gmail com>
Date:   Fri Jun 11 18:29:41 2010 -0400

    Added a "SourceView" widget and corresponding components.
    
    - SourceItem: the basic button widget
    - SourceGroup: a group of items, with a header
    - SourceList: a group of groups, controls a GtkBin
    - SourceView: a simple implementation of SourceList and a bin.

 Makefile.am          |    4 +
 src/Main.vala        |   46 ++++++++++++-
 src/SourceGroup.vala |  119 ++++++++++++++++++++++++++++++
 src/SourceItem.vala  |  197 ++++++++++++++++++++++++++++++++++++++++++++++++++
 src/SourceList.vala  |  132 +++++++++++++++++++++++++++++++++
 src/SourceView.vala  |   64 ++++++++++++++++
 6 files changed, 561 insertions(+), 1 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index b6651b5..1bd1c99 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -42,6 +42,10 @@ ease_SOURCES = \
 	src/SlidePane.vala \
 	src/SlideSet.vala \
 	src/Slide.vala \
+	src/SourceGroup.vala \
+	src/SourceItem.vala \
+	src/SourceList.vala \
+	src/SourceView.vala \
 	src/Temp.vala \
 	src/TextActor.vala \
 	src/TextElement.vala \
diff --git a/src/Main.vala b/src/Main.vala
index cedade8..55f556c 100644
--- a/src/Main.vala
+++ b/src/Main.vala
@@ -55,7 +55,7 @@ public static class Ease.Main : GLib.Object
 	 * @param args Program arguments.
 	 */
 	public static int main(string[] args)
-	{
+	{	
 		// parse command line options
 		var context = new OptionContext(_(" - a presentation editor"));
 		
@@ -128,6 +128,8 @@ public static class Ease.Main : GLib.Object
 		{
 			show_welcome();
 		}
+		
+		test_sourceview();
 	
 		Gtk.main();
 		
@@ -239,5 +241,47 @@ public static class Ease.Main : GLib.Object
 			Gtk.main_quit();
 		}
 	}
+	
+	public static void test_sourceview()
+	{
+		SourceView view = new SourceView();
+		
+		var group = new SourceGroup("Test Group 1");
+		var text = new Gtk.TextView();
+		var item = new SourceItem.from_stock("gtk-new", text);
+		group.add_item(item);
+		text = new Gtk.TextView();
+		item = new SourceItem.from_stock("gtk-open", text);
+		group.add_item(item);
+		text = new Gtk.TextView();
+		item = new SourceItem.from_stock("gtk-undo", text);
+		group.add_item(item);
+		text = new Gtk.TextView();
+		item = new SourceItem.from_stock("gtk-redo", text);
+		group.add_item(item);
+		view.add_group(group);
+		
+		group = new SourceGroup("Test Group 2");
+		text = new Gtk.TextView();
+		item = new SourceItem.from_stock("gtk-add", text);
+		group.add_item(item);
+		text = new Gtk.TextView();
+		item = new SourceItem.from_stock("gtk-about", text);
+		group.add_item(item);
+		text = new Gtk.TextView();
+		item = new SourceItem.from_stock("gtk-floppy", text);
+		group.add_item(item);
+		view.add_group(group);
+		
+		item.selected = true;
+		
+		text = new Gtk.TextView();
+		
+		var window = new Gtk.Window(Gtk.WindowType.TOPLEVEL);
+		window.add(view);
+		//window.add(new SourceItem.from_stock("gtk-new", text));
+		window.set_size_request(640, 480);
+		window.show_all();
+	}
 }
 
diff --git a/src/SourceGroup.vala b/src/SourceGroup.vala
new file mode 100644
index 0000000..6fc3a82
--- /dev/null
+++ b/src/SourceGroup.vala
@@ -0,0 +1,119 @@
+/*  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 group in a { link SourceList}.
+ *
+ * SourceGroup can contain any amount of { link SourceItem}s. Above these items,
+ * a header is shown in order to categorize a { link SourceList}.
+ */
+public class Ease.SourceGroup : Gtk.Alignment
+{
+	/**
+	 * The group header, displayed on top of the { link SourceItem}s.
+	 */
+	private Gtk.Label header;
+	
+	/**
+	 * The Gtk.VBox containing all { link SourceItem}s.
+	 */
+	private Gtk.VBox items_box;
+	
+	/**
+	 * The Gtk.VBox containing the header and items_box.
+	 */
+	private Gtk.VBox all_box;
+	
+	/**
+	 * Format string for the group header.
+	 */
+	private const string HEADER_FORMAT = "<b>%s</b>";
+	
+	/**
+	 * Padding between each { link SourceItem}.
+	 */
+	private const int ITEM_PADDING = 2;
+	
+	/**
+	 * Padding to the left of all items.
+	 */
+	private const int ITEMS_PADDING_LEFT = 15;
+	
+	/**
+	 * 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 SourceItem} of this group is clicked.
+	 *
+	 * @param sender The { link SourceItem} that was clicked.
+	 */
+	public signal void clicked(SourceItem sender);
+	
+	/**
+	 * Create a new, empty, SourceGroup.
+	 *
+	 * @param title The header of the SourceGroup.
+	 */
+	public SourceGroup(string title)
+	{
+		// create subwidgets
+		all_box = new Gtk.VBox(false, 0);
+		items_box = new Gtk.VBox(true, ITEM_PADDING);
+		var items_align = new Gtk.Alignment(0, 0, 0, 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;
+		var 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);
+		all_box.pack_start(header_align, false, false, 0);
+		all_box.pack_start(items_align, false, false, 0);
+		add(all_box);
+	}
+	
+	/**
+	 * Adds a { link SourceItem} to the end of this group.
+	 *
+	 * @param item The { link SourceItem} to add.
+	 */
+	public void add_item(SourceItem item)
+	{
+		items_box.pack_start(item, false, false, 0);
+		
+		item.clicked.connect((sender) => clicked(sender));
+	}
+}
+
diff --git a/src/SourceItem.vala b/src/SourceItem.vala
new file mode 100644
index 0000000..c2b04ff
--- /dev/null
+++ b/src/SourceItem.vala
@@ -0,0 +1,197 @@
+/*  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/>.
+*/
+
+/**
+ * An individual item in a { link SourceGroup}.
+ *
+ * SourceItem contains a Gtk.Button, which in turn contains an image and a
+ * label. When added to a { link SourceGroup}, signals are automatically set
+ * up to manage the { link SourceView} this item is a part of.
+ */
+public class Ease.SourceItem : Gtk.HBox
+{
+	/**
+	 * The SourceItem's image widget, displayed on the left.
+	 */
+	private Gtk.Image image;
+	
+	/**
+	 * The SourceItem's label widget, displayed to the right of the image.
+	 */
+	private Gtk.Label label;
+	
+	/**
+	 * The SourceItem's button widget, containing the image and label.
+	 */
+	private Gtk.Button button;
+	
+	/**
+	 * The widget this SourceItem is linked with in its { link SourceView}.
+	 */
+	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";
+	
+	/**
+	 * Left padding of label.
+	 */
+	private const int LABEL_LEFT_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 SourceItem is the selected item in its { link SourceList}.
+	 */
+	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);
+			}
+		}
+	}
+	
+	/**
+	 * Emitted when the SourceItem's Gtk.Button is clicked. Generally used
+	 * internally to change { link SourceList} selection.
+	 *
+	 * @param sender The SourceItem that emitted the signal (generally, "this").
+	 */
+	public signal void clicked(SourceItem sender);
+	
+	/**
+	 * Creates a SourceItem 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 SourceItem should be linked with.
+	 */
+	public SourceItem(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, LABEL_LEFT_PADDING, 0);
+		
+		// build the source item
+		label_align.add(label);
+		var hbox = new Gtk.HBox(false, HBOX_PADDING);
+		hbox.pack_start(image, false, false, 0);
+		hbox.pack_start(label_align, true, true, 0);
+		button.add(hbox);
+		
+		pack_start(button, false, false, 0);
+		
+		// send the clicked signal when the button is clicked
+		button.clicked.connect(() => {
+			if (!selected)
+			{
+				clicked(this);
+			}
+		});
+	}
+	
+	/**
+	 * Creates a SourceItem 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 SourceItem should be linked with.
+	 */
+	public SourceItem.stock_icon(string text, string item, Gtk.Widget widg)
+	{
+		this(text, new Gtk.Image.from_stock(item, ICON_SIZE), widg);
+	}
+	
+	/**
+	 * Creates a SourceItem with a stock icon and text.
+	 *
+	 * @param item The stock item to take the icon and text from.
+	 * @param widg The widget that this SourceItem should be linked with.
+	 */
+	public SourceItem.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);
+		}
+	}
+}
+
diff --git a/src/SourceList.vala b/src/SourceList.vala
new file mode 100644
index 0000000..62578cc
--- /dev/null
+++ b/src/SourceList.vala
@@ -0,0 +1,132 @@
+/*  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 for switching between multiple data sources.
+ *
+ * SourceList contains { link SourceGroup}s, which in turn contain
+ * { link SourceItem}s. Each SourceItem is linked to a Gtk.Widget, which
+ * is displayed in the SourceList's linked Gtk.Bin when clicked.
+ *
+ * For a simple SourceList next to bin implementation, use { link SourceView}.
+ */
+public class Ease.SourceList : Gtk.Alignment
+{
+	/**
+	 * The child of this widget, provides scrollbars if necessary.
+	 */
+	private Gtk.ScrolledWindow scroll;
+	
+	/**
+	 * Gtk.VBox to contain this SourceList's { link SourceGroup}s.
+	 */
+	private Gtk.VBox box;
+	
+	/**
+	 * The bin used by this widget's { link SourceItem}s to display their
+	 * linked widgets.
+	 */
+	private Gtk.Bin bin;
+	
+	/**
+	 * The currently selected { link SourceItem}.
+	 */
+	private SourceItem 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;
+	
+	/**
+	 * Emitted when a { link SourceItem} in this SourceList is clicked.
+	 *
+	 * @param sender The SourceItem that was clicked.
+	 */
+	public signal void clicked(SourceItem sender);
+
+	/**
+	 * Creates a SourceList and links it to a Gtk.Bin
+	 *
+	 * @param linked_bin The Gtk.Bin to link this SourceView with.
+	 */
+	public SourceList(Gtk.Bin linked_bin)
+	{
+		// create widgets
+		scroll = new Gtk.ScrolledWindow(null, null);
+		box = new Gtk.VBox(false, 0);
+		
+		// set properties
+		bin = linked_bin;
+		scroll.shadow_type = SHADOW;
+		scroll.hscrollbar_policy = H_POLICY;
+		scroll.vscrollbar_policy = V_POLICY;
+		set(0, 0, 1, 1);
+		
+		// assemble
+		scroll.add_with_viewport(box);
+		add(scroll);
+	}
+	
+	/**
+	 * Adds a group to the { link SourceList}, automatically setting up click
+	 * signals.
+	 *
+	 * @param group The group to add.
+	 */
+	public void add_group(SourceGroup 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;
+			}
+			
+			// 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/src/SourceView.vala b/src/SourceView.vala
new file mode 100644
index 0000000..cb6b0e5
--- /dev/null
+++ b/src/SourceView.vala
@@ -0,0 +1,64 @@
+/*  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 simple implementation of a widget using { link SourceList}.
+ *
+ * SourceView consists of a { link SourceList} and a Gtk.Bin packed into a
+ * Gtk.HBox.
+ */
+public class Ease.SourceView : Gtk.HBox
+{
+	/**
+	 * The content view.
+	 */
+	private Gtk.Alignment bin;
+	
+	/**
+	 * The { link SourceList} for this SourceView.
+	 */
+	private SourceList list;
+	
+	/**
+	 * Creates an empty SourceView. Add groups with add_group().
+	 */
+	public SourceView()
+	{
+		// create widgets
+		bin = new Gtk.Alignment(0, 0, 1, 1);
+		list = new SourceList(bin);
+		
+		// set properties
+		homogeneous = false;
+		
+		// assemble
+		pack_start(list, false, false, 0);
+		pack_start(new Gtk.VSeparator(), false, false, 0);
+		pack_start(bin, true, true, 0);
+	}
+	
+	/**
+	 * Adds a { link SourceGroup} to this SourceView's { link SourceList}.
+	 *
+	 * @param group The group to add.
+	 */
+	public void add_group(SourceGroup group)
+	{
+		list.add_group(group);
+	}
+}
+



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