[iagno] Introduce ThemeManager.
- From: Arnaud B. <arnaudb src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [iagno] Introduce ThemeManager.
- Date: Sun, 26 Jan 2020 01:31:08 +0000 (UTC)
commit 38f1ecac6a5361a421a3da7c9fe41b370eb29da1
Author: Arnaud Bonatti <arnaud bonatti gmail com>
Date: Tue Jan 14 17:59:28 2020 +0100
Introduce ThemeManager.
Just moving code, for now.
src/iagno.vala | 29 ++---
src/meson.build | 4 +-
src/reversi-view.vala | 280 +++++++++++++------------------------------------
src/theme-manager.vala | 187 +++++++++++++++++++++++++++++++++
4 files changed, 281 insertions(+), 219 deletions(-)
---
diff --git a/src/iagno.vala b/src/iagno.vala
index 5aed9cf..888de5e 100644
--- a/src/iagno.vala
+++ b/src/iagno.vala
@@ -54,6 +54,8 @@ private class Iagno : Gtk.Application, BaseApplication
private HistoryButton history_button_1;
private HistoryButton history_button_2;
+ private ThemeManager theme_manager = new ThemeManager ();
+
/* Computer player (if there is one) */
internal ComputerPlayer? computer { internal get; private set; default = null; }
@@ -258,7 +260,7 @@ private class Iagno : Gtk.Application, BaseApplication
}
/* UI parts */
- view = new ReversiView (this);
+ view = new ReversiView (this, theme_manager);
view.move.connect (player_move_cb);
view.clear_impossible_to_move_here_warning.connect (clear_impossible_to_move_here_warning);
@@ -364,7 +366,7 @@ private class Iagno : Gtk.Application, BaseApplication
if (wanted_theme_id == (!) filename)
{
theme_name_found = true;
- view.theme = wanted_theme_id;
+ theme_manager.theme = wanted_theme_id;
}
}
}
@@ -377,7 +379,7 @@ private class Iagno : Gtk.Application, BaseApplication
warning (@"Theme $wanted_theme_id not found, using default.");
settings.set_string ("theme", "default");
wanted_theme_id = "default";
- // view.theme defaults on "default" (in fact, on null)
+ // theme_manager.theme defaults on "default" (in fact, on null)
}
section.freeze ();
appearance_menu.append_section (null, section);
@@ -425,7 +427,7 @@ private class Iagno : Gtk.Application, BaseApplication
window.back.connect (back_cb);
window.undo.connect (undo_cb);
- window.gtk_theme_changed.connect (view.gtk_theme_changed);
+ window.gtk_theme_changed.connect (theme_manager.gtk_theme_changed);
/* Actions and preferences */
add_action_entries (app_actions, this);
@@ -447,9 +449,9 @@ private class Iagno : Gtk.Application, BaseApplication
add_action (settings.create_action ("theme"));
add_action (settings.create_action ("type")); // TODO window action?
- settings.bind ("highlight-playable-tiles", view, "show-playable-tiles", SettingsBindFlags.GET);
- settings.bind ("highlight-turnable-tiles", view, "show-turnable-tiles", SettingsBindFlags.GET);
- settings.bind ("theme", view, "theme", SettingsBindFlags.GET);
+ settings.bind ("highlight-playable-tiles", view, "show-playable-tiles",
SettingsBindFlags.GET);
+ settings.bind ("highlight-turnable-tiles", view, "show-turnable-tiles",
SettingsBindFlags.GET);
+ settings.bind ("theme", theme_manager, "theme",
SettingsBindFlags.GET);
/* New-game screen signals */
alternate_who_starts_action = (SimpleAction) lookup_action ("alternate-who-starts");
@@ -542,7 +544,7 @@ private class Iagno : Gtk.Application, BaseApplication
requires (gvariant != null)
{
night_light_monitor.set_use_night_mode (((!) gvariant).get_boolean ());
- view.gtk_theme_changed ();
+ theme_manager.gtk_theme_changed ();
}
/*\
@@ -953,25 +955,28 @@ private class Iagno : Gtk.Application, BaseApplication
if (sound_context_state == SoundContextState.INITIAL)
init_sound ();
if (sound_context_state == SoundContextState.WORKING)
- _play_sound (sound, sound_context, ref view);
+ _play_sound (sound, sound_context, theme_manager);
}
}
- private static void _play_sound (Sound sound, GSound.Context sound_context, ref ReversiView view)
+ private static inline void _play_sound (Sound sound, GSound.Context sound_context, ThemeManager
theme_manager)
// requires (sound_context_state == SoundContextState.WORKING)
{
string name;
switch (sound)
{
case Sound.FLIP:
- name = view.sound_flip;
+ name = theme_manager.sound_flip;
break;
case Sound.GAMEOVER:
- name = view.sound_gameover;
+ name = theme_manager.sound_gameover;
break;
default:
return;
}
+ if (name == "")
+ assert_not_reached ();
+
string path = Path.build_filename (SOUND_DIRECTORY, name);
try
{
diff --git a/src/meson.build b/src/meson.build
index 3ab390b..f3d3a20 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -86,8 +86,8 @@ executable(meson.project_name(),
'overlayed-list.vala',
'player.vala',
'registry-placeholder.vala',
- 'reversi-view.vala'
-
+ 'reversi-view.vala',
+ 'theme-manager.vala'
] + resources,
install: true,
c_args: [
diff --git a/src/reversi-view.vala b/src/reversi-view.vala
index 4b30099..f09483a 100644
--- a/src/reversi-view.vala
+++ b/src/reversi-view.vala
@@ -30,48 +30,6 @@ private class ReversiView : Gtk.DrawingArea
}
[CCode (notify = false)] internal bool show_turnable_tiles { private get; internal set; default = false;
}
- /* Theme */
- private string pieces_file;
-
- private double background_red = 0.2;
- private double background_green = 0.6;
- private double background_blue = 0.4;
- private int background_radius = 0;
-
- private double texture_alpha = 0.25;
- private bool apply_texture = false;
-
- // private double mark_red = 0.2;
- // private double mark_green = 0.6;
- // private double mark_blue = 0.4;
- // private int mark_width = 2;
-
- private double border_red = 0.1;
- private double border_green = 0.1;
- private double border_blue = 0.1;
- private int border_width = 3;
- private double half_border_width = 1.5;
-
- private double spacing_red = 0.1;
- private double spacing_green = 0.3;
- private double spacing_blue = 0.2;
- private int spacing_width = 2;
-
- private double highlight_hard_red = 0.1;
- private double highlight_hard_green = 0.3;
- private double highlight_hard_blue = 0.2;
- private double highlight_hard_alpha = 0.4;
-
- private double highlight_soft_red = 0.1;
- private double highlight_soft_green = 0.3;
- private double highlight_soft_blue = 0.2;
- private double highlight_soft_alpha = 0.2;
-
- // private int margin_width = 0;
-
- [CCode (notify = false)] internal string sound_flip { internal get; private set; }
- [CCode (notify = false)] internal string sound_gameover { internal get; private set; }
-
private int board_x;
private int board_y;
@@ -218,131 +176,18 @@ private class ReversiView : Gtk.DrawingArea
| Gdk.EventMask.LEAVE_NOTIFY_MASK
| Gdk.EventMask.STRUCTURE_MASK);
init_mouse ();
- }
-
- private Iagno iagno_instance;
- internal ReversiView (Iagno iagno_instance)
- {
- this.iagno_instance = iagno_instance;
- }
-
- /*\
- * * theme
- \*/
-
- internal void gtk_theme_changed ()
- {
- if (theme == null || (!) theme == "default")
- theme = "default"; // yes
- }
-
- private string? _theme = null;
- [CCode (notify = false)] internal string? theme
- {
- get { return _theme; }
- set {
- KeyFile key = new KeyFile ();
- if (value == null || (!) value == "default")
- set_default_theme (ref key);
- else
- try
- {
- string key_path = Path.build_filename (DATA_DIRECTORY, "themes", "key");
- string filepath = Path.build_filename (key_path, (!) value);
- if (Path.get_dirname (filepath) != key_path)
- throw new FileError.FAILED ("Theme file is not in the \"key\" directory.");
-
- key.load_from_file (filepath, GLib.KeyFileFlags.NONE);
- }
- catch (Error e)
- {
- warning ("Failed to load theme: %s", e.message);
- set_default_theme (ref key);
- value = "default";
- }
-
- load_theme (key);
- _theme = value;
- /* redraw all */
- tiles_pattern = null;
- queue_draw ();
- }
- }
-
- private void set_default_theme (ref KeyFile key)
- {
- Gtk.Settings? defaults = Gtk.Settings.get_default ();
-
- string filename;
- if (defaults != null && "HighContrast" in ((!) defaults).gtk_theme_name)
- filename = "high_contrast.theme";
- else if (defaults != null && (((!) defaults).gtk_application_prefer_dark_theme == true
- || ((!) defaults).gtk_theme_name == "Adwaita-dark"))
- filename = "adwaita.theme";
- else
- filename = "classic.theme";
-
- string filepath = Path.build_filename (DATA_DIRECTORY, "themes", "key", filename);
- try
- {
- key.load_from_file (filepath, GLib.KeyFileFlags.NONE);
- }
- catch { assert_not_reached (); }
+ theme_manager.theme_changed.connect (() => {
+ tiles_pattern = null;
+ queue_draw ();
+ });
}
- private void load_theme (GLib.KeyFile key)
+ [CCode (notify = false)] public Iagno iagno_instance { private get; protected construct; }
+ [CCode (notify = false)] public ThemeManager theme_manager { private get; protected construct; }
+ internal ReversiView (Iagno iagno_instance, ThemeManager theme_manager)
{
- try
- {
- string svg_path = Path.build_filename (DATA_DIRECTORY, "themes", "svg");
- pieces_file = Path.build_filename (svg_path, key.get_string ("Pieces", "File"));
- if (Path.get_dirname (pieces_file) != svg_path)
- pieces_file = Path.build_filename (svg_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");
- background_radius = key.get_integer ("Background", "Radius");
-
- texture_alpha = key.get_double ("Background", "TextureAlpha");
- apply_texture = (texture_alpha > 0.0) && (texture_alpha <= 1.0);
-
- // mark_red = key.get_double ("Mark", "Red");
- // mark_green = key.get_double ("Mark", "Green");
- // mark_blue = key.get_double ("Mark", "Blue");
- // mark_width = key.get_integer ("Mark", "Width");
-
- 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");
- half_border_width = (double) border_width / 2.0;
-
- 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");
-
- highlight_hard_red = key.get_double ("Highlight hard", "Red");
- highlight_hard_green = key.get_double ("Highlight hard", "Green");
- highlight_hard_blue = key.get_double ("Highlight hard", "Blue");
- highlight_hard_alpha = key.get_double ("Highlight hard", "Alpha");
-
- highlight_soft_red = key.get_double ("Highlight soft", "Red");
- highlight_soft_green = key.get_double ("Highlight soft", "Green");
- highlight_soft_blue = key.get_double ("Highlight soft", "Blue");
- highlight_soft_alpha = key.get_double ("Highlight soft", "Alpha");
-
- // margin_width = key.get_integer ("Margin", "Width");
-
- sound_flip = key.get_string ("Sound", "Flip");
- sound_gameover = key.get_string ("Sound", "GameOver");
- }
- catch (KeyFileError e) // TODO better
- {
- warning ("Errors when loading theme: %s", e.message);
- }
+ Object (iagno_instance: iagno_instance, theme_manager: theme_manager);
}
/*\
@@ -362,11 +207,11 @@ private class ReversiView : Gtk.DrawingArea
int allocated_width = get_allocated_width ();
int allocated_height = get_allocated_height ();
int size = int.min (allocated_width, allocated_height);
- paving_size = (size - 2 * border_width + spacing_width) / game_size;
- tile_size = paving_size - spacing_width;
- board_size = paving_size * game_size - spacing_width + 2 * border_width;
- board_x = (allocated_width - board_size) / 2 + border_width;
- board_y = (allocated_height - board_size) / 2 + border_width;
+ paving_size = (size - 2 * theme_manager.border_width + theme_manager.spacing_width) / game_size;
+ tile_size = paving_size - theme_manager.spacing_width;
+ board_size = paving_size * game_size - theme_manager.spacing_width + 2 * theme_manager.border_width;
+ board_x = (allocated_width - board_size) / 2 + theme_manager.border_width;
+ board_y = (allocated_height - board_size) / 2 + theme_manager.border_width;
if (humans_opening_intensity != 0)
configure_overture_origin ();
@@ -386,33 +231,33 @@ private class ReversiView : Gtk.DrawingArea
{
if (game_size % 2 == 0)
{
- overture_origin_xs [0] = (game_size - 3) * board_size / (2 * game_size) - border_width -
tile_size / 2;
- overture_origin_xs [1] = (game_size - 1) * board_size / (2 * game_size) - border_width -
tile_size / 2;
- overture_origin_xs [2] = (game_size + 1) * board_size / (2 * game_size) - border_width -
tile_size / 2;
- overture_origin_xs [3] = (game_size + 3) * board_size / (2 * game_size) - border_width -
tile_size / 2;
+ overture_origin_xs [0] = (game_size - 3) * board_size / (2 * game_size) -
theme_manager.border_width - tile_size / 2;
+ overture_origin_xs [1] = (game_size - 1) * board_size / (2 * game_size) -
theme_manager.border_width - tile_size / 2;
+ overture_origin_xs [2] = (game_size + 1) * board_size / (2 * game_size) -
theme_manager.border_width - tile_size / 2;
+ overture_origin_xs [3] = (game_size + 3) * board_size / (2 * game_size) -
theme_manager.border_width - tile_size / 2;
if (game_size == 4)
// where we can
- overture_origin_y = (int) ((game_size + 2.6) * board_size / (2 * game_size) - border_width
- tile_size / 2);
+ overture_origin_y = (int) ((game_size + 2.6) * board_size / (2 * game_size) -
theme_manager.border_width - tile_size / 2);
else
// on the line under the center zone
- overture_origin_y = (game_size + 4) * board_size / (2 * game_size) - border_width -
tile_size / 2;
+ overture_origin_y = (game_size + 4) * board_size / (2 * game_size) -
theme_manager.border_width - tile_size / 2;
}
else
{
- overture_origin_xs [0] = (game_size - 2) * board_size / (2 * game_size) - border_width -
tile_size / 2;
- overture_origin_xs [2] = game_size * board_size / (2 * game_size) - border_width -
tile_size / 2;
- overture_origin_xs [4] = (game_size + 2) * board_size / (2 * game_size) - border_width -
tile_size / 2;
+ overture_origin_xs [0] = (game_size - 2) * board_size / (2 * game_size) -
theme_manager.border_width - tile_size / 2;
+ overture_origin_xs [2] = game_size * board_size / (2 * game_size) -
theme_manager.border_width - tile_size / 2;
+ overture_origin_xs [4] = (game_size + 2) * board_size / (2 * game_size) -
theme_manager.border_width - tile_size / 2;
overture_origin_xs [1] = overture_origin_xs [0];
overture_origin_xs [3] = overture_origin_xs [2];
overture_origin_xs [5] = overture_origin_xs [4];
if (game_size == 5)
// where we can
- overture_origin_y = (int) ((game_size + 3.6) * board_size / (2 * game_size) - border_width
- tile_size / 2);
+ overture_origin_y = (int) ((game_size + 3.6) * board_size / (2 * game_size) -
theme_manager.border_width - tile_size / 2);
else
// on the line under the center zone
- overture_origin_y = (game_size + 5) * board_size / (2 * game_size) - border_width -
tile_size / 2;
+ overture_origin_y = (game_size + 5) * board_size / (2 * game_size) -
theme_manager.border_width - tile_size / 2;
}
}
@@ -425,14 +270,17 @@ private class ReversiView : Gtk.DrawingArea
init_patterns (cr);
// draw board
- cr.translate (board_x - border_width, board_y - border_width);
+ cr.translate (board_x - theme_manager.border_width, board_y - theme_manager.border_width);
cr.set_source ((!) board_pattern);
- cr.rectangle (0, 0, /* width and height */ board_size, board_size);
+ cr.rectangle (/* x and y */ 0.0,
+ 0.0,
+ /* w and h */ board_size,
+ board_size);
cr.fill ();
// draw tiles (and highlight)
- cr.translate (border_width, border_width);
+ cr.translate (theme_manager.border_width, theme_manager.border_width);
if (humans_opening_intensity != 0)
draw_overture (cr);
@@ -464,7 +312,7 @@ private class ReversiView : Gtk.DrawingArea
// noise pattern
Cairo.Pattern? noise_pattern = null;
- if (apply_texture)
+ if (theme_manager.apply_texture)
{
Gdk.Pixbuf? noise_pixbuf = null;
@@ -482,7 +330,7 @@ private class ReversiView : Gtk.DrawingArea
tile_size);
context = new Cairo.Context (surface);
Gdk.cairo_set_source_pixbuf (context, (!) noise_pixbuf, 0, 0);
- context.paint_with_alpha (texture_alpha);
+ context.paint_with_alpha (theme_manager.texture_alpha);
// or surface = Gdk.cairo_surface_create_from_pixbuf ((!) noise_pixbuf, 0, null); ?
noise_pattern = new Cairo.Pattern.for_surface (surface);
@@ -503,17 +351,20 @@ private class ReversiView : Gtk.DrawingArea
private inline void draw_board_background (Cairo.Context cr)
{
- cr.set_source_rgba (spacing_red, spacing_green, spacing_blue, 1.0);
- cr.rectangle (half_border_width, half_border_width, /* width and height */ board_size -
border_width, board_size - border_width);
+ cr.set_source_rgba (theme_manager.spacing_red, theme_manager.spacing_green,
theme_manager.spacing_blue, 1.0);
+ cr.rectangle (/* x and y */ theme_manager.half_border_width,
+ theme_manager.half_border_width,
+ /* w and h */ board_size - theme_manager.border_width,
+ board_size - theme_manager.border_width);
cr.fill_preserve ();
- cr.set_source_rgba (border_red, border_green, border_blue, 1.0);
- cr.set_line_width (border_width);
+ cr.set_source_rgba (theme_manager.border_red, theme_manager.border_green, theme_manager.border_blue,
1.0);
+ cr.set_line_width (theme_manager.border_width);
cr.stroke ();
}
private inline void draw_tiles_background (Cairo.Context cr, ref Cairo.Pattern? noise_pattern)
{
- cr.translate (border_width, border_width);
+ cr.translate (theme_manager.border_width, theme_manager.border_width);
for (uint8 x = 0; x < game_size; x++)
for (uint8 y = 0; y < game_size; y++)
@@ -521,9 +372,9 @@ private class ReversiView : Gtk.DrawingArea
}
private inline void draw_tile_background (Cairo.Context cr, ref Cairo.Pattern? noise_pattern, int
tile_x, int tile_y)
{
- cr.set_source_rgba (background_red, background_green, background_blue, 1.0);
- rounded_square (cr, tile_x, tile_y, tile_size, 0, background_radius);
- if (apply_texture && noise_pixbuf_loaded)
+ cr.set_source_rgba (theme_manager.background_red, theme_manager.background_green,
theme_manager.background_blue, 1.0);
+ rounded_square (cr, tile_x, tile_y, tile_size, 0, theme_manager.background_radius);
+ if (theme_manager.apply_texture && noise_pixbuf_loaded)
{
cr.fill_preserve ();
@@ -702,7 +553,10 @@ private class ReversiView : Gtk.DrawingArea
/* texture y */ (pixmap / 8) * tile_size - /* y position */ tile_y);
((!) tiles_pattern).set_matrix (matrix);
cr.set_source ((!) tiles_pattern);
- cr.rectangle (tile_x, tile_y, /* width and height */ tile_size, tile_size);
+ cr.rectangle (/* x and y */ tile_x,
+ tile_y,
+ /* w and h */ tile_size,
+ tile_size);
cr.fill ();
}
@@ -732,7 +586,7 @@ private class ReversiView : Gtk.DrawingArea
private inline void draw_overture_indicator (Cairo.Context cr)
{
double diameter_factor = game_size == 4 ? 1.95 : 1.8;
- cr.set_source_rgba (background_red, background_green, background_blue, 1.0);
+ cr.set_source_rgba (theme_manager.background_red, theme_manager.background_green,
theme_manager.background_blue, 1.0);
cr.arc ((double) overture_origin_xs [current_overture_playable] + (double) tile_size / 2.0,
(double) overture_origin_y + (double) tile_size / 2.0,
(double) tile_size / diameter_factor,
@@ -775,7 +629,10 @@ private class ReversiView : Gtk.DrawingArea
/* texture y */ (pixmap / 8) * tile_size - /* y position */ tile_y);
((!) tiles_pattern).set_matrix (matrix);
cr.set_source ((!) tiles_pattern);
- cr.rectangle (tile_x, tile_y, /* width and height */ tile_size, tile_size);
+ cr.rectangle (/* x and y */ tile_x,
+ tile_y,
+ /* w and h */ tile_size,
+ tile_size);
cr.fill ();
}
private void get_x_and_y (uint8 playable_id, out uint8 x, out uint8 y)
@@ -814,7 +671,10 @@ private class ReversiView : Gtk.DrawingArea
{
if (radius_percent <= 0)
{
- cr.rectangle (x + width / 2.0, y + width / 2.0, /* width and height */ size + width, size +
width);
+ cr.rectangle (/* x and y */ x + width / 2.0,
+ y + width / 2.0,
+ /* w and h */ size + width,
+ size + width);
return;
}
@@ -835,10 +695,11 @@ private class ReversiView : Gtk.DrawingArea
}
private void load_image (Cairo.Context c, int width, int height)
+ // requires (theme_manager.pieces_file != "")
{
try
{
- Rsvg.Handle h = new Rsvg.Handle.from_file (pieces_file);
+ Rsvg.Handle h = new Rsvg.Handle.from_file (theme_manager.pieces_file);
Cairo.Matrix m = Cairo.Matrix.identity ();
m.scale ((double) width / h.width, (double) height / h.height);
@@ -854,43 +715,52 @@ private class ReversiView : Gtk.DrawingArea
try
{
- Gdk.Pixbuf p = new Gdk.Pixbuf.from_file_at_scale (pieces_file, width, height, false);
+ Gdk.Pixbuf p = new Gdk.Pixbuf.from_file_at_scale (theme_manager.pieces_file, width, height,
false);
Gdk.cairo_set_source_pixbuf (c, p, 0, 0);
c.paint ();
}
catch (Error e)
{
- warning ("Failed to load theme image %s: %s", pieces_file, e.message);
+ warning ("Failed to load theme image %s: %s", theme_manager.pieces_file, e.message);
}
}
private void highlight_tile (Cairo.Context cr, uint8 x, uint8 y, uint8 intensity, bool soft_highlight)
{
if (soft_highlight)
- cr.set_source_rgba (highlight_soft_red, highlight_soft_green, highlight_soft_blue,
highlight_soft_alpha);
+ cr.set_source_rgba (theme_manager.highlight_soft_red,
+ theme_manager.highlight_soft_green,
+ theme_manager.highlight_soft_blue,
+ theme_manager.highlight_soft_alpha);
else
- cr.set_source_rgba (highlight_hard_red, highlight_hard_green, highlight_hard_blue,
highlight_hard_alpha);
+ cr.set_source_rgba (theme_manager.highlight_hard_red,
+ theme_manager.highlight_hard_green,
+ theme_manager.highlight_hard_blue,
+ theme_manager.highlight_hard_alpha);
rounded_square (cr,
// TODO odd/even sizes problem
tile_xs [x, y] + tile_size * (HIGHLIGHT_MAX - intensity) / (2 * HIGHLIGHT_MAX),
tile_ys [x, y] + tile_size * (HIGHLIGHT_MAX - intensity) / (2 * HIGHLIGHT_MAX),
tile_size * intensity / HIGHLIGHT_MAX,
0,
- background_radius);
+ theme_manager.background_radius);
cr.fill ();
}
private void darken_tile (Cairo.Context cr, uint8 x, uint8 y)
{
- double alpha = highlight_hard_alpha * 1.6 * (double) humans_opening_intensity / (double)
HUMANS_OPENING_INTENSITY_MAX;
- cr.set_source_rgba (highlight_hard_red, highlight_hard_green, highlight_hard_blue, alpha);
+ double alpha = theme_manager.highlight_hard_alpha * 1.6 * (double) humans_opening_intensity /
(double) HUMANS_OPENING_INTENSITY_MAX;
+ cr.set_source_rgba (theme_manager.highlight_hard_red,
+ theme_manager.highlight_hard_green,
+ theme_manager.highlight_hard_blue,
+ alpha);
rounded_square (cr,
// TODO odd/even sizes problem
tile_xs [x, y],
tile_ys [x, y],
tile_size,
0,
- background_radius);
+ theme_manager.background_radius);
cr.fill ();
}
diff --git a/src/theme-manager.vala b/src/theme-manager.vala
new file mode 100644
index 0000000..2b0aaeb
--- /dev/null
+++ b/src/theme-manager.vala
@@ -0,0 +1,187 @@
+/* -*- Mode: vala; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ This file is part of GNOME Reversi, also known as Iagno.
+
+ Copyright 2020 Arnaud Bonatti
+
+ GNOME Reversi 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.
+
+ GNOME Reversi 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 GNOME Reversi. If not, see <https://www.gnu.org/licenses/>.
+*/
+
+private class ThemeManager : Object
+{
+ internal signal void theme_changed ();
+
+ /*\
+ * * theme
+ \*/
+
+ internal void gtk_theme_changed ()
+ {
+ if (theme == null || (!) theme == "default")
+ theme = "default"; // yes
+ }
+
+ private string? _theme = null;
+ [CCode (notify = false)] internal string? theme
+ {
+ get { return _theme; }
+ set {
+ KeyFile key = new KeyFile ();
+ if (value == null || (!) value == "default")
+ set_default_theme (ref key);
+ else
+ try
+ {
+ string key_path = Path.build_filename (DATA_DIRECTORY, "themes", "key");
+ string filepath = Path.build_filename (key_path, (!) value);
+ if (Path.get_dirname (filepath) != key_path)
+ throw new FileError.FAILED ("Theme file is not in the \"key\" directory.");
+
+ key.load_from_file (filepath, GLib.KeyFileFlags.NONE);
+ }
+ catch (Error e)
+ {
+ warning ("Failed to load theme: %s", e.message);
+ set_default_theme (ref key);
+ value = "default";
+ }
+
+ load_theme (key);
+ _theme = value;
+
+ /* redraw all */
+ theme_changed ();
+ }
+ }
+
+ private void set_default_theme (ref KeyFile key)
+ {
+ Gtk.Settings? defaults = Gtk.Settings.get_default ();
+
+ string filename;
+ if (defaults != null && "HighContrast" in ((!) defaults).gtk_theme_name)
+ filename = "high_contrast.theme";
+ else if (defaults != null && (((!) defaults).gtk_application_prefer_dark_theme == true
+ || ((!) defaults).gtk_theme_name == "Adwaita-dark"))
+ filename = "adwaita.theme";
+ else
+ filename = "classic.theme";
+
+ string filepath = Path.build_filename (DATA_DIRECTORY, "themes", "key", filename);
+ try
+ {
+ key.load_from_file (filepath, GLib.KeyFileFlags.NONE);
+ }
+ catch { assert_not_reached (); }
+ }
+
+ /*\
+ * * theme
+ \*/
+
+ [CCode (notify = false)] internal string pieces_file { internal get; private set; default =
""; }
+
+ [CCode (notify = false)] internal double background_red { internal get; private set; default =
0.2; }
+ [CCode (notify = false)] internal double background_green { internal get; private set; default =
0.6; }
+ [CCode (notify = false)] internal double background_blue { internal get; private set; default =
0.4; }
+ [CCode (notify = false)] internal int background_radius { internal get; private set; default =
0; }
+
+ [CCode (notify = false)] internal double texture_alpha { internal get; private set; default =
0.25; }
+ [CCode (notify = false)] internal bool apply_texture { internal get; private set; default =
false; }
+
+ // [CCode (notify = false)] internal double mark_red { internal get; private set; default =
0.2; }
+ // [CCode (notify = false)] internal double mark_green { internal get; private set; default =
0.6; }
+ // [CCode (notify = false)] internal double mark_blue { internal get; private set; default =
0.4; }
+ // [CCode (notify = false)] internal int mark_width { internal get; private set; default =
2; }
+
+ [CCode (notify = false)] internal double border_red { internal get; private set; default =
0.1; }
+ [CCode (notify = false)] internal double border_green { internal get; private set; default =
0.1; }
+ [CCode (notify = false)] internal double border_blue { internal get; private set; default =
0.1; }
+ [CCode (notify = false)] internal int border_width { internal get; private set; default =
3; }
+ [CCode (notify = false)] internal double half_border_width { internal get; private set; default =
1.5; }
+
+ [CCode (notify = false)] internal double spacing_red { internal get; private set; default =
0.1; }
+ [CCode (notify = false)] internal double spacing_green { internal get; private set; default =
0.3; }
+ [CCode (notify = false)] internal double spacing_blue { internal get; private set; default =
0.2; }
+ [CCode (notify = false)] internal int spacing_width { internal get; private set; default =
2; }
+
+ [CCode (notify = false)] internal double highlight_hard_red { internal get; private set; default =
0.1; }
+ [CCode (notify = false)] internal double highlight_hard_green { internal get; private set; default =
0.3; }
+ [CCode (notify = false)] internal double highlight_hard_blue { internal get; private set; default =
0.2; }
+ [CCode (notify = false)] internal double highlight_hard_alpha { internal get; private set; default =
0.4; }
+
+ [CCode (notify = false)] internal double highlight_soft_red { internal get; private set; default =
0.1; }
+ [CCode (notify = false)] internal double highlight_soft_green { internal get; private set; default =
0.3; }
+ [CCode (notify = false)] internal double highlight_soft_blue { internal get; private set; default =
0.2; }
+ [CCode (notify = false)] internal double highlight_soft_alpha { internal get; private set; default =
0.2; }
+
+ // [CCode (notify = false)] internal int margin_width { internal get; private set; default =
0; }
+
+ [CCode (notify = false)] internal string sound_flip { internal get; private set; default =
""; }
+ [CCode (notify = false)] internal string sound_gameover { internal get; private set; default =
""; }
+
+ private inline void load_theme (GLib.KeyFile key)
+ {
+ try
+ {
+ string svg_path = Path.build_filename (DATA_DIRECTORY, "themes", "svg");
+ pieces_file = Path.build_filename (svg_path, key.get_string ("Pieces", "File"));
+ if (Path.get_dirname (pieces_file) != svg_path)
+ pieces_file = Path.build_filename (svg_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");
+ background_radius = key.get_integer ("Background", "Radius");
+
+ texture_alpha = key.get_double ("Background", "TextureAlpha");
+ apply_texture = (texture_alpha > 0.0) && (texture_alpha <= 1.0);
+
+ // mark_red = key.get_double ("Mark", "Red");
+ // mark_green = key.get_double ("Mark", "Green");
+ // mark_blue = key.get_double ("Mark", "Blue");
+ // mark_width = key.get_integer ("Mark", "Width");
+
+ 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");
+ half_border_width = (double) border_width / 2.0;
+
+ 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");
+
+ highlight_hard_red = key.get_double ("Highlight hard", "Red");
+ highlight_hard_green = key.get_double ("Highlight hard", "Green");
+ highlight_hard_blue = key.get_double ("Highlight hard", "Blue");
+ highlight_hard_alpha = key.get_double ("Highlight hard", "Alpha");
+
+ highlight_soft_red = key.get_double ("Highlight soft", "Red");
+ highlight_soft_green = key.get_double ("Highlight soft", "Green");
+ highlight_soft_blue = key.get_double ("Highlight soft", "Blue");
+ highlight_soft_alpha = key.get_double ("Highlight soft", "Alpha");
+
+ // margin_width = key.get_integer ("Margin", "Width");
+
+ sound_flip = key.get_string ("Sound", "Flip");
+ sound_gameover = key.get_string ("Sound", "GameOver");
+ }
+ catch (KeyFileError e) // TODO better
+ {
+ warning ("Errors when loading theme: %s", e.message);
+ }
+ }
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]