[ease/themes] Switch to using a string/strut style method of scaling themes.



commit dc022e01cea22fc74d121af790dfb4e98ce5784b
Author: Nate Stedman <natesm gmail com>
Date:   Mon Jun 7 18:20:03 2010 -0400

    Switch to using a string/strut style method of scaling themes.
    
    - Adds the MasterElement class, an element on a master slide.
    - Theme elements expand and contract intelligently, rather than with scaling
    - Modified example theme to reflect these changes.

 Makefile.am             |    2 +
 src/JSONParser.vala     |   20 +++-
 src/MasterElement.vala  |  241 +++++++++++++++++++++++++++++++++++++++++++++++
 src/Slide.vala          |   17 +---
 themes/White/Theme.json |   39 +++++---
 5 files changed, 285 insertions(+), 34 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index ea295c1..cf8da45 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -31,6 +31,7 @@ ease_SOURCES = \
 	src/JSONParser.vala\
 	src/MainToolbar.vala \
 	src/Main.vala \
+	src/MasterElement.vala \
 	src/OpenDialog.vala \
 	src/PDFExporter.vala \
 	src/Player.vala \
@@ -53,6 +54,7 @@ ease_SOURCES = \
 	src/WelcomeWindow.vala \
 	src/ZoomSlider.vala \
 	$(NULL)
+
 # ease_VALAFLAGS = $(EASE_PACKAGES)
 VALAFLAGS = --pkg glib-2.0 \
 		--pkg gtk+-2.0 \
diff --git a/src/JSONParser.vala b/src/JSONParser.vala
index 1b6d328..4192901 100644
--- a/src/JSONParser.vala
+++ b/src/JSONParser.vala
@@ -51,7 +51,7 @@ public static class Ease.JSONParser
 		for (var i = 0; i < slides.get_length(); i++)
 		{
 			var node = slides.get_object_element(i);
-			document.add_slide(document.length, parse_slide(node));
+			document.add_slide(document.length, parse_slide(node, false));
 		}
 		
 		return document;
@@ -85,13 +85,13 @@ public static class Ease.JSONParser
 		for (var i = 0; i < slides.get_length(); i++)
 		{
 			var node = slides.get_object_element(i);
-			theme.add_slide(theme.length, parse_slide(node));
+			theme.add_slide(theme.length, parse_slide(node, true));
 		}
 		
 		return theme;
 	}
 	
-	private static Slide parse_slide(Json.Object obj)
+	private static Slide parse_slide(Json.Object obj, bool theme)
 	{
 		var slide = new Slide();
 		
@@ -138,15 +138,23 @@ public static class Ease.JSONParser
 		for (var i = 0; i < elements.get_length(); i++)
 		{
 			var node = elements.get_object_element(i);
-			slide.add_element(slide.count, parse_element(node));
+			slide.add_element(slide.count, parse_element(node, theme));
 		}
 		
 		return slide;
 	}
 	
-	private static Element parse_element(Json.Object obj)
+	private static Element parse_element(Json.Object obj, bool theme)
 	{
-		var element = new Element();
+		Element element;
+		if (theme)
+		{
+			element = new MasterElement();
+		}
+		else
+		{
+			element = new Element();
+		}
 		
 		// set the Element's properties
 		for (unowned List<string>* itr = obj.get_members();
diff --git a/src/MasterElement.vala b/src/MasterElement.vala
new file mode 100644
index 0000000..80a03bb
--- /dev/null
+++ b/src/MasterElement.vala
@@ -0,0 +1,241 @@
+/*  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 master { link Element}, which supports resizing to different resolutions.
+ *
+ * MasterElement is mostly a set of extension convenience properties on top of
+ * the base { link Element} class. These properties, list those in
+ * { link Element}, are simply wrappers around data store, { link ElementMap},
+ * translating to and from string.
+ *
+ * Ease uses a "base resolution" of 1024 by 768, a common projector resolution.
+ * Unlike { link Element}, which expresses positions in x, y, width, and height,
+ * MasterElement expressed them in left, right, top, and bottom. As the total
+ * size of the presentation is known, the actual sizes can be easily calculated.
+ * Then, the Element's size can be increased or decreased by using the
+ * four directional bind_ properties and the expand_.
+ *
+ * For example, the "header" font for a theme will often be selected so that a
+ * single line fits perfectly in the space allocated for the header. Therefore,
+ * increasing the height at a greater resolution is a waste of space, and
+ * decreasing the size at a lower resolution will cause the text not to fit in
+ * the box. Therefore, the header should be bound to the top, but not to the
+ * bottom. expand_vertically should be false.
+ *
+ * In contrast, the content box below the header is designed for an arbitrary
+ * amount of lines. Therefore, this box should scale vertically, shrinking as
+ * the presentation gets smaller, and enlarging as the presentation gets larger.
+ * To do this, both bind_bottom and bind_top should be true, as well as
+ * expand_vertically.
+ *
+ * While the bind_left and bind_right properties exist, it's not clear whether
+ * or not they will actually be useful at any point. They perform in the same
+ * manner as the other two bind_ properties, but for horizontal scaling. The
+ * same applies to the expand_horizontally property. In general
+ */
+public class Ease.MasterElement : Element
+{
+	private const float WIDTH = 1024;
+	private const float HEIGHT = 768;
+
+	/**
+	 * If the Element should maintain "top" when resized.
+	 *
+	 * To scale to different resolutions, MasterElement tracks the distance of
+	 * Elements from each edge, and maintains them as these edges expand if the
+	 * appropriate bind_ and expand_ properties are true.
+	 */
+	public bool bind_top
+	{
+		get { return data.get("bind_top").to_bool(); }
+		set { data.set("bind_top", value.to_string()); }
+	}
+	
+	/**
+	 * If the Element should maintain "bottom" when resized.
+	 *
+	 * To scale to different resolutions, MasterElement tracks the distance of
+	 * Elements from each edge, and maintains them as these edges expand if the
+	 * appropriate bind_ and expand_ properties are true.
+	 */
+	public bool bind_bottom
+	{
+		get { return data.get("bind_bottom").to_bool(); }
+		set { data.set("bind_bottom", value.to_string()); }
+	}
+	
+	/**
+	 * If the Element should maintain "left" when resized.
+	 *
+	 * To scale to different resolutions, MasterElement tracks the distance of
+	 * Elements from each edge, and maintains them as these edges expand if the
+	 * appropriate bind_ and expand_ properties are true.
+	 */
+	public bool bind_left
+	{
+		get { return data.get("bind_left").to_bool(); }
+		set { data.set("bind_left", value.to_string()); }
+	}
+	
+	/**
+	 * If the Element should maintain "right" when resized.
+	 *
+	 * To scale to different resolutions, MasterElement tracks the distance of
+	 * Elements from each edge, and maintains them as these edges expand if the
+	 * appropriate bind_ and expand_ properties are true.
+	 */
+	public bool bind_right
+	{
+		get { return data.get("bind_right").to_bool(); }
+		set { data.set("bind_right", value.to_string()); }
+	}
+	
+	/**
+	 * If the Element should expand horizontally when resized.
+	 *
+	 * To scale to different resolutions, MasterElement tracks the distance of
+	 * Elements from each edge, and maintains them as these edges expand if the
+	 * appropriate bind_ and expand_ properties are true.
+	 */
+	public bool expand_horizontally
+	{
+		get { return data.get("expand_horizontally").to_bool(); }
+		set { data.set("expand_horizontally", value.to_string()); }
+	}
+	
+	/**
+	 * If the Element should expand vertically when resized.
+	 *
+	 * To scale to different resolutions, MasterElement tracks the distance of
+	 * Elements from each edge, and maintains them as these edges expand if the
+	 * appropriate bind_ and expand_ properties are true.
+	 */
+	public bool expand_vertically
+	{
+		get { return data.get("expand_vertically").to_bool(); }
+		set { data.set("expand_vertically", value.to_string()); }
+	}
+	
+	/**
+	 * The Element's distance from the top of the screen.
+	 */
+	public float top
+	{
+		get { return (float)data.get("top").to_double(); }
+		set { data.set("top", value.to_string()); }
+	}
+	
+	/**
+	 * The Element's distance from the bottom of the screen.
+	 */
+	public float bottom
+	{
+		get { return (float)data.get("bottom").to_double(); }
+		set { data.set("bottom", value.to_string()); }
+	}
+	
+	/**
+	 * The Element's distance from the left edge of the screen.
+	 */
+	public float left
+	{
+		get { return (float)data.get("left").to_double(); }
+		set { data.set("left", value.to_string()); }
+	}
+	
+	/**
+	 * The Element's distance from the right edge of the screen.
+	 */
+	public float right
+	{
+		get { return (float)data.get("right").to_double(); }
+		set { data.set("right", value.to_string()); }
+	}
+	
+	/**
+	 * Creates an { link Element} from this MasterElement at the specified size.
+	 *
+	 * @param w The width of the { link Document} the new Element will be a
+	 * part of.
+	 * @param w The height of the { link Document} the new Element will be a
+	 * part of.
+	 */
+	public Element sized_element(float w, float h)
+	{
+		// copy this MasterElement into the Element
+		var element = copy();
+		
+		// find the differences in each direction for the new resolution
+		var x_diff = (w - WIDTH) / 2;
+		var y_diff = (h - HEIGHT) / 2;
+		
+		// set the base size (at 1024x768)
+		element.width = WIDTH - left - right;
+		element.height = HEIGHT - top - bottom;
+		
+		// handle binding to the left
+		if (bind_left)
+		{
+			element.x = left;
+			
+			if (expand_horizontally)
+			{
+				element.width += x_diff;
+			}
+		}
+		else
+		{
+			element.x = left + x_diff; 
+		}
+		
+		// handle binding to the top
+		if (bind_top)
+		{
+			element.y = top;
+			
+			if (expand_vertically)
+			{
+				element.height += y_diff;
+			}
+		}
+		else
+		{
+			element.y = top + y_diff;
+		}
+		
+		// handle binding to the right
+		if (bind_right)
+		{	
+			if (expand_horizontally)
+			{
+				element.width += x_diff;
+			}
+		}
+		
+		// handle binding to the bottom
+		if (bind_bottom)
+		{	
+			if (expand_vertically)
+			{
+				element.height += y_diff;
+			}
+		}
+		
+		return element;
+	}
+}
diff --git a/src/Slide.vala b/src/Slide.vala
index de1ee45..ae358c6 100644
--- a/src/Slide.vala
+++ b/src/Slide.vala
@@ -22,7 +22,7 @@
  * children. The currently selected Slide is often acted upon by an
  * { link EditorWindow}.
  */
-public class Ease.Slide
+public class Ease.Slide : GLib.Object
 {
 	/**
 	 * The { link Element}s contained by this Slide
@@ -198,20 +198,7 @@ public class Ease.Slide
 		// add all of the master Slide's elements
 		foreach (var e in master.elements)
 		{
-			// copy the Element
-			var element = e.copy();
-			element.parent = this;
-			
-			// resize the Element to fit the Document
-			element.x = (int)(element.get("x").to_double() * width);
-			element.y = (int)(element.get("y").to_double() * height);
-			element.width = (int)(element.get("width").to_double() *
-			                      width);
-			element.height = (int)(element.get("height").to_double() *
-			                       height);
-			
-			// add the Element to the new Slide
-			elements.add(element);
+			elements.add(((MasterElement)e).sized_element(width, height));
 		}
 	}
 	
diff --git a/themes/White/Theme.json b/themes/White/Theme.json
index ae7fbef..dfa7d2e 100644
--- a/themes/White/Theme.json
+++ b/themes/White/Theme.json
@@ -10,41 +10,54 @@
       "elements" : [
         {
           "font_variant" : "Normal",
-          "y" : "0.05",
-          "x" : "0.05",
-          "height" : "0.1",
           "font_style" : "Normal",
           "element_type" : "text",
           "identifier" : "header",
           "green" : "0",
           "align" : "left",
           "text" : "Lorem Ipsum Dolor",
-          "width" : "0.9",
           "blue" : "0",
           "font_weight" : "900",
           "red" : "0",
           "ease_name" : "header",
           "font_name" : "Sans",
-          "font_size" : "36"
+          "font_size" : "36",
+          "left" : "30",
+          "right" : "30",
+          "top" : "30",
+          "bottom" : "678",
+          "bind_left" : "true",
+          "bind_right" : "true",
+          "bind_top" : "true",
+          "bind_bottom" : "false",
+          "expand_horizontally" : "true",
+          "expand_vertically" : "false"
         },
+        
         {
           "font_variant" : "Normal",
-          "y" : "0.2",
-          "x" : "0.05",
-          "height" : "0.75",
           "font_style" : "Normal",
           "element_type" : "text",
-          "identifier" : "main-text",
+          "identifier" : "header",
           "green" : "0",
           "align" : "left",
           "text" : "Sit amet, consectetur adipiscing elit. Maecenas sed odio eget purus laoreet volutpat. Etiam nulla orci, eleifend nec sodales in, tempor cursus urna. Aenean posuere aliquet malesuada. Integer varius placerat massa. Pellentesque enim urna, cursus et molestie et, iaculis vitae libero. Quisque vel metus sed magna lacinia luctus. Suspendisse vel lectus eget diam dapibus condimentum. Aliquam a dolor vel sem rutrum mattis sit amet vitae nisl. Etiam vel sem tortor. Vestibulum varius metus id orci vulputate viverra luctus magna commodo. Duis dignissim sollicitudin leo eget tristique. Maecenas adipiscing neque nec mauris mollis ut ultrices sem porta. Cras vitae massa lectus. Aenean orci lectus, pretium nec sodales eu, aliquam vitae neque. Mauris nibh lectus, porta et vestibulum a, vestibulum a nulla.",
-          "width" : "0.9",
           "blue" : "0",
-          "font_weight" : "500",
+          "font_weight" : "900",
           "red" : "0",
-          "ease_name" : "text",
+          "ease_name" : "header",
           "font_name" : "Sans",
-          "font_size" : "16"
+          "font_size" : "16",
+          "left" : "30",
+          "right" : "30",
+          "top" : "100",
+          "bottom" : "30",
+          "bind_left" : "true",
+          "bind_right" : "true",
+          "bind_top" : "true",
+          "bind_bottom" : "true",
+          "expand_horizontally" : "true",
+          "expand_vertically" : "true"
         }
       ],
       "blue" : "255",



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