[iagno] Themes' dialog.
- From: Arnaud Bonatti <arnaudb src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [iagno] Themes' dialog.
- Date: Fri, 13 Feb 2015 18:31:15 +0000 (UTC)
commit 26ceea8597ca170465e8356bce09be13412f8144
Author: Arnaud Bonatti <arnaud bonatti gmail com>
Date: Fri Feb 13 19:28:17 2015 +0100
Themes' dialog.
configure.ac | 1 +
data/Makefile.am | 7 ++-
data/iagno-menus.ui | 4 +
data/iagno-themes.ui | 80 +++++++++++++++++++++
data/iagno.css | 37 ++++++++++
data/iagno.ui | 2 +-
data/org.gnome.iagno.gschema.xml | 6 +-
data/themes/Makefile.am | 13 ++++
data/themes/adwaita.theme.in | 32 +++++++++
data/themes/high_contrast.theme.in | 32 +++++++++
data/themes/sun_and_star.theme.in | 32 +++++++++
po/POTFILES.in | 5 ++
po/POTFILES.skip | 1 +
src/Makefile.am | 2 +
src/game-view.vala | 134 +++++++++++++++++++++++++++++-------
src/iagno.gresource.xml | 1 +
src/iagno.vala | 136 +++++++++++++++++++++++++-----------
src/themes.vala | 104 +++++++++++++++++++++++++++
18 files changed, 557 insertions(+), 72 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 377180e..cdbd2e8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -65,6 +65,7 @@ data/Makefile
data/icons/Makefile
data/icons/hicolor/Makefile
data/icons/HighContrast/Makefile
+data/themes/Makefile
help/Makefile
src/Makefile
])
diff --git a/data/Makefile.am b/data/Makefile.am
index 5f98865..ebe6885 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -1,6 +1,9 @@
-SUBDIRS = icons
+SUBDIRS = \
+ icons \
+ themes
dist_noinst_DATA = \
+ iagno-themes.ui \
iagno-menus.ui \
iagno.ui \
iagno.css \
@@ -8,7 +11,7 @@ dist_noinst_DATA = \
light.svg \
mark.svg
-themedir = $(datadir)/iagno/themes
+themedir = $(datadir)/iagno/themes/svg
theme_DATA = \
sun_and_star.svg \
black_and_white.svg
diff --git a/data/iagno-menus.ui b/data/iagno-menus.ui
index 56cb8b5..82e755a 100644
--- a/data/iagno-menus.ui
+++ b/data/iagno-menus.ui
@@ -4,6 +4,10 @@
<menu id="app-menu">
<section>
<item>
+ <attribute name="label" translatable="yes">_Theme</attribute>
+ <attribute name="action">app.theme</attribute>
+ </item>
+ <item>
<attribute name="label" translatable="yes">_Sound</attribute>
<attribute name="action">app.sound</attribute>
</item>
diff --git a/data/iagno-themes.ui b/data/iagno-themes.ui
new file mode 100644
index 0000000..30396a3
--- /dev/null
+++ b/data/iagno-themes.ui
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <requires lib="gtk+" version="3.12"/>
+ <template class="ThemesDialog" parent="GtkDialog">
+ <property name="visible">False</property>
+ <property name="width-request">333</property>
+ <property name="height-request">450</property>
+ <property name="resizable">False</property>
+ <property name="title" translatable="yes">Theme</property>
+ <property name="border-width">0</property>
+ <child internal-child="vbox">
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="border-width">0</property>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="margin">0</property>
+ <property name="hscrollbar-policy">never</property>
+ <property name="vscrollbar-policy">automatic</property>
+ <property name="shadow-type">none</property>
+ <property name="valign">fill</property>
+ <child>
+ <object class="GtkFrame">
+ <property name="visible">True</property>
+ <property name="shadow-type">none</property>
+ <child>
+ <object class="GtkListBox" id="listbox">
+ <property name="visible">True</property>
+ <property name="name">themes-listbox</property>
+ <property name="activate-on-single-click">True</property>
+ <property name="selection-mode">single</property>
+ <child>
+ <object class="GtkListBoxRow">
+ <property name="visible">True</property>
+ <property name="name">default</property>
+ <property name="height-request">50</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="orientation">horizontal</property>
+ <child>
+ <object class="GtkImage">
+ <property name="visible">True</property>
+ <property name="icon-name">object-select-symbolic</property>
+ <property name="icon-size">1</property>
+ <property name="width-request">50</property>
+ <style><class name="theme-image"/></style>
+ </object>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Default</property>
+ <style><class name="italic-label"/></style>
+ </object>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">False</property>
+ <property name="label">default</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </template>
+</interface>
diff --git a/data/iagno.css b/data/iagno.css
index 76de693..7965668 100644
--- a/data/iagno.css
+++ b/data/iagno.css
@@ -1,3 +1,40 @@
+/* -*- Mode: vala; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * Copyright (C) 2015 Arnaud Bonatti <arnaud bonatti gmail com>
+ *
+ * This file is part of a GNOME game.
+ *
+ * This application 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 application 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 application. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/* Labels' fonts */
GtkLabel.bold-label {
font-weight: bold;
}
+GtkLabel.italic-label {
+ font-style: italic;
+}
+
+/* Themes' dialog listbox */
+GtkListBox#themes-listbox GtkImage {
+ transition-duration: 200ms;
+ opacity: 0;
+}
+GtkListBox#themes-listbox GtkListBoxRow:selected GtkImage {
+ opacity: 1;
+ color:@theme_selected_fg_color;
+}
+GtkListBox#themes-listbox GtkListBoxRow:selected GtkImage:backdrop {
+ color:@theme_unfocused_selected_fg_color;
+}
diff --git a/data/iagno.ui b/data/iagno.ui
index 407bfdc..34ed20b 100644
--- a/data/iagno.ui
+++ b/data/iagno.ui
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk+" version="3.12"/>
- <object class="GtkApplicationWindow" id="iagno-window">
+ <object class="GtkApplicationWindow" id="window">
<property name="title" translatable="yes">Iagno</property>
<child type="titlebar">
<object class="GtkHeaderBar" id="headerbar">
diff --git a/data/org.gnome.iagno.gschema.xml b/data/org.gnome.iagno.gschema.xml
index 35d67d1..173340d 100644
--- a/data/org.gnome.iagno.gschema.xml
+++ b/data/org.gnome.iagno.gschema.xml
@@ -21,8 +21,10 @@
<summary>Color to play as</summary>
<description>Whether to play as Dark or Light. Ignored for two-player games.</description>
</key>
- <key name="tileset" type="s">
- <default>'black_and_white.svg'</default>
+ <key name="theme" type="s">
+ <default>'default'</default>
+ <summary>Theme</summary>
+ <description>Filename of the theme used, or "default". Are provided "adwaita.theme",
"high_contrast.theme" and "sun_and_star.theme".</description>
</key>
<key name="sound" type="b">
<default>true</default>
diff --git a/data/themes/Makefile.am b/data/themes/Makefile.am
new file mode 100644
index 0000000..50125c2
--- /dev/null
+++ b/data/themes/Makefile.am
@@ -0,0 +1,13 @@
+themes_keydir = $(datadir)/iagno/themes/key
+themes_key_files = \
+ adwaita.theme.in \
+ high_contrast.theme.in \
+ sun_and_star.theme.in
+themes_key_DATA = $(themes_key_files:.theme.in=.theme)
+
+%.theme: %.theme.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po)
+ $(AM_V_GEN) LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache
$(top_srcdir)/po $< $@
+
+EXTRA_DIST = $(themes_key_DATA)
+
+-include $(top_srcdir)/git.mk
diff --git a/data/themes/adwaita.theme.in b/data/themes/adwaita.theme.in
new file mode 100644
index 0000000..078d637
--- /dev/null
+++ b/data/themes/adwaita.theme.in
@@ -0,0 +1,32 @@
+[Theme]
+Id=adwaita
+_Name=Adwaita
+
+[Pieces]
+#Animated=True
+File=black_and_white.svg
+
+[Background]
+#Image=
+Red=0.3
+Green=0.6
+Blue=0.4
+
+[Border]
+Red=0.0
+Green=0.0
+Blue=0.0
+Width=3
+
+[Spacing]
+Red=0.1
+Green=0.3
+Blue=0.2
+Width=2
+
+[Margin]
+#Width=0
+
+[Sound]
+Flip=flip-piece.ogg
+GameOver=gameover.ogg
diff --git a/data/themes/high_contrast.theme.in b/data/themes/high_contrast.theme.in
new file mode 100644
index 0000000..b199b35
--- /dev/null
+++ b/data/themes/high_contrast.theme.in
@@ -0,0 +1,32 @@
+[Theme]
+Id=high_contrast
+_Name=High Contrast
+
+[Pieces]
+#Animated=True
+File=black_and_white.svg
+
+[Background]
+#Image=
+Red=1.0
+Green=1.0
+Blue=1.0
+
+[Border]
+Red=0.0
+Green=0.0
+Blue=0.0
+Width=3
+
+[Spacing]
+Red=0.0
+Green=0.0
+Blue=0.0
+Width=2
+
+[Margin]
+#Width=0
+
+[Sound]
+Flip=flip-piece.ogg
+GameOver=gameover.ogg
diff --git a/data/themes/sun_and_star.theme.in b/data/themes/sun_and_star.theme.in
new file mode 100644
index 0000000..44dbf64
--- /dev/null
+++ b/data/themes/sun_and_star.theme.in
@@ -0,0 +1,32 @@
+[Theme]
+Id=sun_and_star
+_Name=Sun and Star
+
+[Pieces]
+#Animated=True
+File=sun_and_star.svg
+
+[Background]
+#Image=
+Red=0.3
+Green=0.6
+Blue=0.4
+
+[Border]
+Red=0.0
+Green=0.0
+Blue=0.0
+Width=3
+
+[Spacing]
+Red=0.1
+Green=0.3
+Blue=0.2
+Width=2
+
+[Margin]
+#Width=0
+
+[Sound]
+Flip=flip-piece.ogg
+GameOver=gameover.ogg
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 0acece1..3995379 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -4,10 +4,15 @@
data/iagno.appdata.xml.in
data/iagno.desktop.in
[type: gettext/glade]data/iagno-menus.ui
+[type: gettext/glade]data/iagno-themes.ui
[type: gettext/glade]data/iagno.ui
+[type: gettext/ini]data/themes/adwaita.theme.in
+[type: gettext/ini]data/themes/high_contrast.theme.in
+[type: gettext/ini]data/themes/sun_and_star.theme.in
data/org.gnome.iagno.gschema.xml
src/computer-player.vala
src/game.vala
src/game-view.vala
src/iagno.vala
src/player.vala
+src/themes.vala
diff --git a/po/POTFILES.skip b/po/POTFILES.skip
index d0ce332..fbd1b9f 100644
--- a/po/POTFILES.skip
+++ b/po/POTFILES.skip
@@ -3,3 +3,4 @@ src/game.c
src/game-view.c
src/iagno.c
src/player.c
+src/themes.c
diff --git a/src/Makefile.am b/src/Makefile.am
index 7c52e6c..117b5e8 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -8,6 +8,7 @@ iagno_SOURCES = \
computer-player.vala \
game.vala \
game-view.vala \
+ themes.vala \
iagno.vala \
player.vala \
$(BUILT_SOURCES)
@@ -28,6 +29,7 @@ iagno_VALAFLAGS = \
--pkg librsvg-2.0 \
--pkg libcanberra \
--pkg libcanberra-gtk \
+ --gresources=$(builddir)/iagno.gresource.xml \
--target-glib 2.40
iagno_LDADD = $(IAGNO_LIBS)
diff --git a/src/game-view.vala b/src/game-view.vala
index cbd31fa..2d5740c 100644
--- a/src/game-view.vala
+++ b/src/game-view.vala
@@ -21,14 +21,32 @@
public class GameView : Gtk.DrawingArea
{
/* Theme */
- private const int GRID_BORDER = 3;
- private const int GRID_SPACING = 2;
+ private string pieces_file;
+
+ private double background_red;
+ private double background_green;
+ private double background_blue;
+
+ private double border_red;
+ private double border_green;
+ private double border_blue;
+ private int border_width;
+
+ private double spacing_red;
+ private double spacing_green;
+ private double spacing_blue;
+ private int spacing_width;
+
+ // private int margin_width;
+
+ public string sound_flip { get; private set; }
+ public string sound_gameover { get; private set; }
/* Utilities, see calculate () */
private int tile_size;
private int board_size;
- private int x_offset { get { return (get_allocated_width () - board_size) / 2 + GRID_BORDER; }}
- private int y_offset { get { return (get_allocated_height () - board_size) / 2 + GRID_BORDER; }}
+ private int x_offset { get { return (get_allocated_width () - board_size) / 2 + border_width; }}
+ private int y_offset { get { return (get_allocated_height () - board_size) / 2 + border_width; }}
/* Delay in milliseconds between tile flip frames */
private const int PIXMAP_FLIP_DELAY = 20;
@@ -73,7 +91,69 @@ public class GameView : Gtk.DrawingArea
public string? theme
{
get { return _theme; }
- set { _theme = value; tiles_pattern = null; queue_draw (); }
+ set {
+ if (value == "default")
+ {
+ set_default_theme ();
+ _theme = "default";
+ }
+ else
+ {
+ var key = new GLib.KeyFile ();
+ key.load_from_file (Path.build_filename (DATA_DIRECTORY, "themes", "key", value),
GLib.KeyFileFlags.NONE);
+
+ // TODO try ... catch { set_default_theme (); _theme="default"; }
+ load_theme (key);
+ _theme = value;
+ }
+
+ // redraw all
+ tiles_pattern = null;
+ queue_draw ();
+ }
+ }
+
+ private void set_default_theme ()
+ {
+ var defaults = Gtk.Settings.get_default ();
+ var key = new GLib.KeyFile ();
+ string filename;
+ if (defaults.gtk_theme_name == "HighContrast")
+ filename = "high_contrast.theme";
+ /* else if (defaults.gtk_application_prefer_dark_theme == true) // TODO
+ filename = "adwaita_dark.theme"; */
+ else
+ filename = "adwaita.theme";
+ key.load_from_file (Path.build_filename (DATA_DIRECTORY, "themes", "key", filename),
GLib.KeyFileFlags.NONE);
+ load_theme (key);
+ }
+
+ private void load_theme (GLib.KeyFile key)
+ {
+ string path = Path.build_filename (DATA_DIRECTORY, "themes", "svg");
+
+ pieces_file = Path.build_filename (path, key.get_string ("Pieces", "File"));
+ if (Path.get_dirname (pieces_file) != path) // security
+ pieces_file = Path.build_filename (path, "black_and_white.svg");
+
+ background_red = key.get_double ("Background", "Red");
+ background_green = key.get_double ("Background", "Green");
+ background_blue = key.get_double ("Background", "Blue");
+
+ border_red = key.get_double ("Border", "Red");
+ border_green = key.get_double ("Border", "Green");
+ border_blue = key.get_double ("Border", "Blue");
+ border_width = key.get_integer ("Border", "Width");
+
+ spacing_red = key.get_double ("Spacing", "Red");
+ spacing_green = key.get_double ("Spacing", "Green");
+ spacing_blue = key.get_double ("Spacing", "Blue");
+ spacing_width = key.get_integer ("Spacing", "Width");
+
+ // margin_width = key.get_integer ("Margin", "Width");
+
+ sound_flip = key.get_string ("Sound", "Flip");
+ sound_gameover = key.get_string ("Sound", "GameOver");
}
public GameView ()
@@ -86,9 +166,9 @@ public class GameView : Gtk.DrawingArea
{
var size = int.min (get_allocated_width (), get_allocated_height ());
/* tile_size includes a grid spacing */
- tile_size = (size - 2 * GRID_BORDER + GRID_SPACING) / game.size;
+ tile_size = (size - 2 * border_width + spacing_width) / game.size;
/* board_size includes its borders */
- board_size = tile_size * game.size - GRID_SPACING + 2 * GRID_BORDER;
+ board_size = tile_size * game.size - spacing_width + 2 * border_width;
}
public override bool draw (Cairo.Context cr)
@@ -103,34 +183,38 @@ public class GameView : Gtk.DrawingArea
render_size = tile_size;
var surface = new Cairo.Surface.similar (cr.get_target (), Cairo.Content.COLOR_ALPHA, tile_size
* 8, tile_size * 4);
var c = new Cairo.Context (surface);
- load_theme (c);
+ load_image (c);
tiles_pattern = new Cairo.Pattern.for_surface (surface);
}
cr.translate (x_offset, y_offset);
- /* draw border and background */
- cr.set_source_rgba (0.3, 0.6, 0.4, 1.0);
- cr.rectangle (-GRID_BORDER / 2.0, -GRID_BORDER / 2.0, board_size - GRID_BORDER, board_size -
GRID_BORDER);
- cr.fill_preserve ();
- cr.set_source_rgba (0.0, 0.0, 0.0, 1.0);
- cr.set_line_width (GRID_BORDER);
- cr.stroke ();
+ /* draw background; TODO save for border */
+ cr.set_source_rgba (background_red, background_green, background_blue, 1.0);
+ cr.rectangle (-border_width / 2.0, -border_width / 2.0, board_size - border_width, board_size -
border_width);
+ cr.fill ();
/* draw lines */
- cr.set_line_width (GRID_SPACING);
+ cr.set_source_rgba (spacing_red, spacing_green, spacing_blue, 1.0);
+ cr.set_line_width (spacing_width);
for (var i = 1; i < game.size; i++)
{
- cr.move_to (i * tile_size - GRID_SPACING / 2.0, 0);
- cr.rel_line_to (0, board_size - GRID_BORDER);
+ cr.move_to (i * tile_size - spacing_width / 2.0, 0);
+ cr.rel_line_to (0, board_size - border_width);
- cr.move_to (0, i * tile_size - GRID_SPACING / 2.0);
- cr.rel_line_to (board_size - GRID_BORDER, 0);
+ cr.move_to (0, i * tile_size - spacing_width / 2.0);
+ cr.rel_line_to (board_size - border_width, 0);
}
cr.stroke ();
+ /* draw border */
+ cr.set_source_rgba (border_red, border_green, border_blue, 1.0);
+ cr.set_line_width (border_width);
+ cr.rectangle (-border_width / 2.0, -border_width / 2.0, board_size - border_width, board_size -
border_width);
+ cr.stroke ();
+
/* draw pieces */
- cr.translate (-GRID_SPACING / 2, -GRID_SPACING / 2);
+ cr.translate (-spacing_width / 2, -spacing_width / 2);
for (var x = 0; x < game.size; x++)
{
for (var y = 0; y < game.size; y++)
@@ -154,14 +238,14 @@ public class GameView : Gtk.DrawingArea
return false;
}
- private void load_theme (Cairo.Context c)
+ private void load_image (Cairo.Context c)
{
var width = tile_size * 8;
var height = tile_size * 4;
try
{
- var h = new Rsvg.Handle.from_file (theme);
+ var h = new Rsvg.Handle.from_file (pieces_file);
var m = Cairo.Matrix.identity ();
m.scale ((double) width / h.width, (double) height / h.height);
@@ -177,13 +261,13 @@ public class GameView : Gtk.DrawingArea
try
{
- var p = new Gdk.Pixbuf.from_file_at_scale (theme, width, height, false);
+ var p = new Gdk.Pixbuf.from_file_at_scale (pieces_file, width, height, false);
Gdk.cairo_set_source_pixbuf (c, p, 0, 0);
c.paint ();
}
catch (Error e)
{
- warning ("Failed to load theme %s: %s", theme, e.message);
+ warning ("Failed to load theme image %s: %s", pieces_file, e.message);
}
}
diff --git a/src/iagno.gresource.xml b/src/iagno.gresource.xml
index 8260b10..7e29f66 100644
--- a/src/iagno.gresource.xml
+++ b/src/iagno.gresource.xml
@@ -7,6 +7,7 @@
</gresource>
<gresource prefix="/org/gnome/iagno/ui">
<file preprocess="xml-stripblanks" alias="iagno.ui">../data/iagno.ui</file>
+ <file preprocess="xml-stripblanks" alias="themes.ui">../data/iagno-themes.ui</file>
<file alias="iagno.css">../data/iagno.css</file>
</gresource>
<gresource prefix="/org/gnome/iagno/gtk">
diff --git a/src/iagno.vala b/src/iagno.vala
index cd97aa6..d14b7d0 100644
--- a/src/iagno.vala
+++ b/src/iagno.vala
@@ -49,6 +49,7 @@ public class Iagno : Gtk.Application
private Gtk.Label dark_score_label;
private Gtk.Label light_score_label;
private Gtk.Stack main_stack;
+ private ThemesDialog themes_dialog;
private Gtk.Button back_button;
private Gtk.Button undo_button;
@@ -87,6 +88,7 @@ public class Iagno : Gtk.Application
{"undo-move", undo_move_cb},
{"back", back_cb},
+ {"theme", theme_cb},
{"help", help_cb},
{"about", about_cb},
{"quit", quit}
@@ -209,7 +211,7 @@ public class Iagno : Gtk.Application
color_box.sensitive = settings.get_int ("num-players") == 1;
/* Window construction */
- window = builder.get_object ("iagno-window") as Gtk.ApplicationWindow;
+ window = builder.get_object ("window") as Gtk.ApplicationWindow;
window.size_allocate.connect (size_allocate_cb);
window.window_state_event.connect (window_state_event_cb);
window.set_default_size (settings.get_int ("window-width"), settings.get_int ("window-height"));
@@ -228,8 +230,7 @@ public class Iagno : Gtk.Application
/* View construction */
view = new GameView ();
view.move.connect (player_move_cb);
- var tile_set = settings.get_string ("tileset");
- view.theme = Path.build_filename (DATA_DIRECTORY, "themes", tile_set);
+ view.theme = settings.get_string ("theme");
view.halign = Gtk.Align.FILL;
view.show ();
@@ -271,6 +272,10 @@ public class Iagno : Gtk.Application
settings.set_boolean ("window-is-maximized", is_maximized);
}
+ /*\
+ * * Window events
+ \*/
+
private void size_allocate_cb (Gtk.Allocation allocation)
{
if (is_maximized || is_tiled)
@@ -289,6 +294,60 @@ public class Iagno : Gtk.Application
return false;
}
+ /*\
+ * * App-menu callbacks
+ \*/
+
+ private void theme_cb ()
+ {
+ /* Don’t permit to open more than one dialog */
+ if (themes_dialog == null)
+ {
+ themes_dialog = new ThemesDialog (settings, view);
+ themes_dialog.set_transient_for (window);
+ }
+ themes_dialog.present ();
+ }
+
+ private void help_cb ()
+ {
+ try
+ {
+ Gtk.show_uri (window.get_screen (), "help:iagno", Gtk.get_current_event_time ());
+ }
+ catch (Error e)
+ {
+ warning ("Failed to show help: %s", e.message);
+ }
+ }
+
+ private void about_cb ()
+ {
+ string[] authors = { "Ian Peters", "Robert Ancell", null };
+ string[] documenters = { "Tiffany Antopolski", null };
+
+ Gtk.show_about_dialog (window,
+ "name", _("Iagno"),
+ "version", VERSION,
+ "copyright",
+ "Copyright © 1998–2008 Ian Peters\n"+
+ "Copyright © 2013–2015 Michael Catanzaro\n"+
+ "Copyright © 2014–2015 Arnaud Bonatti",
+ "license-type", Gtk.License.GPL_3_0,
+ "comments",
+ _("A disk flipping game derived from Reversi"),
+ "authors", authors,
+ "documenters", documenters,
+ "translator-credits", _("translator-credits"),
+ "logo-icon-name", "iagno",
+ "website", "https://wiki.gnome.org/Apps/Iagno",
+ null);
+ }
+
+ /*\
+ * * Internal calls
+ \*/
+
private void start_game_cb ()
{
main_stack.set_transition_type (Gtk.StackTransitionType.SLIDE_DOWN);
@@ -405,7 +464,7 @@ public class Iagno : Gtk.Application
}
update_ui ();
- play_sound ("flip-piece");
+ play_sound (Sound.FLIP);
}
private void turn_ended_cb ()
@@ -422,7 +481,7 @@ public class Iagno : Gtk.Application
private void prepare_move ()
{
/* for the move that just ended */
- play_sound ("flip-piece");
+ play_sound (Sound.FLIP);
/*
* Get the computer to move after a delay, so it looks like it's
@@ -441,7 +500,7 @@ public class Iagno : Gtk.Application
private void pass ()
{
/* for the move that just ended */
- play_sound ("flip-piece");
+ play_sound (Sound.FLIP);
game.pass ();
if (game.current_color == Player.DARK)
@@ -475,17 +534,7 @@ public class Iagno : Gtk.Application
}
if (play_gameover_sound)
- play_sound ("gameover");
- }
-
- private void play_sound (string name)
- {
- if (!settings.get_boolean ("sound"))
- return;
-
- CanberraGtk.play_for_widget (view, 0,
- Canberra.PROP_MEDIA_NAME, name,
- Canberra.PROP_MEDIA_FILENAME, Path.build_filename (SOUND_DIRECTORY,
"%s.ogg".printf (name)));
+ play_sound (Sound.GAMEOVER);
}
private void player_move_cb (int x, int y)
@@ -501,35 +550,38 @@ public class Iagno : Gtk.Application
}
}
- private void help_cb ()
+ /*\
+ * * Sound
+ \*/
+
+ private enum Sound
{
- try
- {
- Gtk.show_uri (window.get_screen (), "help:iagno", Gtk.get_current_event_time ());
- }
- catch (Error e)
- {
- warning ("Failed to show help: %s", e.message);
- }
+ FLIP,
+ GAMEOVER;
}
- private void about_cb ()
+ private void play_sound (Sound sound)
{
- string[] authors = { "Ian Peters", "Robert Ancell", null };
- string[] documenters = { "Tiffany Antopolski", null };
+ if (!settings.get_boolean ("sound"))
+ return;
- Gtk.show_about_dialog (window,
- "name", _("Iagno"),
- "version", VERSION,
- "copyright",
- "Copyright © 1998–2008 Ian Peters\nCopyright © 2013–2015 Michael Catanzaro",
- "license-type", Gtk.License.GPL_3_0,
- "comments", _("A disk flipping game derived from Reversi"),
- "authors", authors,
- "documenters", documenters,
- "translator-credits", _("translator-credits"),
- "logo-icon-name", "iagno",
- "website", "https://wiki.gnome.org/Apps/Iagno",
- null);
+ string name;
+ switch (sound)
+ {
+ case Sound.FLIP:
+ name = view.sound_flip;
+ break;
+ case Sound.GAMEOVER:
+ name = view.sound_gameover;
+ break;
+ default:
+ return;
+ }
+ string path = Path.build_filename (SOUND_DIRECTORY, name);
+ int r = CanberraGtk.play_for_widget (view, 0,
+ Canberra.PROP_MEDIA_NAME, name,
+ Canberra.PROP_MEDIA_FILENAME, path);
+ if (r != 0)
+ warning ("Error playing file: %s\nfilepath should be:%s", name, path);
}
}
diff --git a/src/themes.vala b/src/themes.vala
new file mode 100644
index 0000000..eb064ad
--- /dev/null
+++ b/src/themes.vala
@@ -0,0 +1,104 @@
+/* -*- Mode: vala; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * Copyright (C) 2015 Arnaud Bonatti <arnaud bonatti gmail com>
+ *
+ * This file is part of a GNOME game.
+ *
+ * This application 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 application 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 application. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+using Gtk;
+
+[GtkTemplate (ui = "/org/gnome/iagno/ui/themes.ui")]
+public class ThemesDialog : Dialog
+{
+ private static const string PREFIX = "theme-";
+
+ private GameView view;
+
+ [GtkChild]
+ private ListBox listbox;
+
+ public ThemesDialog (GLib.Settings settings, GameView view)
+ {
+ Object (use_header_bar: Gtk.Settings.get_default ().gtk_dialogs_use_header ? 1 : 0);
+ this.view = view;
+ delete_event.connect (do_not_close);
+
+ /* load themes key files */
+ Dir dir;
+ string theme = settings.get_string ("theme");
+ try
+ {
+ dir = Dir.open (Path.build_filename (DATA_DIRECTORY, "themes", "key"));
+ while (true)
+ {
+ string filename = dir.read_name ();
+ if (filename == null)
+ break;
+
+ string path = Path.build_filename (DATA_DIRECTORY, "themes", "key", filename);
+ var key = new GLib.KeyFile ();
+ try
+ {
+ key.load_from_file (path, GLib.KeyFileFlags.NONE);
+ }
+ catch (GLib.KeyFileError e)
+ {
+ warning ("oops: %s", e.message);
+ }
+
+ var row = new ListBoxRow ();
+ row.visible = true;
+ row.height_request = 50;
+ var box = new Box (Orientation.HORIZONTAL, 0);
+ box.visible = true;
+ var img = new Image ();
+ img.visible = true;
+ img.width_request = 50;
+ img.icon_name = "object-select-symbolic";
+ var lbl = new Label (key.get_locale_string ("Theme", "Name")); // TODO test translation
+ lbl.visible = true;
+ lbl.xalign = 0;
+ var data = new Label (filename);
+ data.visible = false;
+
+ box.add (img);
+ box.add (lbl);
+ box.add (data);
+ row.add (box);
+ listbox.add (row);
+
+ if (filename == settings.get_string ("theme"))
+ listbox.select_row (row);
+ }
+ // FIXME bug on <ctrl>double-click
+ listbox.row_selected.connect ((row) => {
+ view.theme = ((Label) (((Box) row.get_child ()).get_children ().nth_data (2))).label;
+ // TODO BETTER view.theme may have fall back to "default"
+ settings.set_string ("theme", view.theme);
+ });
+ }
+ catch (FileError e)
+ {
+ warning ("Failed to load themes: %s", e.message);
+ }
+ }
+
+ private bool do_not_close (Widget widget, Gdk.EventAny event)
+ {
+ widget.hide ();
+ return true;
+ }
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]