[ease/themes: 125/125] [themes] Started new themes system.
- From: Nate Stedman <natesm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [ease/themes: 125/125] [themes] Started new themes system.
- Date: Wed, 21 Jul 2010 17:24:06 +0000 (UTC)
commit a8621726f060bacd7ab104a832f08a702868efed
Author: Nate Stedman <natesm gmail com>
Date: Wed Jul 21 13:23:24 2010 -0400
[themes] Started new themes system.
data/Makefile.am | 8 +-
data/theme-defaults.json | 27 ++++
src/ease-json-parser.vala | 34 -----
src/ease-slide.vala | 11 ++
src/ease-theme.vala | 334 ++++++++++++++++++++++++++++++++++++++++++++-
5 files changed, 376 insertions(+), 38 deletions(-)
---
diff --git a/data/Makefile.am b/data/Makefile.am
index a76ec48..ba8b5f5 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -10,5 +10,11 @@ svg_DATA = $(wildcard $(top_srcdir)/data/svg/*.svg)
uidir = $(datadir)/ease/ui
ui_DATA = $(wildcard $(top_srcdir)/data/ui/*.ui)
-EXTRA_DIST = $(ui_DATA) $(svg_DATA) $(desktop_in_files)
+jsondir = $(datadir)/ease
+json_DATA = theme-defaults.json
+EXTRA_DIST = \
+ $(ui_DATA) \
+ $(svg_DATA) \
+ $(desktop_in_files) \
+ $(json_DATA)
diff --git a/data/theme-defaults.json b/data/theme-defaults.json
new file mode 100644
index 0000000..7c9cdd8
--- /dev/null
+++ b/data/theme-defaults.json
@@ -0,0 +1,27 @@
+{
+ "master-defaults" : {
+ "background-color" : "#FFFFFFFF"
+ },
+
+ "text-defaults" : {
+ "text-font" : "Bitstream Vera Sans",
+ "text-size" : "12",
+ "padding-top" : "10",
+ "padding-left" : "10",
+ "padding-right" : "10",
+ "padding-bottom" : "10"
+ }
+
+ "elements" : [
+ "header-text" : {
+ "height" : "30",
+ "text-size" : "24"
+ },
+
+ "author-text" : {
+ "padding-top" : "0",
+ "height" : "20",
+ "text-size" : "18"
+ }
+ ]
+}
diff --git a/src/ease-json-parser.vala b/src/ease-json-parser.vala
index d3b262d..14fb45a 100644
--- a/src/ease-json-parser.vala
+++ b/src/ease-json-parser.vala
@@ -60,40 +60,6 @@ public static class Ease.JSONParser
return document;
}
- /**
- * Parses a theme JSON file, creating a { link Theme}.
- *
- * @param path The path to the { link Theme}
- */
- public static Theme theme(string path) throws GLib.Error
- {
- string filename = absolute_path(path);
- var theme = new Theme();
- theme.path = Temp.extract(filename);
-
- var parser = new Json.Parser();
-
- // attempt to load the file
- parser.load_from_file(Path.build_filename(theme.path, "Theme.json"));
-
- // grab the root object
- var root = parser.get_root().get_object();
-
- // set theme properties
- theme.title = root.get_string_member("title");
-
- // add all slides
- var slides = root.get_array_member("slides");
-
- for (var i = 0; i < slides.get_length(); i++)
- {
- var node = slides.get_object_element(i);
- theme.add_slide(theme.length, parse_slide(node));
- }
-
- return theme;
- }
-
private static Slide parse_slide(Json.Object obj)
{
var slide = new Slide();
diff --git a/src/ease-slide.vala b/src/ease-slide.vala
index 469a98a..7f236d4 100644
--- a/src/ease-slide.vala
+++ b/src/ease-slide.vala
@@ -217,6 +217,17 @@ public class Ease.Slide : GLib.Object
}
/**
+ * Adds an { link Element} to this slide at the end index.
+ *
+ * @param e The element to add;.
+ */
+ public void add(Element e)
+ {
+ e.parent = this;
+ elements.insert(count - 1, e);
+ }
+
+ /**
* Creates HTML markup for this Slide.
*
* The <div> tag for this Slide is appended to the "HTML" parameter.
diff --git a/src/ease-theme.vala b/src/ease-theme.vala
index ad3f891..ecdc6a7 100644
--- a/src/ease-theme.vala
+++ b/src/ease-theme.vala
@@ -16,18 +16,346 @@
*/
/**
- * Internal representation of Ease themes
+ * Internal representation of Ease themes.
*/
-public class Ease.Theme : SlideSet
+public class Ease.Theme : GLib.Object
{
+ // json file
+ private const string DEFAULTS_PATH = "theme-defaults.json";
+ private const string MASTERS = "masters";
+ private const string ELEMENTS = "elements";
+ private const string MASTER_DEF = "master-defaults";
+ private const string ELEMENT_DEF = "element-defaults";
+
+ // master slides
+ public const string TITLE = "title";
+ public const string CONTENT = "content";
+ public const string CONTENT_HEADER = "content-header";
+ public const string CONTENT_DUAL = "content-dual";
+ public const string CONTENT_DUAL_HEADER = "content-dual-header";
+ public const string MEDIA = "media";
+ public const string MEDIA_HEADER = "media-header";
+
+ // text content types
+ private const string TITLE_TEXT = "title-text";
+ private const string AUTHOR_TEXT = "author-text";
+ private const string CONTENT_TEXT = "content-text";
+ private const string HEADER_TEXT = "header-text";
+
+ // text properties
+ private const string TEXT_FONT = "text-font";
+ private const string TEXT_SIZE = "text-size";
+
+ // media content types
+ public const string CONTENT_MEDIA = "content-media";
+
+ // generic element properties
+ public const string PAD_LEFT = "padding-left";
+ public const string PAD_RIGHT = "padding-right";
+ public const string PAD_TOP = "padding-top";
+ public const string PAD_BOTTOM = "padding-bottom";
+ public const string WIDTH = "width";
+ public const string HEIGHT = "height";
+
/**
* The title of the Theme.
*/
public string title { get; set; }
+
+ /**
+ * A map of internal master slide settings overriden by the theme.
+ */
+ private Gee.Map<string, Gee.Map<string, string>> masters;
+
+ /**
+ * A map of internal element settings overriden by the theme.
+ */
+ private Gee.Map<string, Gee.Map<string, string>> elements;
+
+ /**
+ * A map of master slide settings, used as a fallback for all masters when
+ * the specified master does not provide the given property.
+ *
+ * For example, the background properties are typically the same
+ * throughout the theme. This is an efficient place for those properties.
+ */
+ private Gee.Map<string, string> master_defaults;
+
+ /**
+ * A map of element settings, used as a fallback for all elements when
+ * the specified element does not provide the given property.
+ *
+ * For example, the text-font property is often the same throughout the
+ * theme. This is an efficient place for properties like that.
+ */
+ private Gee.Map<string, string> element_defaults;
+
+ /**
+ * A Theme containing default values for elements and master slides.
+ */
+ private static Theme defaults
+ {
+ get
+ {
+ if (defaults_store != null) return defaults_store;
+ return defaults_store = new Theme(data_path(DEFAULTS_PATH));
+ }
+ }
+
+ /**
+ * Storage for "defaults" property.
+ */
+ private static Theme defaults_store;
/**
* Creates an empty Theme.
+ *
+ * @param path The path to the theme's JSON file.
*/
- public Theme() { }
+ public Theme(string path)
+ {
+ // create collections
+ masters = new Gee.HashMap<string, Gee.Map<string, string>>();
+ elements = new Gee.HashMap<string, Gee.Map<string, string>>();
+ master_defaults = new Gee.HashMap<string, string>();
+ element_defaults = new Gee.HashMap<string, string>();
+
+ var parser = new Json.Parser();
+ try { parser.load_from_file(path); }
+ catch (GLib.Error e)
+ {
+ if (path == DEFAULTS_PATH)
+ {
+ error(_("Could not load theme defaults: %s"), e.message);
+ }
+ else
+ {
+ error_dialog(_("Error Loading Theme"),
+ (_("Error loading theme: %s\n\n") + e.message).
+ printf(path));
+ }
+ }
+
+
+ // get the document's root element
+ var root = parser.get_root().get_object();
+
+ // find all masters and element overrides
+ fill_map(root, MASTERS, masters);
+ fill_map(root, ELEMENTS, elements);
+ fill_single_map(root.get_object_member(MASTER_DEF), master_defaults);
+ fill_single_map(root.get_object_member(ELEMENT_DEF), element_defaults);
+ }
+
+ public Slide? create_slide(string master, int width, int height)
+ {
+ Slide slide = new Slide();
+
+ switch (master)
+ {
+ case TITLE:
+ // create the presentation's title
+ int left = element_get(TITLE_TEXT, PAD_LEFT).to_int(),
+ h = element_get(TITLE_TEXT, HEIGHT).to_int();
+ slide.add(create_text(
+ TITLE_TEXT,
+ left,
+ height / 2 - h - element_get(TITLE_TEXT, PAD_BOTTOM).to_int(),
+ width - left - element_get(TITLE_TEXT, PAD_RIGHT).to_int(),
+ h
+ ));
+
+ // create the presentation's author field
+ left = element_get(AUTHOR_TEXT, PAD_LEFT).to_int();
+ slide.add(create_text(
+ AUTHOR_TEXT,
+ left,
+ height / 2 + element_get(AUTHOR_TEXT, PAD_TOP).to_int(),
+ width - left - element_get(AUTHOR_TEXT, PAD_RIGHT).to_int(),
+ element_get(AUTHOR_TEXT, HEIGHT).to_int()
+ ));
+
+ return slide;
+
+ case CONTENT:
+ int left = element_get(CONTENT_TEXT, PAD_LEFT).to_int(),
+ top = element_get(CONTENT_TEXT, PAD_TOP).to_int();
+
+ slide.add(create_text(
+ CONTENT_TEXT,
+ left,
+ top,
+ width - left - element_get(CONTENT_TEXT, PAD_RIGHT).to_int(),
+ height - top - element_get(HEADER_TEXT, PAD_BOTTOM).to_int()
+ ));
+
+ case CONTENT_HEADER:
+ // create the slide's header
+ int left = element_get(HEADER_TEXT, PAD_LEFT).to_int(),
+ top = element_get(HEADER_TEXT, PAD_TOP).to_int();
+
+ slide.add(create_text(
+ HEADER_TEXT,
+ left,
+ top,
+ width - left - element_get(HEADER_TEXT, PAD_RIGHT).to_int(),
+ element_get(HEADER_TEXT, HEIGHT).to_int()
+ ));
+
+ // create the slide's content
+ left = element_get(CONTENT_TEXT, PAD_LEFT).to_int();
+ top += element_get(HEADER_TEXT, HEIGHT).to_int() +
+ element_get(CONTENT_TEXT, PAD_TOP).to_int();
+ slide.add(create_text(
+ CONTENT_TEXT,
+ left,
+ top,
+ width - left - element_get(CONTENT_TEXT, PAD_RIGHT).to_int(),
+ height - top - element_get(HEADER_TEXT, PAD_BOTTOM).to_int()
+ ));
+
+ return slide;
+
+ case CONTENT_DUAL:
+ case CONTENT_DUAL_HEADER:
+ case MEDIA:
+ case MEDIA_HEADER:
+ break;
+ }
+
+ error(_("Invalid master slide title."));
+ }
+
+ /**
+ * Creates a text element, given an element type and dimensions.
+ */
+ private TextElement create_text(string type, int x, int y, int w, int h)
+ {
+ // error if an improper element type is used
+ if (!(type == TITLE_TEXT || type == AUTHOR_TEXT ||
+ type == CONTENT_TEXT || type == HEADER_TEXT))
+ {
+ error(_("Not a valid text element type: %s"), type);
+ }
+
+ // otherwise, construct the text element
+ var text = new TextElement();
+ text.font_name = element_get(TITLE_TEXT, TEXT_FONT);
+ text.font_size = element_get(TITLE_TEXT, TEXT_SIZE).to_int();
+ text.x = x;
+ text.y = y;
+ text.width = w;
+ text.height = h;
+
+ return text;
+ }
+
+ /**
+ * Retrieves an element property.
+ *
+ * @param element The element name to search for.
+ * @param prop The property name to search for.
+ */
+ private string element_get(string element, string prop)
+ {
+ // try local specifics
+ var str = elements.get(element).get(prop);
+ if (str != null) return str;
+
+ // try local generics
+ str = element_defaults.get(prop);
+ if (str != null) return str;
+
+ // use default settings
+ if (defaults == this)
+ {
+ error(_("Could not find property %s on element type %s."),
+ element, prop);
+ }
+
+ return defaults.element_get(element, prop);
+ }
+
+ /**
+ * Retrieves an master property.
+ *
+ * @param master The master name to search for.
+ * @param prop The property name to search for.
+ */
+ private string master_get(string master, string prop)
+ {
+ // try local specifics
+ var str = masters.get(master).get(prop);
+ if (str != null) return str;
+
+ // try local generics
+ str = master_defaults.get(prop);
+ if (str != null) return str;
+
+ // use default settings
+ if (defaults == this)
+ {
+ error(_("Could not find property %s on master type %s."),
+ master, prop);
+ }
+
+ return defaults.master_get(master, prop);
+ }
+
+ /**
+ * Fills a Gee.Map with style property overrides in the form of more
+ * Gee.Maps.
+ *
+ * @param obj The root object.
+ * @param name The name of the JSON array to use.
+ * @param map The map to fill with submaps.
+ */
+ private void fill_map(Json.Object obj, string name,
+ Gee.Map<string, Gee.Map<string, string>> map)
+ {
+ var array = obj.get_array_member(name);
+ if (array == null) return;
+
+ for (unowned List<string>* i = obj.get_members();
+ i != null; i = i->next)
+ {
+ // get the current object (an array)
+ var curr_obj = obj.get_member(i->data).get_object();
+
+ // create a map for the values
+ var submap = new Gee.HashMap<string, string>();
+
+ // add each override to the map
+ fill_single_map(curr_obj, submap);
+
+ // add the map to the map of overrides
+ map.set(i->data, submap);
+ }
+ }
+
+ /**
+ * Fill a Gee.Map with key/value pairs.
+ *
+ * @param obj The json object to use.
+ * @param map The map to fill.
+ */
+ private void fill_single_map(Json.Object obj, Gee.Map<string, string> map)
+ {
+ for (unowned List<string>* j = obj.get_members();
+ j != null; j = j->next)
+ {
+ map.set(j->data, obj.get_member(j->data).get_string());
+ }
+ }
}
+public enum Ease.Master
+{
+ TITLE,
+ CONTENT,
+ CONTENT_HEADER,
+ CONTENT_DUAL,
+ CONTENT_DUAL_HEADER,
+ MEDIA,
+ MEDIA_HEADER
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]