[gnome-games] lightsoff: Implement "Use colors from GNOME theme" checkbox
- From: Tim Horton <hortont src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gnome-games] lightsoff: Implement "Use colors from GNOME theme" checkbox
- Date: Sun, 11 Oct 2009 14:50:16 +0000 (UTC)
commit 16abb3f1d9adf60890fcf4ab92638572511ca9f3
Author: Tim Horton <hortont424 gmail com>
Date: Sun Oct 11 10:35:20 2009 -0400
lightsoff: Implement "Use colors from GNOME theme" checkbox
I'm not currently sure what the correct way to retrieve colors from Gtk is,
but I recognize that what I'm doing now is almost certainly incorrect.
Any alternative themes (which I assume do not exist) will have to be updated
similar to the way I updated themes/up/theme.js in this patch.
lightsoff/data/settings.ui | 1 +
lightsoff/data/themes/tango/theme.js | 128 ++++++++++++++++++++++++++++++++-
lightsoff/data/themes/up/theme.js | 5 ++
lightsoff/lightsoff.schemas.in | 13 ++++
lightsoff/src/Game.js | 28 ++++++++
lightsoff/src/Settings.js | 65 ++++++++++++++---
lightsoff/src/ThemeLoader.js | 3 +
7 files changed, 228 insertions(+), 15 deletions(-)
---
diff --git a/lightsoff/data/settings.ui b/lightsoff/data/settings.ui
index 4d79883..934c18d 100644
--- a/lightsoff/data/settings.ui
+++ b/lightsoff/data/settings.ui
@@ -67,6 +67,7 @@
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="draw_indicator">True</property>
+ <signal name="toggled" handler="set_use_theme_colors"/>
</object>
<packing>
<property name="expand">False</property>
diff --git a/lightsoff/data/themes/tango/theme.js b/lightsoff/data/themes/tango/theme.js
index 5e09714..bd515d4 100644
--- a/lightsoff/data/themes/tango/theme.js
+++ b/lightsoff/data/themes/tango/theme.js
@@ -1,15 +1,135 @@
+cairo = imports.cairo;
Clutter = imports.gi.Clutter;
ThemeLoader = imports.ThemeLoader;
+Gtk = imports.gi.Gtk;
+Settings = imports.Settings;
+main = imports.main;
var name = "Tango";
+var theme_colorable = true;
+var tile_size = 75;
-var light = [ ThemeLoader.load_svg("tango", "off.svg"),
- ThemeLoader.load_svg("tango", "on.svg") ];
+// TODO: catch GNOME-wide theme change, update tiles, recache them, etc.
+
+function rounded_rectangle(cr,x,y,w,h,r)
+{
+ cr.new_path();
+ cr.move_to(x+r,y);
+ cr.line_to(x+w-r,y);
+ cr.curve_to(x+w,y,x+w,y,x+w,y+r);
+ cr.line_to(x+w,y+h-r);
+ cr.curve_to(x+w,y+h,x+w,y+h,x+w-r,y+h);
+ cr.line_to(x+r,y+h);
+ cr.curve_to(x,y+h,x,y+h,x,y+h-r);
+ cr.line_to(x,y+r);
+ cr.curve_to(x,y,x,y,x+r,y);
+ cr.close_path();
+}
+
+function draw_tile(color)
+{
+ var tile = new Clutter.CairoTexture();
+ tile.set_surface_size(tile_size, tile_size);
+ var context = tile.create();
+ var cr = new cairo.Context.steal(context);
+
+ var pattern = new cairo.LinearGradient(tile_size,0,0,0);
+ pattern.add_color_stop_rgba(0,
+ color.red / 255,
+ color.green / 255,
+ color.blue / 255,
+ color.alpha / 255);
+ pattern.add_color_stop_rgba(1,
+ color.red / 255 - 0.15,
+ color.green / 255 - 0.15,
+ color.blue / 255 - 0.15,
+ color.alpha / 255);
+ cr.set_source(pattern);
+
+ rounded_rectangle(cr, 2, 2, tile_size - 4, tile_size - 4, 5);
+ cr.fill();
+
+ cr.set_source_rgba(color.red / 255 + 0.05, color.green / 255 + 0.05, color.blue / 255 + 0.05, 1.0);
+ rounded_rectangle(cr, 2, 2, tile_size - 4, tile_size - 4, 5);
+ cr.line_width = 2.0;
+ cr.stroke();
+
+ cr.destroy();
+
+ return tile;
+}
+
+function draw_glow(color)
+{
+ var tile = new Clutter.CairoTexture();
+ tile.set_surface_size(tile_size, tile_size);
+ var context = tile.create();
+ var cr = new cairo.Context.steal(context);
+
+ var pattern = new cairo.LinearGradient(0,0,0,tile_size);
+ pattern.add_color_stop_rgba(0, 1.0, 1.0, 1.0, 0.3);
+ pattern.add_color_stop_rgba(1, 1.0, 1.0, 1.0, 0.1);
+ cr.set_source(pattern);
+
+ cr.new_path();
+ cr.move_to(0, 0);
+ cr.line_to(0, tile_size);
+ cr.line_to(tile_size, tile_size);
+ cr.line_to(tile_size, 0);
+ cr.close_path();
+ cr.fill();
+
+ cr.set_source_rgba(1.0,1.0,1.0,0.4);
+
+ cr.new_path();
+ cr.move_to(3, 3);
+ cr.line_to(3, tile_size - 3);
+ cr.line_to(tile_size - 3, tile_size - 3);
+ cr.line_to(tile_size - 3, 3);
+ cr.close_path();
+ cr.stroke();
+
+ cr.destroy();
+
+ return tile;
+}
+
+function reload_theme()
+{
+ // TODO: there must be a better way to get the Gtk selection color
+ var gtk_settings = Gtk.Settings.get_default();
+ var gtk_color_scheme = gtk_settings.gtk_color_scheme;
+ var c = new Clutter.Color();
+ c.from_string(gtk_color_scheme.match(/selected_bg_color: (.*)/)[1]);
+
+ // Remove the previous theme's cached lights
+ if(light.length > 0)
+ {
+ main.game.queue_actor_remove(light[0]);
+ main.game.queue_actor_remove(light[1]);
+ }
+
+ if(Settings.use_theme_colors)
+ {
+ light = [ draw_tile({red: 32, green: 32, blue: 32, alpha: 255}),
+ draw_tile(c) ];
+ }
+ else
+ {
+ light = [ ThemeLoader.load_svg("tango", "off.svg"),
+ ThemeLoader.load_svg("tango", "on.svg") ];
+ }
+
+ textures = [light[0], light[1], arrow, backing, led_back, highlight];
+ loaded = false;
+}
+
+var light = [];
var arrow = ThemeLoader.load_svg("tango", "arrow.svg");
var backing = ThemeLoader.load_svg("tango", "backing.svg");
var led_back = ThemeLoader.load_svg("tango", "led-back.svg");
var highlight = ThemeLoader.load_svg("tango", "highlight.svg");
-
var loaded = false;
-var textures = [light[0], light[1], arrow, backing, led_back, highlight];
+var textures = [];
+reload_theme();
diff --git a/lightsoff/data/themes/up/theme.js b/lightsoff/data/themes/up/theme.js
index e20b52a..f2ce6ab 100644
--- a/lightsoff/data/themes/up/theme.js
+++ b/lightsoff/data/themes/up/theme.js
@@ -2,6 +2,7 @@ Clutter = imports.gi.Clutter;
ThemeLoader = imports.ThemeLoader;
var name = "Shine";
+var theme_colorable = false;
var light = [ ThemeLoader.load_svg("up", "off.svg"),
ThemeLoader.load_svg("up", "on.svg") ];
@@ -13,3 +14,7 @@ var highlight = ThemeLoader.load_svg("up", "highlight.svg");
var loaded = false;
var textures = [light[0], light[1], arrow, backing, led_back, highlight];
+function reload_theme()
+{
+ // TODO: draw with Cairo
+}
diff --git a/lightsoff/lightsoff.schemas.in b/lightsoff/lightsoff.schemas.in
index d73622c..a9d6e54 100644
--- a/lightsoff/lightsoff.schemas.in
+++ b/lightsoff/lightsoff.schemas.in
@@ -24,6 +24,19 @@
<long>The users's most recent score.</long>
</locale>
</schema>
+
+ <schema>
+ <key>/schemas/apps/lightsoff/use_theme_colors</key>
+ <applyto>/apps/lightsoff/use_theme_colors</applyto>
+ <owner>lightsoff</owner>
+ <type>bool</type>
+ <default>0</default>
+ <locale name="C">
+ <short>Whether or not to use the GNOME theme colors</short>
+ <long>If enabled, the default background color from the user's
+ default GNOME theme is used to draw the tiles.</long>
+ </locale>
+ </schema>
</schemalist>
diff --git a/lightsoff/src/Game.js b/lightsoff/src/Game.js
index 3355adb..1d35859 100644
--- a/lightsoff/src/Game.js
+++ b/lightsoff/src/Game.js
@@ -4,6 +4,7 @@ Clutter = imports.gi.Clutter;
LED = imports.LED;
Board = imports.Board;
Arrow = imports.Arrow;
+main = imports.main;
var last_direction, last_sign;
@@ -15,6 +16,8 @@ GameView = new GType({
// Private
var self = this;
var current_level = 1;
+ var queue_theme_change = 0;
+ var actor_remove_queue = [];
var score_view = new LED.LEDView();
var board_view = new Board.BoardView();
var backing_view = new Clutter.Clone({source:Settings.theme.backing});
@@ -44,11 +47,28 @@ GameView = new GType({
// The boards have finished transitioning; delete the old one!
var board_transition_complete = function()
{
+ queue_theme_change--;
+
self.remove_actor(board_view);
board_view = new_board_view;
board_view.set_playable(true);
keycursor_view.raise_top();
new_board_view = timeline = 0;
+
+ if(queue_theme_change)
+ {
+ queue_theme_change = 0;
+ theme_changed();
+ }
+
+ // Remove all of the queued-for-removal actors
+ while(actor_remove_queue.length > 0)
+ {
+ act = actor_remove_queue.pop();
+
+ if(act && act.get_parent())
+ act.get_parent().remove_actor(act);
+ }
}
// The player won the game; create a new board, update the level count,
@@ -125,6 +145,8 @@ GameView = new GType({
// The player changed the theme from within the preferences window
var theme_changed = function()
{
+ queue_theme_change++;
+
if(timeline)
return;
@@ -162,6 +184,12 @@ GameView = new GType({
// Public
+ // Queue an actor to be removed after the board is finished reloading
+ this.queue_actor_remove = function (actor)
+ {
+ actor_remove_queue.push(actor);
+ }
+
this.reset_game = function ()
{
if(timeline && timeline.is_playing())
diff --git a/lightsoff/src/Settings.js b/lightsoff/src/Settings.js
index 30f580c..1a7de4d 100644
--- a/lightsoff/src/Settings.js
+++ b/lightsoff/src/Settings.js
@@ -8,40 +8,56 @@ ThemeLoader = imports.ThemeLoader;
GConf.init(Seed.argv);
// Defaults
-var theme, score;
-var default_theme = "Tango";
-
-// Map theme names to themes
-var themes = ThemeLoader.load_themes();
+var theme, score, use_theme_colors, theme_name;
+var themes;
+var default_theme_name = "Tango";
+var default_use_theme_colors = false;
+// Load settings from GConf
try
{
gconf_client = GConf.Client.get_default();
score = gconf_client.get_int("/apps/lightsoff/score");
- theme = themes[gconf_client.get_string("/apps/lightsoff/theme")];
+ theme_name = gconf_client.get_string("/apps/lightsoff/theme")
+ use_theme_colors = gconf_client.get_bool("/apps/lightsoff/use_theme_colors");
if(theme == null)
- theme = themes[default_theme];
+ theme = default_theme_name;
}
catch(e)
{
print("Couldn't load settings from GConf.");
- theme = themes[default_theme];
+ theme_name = default_theme_name;
score = 1;
+ use_theme_colors = default_use_theme_colors;
}
// If (machine isn't restarted?) after schema is installed, defaults
// from GConf aren't set, so revert to defaults...
+// TODO: this seems unacceptable and wrong
if(score == 0)
{
- theme = themes[default_theme];
+ theme_name = default_theme_name;
score = 1;
}
+try
+{
+ // Map theme names to themes
+ themes = ThemeLoader.load_themes();
+
+ // Load selected theme
+ theme = themes[theme_name];
+}
+catch(e)
+{
+ print("Couldn't load selected theme...");
+}
+
// Settings Event Handler
SettingsWatcher = new GType({
- parent: Gtk.Button.type, // TODO: Can I make something inherit directly from GObject?!
+ parent: Gtk.Button.type,
name: "SettingsWatcher",
signals: [{name: "theme_changed"}],
init: function()
@@ -65,16 +81,39 @@ handlers = {
theme = new_theme;
ThemeLoader.load_theme(main.stage, theme);
+ b.get_object("use-gnome-theme-checkbox").sensitive = theme.theme_colorable;
+
+ if(!theme.theme_colorable)
+ b.get_object("use-gnome-theme-checkbox").active = false;
+
try
{
gconf_client.set_string("/apps/lightsoff/theme", selector.get_active_text());
}
catch(e)
{
- Seed.print("Couldn't save settings to GConf.");
+ print("Couldn't save settings to GConf.");
}
Watcher.signal.theme_changed.emit();
+ },
+ set_use_theme_colors: function(widget, ud)
+ {
+ use_theme_colors = widget.active;
+
+ theme.reload_theme();
+ ThemeLoader.load_theme(main.stage, theme);
+
+ try
+ {
+ gconf_client.set_bool("/apps/lightsoff/use_theme_colors", use_theme_colors);
+ }
+ catch(e)
+ {
+ print("Couldn't save settings to GConf.");
+ }
+
+ Watcher.signal.theme_changed.emit();
}
};
@@ -88,6 +127,10 @@ function show_settings()
populate_theme_selector(b.get_object("theme-selector"));
+ // Set current values
+ b.get_object("use-gnome-theme-checkbox").active = use_theme_colors;
+ b.get_object("use-gnome-theme-checkbox").sensitive = theme.theme_colorable;
+
settings_dialog = b.get_object("dialog1");
settings_dialog.set_transient_for(main.window);
diff --git a/lightsoff/src/ThemeLoader.js b/lightsoff/src/ThemeLoader.js
index 1367f69..a19bf9e 100644
--- a/lightsoff/src/ThemeLoader.js
+++ b/lightsoff/src/ThemeLoader.js
@@ -19,6 +19,9 @@ function load_theme(stage, theme)
for(actor in theme.textures)
{
+ if(theme.textures[actor].get_parent())
+ continue;
+
stage.add_actor(theme.textures[actor]);
theme.textures[actor].hide();
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]