[gbrainy/gbrainy-17x] Initial theme support



commit 17e993bb2b1c082dab6efff2d2af073f1738b42b
Author: Jordi Mas <jmas softcatala org>
Date:   Wed Dec 29 22:05:23 2010 +0100

    Initial theme support

 data/Makefile.am                                   |   16 +-
 data/themes/blackboard_background.svg              |  248 ++++++++++++++++++++
 .../classic_background.svg}                        |    0
 data/themes/themes.xml                             |   17 ++
 po/POTFILES.in                                     |    1 +
 src/Clients/Classical/Dialogs/PreferencesDialog.cs |   41 ++++
 .../Classical/Dialogs/ui/PreferencesDialog.ui      |   35 +++-
 src/Clients/Classical/gbrainy.cs                   |    2 +-
 src/Core/Libraries/CairoContext.cs                 |    7 +
 src/Core/Main/CairoContextEx.cs                    |   25 ++-
 src/Core/Main/Preferences.cs                       |   12 +
 src/Core/Main/Theme.cs                             |   88 +++++++
 src/Core/Main/ThemeManager.cs                      |   88 +++++++
 src/Core/Makefile.am                               |    9 +-
 14 files changed, 565 insertions(+), 24 deletions(-)
---
diff --git a/data/Makefile.am b/data/Makefile.am
index be94a47..8bc43ac 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -1,10 +1,10 @@
-
 pixmapdir = $(datadir)/pixmaps
 pixmap_DATA = app-graphics/gbrainy.png \
 		app-graphics/gbrainy.svg \
 		app-graphics/gbrainy16.png
 
 analogiesdir = $(datadir)/games/gbrainy
+themesdir = $(datadir)/games/gbrainy
 
 hicolordir = $(datadir)/icons/hicolor
 images = $(datadir)/games/gbrainy
@@ -26,10 +26,6 @@ pkgconfig_DATA = gbrainy.pc
 tango_icons = 				\
 	app-graphics/gbrainy.png	\
 	app-graphics/gbrainy.svg	\
-	app-graphics/background.svg	\
-	app-graphics/math-games.svg	\
-	app-graphics/logic-games.svg	\
-	app-graphics/memory-games.svg	\
 	app-graphics/math-games-32.png	\
 	app-graphics/logic-games-32.png	\
 	app-graphics/memory-games-32.png	\
@@ -37,7 +33,6 @@ tango_icons = 				\
 	app-graphics/endgame-32.png		\
 	app-graphics/allgames-32.png		\
 	app-graphics/pause-32.png \
-	app-graphics/verbal-games.svg \
 	app-graphics/verbal-games-32.png
 
 
@@ -54,7 +49,12 @@ analogies_DATA = \
 	game-graphics/dartboard.svg \
 	game-graphics/horses_men.svg \
 	game-graphics/lever.svg
-	
+
+
+themes_DATA = \
+	themes/themes.xml \
+	themes/classic_background.svg \
+	themes/blackboard_background.svg
 
 install-data-local:
 	@-$(mkinstalldirs) $(DESTDIR)$(hicolordir)/scalable/apps
@@ -100,4 +100,4 @@ noinst_DATA =
 
 DISTCLEANFILES = $(desktop_files)
 
-EXTRA_DIST = $(pixmap_DATA) $(tango_icons) $(man_MANS) $(analogies_DATA) $(desktop_in_files) gbrainy.pc.in
+EXTRA_DIST = $(pixmap_DATA) $(tango_icons) $(man_MANS) $(analogies_DATA) $(desktop_in_files) $(themes_DATA) gbrainy.pc.in
diff --git a/data/themes/blackboard_background.svg b/data/themes/blackboard_background.svg
new file mode 100644
index 0000000..3e1c212
--- /dev/null
+++ b/data/themes/blackboard_background.svg
@@ -0,0 +1,248 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/";
+   xmlns:cc="http://creativecommons.org/ns#";
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+   xmlns:svg="http://www.w3.org/2000/svg";
+   xmlns="http://www.w3.org/2000/svg";
+   xmlns:xlink="http://www.w3.org/1999/xlink";
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
+   version="1.1"
+   width="346"
+   height="245.35001"
+   id="svg5444"
+   inkscape:version="0.48.0 r9654"
+   sodipodi:docname="notebook_background.svg">
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1152"
+     inkscape:window-height="694"
+     id="namedview40"
+     showgrid="false"
+     inkscape:zoom="0.5147394"
+     inkscape:cx="-191.71116"
+     inkscape:cy="227.0452"
+     inkscape:window-x="0"
+     inkscape:window-y="52"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg5444" />
+  <defs
+     id="defs5446">
+    <linearGradient
+       id="linearGradient7102">
+      <stop
+         id="stop7104"
+         style="stop-color:#b8b8b8;stop-opacity:1"
+         offset="0" />
+      <stop
+         id="stop7110"
+         style="stop-color:#e3e3e3;stop-opacity:1"
+         offset="0.5" />
+      <stop
+         id="stop7106"
+         style="stop-color:#b9b9b9;stop-opacity:1"
+         offset="1" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient7033">
+      <stop
+         id="stop7035"
+         style="stop-color:#867850;stop-opacity:1"
+         offset="0" />
+      <stop
+         id="stop7041"
+         style="stop-color:#a08872;stop-opacity:1"
+         offset="0.35474342" />
+      <stop
+         id="stop7037"
+         style="stop-color:#867850;stop-opacity:1"
+         offset="1" />
+    </linearGradient>
+    <linearGradient
+       x1="125.8874"
+       y1="286.38242"
+       x2="569.34814"
+       y2="130.07462"
+       id="linearGradient7056"
+       xlink:href="#linearGradient7033"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       x1="412.43628"
+       y1="330.39026"
+       x2="411.63953"
+       y2="335.08582"
+       id="linearGradient7108"
+       xlink:href="#linearGradient7102"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       x1="412.43628"
+       y1="330.39026"
+       x2="411.63953"
+       y2="335.08582"
+       id="linearGradient7108-1"
+       xlink:href="#linearGradient7102-6"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       id="linearGradient7102-6">
+      <stop
+         id="stop7104-7"
+         style="stop-color:#b8b8b8;stop-opacity:1"
+         offset="0" />
+      <stop
+         id="stop7110-8"
+         style="stop-color:#e3e3e3;stop-opacity:1"
+         offset="0.5" />
+      <stop
+         id="stop7106-8"
+         style="stop-color:#b9b9b9;stop-opacity:1"
+         offset="1" />
+    </linearGradient>
+    <linearGradient
+       x1="412.43628"
+       y1="330.39026"
+       x2="411.63953"
+       y2="335.08582"
+       id="linearGradient7130"
+       xlink:href="#linearGradient7102-6"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0.907465,-0.420127,0.420127,0.907465,-96.4932,204.078)" />
+    <linearGradient
+       x1="412.43628"
+       y1="330.39026"
+       x2="411.63953"
+       y2="335.08582"
+       id="linearGradient7108-9"
+       xlink:href="#linearGradient7102-3"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       id="linearGradient7102-3">
+      <stop
+         id="stop7104-5"
+         style="stop-color:#b8b8b8;stop-opacity:1"
+         offset="0" />
+      <stop
+         id="stop7110-4"
+         style="stop-color:#e3e3e3;stop-opacity:1"
+         offset="0.5" />
+      <stop
+         id="stop7106-1"
+         style="stop-color:#b9b9b9;stop-opacity:1"
+         offset="1" />
+    </linearGradient>
+    <linearGradient
+       x1="412.43628"
+       y1="330.39026"
+       x2="411.63953"
+       y2="335.08582"
+       id="linearGradient7130-2"
+       xlink:href="#linearGradient7102-3"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(-0.968835,-0.247707,0.247707,-0.968835,748.049,756.692)" />
+    <linearGradient
+       x1="125.8874"
+       y1="286.38242"
+       x2="569.34814"
+       y2="130.07462"
+       id="linearGradient7215"
+       xlink:href="#linearGradient7033"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.9813949,0,0,1.0042082,51.606082,96.312723)" />
+    <linearGradient
+       x1="412.43628"
+       y1="330.39026"
+       x2="411.63953"
+       y2="335.08582"
+       id="linearGradient7217"
+       xlink:href="#linearGradient7102"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.9813949,0,0,1.0042082,51.606082,96.312723)" />
+    <linearGradient
+       x1="412.43628"
+       y1="330.39026"
+       x2="411.63953"
+       y2="335.08582"
+       id="linearGradient7219"
+       xlink:href="#linearGradient7102-6"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.7980464,-0.42189496,0.83243745,0.91128368,-139.58504,301.24953)" />
+    <linearGradient
+       x1="412.43628"
+       y1="330.39026"
+       x2="411.63953"
+       y2="335.08582"
+       id="linearGradient7221"
+       xlink:href="#linearGradient7102-3"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(-1.9196447,-0.24874938,0.49080539,-0.97291195,1533.7865,856.18902)" />
+  </defs>
+  <metadata
+     id="metadata5449">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage"; />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <rect
+     width="344.00208"
+     height="242.55431"
+     ry="3.8440552"
+     x="2.0208871"
+     y="1.6201953"
+     id="rect5454"
+     style="color:#000000;fill:url(#linearGradient7215);fill-opacity:1;fill-rule:nonzero;stroke:#777777;stroke-width:0.28211579;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
+     rx="7.5846729" />
+  <rect
+     width="331.94244"
+     height="212.60182"
+     ry="3.8440549"
+     x="8.7375584"
+     y="11.881927"
+     id="rect5454-1"
+     style="color:#000000;fill:#d0ced3;fill-opacity:1;fill-rule:nonzero;stroke:#777777;stroke-width:0.28211576;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
+     rx="7.5846734" />
+  <path
+     d="m 192.2477,230.23187 21.58197,3.80729 -0.57224,5.41804 -21.4727,-4.8419 0.46297,-4.38343 z"
+     id="rect7048-4"
+     style="color:#000000;fill:url(#linearGradient7217);fill-opacity:1;fill-rule:nonzero;stroke:#858585;stroke-width:0.14105789;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
+     inkscape:connector-curvature="0" />
+  <path
+     d="m 195.54434,236.81647 20.73831,-9.11913 1.12213,5.25009 -20.95259,8.11658 -0.90785,-4.24754 z"
+     id="rect7048-4-2"
+     style="color:#000000;fill:url(#linearGradient7219);fill-opacity:1;fill-rule:nonzero;stroke:#858585;stroke-width:0.14105789;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
+     inkscape:connector-curvature="0" />
+  <path
+     d="m 225.45884,242.09081 -20.22931,-11.10232 1.52218,-5.05264 19.93864,12.06718 -1.23151,4.08778 z"
+     id="rect7048-4-27"
+     style="color:#000000;fill:url(#linearGradient7221);fill-opacity:1;fill-rule:nonzero;stroke:#858585;stroke-width:0.14105789;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
+     inkscape:connector-curvature="0" />
+  <rect
+     width="26.953133"
+     height="11.804807"
+     x="96.31575"
+     y="221.6649"
+     id="rect7204"
+     style="color:#000000;fill:#493a3d;fill-opacity:1;fill-rule:nonzero;stroke:#858585;stroke-width:0.14108597;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
+     transform="matrix(0.99827115,0.05877679,-0.03060147,0.99953167,0,0)" />
+  <rect
+     width="346.58371"
+     height="7.1602745"
+     x="0.73005718"
+     y="237.64714"
+     id="rect6009"
+     style="color:#000000;fill:#60553f;fill-opacity:1;fill-rule:nonzero;stroke:#777777;stroke-width:0.28211579;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible" />
+</svg>
diff --git a/data/app-graphics/background.svg b/data/themes/classic_background.svg
similarity index 100%
rename from data/app-graphics/background.svg
rename to data/themes/classic_background.svg
diff --git a/data/themes/themes.xml b/data/themes/themes.xml
new file mode 100644
index 0000000..d53fc06
--- /dev/null
+++ b/data/themes/themes.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ArrayOfTheme xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; xmlns:xsd="http://www.w3.org/2001/XMLSchema";>
+  <Theme>
+    <name>classic</name>
+    <_localized_name>Classic</_localized_name>
+    <background_image>classic_background.svg</background_image>
+    <font_face></font_face>
+    <ink_color></ink_color>
+  </Theme>
+  <Theme>
+    <name>Blackboard</name>
+    <_localized_name>Blackboard</_localized_name>
+    <background_image>blackboard_background.svg</background_image>
+    <font_face></font_face>
+    <ink_color></ink_color>
+  </Theme>
+</ArrayOfTheme>
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 873cfe6..9571c29 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -1,6 +1,7 @@
 tools/GameXmlGetString.cs
 data/games.xml
 data/gbrainy.desktop.in
+data/themes/themes.xml
 data/verbal_analogies.xml
 src/Core/Views/CountDownView.cs
 src/Core/Views/FinishView.cs
diff --git a/src/Clients/Classical/Dialogs/PreferencesDialog.cs b/src/Clients/Classical/Dialogs/PreferencesDialog.cs
index 650f72b..b0bea97 100644
--- a/src/Clients/Classical/Dialogs/PreferencesDialog.cs
+++ b/src/Clients/Classical/Dialogs/PreferencesDialog.cs
@@ -35,7 +35,9 @@ namespace gbrainy.Clients.Classical.Dialogs
 		[GtkBeans.Builder.Object] Gtk.RadioButton rb_easy;
 		[GtkBeans.Builder.Object] Gtk.RadioButton rb_medium;
 		[GtkBeans.Builder.Object] Gtk.RadioButton rb_master;
+		[GtkBeans.Builder.Object] Gtk.ComboBox themes_combobox;
 
+		const int COLUMN_VALUE = 1;
 		PlayerHistory history;
 
 		public PreferencesDialog (PlayerHistory history) : base ("PreferencesDialog.ui", "preferences")
@@ -58,6 +60,33 @@ namespace gbrainy.Clients.Classical.Dialogs
 				rb_master.Active = rb_master.HasFocus = true;
 				break;
 			}
+
+			ListStore store = new ListStore (typeof (string), typeof (Theme)); // DisplayName, theme referenece
+			CellRenderer layout_cell = new CellRendererText ();
+			themes_combobox.Model = store;
+			themes_combobox.PackStart (layout_cell, true);
+			themes_combobox.SetCellDataFunc (layout_cell, ComboBoxCellFunc);
+
+
+			Theme [] themes = ThemeManager.Themes;
+
+			foreach (Theme theme in ThemeManager.Themes)
+				store.AppendValues (Catalog.GetString(theme.LocalizedName), theme);
+
+			// Default value
+			TreeIter iter;
+			bool more = store.GetIterFirst (out iter);
+			while (more)
+			{
+				Theme theme = (Theme) store.GetValue (iter, COLUMN_VALUE);
+
+				if (String.Compare (theme.Name, Preferences.GetStringValue (Preferences.ThemeKey), true) == 0)
+				{
+					themes_combobox.SetActiveIter (iter);
+					break;
+				}
+				more = store.IterNext (ref iter);
+			}
 		}
 
 		private GameDifficulty Difficulty {
@@ -94,7 +123,19 @@ namespace gbrainy.Clients.Classical.Dialogs
 			Preferences.SetIntValue (Preferences.MaxStoredGamesKey, (int) maxstoredspinbutton.Value);
 			Preferences.SetIntValue (Preferences.MinPlayedGamesKey, (int) minplayedspinbutton.Value);
 			Preferences.SetBoolValue (Preferences.ColorBlindKey, colorblindcheckbutton.Active);
+
+			TreeIter iter;
+			themes_combobox.GetActiveIter (out iter);
+			Theme theme = (Theme) themes_combobox.Model.GetValue (iter, COLUMN_VALUE);
+			Preferences.SetStringValue (Preferences.ThemeKey, theme.Name);
+
 			Preferences.Save ();
 		}
+
+		static public void ComboBoxCellFunc (CellLayout cell_layout, CellRenderer cell, TreeModel tree_model, TreeIter iter)
+		{
+			string name = (string)tree_model.GetValue (iter, 0);
+			(cell as CellRendererText).Text = name;
+		}
 	}
 }
diff --git a/src/Clients/Classical/Dialogs/ui/PreferencesDialog.ui b/src/Clients/Classical/Dialogs/ui/PreferencesDialog.ui
index 5cbd762..f364442 100644
--- a/src/Clients/Classical/Dialogs/ui/PreferencesDialog.ui
+++ b/src/Clients/Classical/Dialogs/ui/PreferencesDialog.ui
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
 <interface>
   <!-- interface-requires gtk+ 2.12 -->
   <!-- interface-naming-policy toplevel-contextual -->
@@ -7,15 +7,12 @@
     <property name="border_width">7</property>
     <property name="title" translatable="yes">Preferences</property>
     <property name="type_hint">dialog</property>
-    <property name="has_separator">False</property>
     <child internal-child="vbox">
       <object class="GtkVBox" id="preferencesbox">
         <property name="visible">True</property>
-        <property name="orientation">vertical</property>
         <child>
           <object class="GtkVBox" id="vbox13">
             <property name="visible">True</property>
-            <property name="orientation">vertical</property>
             <child>
               <object class="GtkLabel" id="label33">
                 <property name="visible">True</property>
@@ -45,6 +42,33 @@
                 <property name="position">1</property>
               </packing>
             </child>
+            <child>
+              <object class="GtkHBox" id="hbox1">
+                <property name="visible">True</property>
+                <child>
+                  <object class="GtkLabel" id="label1">
+                    <property name="visible">True</property>
+                    <property name="xalign">0</property>
+                    <property name="label" translatable="yes">Theme:</property>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkComboBox" id="themes_combobox">
+                    <property name="visible">True</property>
+                  </object>
+                  <packing>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </object>
+              <packing>
+                <property name="position">2</property>
+              </packing>
+            </child>
           </object>
           <packing>
             <property name="position">1</property>
@@ -53,7 +77,6 @@
         <child>
           <object class="GtkVBox" id="vbox11">
             <property name="visible">True</property>
-            <property name="orientation">vertical</property>
             <child>
               <object class="GtkLabel" id="label27">
                 <property name="height_request">25</property>
@@ -124,7 +147,6 @@
         <child>
           <object class="GtkVBox" id="vbox9">
             <property name="visible">True</property>
-            <property name="orientation">vertical</property>
             <child>
               <object class="GtkLabel" id="label26">
                 <property name="visible">True</property>
@@ -207,7 +229,6 @@
         <child>
           <object class="GtkVBox" id="vbox12">
             <property name="visible">True</property>
-            <property name="orientation">vertical</property>
             <child>
               <object class="GtkLabel" id="label29">
                 <property name="visible">True</property>
diff --git a/src/Clients/Classical/gbrainy.cs b/src/Clients/Classical/gbrainy.cs
index b601c2f..f6e6a1a 100755
--- a/src/Clients/Classical/gbrainy.cs
+++ b/src/Clients/Classical/gbrainy.cs
@@ -838,10 +838,10 @@ namespace gbrainy.Clients.Classical
 			}
 			app.Session.GameManager.RandomOrder = line.RandomOrder;
 			app.ProcessDefaults ();
+			ThemeManager.Load ();
 
 			TimeSpan span = DateTime.Now - start_time;
 			Console.WriteLine (Catalog.GetString ("Startup time {0}"), span);
-
 #if GNOME
 			app.Run ();
 #else
diff --git a/src/Core/Libraries/CairoContext.cs b/src/Core/Libraries/CairoContext.cs
index 3bab357..1aa3c4a 100644
--- a/src/Core/Libraries/CairoContext.cs
+++ b/src/Core/Libraries/CairoContext.cs
@@ -59,6 +59,13 @@ namespace gbrainy.Core.Libraries
 			}
 		}
 
+		public string FontFace {
+			set {
+				if (String.IsNullOrEmpty (value) == false)
+					layout.FontDescription = Pango.FontDescription.FromString (value);
+			}
+		}
+
 		// True if we want Pango to process XML entites and formatting attributes
 		public bool UseMarkup  { get; set; }
 
diff --git a/src/Core/Main/CairoContextEx.cs b/src/Core/Main/CairoContextEx.cs
index 681b985..3ca7302 100644
--- a/src/Core/Main/CairoContextEx.cs
+++ b/src/Core/Main/CairoContextEx.cs
@@ -31,12 +31,22 @@ namespace gbrainy.Core.Main
 
 		public CairoContextEx (IntPtr state, Gtk.Widget widget) : base (state, widget)
 		{
-			SetPangoNormalFontSize ();
+			CommonConstructor ();		
 		}
 
 		// Used by GeneratePDF
 		public CairoContextEx (Cairo.Surface s, string font, int dpis) : base (s, font, dpis)
 		{
+			CommonConstructor ();
+		}
+
+		void CommonConstructor ()
+		{
+			Theme theme;
+	
+			theme = ThemeManager.FromName (Preferences.GetStringValue (Preferences.ThemeKey));
+			FontFace = theme.FontFace;
+
 			SetPangoNormalFontSize ();
 		}
 
@@ -44,15 +54,22 @@ namespace gbrainy.Core.Main
 		{
 			try {
 				if (image == null)
-					image = new SVGImage (System.Reflection.Assembly.GetCallingAssembly (), "background.svg");
+				{
+					Theme theme;
+	
+					theme = ThemeManager.FromName (Preferences.GetStringValue (Preferences.ThemeKey));
+					image = new SVGImage (System.IO.Path.Combine (Defines.DATA_DIR, theme.BackgroundImage));
+				}
 
 				Save ();
 				Rectangle (0, 0, 1, 1);
 				Scale (0.999 / image.Width, 0.999 / image.Height);
 				image.RenderToCairo (Handle);
 				Restore ();
-
-			} catch {
+			}
+			catch (Exception e)
+			{
+				Console.WriteLine ("CairoContextEx.DrawBackground {0}", e);
 			}
 		}
 
diff --git a/src/Core/Main/Preferences.cs b/src/Core/Main/Preferences.cs
index c198164..9cf307d 100644
--- a/src/Core/Main/Preferences.cs
+++ b/src/Core/Main/Preferences.cs
@@ -39,6 +39,7 @@ namespace gbrainy.Core.Main
 		public const string ToolbarShowKey = "ToolbarShow";
 		public const string ToolbarOrientationKey = "ToolbarOrientation";
 		public const string ColorBlindKey = "ColorBlind";
+		public const string ThemeKey = "Theme";
 
 		const string element_item = "item";
 		const string element_key = "key";
@@ -146,6 +147,11 @@ namespace gbrainy.Core.Main
 			return Boolean.Parse (properties [key]);
 		}
 
+		public static string GetStringValue (string key)
+		{
+			return properties [key];
+		}
+
 		public static void SetIntValue (string key, int value)
 		{
 			properties[key] = value.ToString ();
@@ -156,6 +162,11 @@ namespace gbrainy.Core.Main
 			properties [key] = value.ToString ();
 		}
 
+		public static void SetStringValue (string key, string value)
+		{
+			properties [key] = value;
+		}
+
 		public static void LoadDefaultValues ()
 		{
 			properties.Clear ();
@@ -167,6 +178,7 @@ namespace gbrainy.Core.Main
 			properties.Add (ToolbarShowKey, true.ToString ());
 			properties.Add (ToolbarOrientationKey, "0");
 			properties.Add (ColorBlindKey, false.ToString ());
+			properties.Add (ThemeKey, "classic");
 		}
 
 		static void Load ()
diff --git a/src/Core/Main/Theme.cs b/src/Core/Main/Theme.cs
new file mode 100644
index 0000000..9a9040c
--- /dev/null
+++ b/src/Core/Main/Theme.cs
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2010 Jordi Mas i Hernàndez <jmas softcatala org>
+ *
+ * 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 2 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, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+using System;
+using System.Xml.Serialization;
+using System.Text.RegularExpressions;
+using System.Globalization;
+
+using Cairo;
+
+namespace gbrainy.Core.Main
+{
+	public class Theme
+	{
+		[XmlElementAttribute ("name")]
+		public string Name { get; set; }
+
+		[XmlElementAttribute ("_localized_name")]
+		public string LocalizedName { get; set; }
+
+		[XmlElementAttribute ("background_image")]
+		public string BackgroundImage { get; set; }
+
+		[XmlElementAttribute ("font_face")]
+		public string FontFace { get; set; }
+
+		[XmlElementAttribute ("ink_color")]
+		public string InkColor { get; set; }
+
+		Regex regex;
+		static Cairo.Color default_color = new Cairo.Color (0, 0, 0);
+
+		public Cairo.Color InkCairoColor {
+			get {
+				Match match;
+				int r, g, b, a = 255;
+
+				if (regex == null)
+					regex = new Regex ("[A-Fa-f0-9]{2}", RegexOptions.IgnoreCase);
+
+				match = regex.Match (InkColor);
+
+				// r
+				if (String.IsNullOrEmpty (match.Value))
+					return default_color;
+
+				int.TryParse (match.Value, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out r);
+				match = match.NextMatch ();
+
+				// g
+				if (String.IsNullOrEmpty (match.Value))
+					return default_color;
+
+				int.TryParse (match.Value, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out g);
+				match = match.NextMatch ();
+
+				// b
+				if (String.IsNullOrEmpty (match.Value))
+					return default_color;
+
+				int.TryParse (match.Value, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out b);
+				match = match.NextMatch ();
+
+				// a
+				int.TryParse (match.Value, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out a);
+
+				return new Cairo.Color ((double) r / 255d, (double) g / 255d, (double) b / 255d, (double) a / 255d);
+			}
+		}
+	}
+}
+
diff --git a/src/Core/Main/ThemeManager.cs b/src/Core/Main/ThemeManager.cs
new file mode 100644
index 0000000..ee484d9
--- /dev/null
+++ b/src/Core/Main/ThemeManager.cs
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2010 Jordi Mas i Hernàndez <jmas softcatala org>
+ *
+ * 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 2 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, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Xml.Serialization;
+
+namespace gbrainy.Core.Main
+{
+	public static class ThemeManager
+	{
+		static string file, config_path;
+		static List <Theme> themes;
+
+		static ThemeManager ()
+		{
+			ConfigPath = Defines.DATA_DIR;
+		}
+
+		static public string ConfigPath {
+			set {
+				config_path = value;
+				file = Path.Combine (config_path, "themes.xml");
+			}
+		}
+
+		static public Theme [] Themes {
+			get {
+				if (themes == null)
+				{
+					Load ();
+					if (themes == null)
+						themes = new List <Theme> ();
+				}
+				return themes.ToArray ();
+			}
+		}
+
+		static public Theme FromName (string name)
+		{
+			foreach (Theme theme in Themes)
+			{
+				if (String.Compare (name, theme.Name, true) == 0)
+				{
+					return theme;
+				}
+			}
+			throw new InvalidOperationException (String.Format ("ThemeManager. Theme not found '{0}'", name));
+		}
+
+
+
+		static public void Load ()
+		{
+			try {
+				if (File.Exists (file) == false)
+					return;
+
+				using (FileStream str = File.OpenRead (file))
+				{
+					XmlSerializer bf = new XmlSerializer (typeof (List <Theme>));
+				    	themes = (List <Theme>) bf.Deserialize(str);
+				}
+			}
+			catch (Exception e)
+			{
+				Console.WriteLine ("ThemeManager.Load. Could not load file {0}. Error {1}", file, e);
+			}
+		}
+	}
+}
diff --git a/src/Core/Makefile.am b/src/Core/Makefile.am
index 499bb66..013431d 100644
--- a/src/Core/Makefile.am
+++ b/src/Core/Makefile.am
@@ -1,4 +1,4 @@
-CSFLAGS = -unsafe -target:library $(CSC_DEFINES) 
+CSFLAGS = -unsafe -target:library $(CSC_DEFINES)
 
 #Active when designing games
 #CSFLAGS += -D:DESIGN_MODE
@@ -31,11 +31,13 @@ CSDISTFILES =  \
 		$(srcdir)/Main/Xml/OptionDrawingObject.cs \
 		$(srcdir)/Main/Xml/TextDrawingObject.cs	\
 		$(srcdir)/Main/Memory.cs		\
-		$(srcdir)/Main/PdfExporter.cs		\		
+		$(srcdir)/Main/PdfExporter.cs		\
 		$(srcdir)/Main/PlayerHistory.cs		\
 		$(srcdir)/Main/PlayerPersonalRecord.cs	\
 		$(srcdir)/Main/Preferences.cs		\
 		$(srcdir)/Main/Score.cs			\
+		$(srcdir)/Main/Theme.cs			\
+		$(srcdir)/Main/ThemeManager.cs		\
 		$(srcdir)/Main/UpdateUIStateEventArgs.cs \
 		$(srcdir)/Main/Verbal/Analogies.cs 	\
 		$(srcdir)/Main/Verbal/AnalogiesFactory.cs	\
@@ -64,10 +66,9 @@ CSDISTFILES =  \
 
 CSFILES = $(CSDISTFILES)	\
 	Main/Defines.cs	\
-	AssemblyInfo.cs	
+	AssemblyInfo.cs
 
 RES = \
-$(top_srcdir)/data/app-graphics/background.svg  	\
 $(top_srcdir)/data/app-graphics/logic-games.svg		\
 $(top_srcdir)/data/app-graphics/math-games.svg		\
 $(top_srcdir)/data/app-graphics/memory-games.svg	\



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