[gnome-tetravex] Introduce new theme.
- From: Arnaud B. <arnaudb src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-tetravex] Introduce new theme.
- Date: Wed, 9 Oct 2019 01:15:09 +0000 (UTC)
commit f5f3e3ddbe0caecbc6998dbc23aa5dc4bf1f2228
Author: Arnaud B <arnaud bonatti gmail com>
Date: Wed Oct 9 01:15:01 2019 +0000
Introduce new theme.
Welcome NeoRetro. The old theme
is kept available as Nostalgia.
Initial work on #3.
data/org.gnome.Tetravex.gschema.xml | 6 +
po/POTFILES.in | 3 +-
po/POTFILES.skip | 3 +-
src/app-menu.ui | 18 ++
src/gnome-tetravex.vala | 42 ++-
src/meson.build | 41 +--
src/puzzle-view.vala | 21 +-
src/theme-neoretro.vala | 441 +++++++++++++++++++++++++++++++
src/{theme.vala => theme-nostalgia.vala} | 179 +++++++------
9 files changed, 630 insertions(+), 124 deletions(-)
---
diff --git a/data/org.gnome.Tetravex.gschema.xml b/data/org.gnome.Tetravex.gschema.xml
index b7138af..6d62baf 100644
--- a/data/org.gnome.Tetravex.gschema.xml
+++ b/data/org.gnome.Tetravex.gschema.xml
@@ -31,6 +31,12 @@
<!-- Translators: description of a settings key, see 'dconf-editor
/org/gnome/Tetravex/mouse-forward-buttons' -->
<description>For users which have a mouse with “Forward” and “Back” buttons, this key will set which
button activates the “Redo” command. Possible values range between 6 and 14.</description>
</key>
+ <key name="theme" type="s">
+ <default>'neoretro'</default>
+ <!-- Translators: summary of a settings key, see 'dconf-editor /org/gnome/Tetravex/theme' -->
+ <summary>Theme</summary>
+ <!-- TODO add description, see Reversi -->
+ </key>
<key name="window-width" type="i">
<default>600</default>
<!-- Translators: summary of a settings key, see 'dconf-editor /org/gnome/Tetravex/window-width' -->
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 634ef6a..21ac813 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -10,4 +10,5 @@ src/help-overlay.ui
src/puzzle.vala
src/puzzle-view.vala
src/score-dialog.vala
-src/theme.vala
+src/theme-neoretro.vala
+src/theme-nostalgia.vala
diff --git a/po/POTFILES.skip b/po/POTFILES.skip
index 61008a4..98bc2e7 100644
--- a/po/POTFILES.skip
+++ b/po/POTFILES.skip
@@ -2,4 +2,5 @@ src/gnome-tetravex.c
src/puzzle.c
src/puzzle-view.c
src/score-dialog.c
-src/theme.c
+src/theme-neoretro.c
+src/theme-nostalgia.c
diff --git a/src/app-menu.ui b/src/app-menu.ui
index 84f95e4..b96b4ef 100644
--- a/src/app-menu.ui
+++ b/src/app-menu.ui
@@ -11,6 +11,24 @@
<attribute name="label" translatable="yes">_Scores</attribute>
<attribute name="action">app.scores</attribute>
</item>
+ <submenu>
+ <!-- Translators: entry of the hamburger menu (with a mnemonic that appears when pressing Alt);
displays allows to change the theme -->
+ <attribute name="label" translatable="yes">A_ppearance</attribute>
+ <section>
+ <item>
+ <!-- Translators: entry of the Appearance submenu of the hamburger menu (with a mnemonic that
appears when pressing Alt); set theme to NeoRetro; other possible theme is _Nostalgia -->
+ <attribute name="label" translatable="yes">Neo_Retro</attribute>
+ <attribute name="action">app.theme</attribute>
+ <attribute name="target">neoretro</attribute>
+ </item>
+ <item>
+ <!-- Translators: entry of the Appearance submenu of the hamburger menu (with a mnemonic that
appears when pressing Alt); set theme to Nostalgia; other possible theme is Neo_Retro -->
+ <attribute name="label" translatable="yes">_Nostalgia</attribute>
+ <attribute name="action">app.theme</attribute>
+ <attribute name="target">nostalgia</attribute>
+ </item>
+ </section>
+ </submenu>
</section>
<section>
<submenu>
diff --git a/src/gnome-tetravex.vala b/src/gnome-tetravex.vala
index fd4176a..1252879 100644
--- a/src/gnome-tetravex.vala
+++ b/src/gnome-tetravex.vala
@@ -60,21 +60,21 @@ private class Tetravex : Gtk.Application
private const GLib.ActionEntry[] action_entries =
{
- { "new-game", new_game_cb },
- { "pause", pause_cb },
- { "solve", solve_cb },
- { "finish", finish_cb },
- { "scores", scores_cb },
- { "quit", quit },
- { "move-up", move_up },
- { "move-down", move_down },
- { "move-left", move_left },
- { "move-right", move_right },
- { "undo", undo_cb },
- { "redo", redo_cb },
- { "size", radio_cb, "s", "'2'", size_changed },
- { "help", help_cb },
- { "about", about_cb }
+ { "new-game", new_game_cb },
+ { "pause", pause_cb },
+ { "solve", solve_cb },
+ { "finish", finish_cb },
+ { "scores", scores_cb },
+ { "quit", quit },
+ { "move-up", move_up },
+ { "move-down", move_down },
+ { "move-left", move_left },
+ { "move-right", move_right },
+ { "undo", undo_cb },
+ { "redo", redo_cb },
+ { "size", null, "s", "'2'", size_changed },
+ { "help", help_cb },
+ { "about", about_cb }
};
private static int main (string[] args)
@@ -102,7 +102,11 @@ private class Tetravex : Gtk.Application
Environment.set_application_name (PROGRAM_NAME);
Window.set_default_icon_name ("org.gnome.Tetravex");
+ settings = new GLib.Settings ("org.gnome.Tetravex");
+
add_action_entries (action_entries, this);
+ add_action (settings.create_action ("theme"));
+
set_accels_for_action ("app.solve", { "<Primary>h" });
set_accels_for_action ("app.scores", { "<Primary>i" });
set_accels_for_action ("app.new-game", { "<Primary>n" });
@@ -119,8 +123,6 @@ private class Tetravex : Gtk.Application
Builder builder = new Builder.from_resource ("/org/gnome/Tetravex/gnome-tetravex.ui");
- settings = new GLib.Settings ("org.gnome.Tetravex");
-
history = new History (Path.build_filename (Environment.get_user_data_dir (), "gnome-tetravex",
"history"));
window = (ApplicationWindow) builder.get_object ("gnome-tetravex-window");
@@ -172,6 +174,7 @@ private class Tetravex : Gtk.Application
view.hexpand = true;
view.vexpand = true;
view.button_release_event.connect (view_button_release_event);
+ settings.bind ("theme", view, "theme-id", SettingsBindFlags.GET | SettingsBindFlags.NO_SENSITIVITY);
grid.attach (view, 0, 0, 3, 1);
settings.bind ("mouse-use-extra-buttons", view,
@@ -624,11 +627,6 @@ private class Tetravex : Gtk.Application
play_pause_stack.set_visible_child_name (puzzle.paused ? "play" : "pause");
}
- private void radio_cb (SimpleAction action, Variant? parameter)
- {
- action.change_state (parameter);
- }
-
private bool on_key_press_event (Widget widget, Gdk.EventKey event)
{
string name = (!) (Gdk.keyval_name (event.keyval) ?? "");
diff --git a/src/meson.build b/src/meson.build
index 5aaf72b..e9cb467 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -2,20 +2,27 @@ resources = gnome.compile_resources ('resources', 'gnome-tetravex.gresource.xml'
source_dir: '.',
c_name: 'resources')
-gnome_tetravex = executable ('gnome-tetravex',
- [ 'config.vapi',
- 'gnome-tetravex.vala',
- 'history.vala',
- 'puzzle.vala',
- 'puzzle-view.vala',
- 'score-dialog.vala',
- 'theme.vala'] + resources,
- dependencies: [ glib_dep,
- gtk_dep,
- libm_dep ],
- vala_args: [ '--pkg=posix',
- '--enable-experimental-non-null' ],
- c_args: [ '-DVERSION="@0@"'.format (meson.project_version ()),
- '-DGETTEXT_PACKAGE="gnome-tetravex"',
- '-DLOCALEDIR="@0@"'.format (localedir) ],
- install: true )
+sources = files (
+ 'config.vapi',
+ 'gnome-tetravex.vala',
+ 'history.vala',
+ 'puzzle.vala',
+ 'puzzle-view.vala',
+ 'score-dialog.vala',
+ 'theme-neoretro.vala',
+ 'theme-nostalgia.vala'
+)
+
+gnome_tetravex = executable (
+ 'gnome-tetravex',
+ sources + resources,
+ dependencies: [ glib_dep,
+ gtk_dep,
+ libm_dep ],
+ vala_args: [ '--pkg=posix',
+ '--enable-experimental-non-null' ],
+ c_args: [ '-DVERSION="@0@"'.format (meson.project_version ()),
+ '-DGETTEXT_PACKAGE="gnome-tetravex"',
+ '-DLOCALEDIR="@0@"'.format (localedir) ],
+ install: true
+ )
diff --git a/src/puzzle-view.vala b/src/puzzle-view.vala
index da187c3..7a52cf2 100644
--- a/src/puzzle-view.vala
+++ b/src/puzzle-view.vala
@@ -9,6 +9,15 @@
* license.
*/
+private abstract class Theme : Object
+{
+ internal abstract void configure (uint size);
+ internal abstract void draw_arrow (Cairo.Context context);
+ internal abstract void draw_socket (Cairo.Context context);
+ internal abstract void draw_paused_tile (Cairo.Context context);
+ internal abstract void draw_tile (Cairo.Context context, Tile tile);
+}
+
private class PuzzleView : Gtk.DrawingArea
{
private class TileImage : Object
@@ -89,7 +98,17 @@ private class PuzzleView : Gtk.DrawingArea
}
/* Theme */
- private Theme theme = new Theme ();
+ private Theme theme;
+ [CCode (notify = true)] public string theme_id
+ {
+ internal set
+ {
+ if (value != "nostalgia") // including "value == neoretro"
+ { theme = new NeoRetroTheme (); if (tilesize != 0) theme.configure (tilesize); queue_draw
(); return; }
+ else
+ { theme = new NostalgiaTheme (); if (tilesize != 0) theme.configure (tilesize); queue_draw
(); return; }
+ }
+ }
/* Tile being controlled by the mouse */
private TileImage? selected_tile = null;
diff --git a/src/theme-neoretro.vala b/src/theme-neoretro.vala
new file mode 100644
index 0000000..069cf22
--- /dev/null
+++ b/src/theme-neoretro.vala
@@ -0,0 +1,441 @@
+/* -*- Mode: vala; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * Copyright (C) 2019 Arnaud Bonatti
+ *
+ * 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. See http://www.gnu.org/copyleft/gpl.html the full text of the
+ * license.
+ */
+
+private class NeoRetroTheme : Theme
+{
+ /*\
+ * * colors arrays
+ \*/
+
+ private Cairo.Pattern tile_colors_h [10];
+ private Cairo.Pattern tile_colors_v [10];
+
+ private unowned Cairo.Pattern text_colors [10];
+ private Cairo.Pattern black_text_color = new Cairo.Pattern.rgb (0.0, 0.0, 0.0);
+ private Cairo.Pattern white_text_color = new Cairo.Pattern.rgb (1.0, 1.0, 1.0);
+
+ private Cairo.Pattern paused_color_h;
+ private Cairo.Pattern paused_color_v;
+
+ construct // white text // L H V
+ { // +45
+ make_color_pattern (0, "000000", true ); // 0 // dark
+ make_color_pattern (1, "850023", true ); // 20 75 10 // red
+ make_color_pattern (2, "e26e1e", false ); // 60 75 55 // orange
+ make_color_pattern (3, "cccc24", false ); // 80 75 100 // yellow
+ make_color_pattern (4, "00c656", false ); // 70 75 145 // light green
+ make_color_pattern (5, "005c59", true ); // 30 75 190 // dark green
+ make_color_pattern (6, "008de0", false ); // 50 75 235 // light blue
+ make_color_pattern (7, "001d87", true ); // 10 75 280 // dark blue
+ make_color_pattern (8, "a021a6", true ); // 40 75 325 // purple
+ make_color_pattern (9, "e2e2e2", false ); // 90 // white
+
+ paused_color_h = make_h_color_pattern ("CCCCCC");
+ paused_color_v = make_v_color_pattern ("CCCCCC");
+ }
+
+ private void make_color_pattern (uint position, string color, bool white_text)
+ {
+ tile_colors_h [position] = make_h_color_pattern (color);
+ tile_colors_v [position] = make_v_color_pattern (color);
+
+ if (white_text)
+ text_colors [position] = white_text_color;
+ else
+ text_colors [position] = black_text_color;
+ }
+
+ private static Cairo.Pattern make_h_color_pattern (string color)
+ {
+ double r0 = (hex_value (color [0]) * 16 + hex_value (color [1])) / 255.0;
+ double g0 = (hex_value (color [2]) * 16 + hex_value (color [3])) / 255.0;
+ double b0 = (hex_value (color [4]) * 16 + hex_value (color [5])) / 255.0;
+
+ double r1 = double.min (r0 + 0.10, 1.0);
+ double g1 = double.min (g0 + 0.10, 1.0);
+ double b1 = double.min (b0 + 0.10, 1.0);
+
+ double r2 = double.min (r0 + 0.25, 1.0);
+ double g2 = double.min (g0 + 0.25, 1.0);
+ double b2 = double.min (b0 + 0.25, 1.0);
+
+ double r5 = double.min (r0 + 0.15, 1.0);
+ double g5 = double.min (g0 + 0.15, 1.0);
+ double b5 = double.min (b0 + 0.15, 1.0);
+
+ Cairo.Pattern pattern = new Cairo.Pattern.linear (0.0, 0.0, 0.0, 1.0);
+ pattern.add_color_stop_rgba (0.00, r2, g2, b2, 1.0);
+ pattern.add_color_stop_rgba (0.08, r1, g1, b1, 1.0);
+ pattern.add_color_stop_rgba (0.50, r5, g5, b5, 1.0);
+ pattern.add_color_stop_rgba (0.92, r1, g1, b1, 1.0);
+ pattern.add_color_stop_rgba (1.00, r0, g0, b0, 1.0);
+
+ return pattern;
+ }
+
+ private static Cairo.Pattern make_v_color_pattern (string color)
+ {
+ double r0 = (hex_value (color [0]) * 16.0 + hex_value (color [1]) + 0.02) / 255.0;
+ double g0 = (hex_value (color [2]) * 16.0 + hex_value (color [3]) + 0.02) / 255.0;
+ double b0 = (hex_value (color [4]) * 16.0 + hex_value (color [5]) + 0.02) / 255.0;
+
+ double r1 = double.min (r0 + 0.10, 1.0);
+ double g1 = double.min (g0 + 0.10, 1.0);
+ double b1 = double.min (b0 + 0.10, 1.0);
+
+ double r2 = double.min (r0 + 0.20, 1.0);
+ double g2 = double.min (g0 + 0.20, 1.0);
+ double b2 = double.min (b0 + 0.20, 1.0);
+
+ double r5 = double.min (r0 + 0.15, 1.0);
+ double g5 = double.min (g0 + 0.15, 1.0);
+ double b5 = double.min (b0 + 0.15, 1.0);
+
+ Cairo.Pattern pattern = new Cairo.Pattern.linear (0.0, 0.0, 1.0, 0.0);
+ pattern.add_color_stop_rgba (0.00, r2, g2, b2, 1.0);
+ pattern.add_color_stop_rgba (0.08, r1, g1, b1, 1.0);
+ pattern.add_color_stop_rgba (0.50, r5, g5, b5, 1.0);
+ pattern.add_color_stop_rgba (0.92, r1, g1, b1, 1.0);
+ pattern.add_color_stop_rgba (1.00, r0, g0, b0, 1.0);
+
+ return pattern;
+ }
+
+ private static double hex_value (char c)
+ {
+ if (c >= '0' && c <= '9')
+ return c - '0';
+ else if (c >= 'a' && c <= 'f')
+ return c - 'a' + 10;
+ else if (c >= 'A' && c <= 'F')
+ return c - 'A' + 10;
+ else
+ return 0.0;
+ }
+
+ /*\
+ * * configuring variables
+ \*/
+
+ private uint size = 0;
+
+ /* arrow */
+ private double arrow_half_h;
+ private double neg_arrow_half_h;
+ private double arrow_w;
+ private double arrow_x;
+
+ private double arrow_clip_x;
+ private double arrow_clip_y;
+ private double arrow_clip_w;
+ private double arrow_clip_h;
+
+ /* socket */
+ private uint socket_margin;
+ private int socket_size;
+ private Cairo.MeshPattern socket_pattern;
+ private Cairo.Matrix matrix; // also used for tile
+
+ /* tile only */
+ private uint tile_margin;
+ private int tile_size;
+ private double half_tile_size;
+
+ /* numbers */
+ private double font_size;
+ private double north_number_y;
+ private double south_number_y;
+ private double east_number_x;
+ private double west_number_x;
+
+ internal override void configure (uint new_size)
+ {
+ if (size != 0 && size == new_size)
+ return;
+
+ /* arrow */
+ arrow_half_h = new_size * 0.5;
+ neg_arrow_half_h = -arrow_half_h;
+ arrow_w = new_size * PuzzleView.gap_factor * 0.5;
+ arrow_x = (new_size * PuzzleView.gap_factor - arrow_w) * 0.5;
+
+ arrow_clip_x = -arrow_x;
+ arrow_clip_y = -new_size;
+ arrow_clip_w = 2.0 * arrow_x + arrow_w;
+ arrow_clip_h = 2.0 * new_size;
+
+ /* socket and tile */
+ matrix = Cairo.Matrix.identity ();
+ matrix.scale (1.0 / new_size, 1.0 / new_size);
+
+ /* socket */
+ socket_margin = uint.min ((uint) (new_size * 0.05), 2);
+ socket_size = (int) new_size - (int) socket_margin * 2;
+
+ socket_pattern = new Cairo.MeshPattern ();
+ socket_pattern.begin_patch ();
+ socket_pattern.move_to (0.0, 0.0);
+ socket_pattern.line_to (1.0, 0.0);
+ socket_pattern.line_to (1.0, 1.0);
+ socket_pattern.line_to (0.0, 1.0);
+ socket_pattern.set_corner_color_rgba (0, 0.3, 0.3, 0.3, 0.3);
+ socket_pattern.set_corner_color_rgba (1, 0.4, 0.4, 0.4, 0.3);
+ socket_pattern.set_corner_color_rgba (2, 0.7, 0.7, 0.7, 0.3);
+ socket_pattern.set_corner_color_rgba (3, 0.6, 0.6, 0.6, 0.3);
+ socket_pattern.end_patch ();
+ socket_pattern.set_matrix (matrix);
+
+ /* tile */
+ tile_margin = uint.min ((uint) (new_size * 0.05), 2) - 1;
+ tile_size = (int) new_size - (int) tile_margin * 2;
+ half_tile_size = new_size * 0.5;
+
+ /* numbers */
+ font_size = new_size * 4.0 / 19.0;
+ north_number_y = new_size * 4.0 / 18.0;
+ south_number_y = new_size * 14.0 / 18.0;
+ east_number_x = new_size * 15.0 / 19.0;
+ west_number_x = new_size * 4.0 / 19.0;
+
+ /* end */
+ size = new_size;
+ }
+
+ /*\
+ * * drawing arrow
+ \*/
+
+ internal override void draw_arrow (Cairo.Context context)
+ {
+ context.translate (arrow_x, 0.0);
+
+ /*\
+ * To ease the drawing, we base the arrow on a simple shape. We clip
+ * the exterior of this shape, by clipping a large rectangle around,
+ * and excluding the shape. Then we stroke the shape, only drawing a
+ * border at its exterior; two times, the first a bit larger, making
+ * a border. Then, we reset the exterior clip, we clip the shape for
+ * real (its interior), and we fill it (two times) with same colors.
+ \*/
+
+ /* clipping exterior */
+
+ context.rectangle (arrow_clip_x, arrow_clip_y, arrow_clip_w, arrow_clip_h);
+
+ context.move_to (arrow_w, arrow_half_h);
+ context.line_to (0.0, 0.0);
+ context.line_to (arrow_w, neg_arrow_half_h);
+ context.curve_to (0.0, 10.0, // Bézier control point for origin
+ 0.0, -10.0, // Bézier control point for destination
+ arrow_w, arrow_half_h); // destination
+
+ context.clip ();
+
+ /* drawing exterior border */
+
+ context.move_to (arrow_w, arrow_half_h);
+ context.line_to (0.0, 0.0);
+ context.line_to (arrow_w, neg_arrow_half_h);
+ context.curve_to (0.0, 10.0, // Bézier control point for origin
+ 0.0, -10.0, // Bézier control point for destination
+ arrow_w, arrow_half_h); // destination
+
+ context.set_line_join (Cairo.LineJoin.ROUND);
+ context.set_line_cap (Cairo.LineCap.ROUND);
+
+ context.set_line_width (14.0);
+ context.set_source_rgba (0.4, 0.4, 0.4, 0.3); // fill color 1, including border
+ context.stroke_preserve ();
+
+ context.set_line_width (12.0);
+ context.set_source_rgba (1.0, 1.0, 1.0, 0.1); // fill color 2
+ context.stroke_preserve ();
+
+ /* filling interior */
+
+ context.reset_clip (); // forget the border clip
+ context.clip (); // clip to the current path
+
+ context.set_source_rgba (0.4, 0.4, 0.4, 0.3); // fill color 1
+ context.fill_preserve ();
+
+ context.set_source_rgba (1.0, 1.0, 1.0, 0.1); // fill color 2
+ context.fill ();
+ }
+
+ /*\
+ * * drawing sockets
+ \*/
+
+ internal override void draw_socket (Cairo.Context context)
+ {
+ context.save ();
+
+ context.set_source (socket_pattern);
+
+ rounded_square (context,
+ /* x and y */ socket_margin, socket_margin,
+ /* size */ socket_size,
+ /* radius */ 8);
+ context.fill_preserve ();
+
+ context.set_line_width (1.0);
+ context.set_source_rgba (0.4, 0.4, 0.4, 0.3);
+ context.stroke ();
+
+ context.restore ();
+ }
+
+ /*\
+ * * drawing tiles
+ \*/
+
+ internal override void draw_paused_tile (Cairo.Context context)
+ {
+ draw_tile_background (context, paused_color_h, paused_color_v, paused_color_h, paused_color_v);
+ }
+
+ internal override void draw_tile (Cairo.Context context, Tile tile)
+ {
+ tile_colors_h [tile.north].set_matrix (matrix);
+ tile_colors_h [tile.east ].set_matrix (matrix);
+ tile_colors_h [tile.south].set_matrix (matrix);
+ tile_colors_h [tile.west ].set_matrix (matrix);
+ tile_colors_v [tile.north].set_matrix (matrix);
+ tile_colors_v [tile.east ].set_matrix (matrix);
+ tile_colors_v [tile.south].set_matrix (matrix);
+ tile_colors_v [tile.west ].set_matrix (matrix);
+
+ draw_tile_background (context, tile_colors_h [tile.north], tile_colors_v [tile.east], tile_colors_h
[tile.south], tile_colors_v [tile.west]);
+
+ context.select_font_face ("Sans", Cairo.FontSlant.NORMAL, Cairo.FontWeight.BOLD);
+ context.set_font_size (font_size);
+ draw_number (context, text_colors [tile.north], half_tile_size, north_number_y, tile.north);
+ draw_number (context, text_colors [tile.south], half_tile_size, south_number_y, tile.south);
+ draw_number (context, text_colors [tile.east ], east_number_x , half_tile_size, tile.east);
+ draw_number (context, text_colors [tile.west ], west_number_x , half_tile_size, tile.west);
+ }
+
+ private void draw_tile_background (Cairo.Context context, Cairo.Pattern north_color, Cairo.Pattern
east_color, Cairo.Pattern south_color, Cairo.Pattern west_color)
+ {
+ context.save ();
+
+ /* Only write in a rounded square */
+ rounded_square (context,
+ /* x and y */ tile_margin, tile_margin,
+ /* size */ tile_size,
+ /* radius */ 8);
+ context.clip_preserve ();
+
+ /* North */
+ context.save ();
+
+ // fill all the clip, part of it will be rewritten after */
+
+ context.set_source (north_color);
+ context.fill ();
+
+ context.restore ();
+
+ /* South */
+ context.save ();
+
+ context.rectangle (0.0, half_tile_size, size, half_tile_size);
+
+ context.set_source (south_color);
+ context.fill ();
+
+ context.restore ();
+
+ /* East */
+ context.save ();
+
+ context.move_to (size, 0.0);
+ context.line_to (size, size);
+ context.line_to (half_tile_size, half_tile_size);
+ context.close_path ();
+
+ context.set_source (east_color);
+ context.fill ();
+
+ context.restore ();
+
+ /* West */
+ context.save ();
+
+ context.move_to (0.0, 0.0);
+ context.line_to (0.0, size);
+ context.line_to (half_tile_size, half_tile_size);
+ context.close_path ();
+
+ context.set_source (west_color);
+ context.fill ();
+
+ context.restore ();
+
+ /* Draw outline and diagonal lines */
+ context.reset_clip ();
+ context.set_line_width (1.5);
+ rounded_square (context,
+ /* x and y */ tile_margin, tile_margin,
+ /* size */ tile_size,
+ /* radius */ 8);
+
+ context.set_source_rgba (0.4, 0.4, 0.4, 0.4);
+ context.stroke_preserve ();
+ context.clip ();
+
+ context.move_to (0.0, 0.0);
+ context.line_to (size, size);
+ context.move_to (0.0, size);
+ context.line_to (size, 0.0);
+ context.stroke ();
+
+ context.restore ();
+ }
+
+ private static void draw_number (Cairo.Context context, Cairo.Pattern text_color, double x, double y,
uint8 number)
+ {
+ context.set_source (text_color);
+
+ string text = "%hu".printf (number);
+ Cairo.TextExtents extents;
+ context.text_extents (text, out extents);
+ context.move_to (x - extents.width / 2.0, y + extents.height / 2.0);
+ context.show_text (text);
+ }
+
+ /*\
+ * * drawing utilities
+ \*/
+
+ private const double HALF_PI = Math.PI_2;
+ private static void rounded_square (Cairo.Context context, double x, double y, int size, double
radius_percent)
+ {
+ if (radius_percent <= 0.0)
+ assert_not_reached (); // could be replaced by drawing a rectangle, but not used here
+
+ if (radius_percent > 50.0)
+ radius_percent = 50.0;
+ double radius_arc = radius_percent * size / 100.0;
+ double x1 = x + radius_arc;
+ double y1 = y + radius_arc;
+ double x2 = x + size - radius_arc;
+ double y2 = y + size - radius_arc;
+
+ context.move_to (x, y1);
+ context.arc (x1, y1, radius_arc, Math.PI, -HALF_PI);
+ context.arc (x2, y1, radius_arc, -HALF_PI, 0.0);
+ context.arc (x2, y2, radius_arc, 0.0, HALF_PI);
+ context.arc (x1, y2, radius_arc, HALF_PI, Math.PI);
+ context.close_path ();
+ }
+}
diff --git a/src/theme.vala b/src/theme-nostalgia.vala
similarity index 65%
rename from src/theme.vala
rename to src/theme-nostalgia.vala
index 95a8784..9a16d39 100644
--- a/src/theme.vala
+++ b/src/theme-nostalgia.vala
@@ -9,7 +9,7 @@
* license.
*/
-private class Theme : Object
+private class NostalgiaTheme : Theme
{
/*\
* * colors arrays
@@ -17,40 +17,43 @@ private class Theme : Object
private Cairo.Pattern tile_colors [10];
private Cairo.Pattern paused_color;
- private Cairo.Pattern text_colors [10];
+
+ private unowned Cairo.Pattern text_colors [10];
+ private Cairo.Pattern black_text_color = new Cairo.Pattern.rgb (0, 0, 0);
+ private Cairo.Pattern white_text_color = new Cairo.Pattern.rgb (1, 1, 1);
construct
{
- tile_colors [0] = make_color_pattern ("#000000");
- tile_colors [1] = make_color_pattern ("#C17D11");
- tile_colors [2] = make_color_pattern ("#CC0000");
- tile_colors [3] = make_color_pattern ("#F57900");
- tile_colors [4] = make_color_pattern ("#EDD400");
- tile_colors [5] = make_color_pattern ("#73D216");
- tile_colors [6] = make_color_pattern ("#3465A4");
- tile_colors [7] = make_color_pattern ("#75507B");
- tile_colors [8] = make_color_pattern ("#BABDB6");
- tile_colors [9] = make_color_pattern ("#FFFFFF");
-
- paused_color = make_color_pattern ("#CCCCCC");
-
- text_colors [0] = new Cairo.Pattern.rgb (1, 1, 1);
- text_colors [1] = new Cairo.Pattern.rgb (1, 1, 1);
- text_colors [2] = new Cairo.Pattern.rgb (1, 1, 1);
- text_colors [3] = new Cairo.Pattern.rgb (1, 1, 1);
- text_colors [4] = new Cairo.Pattern.rgb (0, 0, 0);
- text_colors [5] = new Cairo.Pattern.rgb (0, 0, 0);
- text_colors [6] = new Cairo.Pattern.rgb (1, 1, 1);
- text_colors [7] = new Cairo.Pattern.rgb (1, 1, 1);
- text_colors [8] = new Cairo.Pattern.rgb (0, 0, 0);
- text_colors [9] = new Cairo.Pattern.rgb (0, 0, 0);
+ tile_colors [0] = make_color_pattern ("000000");
+ tile_colors [1] = make_color_pattern ("C17D11");
+ tile_colors [2] = make_color_pattern ("CC0000");
+ tile_colors [3] = make_color_pattern ("F57900");
+ tile_colors [4] = make_color_pattern ("EDD400");
+ tile_colors [5] = make_color_pattern ("73D216");
+ tile_colors [6] = make_color_pattern ("3465A4");
+ tile_colors [7] = make_color_pattern ("75507B");
+ tile_colors [8] = make_color_pattern ("BABDB6");
+ tile_colors [9] = make_color_pattern ("FFFFFF");
+
+ paused_color = make_color_pattern ("CCCCCC");
+
+ text_colors [0] = white_text_color;
+ text_colors [1] = white_text_color;
+ text_colors [2] = white_text_color;
+ text_colors [3] = white_text_color;
+ text_colors [4] = black_text_color;
+ text_colors [5] = black_text_color;
+ text_colors [6] = white_text_color;
+ text_colors [7] = white_text_color;
+ text_colors [8] = black_text_color;
+ text_colors [9] = black_text_color;
}
private static Cairo.Pattern make_color_pattern (string color)
{
- double r = (hex_value (color [1]) * 16 + hex_value (color [2])) / 255.0;
- double g = (hex_value (color [3]) * 16 + hex_value (color [4])) / 255.0;
- double b = (hex_value (color [5]) * 16 + hex_value (color [6])) / 255.0;
+ double r = (hex_value (color [0]) * 16.0 + hex_value (color [1])) / 255.0;
+ double g = (hex_value (color [2]) * 16.0 + hex_value (color [3])) / 255.0;
+ double b = (hex_value (color [4]) * 16.0 + hex_value (color [5])) / 255.0;
return new Cairo.Pattern.rgb (r, g, b);
}
@@ -63,7 +66,7 @@ private class Theme : Object
else if (c >= 'A' && c <= 'F')
return c - 'A' + 10;
else
- return 0;
+ return 0.0;
}
/*\
@@ -97,7 +100,14 @@ private class Theme : Object
private double half_tile_size_plus_dy;
private double size_minus_one;
- internal void configure (uint new_size)
+ /* numbers */
+ private double font_size;
+ private double north_number_y;
+ private double south_number_y;
+ private double east_number_x;
+ private double west_number_x;
+
+ internal override void configure (uint new_size)
{
if (size != 0 && size == new_size)
return;
@@ -127,6 +137,13 @@ private class Theme : Object
half_tile_size_plus_dy = half_tile_size + tile_dy;
size_minus_one = (double) (new_size - 1);
+ /* numbers */
+ font_size = new_size / 3.5;
+ north_number_y = new_size / 5.0;
+ south_number_y = new_size * 4.0 / 5.0;
+ east_number_x = south_number_y;
+ west_number_x = north_number_y;
+
/* end */
size = new_size;
}
@@ -135,16 +152,16 @@ private class Theme : Object
* * drawing arrow
\*/
- internal void draw_arrow (Cairo.Context context)
+ internal override void draw_arrow (Cairo.Context context)
{
context.translate (arrow_x, 0.0);
/* Background */
- context.move_to (0, 0);
+ context.move_to (0.0, 0.0);
context.line_to (arrow_w, arrow_half_h);
context.line_to (arrow_w, neg_arrow_half_h);
context.close_path ();
- context.set_source_rgba (0, 0, 0, 0.125);
+ context.set_source_rgba (0.0, 0.0, 0.0, 0.125);
context.fill ();
/* Arrow highlight */
@@ -153,18 +170,18 @@ private class Theme : Object
context.line_to (arrow_w_minus_depth, arrow_dy);
context.line_to (arrow_w_minus_depth, neg_arrow_dy);
context.close_path ();
- context.set_source_rgba (1, 1, 1, 0.125);
+ context.set_source_rgba (1.0, 1.0, 1.0, 0.125);
context.fill ();
/* Arrow shadow */
context.move_to (arrow_w, neg_arrow_half_h);
- context.line_to (0, 0);
+ context.line_to (0.0, 0.0);
context.line_to (arrow_w, arrow_half_h);
context.line_to (arrow_w_minus_depth, arrow_dy);
- context.line_to (arrow_dx, 0);
+ context.line_to (arrow_dx, 0.0);
context.line_to (arrow_w_minus_depth, neg_arrow_dy);
context.close_path ();
- context.set_source_rgba (0, 0, 0, 0.25);
+ context.set_source_rgba (0.0, 0.0, 0.0, 0.25);
context.fill ();
}
@@ -172,33 +189,33 @@ private class Theme : Object
* * drawing sockets
\*/
- internal void draw_socket (Cairo.Context context)
+ internal override void draw_socket (Cairo.Context context)
{
/* Background */
context.rectangle (tile_depth, tile_depth, size_minus_two_tile_depths, size_minus_two_tile_depths);
- context.set_source_rgba (0, 0, 0, 0.125);
+ context.set_source_rgba (0.0, 0.0, 0.0, 0.125);
context.fill ();
/* Shadow */
- context.move_to (size, 0);
- context.line_to (0, 0);
- context.line_to (0, size);
+ context.move_to (size, 0.0);
+ context.line_to (0.0, 0.0);
+ context.line_to (0.0, size);
context.line_to (tile_depth, size_minus_tile_depth);
context.line_to (tile_depth, tile_depth);
context.line_to (size_minus_tile_depth, tile_depth);
context.close_path ();
- context.set_source_rgba (0, 0, 0, 0.25);
+ context.set_source_rgba (0.0, 0.0, 0.0, 0.25);
context.fill ();
/* Highlight */
- context.move_to (0, size);
+ context.move_to (0.0, size);
context.line_to (size, size);
- context.line_to (size, 0);
+ context.line_to (size, 0.0);
context.line_to (size_minus_tile_depth, tile_depth);
context.line_to (size_minus_tile_depth, size_minus_tile_depth);
context.line_to (tile_depth, size_minus_tile_depth);
context.close_path ();
- context.set_source_rgba (1, 1, 1, 0.125);
+ context.set_source_rgba (1.0, 1.0, 1.0, 0.125);
context.fill ();
}
@@ -206,81 +223,77 @@ private class Theme : Object
* * drawing tiles
\*/
- internal void draw_paused_tile (Cairo.Context context)
+ internal override void draw_paused_tile (Cairo.Context context)
{
draw_tile_background (context, paused_color, paused_color, paused_color, paused_color);
}
- internal void draw_tile (Cairo.Context context, Tile tile)
+ internal override void draw_tile (Cairo.Context context, Tile tile)
{
draw_tile_background (context, tile_colors [tile.north], tile_colors [tile.east], tile_colors
[tile.south], tile_colors [tile.west]);
context.select_font_face ("Sans", Cairo.FontSlant.NORMAL, Cairo.FontWeight.BOLD);
- context.set_font_size (size / 3.5);
- context.set_source (text_colors [tile.north]);
- draw_number (context, half_tile_size, size / 5, tile.north);
- context.set_source (text_colors [tile.south]);
- draw_number (context, half_tile_size, size * 4 / 5, tile.south);
- context.set_source (text_colors [tile.east]);
- draw_number (context, size * 4 / 5, half_tile_size, tile.east);
- context.set_source (text_colors [tile.west]);
- draw_number (context, size / 5, half_tile_size, tile.west);
+ context.set_font_size (font_size);
+ draw_number (context, text_colors [tile.north], half_tile_size, north_number_y, tile.north);
+ draw_number (context, text_colors [tile.south], half_tile_size, south_number_y, tile.south);
+ draw_number (context, text_colors [tile.east ], east_number_x , half_tile_size, tile.east);
+ draw_number (context, text_colors [tile.west ], west_number_x , half_tile_size, tile.west);
}
private void draw_tile_background (Cairo.Context context, Cairo.Pattern north_color, Cairo.Pattern
east_color, Cairo.Pattern south_color, Cairo.Pattern west_color)
{
/* North */
- context.rectangle (0, 0, size, half_tile_size);
+ context.rectangle (0.0, 0.0, size, half_tile_size);
context.set_source (north_color);
context.fill ();
/* North highlight */
- context.move_to (0, 0);
- context.line_to (size, 0);
+ context.move_to (0.0, 0.0);
+ context.line_to (size, 0.0);
context.line_to (size_minus_tile_dx, tile_depth);
context.line_to (tile_dx, tile_depth);
context.line_to (half_tile_size, half_tile_size_minus_dy);
context.line_to (half_tile_size, half_tile_size);
context.close_path ();
- context.set_source_rgba (1, 1, 1, 0.125);
+ context.set_source_rgba (1.0, 1.0, 1.0, 0.125);
context.fill ();
/* North shadow */
- context.move_to (size, 0);
+ context.move_to (size, 0.0);
context.line_to (half_tile_size, half_tile_size);
context.line_to (half_tile_size, half_tile_size_minus_dy);
context.line_to (size_minus_tile_dx, tile_depth);
context.close_path ();
- context.set_source_rgba (0, 0, 0, 0.25);
+ context.set_source_rgba (0.0, 0.0, 0.0, 0.25);
context.fill ();
/* South */
- context.rectangle (0, half_tile_size, size, half_tile_size);
+ context.rectangle (0.0, half_tile_size, size, half_tile_size);
context.set_source (south_color);
context.fill ();
/* South highlight */
- context.move_to (0, size);
+ context.move_to (0.0, size);
context.line_to (tile_dx, size_minus_tile_depth);
context.line_to (half_tile_size, half_tile_size_plus_dy);
context.line_to (half_tile_size, half_tile_size);
context.close_path ();
- context.set_source_rgba (1, 1, 1, 0.125);
+ context.set_source_rgba (1.0, 1.0, 1.0, 0.125);
context.fill ();
/* South shadow */
- context.move_to (0, size);
+ context.move_to (0.0, size);
context.line_to (size, size);
context.line_to (half_tile_size, half_tile_size);
context.line_to (half_tile_size, half_tile_size_plus_dy);
context.line_to (size_minus_tile_dx, size_minus_tile_depth);
context.line_to (tile_dx, size_minus_tile_depth);
context.close_path ();
- context.set_source_rgba (0, 0, 0, 0.25);
+ context.set_source_rgba (0.0, 0.0, 0.0, 0.25);
context.fill ();
/* East */
- context.move_to (size, 0);
+ context.move_to (size, 0.0);
context.line_to (size, size);
context.line_to (half_tile_size, half_tile_size);
context.close_path ();
@@ -288,51 +301,51 @@ private class Theme : Object
context.fill ();
/* East highlight */
- context.move_to (size, 0);
+ context.move_to (size, 0.0);
context.line_to (half_tile_size, half_tile_size);
context.line_to (size, size);
context.line_to (size_minus_tile_depth, size_minus_tile_dx);
context.line_to (half_tile_size_plus_dy, half_tile_size);
context.line_to (size_minus_tile_depth, tile_dx);
context.close_path ();
- context.set_source_rgba (1, 1, 1, 0.125);
+ context.set_source_rgba (1.0, 1.0, 1.0, 0.125);
context.fill ();
/* East shadow */
- context.move_to (size, 0);
+ context.move_to (size, 0.0);
context.line_to (size, size);
context.line_to (size_minus_tile_depth, size_minus_tile_dx);
context.line_to (size_minus_tile_depth, tile_dx);
context.close_path ();
- context.set_source_rgba (0, 0, 0, 0.25);
+ context.set_source_rgba (0.0, 0.0, 0.0, 0.25);
context.fill ();
/* West */
- context.move_to (0, 0);
- context.line_to (0, size);
+ context.move_to (0.0, 0.0);
+ context.line_to (0.0, size);
context.line_to (half_tile_size, half_tile_size);
context.close_path ();
context.set_source (west_color);
context.fill ();
/* West highlight */
- context.move_to (0, 0);
- context.line_to (0, size);
+ context.move_to (0.0, 0.0);
+ context.line_to (0.0, size);
context.line_to (tile_depth, size_minus_tile_dx);
context.line_to (tile_depth, tile_dx);
context.close_path ();
- context.set_source_rgba (1, 1, 1, 0.125);
+ context.set_source_rgba (1.0, 1.0, 1.0, 0.125);
context.fill ();
/* West shadow */
- context.move_to (0, 0);
+ context.move_to (0.0, 0.0);
context.line_to (half_tile_size, half_tile_size);
- context.line_to (0, size);
+ context.line_to (0.0, size);
context.line_to (tile_depth, size_minus_tile_dx);
context.line_to (half_tile_size_minus_dy, half_tile_size);
context.line_to (tile_depth, tile_dx);
context.close_path ();
- context.set_source_rgba (0, 0, 0, 0.25);
+ context.set_source_rgba (0.0, 0.0, 0.0, 0.25);
context.fill ();
/* Draw outline */
@@ -342,8 +355,10 @@ private class Theme : Object
context.stroke ();
}
- private void draw_number (Cairo.Context context, double x, double y, uint8 number)
+ private static void draw_number (Cairo.Context context, Cairo.Pattern text_color, double x, double y,
uint8 number)
{
+ context.set_source (text_color);
+
string text = "%hu".printf (number);
Cairo.TextExtents extents;
context.text_extents (text, out extents);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]