[gnome-tetravex/arnaudb/new-theme] Introduce new theme.



commit a1e4376c07916c8ad058f5aafdf09ec885526302
Author: Arnaud Bonatti <arnaud bonatti gmail com>
Date:   Sun Sep 29 03:43:36 2019 +0200

    Introduce new theme.

 data/org.gnome.Tetravex.gschema.xml |   6 +
 src/app-menu.ui                     |  18 ++
 src/gnome-tetravex.vala             |  42 ++--
 src/meson.build                     |  41 ++--
 src/puzzle-view.vala                |  21 +-
 src/theme-new.vala                  | 399 ++++++++++++++++++++++++++++++++++++
 src/{theme.vala => theme-old.vala}  |  28 ++-
 7 files changed, 500 insertions(+), 55 deletions(-)
---
diff --git a/data/org.gnome.Tetravex.gschema.xml b/data/org.gnome.Tetravex.gschema.xml
index b7138af..1d5f0fc 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>'new'</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/src/app-menu.ui b/src/app-menu.ui
index 84f95e4..0e20701 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 New Theme; other possible theme is _Old theme -->
+            <attribute name="label" translatable="yes">_New theme</attribute>
+            <attribute name="action">app.theme</attribute>
+            <attribute name="target">new</attribute>
+          </item>
+          <item>
+            <!-- Translators: entry of the Appearance submenu of the hamburger menu (with a mnemonic that 
appears when pressing Alt); set theme to Old Theme; other possible theme is _New theme -->
+            <attribute name="label" translatable="yes">_Old theme</attribute>
+            <attribute name="action">app.theme</attribute>
+            <attribute name="target">old</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..59eeda7 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-new.vala',
+    'theme-old.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..8c52464 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 != "old") // including "value == new"
+                { theme = new NewTheme (); if (tilesize != 0) theme.configure (tilesize); queue_draw (); 
return; }
+            else
+                { theme = new OldTheme (); 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-new.vala b/src/theme-new.vala
new file mode 100644
index 0000000..1e06490
--- /dev/null
+++ b/src/theme-new.vala
@@ -0,0 +1,399 @@
+/* -*- 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 NewTheme : Theme
+{
+    /*\
+    * * colors arrays
+    \*/
+
+    private Cairo.Pattern tile_colors_h [10];
+    private Cairo.Pattern tile_colors_v [10];
+    private Cairo.Pattern text_colors   [10];
+
+    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] = new Cairo.Pattern.rgb (1, 1, 1);
+        else
+            text_colors [position] = new Cairo.Pattern.rgb (0, 0, 0);
+    }
+
+    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 + hex_value (color [1]) + 0.02) / 255.0;
+        double g0 = (hex_value (color [2]) * 16 + hex_value (color [3]) + 0.02) / 255.0;
+        double b0 = (hex_value (color [4]) * 16 + 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;
+    }
+
+    /*\
+    * * configuring variables
+    \*/
+
+    private uint size = 0;
+
+    /* arrow */
+    private double arrow_half_h;
+    private double neg_arrow_half_h;
+    private uint arrow_depth;
+    private double arrow_dx;
+    private double arrow_dy;
+    private double neg_arrow_dy;
+    private double arrow_w;
+    private double arrow_x;
+    private double arrow_w_minus_depth;
+
+    /* 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;
+
+    internal override void configure (uint new_size)
+    {
+        if (size != 0 && size == new_size)
+            return;
+
+        /* arrow */
+        arrow_half_h = new_size * 0.75;
+        neg_arrow_half_h = -arrow_half_h;
+        arrow_depth = uint.min ((uint) (new_size * 0.025), 2);
+        arrow_dx = 1.4142 * arrow_depth;
+        arrow_dy = arrow_half_h - 6.1623 * arrow_depth;
+        neg_arrow_dy = -arrow_dy;
+        arrow_w = new_size * PuzzleView.gap_factor * 0.5;
+        arrow_x = (new_size * PuzzleView.gap_factor - arrow_w) * 0.5;
+        arrow_w_minus_depth = arrow_w - arrow_depth;
+
+        /* 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;
+
+        /* end */
+        size = new_size;
+    }
+
+    /*\
+    * * drawing arrow
+    \*/
+
+    internal override void draw_arrow (Cairo.Context context)
+    {
+        context.translate (arrow_x, 0.0);
+
+        /* Background */
+        context.move_to (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.fill ();
+
+        /* Arrow highlight */
+        context.move_to (arrow_w, neg_arrow_half_h);
+        context.line_to (arrow_w, arrow_half_h);
+        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.fill ();
+
+        /* Arrow shadow */
+        context.move_to (arrow_w, neg_arrow_half_h);
+        context.line_to (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_w_minus_depth, neg_arrow_dy);
+        context.close_path ();
+        context.set_source_rgba (0, 0, 0, 0.25);
+        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.3, 1.0, 0.6, 0.2);
+        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 (size * 4.0 / 19.0);
+        draw_number (context, text_colors [tile.north], half_tile_size    , size *  4.0 / 18.0, tile.north);
+        draw_number (context, text_colors [tile.south], half_tile_size    , size * 14.0 / 18.0, tile.south);
+        draw_number (context, text_colors [tile.east ], size * 15.0 / 19.0, half_tile_size    , tile.east);
+        draw_number (context, text_colors [tile.west ], size *  4.0 / 19.0, 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 cr, 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;
+
+        cr.move_to (x, y1);
+        cr.arc (x1, y1, radius_arc,  Math.PI, -HALF_PI);
+        cr.arc (x2, y1, radius_arc, -HALF_PI,        0);
+        cr.arc (x2, y2, radius_arc,        0,  HALF_PI);
+        cr.arc (x1, y2, radius_arc,  HALF_PI,  Math.PI);
+        cr.close_path ();
+    }
+}
diff --git a/src/theme.vala b/src/theme-old.vala
similarity index 92%
rename from src/theme.vala
rename to src/theme-old.vala
index 95a8784..5b1019a 100644
--- a/src/theme.vala
+++ b/src/theme-old.vala
@@ -9,7 +9,7 @@
  * license.
  */
 
-private class Theme : Object
+private class OldTheme : Theme
 {
     /*\
     * * colors arrays
@@ -97,7 +97,7 @@ private class Theme : Object
     private double half_tile_size_plus_dy;
     private double size_minus_one;
 
-    internal void configure (uint new_size)
+    internal override void configure (uint new_size)
     {
         if (size != 0 && size == new_size)
             return;
@@ -135,7 +135,7 @@ 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);
 
@@ -172,7 +172,7 @@ 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);
@@ -206,25 +206,21 @@ 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);
+        draw_number (context, text_colors [tile.north], half_tile_size, size     / 5  , tile.north);
+        draw_number (context, text_colors [tile.south], half_tile_size, size * 4 / 5  , tile.south);
+        draw_number (context, text_colors [tile.east ], size * 4 / 5  , half_tile_size, tile.east);
+        draw_number (context, text_colors [tile.west ], size     / 5  , 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)
@@ -342,8 +338,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]