[gnome-tetravex/arnaudb/new-theme-2] Introduce new default theme.
- From: Arnaud B. <arnaudb src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-tetravex/arnaudb/new-theme-2] Introduce new default theme.
- Date: Wed, 9 Oct 2019 19:48:04 +0000 (UTC)
commit 93b2550ac58ebfc6e79067277536275a69e4b8c7
Author: Arnaud Bonatti <arnaud bonatti gmail com>
Date: Wed Oct 9 04:32:09 2019 +0200
Introduce new default theme.
data/org.gnome.Tetravex.gschema.xml | 2 +-
po/POTFILES.in | 1 +
po/POTFILES.skip | 1 +
src/app-menu.ui | 10 +-
src/meson.build | 1 +
src/puzzle-view.vala | 27 ++-
src/theme-adwaita.vala | 429 ++++++++++++++++++++++++++++++++++++
7 files changed, 459 insertions(+), 12 deletions(-)
---
diff --git a/data/org.gnome.Tetravex.gschema.xml b/data/org.gnome.Tetravex.gschema.xml
index 6d62baf..775f418 100644
--- a/data/org.gnome.Tetravex.gschema.xml
+++ b/data/org.gnome.Tetravex.gschema.xml
@@ -32,7 +32,7 @@
<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>
+ <default>'adwaita'</default>
<!-- Translators: summary of a settings key, see 'dconf-editor /org/gnome/Tetravex/theme' -->
<summary>Theme</summary>
<!-- TODO add description, see Reversi -->
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 21ac813..91fbd5c 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -10,5 +10,6 @@ src/help-overlay.ui
src/puzzle.vala
src/puzzle-view.vala
src/score-dialog.vala
+src/theme-adwaita.vala
src/theme-neoretro.vala
src/theme-nostalgia.vala
diff --git a/po/POTFILES.skip b/po/POTFILES.skip
index 98bc2e7..8cd780c 100644
--- a/po/POTFILES.skip
+++ b/po/POTFILES.skip
@@ -2,5 +2,6 @@ src/gnome-tetravex.c
src/puzzle.c
src/puzzle-view.c
src/score-dialog.c
+src/theme-adwaita.c
src/theme-neoretro.c
src/theme-nostalgia.c
diff --git a/src/app-menu.ui b/src/app-menu.ui
index b96b4ef..67d3b83 100644
--- a/src/app-menu.ui
+++ b/src/app-menu.ui
@@ -16,13 +16,19 @@
<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 -->
+ <!-- Translators: entry of the Appearance submenu of the hamburger menu (with a mnemonic that
appears when pressing Alt); set theme to Adwaita; other possible themes are Neo_Retro and _Nostalgia -->
+ <attribute name="label" translatable="yes">_Adwaita</attribute>
+ <attribute name="action">app.theme</attribute>
+ <attribute name="target">adwaita</attribute>
+ </item>
+ <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 themes are _Adwaita and _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 -->
+ <!-- Translators: entry of the Appearance submenu of the hamburger menu (with a mnemonic that
appears when pressing Alt); set theme to Nostalgia; other possible themes are _Adwaita and Neo_Retro -->
<attribute name="label" translatable="yes">_Nostalgia</attribute>
<attribute name="action">app.theme</attribute>
<attribute name="target">nostalgia</attribute>
diff --git a/src/meson.build b/src/meson.build
index e9cb467..771a616 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -9,6 +9,7 @@ sources = files (
'puzzle.vala',
'puzzle-view.vala',
'score-dialog.vala',
+ 'theme-adwaita.vala',
'theme-neoretro.vala',
'theme-nostalgia.vala'
)
diff --git a/src/puzzle-view.vala b/src/puzzle-view.vala
index 3fca585..6cae849 100644
--- a/src/puzzle-view.vala
+++ b/src/puzzle-view.vala
@@ -11,6 +11,12 @@
private abstract class Theme : Object
{
+ // FIXME it is of the responsability of the themes to ensure the overdraw does NOT draw over an neighbor
tile; else bad things happen
+ internal int overdraw_top { internal get; protected set; default = 0; }
+ internal int overdraw_left { internal get; protected set; default = 0; }
+ internal int overdraw_right { internal get; protected set; default = 0; }
+ internal int overdraw_bottom { internal get; protected set; default = 0; }
+
internal abstract void configure (uint size);
internal abstract void draw_arrow (Cairo.Context context);
internal abstract void draw_socket (Cairo.Context context);
@@ -112,10 +118,13 @@ private class PuzzleView : Gtk.DrawingArea
{
internal set
{
- if (value != "nostalgia") // including "value == neoretro"
- theme = new NeoRetroTheme ();
- else
- theme = new NostalgiaTheme ();
+ switch (value)
+ {
+ default:
+ case "adwaita" : theme = new AdwaitaTheme (); break;
+ case "neoretro" : theme = new NeoRetroTheme (); break;
+ case "nostalgia" : theme = new NostalgiaTheme (); break;
+ }
if (tilesize != 0)
theme.configure (tilesize);
@@ -177,10 +186,10 @@ private class PuzzleView : Gtk.DrawingArea
private void redraw_tile (TileImage image)
{
- queue_draw_area ((int) (image.x + 0.5),
- (int) (image.y + 0.5),
- (int) tilesize,
- (int) tilesize);
+ queue_draw_area ((int) image.x - theme.overdraw_left,
+ (int) image.y - theme.overdraw_top,
+ (int) tilesize + theme.overdraw_left + theme.overdraw_right,
+ (int) tilesize + theme.overdraw_top + theme.overdraw_bottom);
}
private void move_tile_to_location (TileImage image, uint x, uint y, double duration = 0)
@@ -453,7 +462,7 @@ private class PuzzleView : Gtk.DrawingArea
private inline void draw_image (Cairo.Context context, TileImage image)
{
context.save ();
- context.translate ((int) (image.x + 0.5), (int) (image.y + 0.5));
+ context.translate ((int) image.x, (int) image.y);
if (puzzle.paused)
theme.draw_paused_tile (context);
else
diff --git a/src/theme-adwaita.vala b/src/theme-adwaita.vala
new file mode 100644
index 0000000..6af8796
--- /dev/null
+++ b/src/theme-adwaita.vala
@@ -0,0 +1,429 @@
+/* -*- Mode: vala; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * Copyright (C) 2019 Arnaud Bonatti, with guidance from Jakub Steiner
+ *
+ * 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 AdwaitaTheme : Theme
+{
+ /*\
+ * * colors arrays
+ \*/
+
+ private Cairo.Pattern tile_colors_h [10];
+ private Cairo.Pattern tile_colors_v [10];
+ private Cairo.Pattern tile_shadows [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
+ { // based on GNOME color palette // white text
+ make_color_pattern (0, "3d3846", true ); // black // Dark 3
+ make_color_pattern (1, "C01C28", true ); // red // Red 4
+ make_color_pattern (2, "FFA348", false ); // orange // Orange 2
+ make_color_pattern (3, "f6d32d", false ); // yellow // Yellow 3
+ make_color_pattern (4, "57E389", false ); // green // Green 2
+ make_color_pattern (5, "B5835A", true ); // brown // Brown 2
+ make_color_pattern (6, "99c1f1", false ); // light blue // Blue 1
+ make_color_pattern (7, "1a5fb4", true ); // dark blue // Blue 5
+ make_color_pattern (8, "c061cb", true ); // purple // Purple 2
+ make_color_pattern (9, "f6f5f4", false ); // white // Light 2
+
+ paused_color_h = make_dir_color_pattern ("CCCCCC", /* vertical */ false);
+ paused_color_v = make_dir_color_pattern ("CCCCCC", /* vertical */ true);
+ }
+
+ private void make_color_pattern (uint position, string color, bool white_text)
+ {
+ tile_colors_h [position] = make_dir_color_pattern (color, /* vertical */ false);
+ tile_colors_v [position] = make_dir_color_pattern (color, /* vertical */ true);
+
+ tile_shadows [position] = make_shadow_color_pattern (color);
+
+ if (white_text)
+ text_colors [position] = white_text_color;
+ else
+ text_colors [position] = black_text_color;
+ }
+
+ private static Cairo.Pattern make_dir_color_pattern (string color, bool vertical)
+ {
+ 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.01, 1.0);
+ double g1 = double.min (g0 + 0.01, 1.0);
+ double b1 = double.min (b0 + 0.01, 1.0);
+
+ Cairo.Pattern pattern;
+ if (vertical)
+ pattern = new Cairo.Pattern.linear (0.0, 0.0, 1.0, 0.0);
+ else
+ pattern = new Cairo.Pattern.linear (0.0, 0.0, 0.0, 1.0);
+ pattern.add_color_stop_rgba (0.00, r0, g0, b0, 1.0);
+ pattern.add_color_stop_rgba (0.50, r1, g1, b1, 1.0);
+ pattern.add_color_stop_rgba (1.00, r0, g0, b0, 1.0);
+
+ return pattern;
+ }
+
+ private static Cairo.Pattern make_shadow_color_pattern (string color)
+ {
+ double r = double.max ((hex_value (color [0]) * 16 + hex_value (color [1]) - 40.0) / 255.0, 0.0);
+ double g = double.max ((hex_value (color [2]) * 16 + hex_value (color [3]) - 40.0) / 255.0, 0.0);
+ double b = double.max ((hex_value (color [4]) * 16 + hex_value (color [5]) - 40.0) / 255.0, 0.0);
+
+ return new Cairo.Pattern.rgb (r, g, b);
+ }
+
+ 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;
+
+ /* tile only */
+ private const uint radius_percent = 8;
+ private Cairo.Matrix matrix;
+ private uint tile_margin;
+ private int tile_size;
+ private double half_tile_size;
+ private double extrusion;
+
+ private double lateral_shadow_width;
+ private double west_shadow_limit;
+
+ /* numbers */
+ private double font_size;
+ private double half_tile_size_extruded;
+ private double north_number_y_extruded;
+ private double south_number_y_extruded;
+ 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_w = new_size * PuzzleView.gap_factor / 3.0;
+ arrow_x = (new_size * PuzzleView.gap_factor - arrow_w) * 0.5;
+ arrow_half_h = arrow_w;
+ neg_arrow_half_h = -arrow_half_h;
+
+ 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;
+
+ /* tile */
+ matrix = Cairo.Matrix.identity ();
+ matrix.scale (1.0 / new_size, 1.0 / new_size);
+ tile_margin = uint.max ((uint) (new_size * 0.03), 2);
+ tile_size = (int) new_size - (int) tile_margin * 2;
+ half_tile_size = new_size * 0.5;
+ overdraw_top = (int) (1.5 * tile_margin);
+ extrusion = -overdraw_top;
+
+ lateral_shadow_width = tile_margin + tile_size * Math.SQRT2 / /* 2 * radius_percent / (2 * 100)
*/50.0;
+ west_shadow_limit = new_size - lateral_shadow_width;
+
+ /* numbers */
+ font_size = new_size * 4.0 / 19.0;
+ half_tile_size_extruded = half_tile_size + extrusion;
+ north_number_y_extruded = new_size * 4.0 / 18.0 + extrusion;
+ south_number_y_extruded = new_size * 14.0 / 18.0 + extrusion;
+ 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);
+
+ 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.5, 0.5, 0.5, 0.4);
+ context.fill ();
+ }
+
+ /*\
+ * * drawing sockets
+ \*/
+
+ internal override void draw_socket (Cairo.Context context)
+ {
+ context.save ();
+
+ context.set_source_rgba (0.5, 0.5, 0.5, 0.3);
+ rounded_square (context,
+ /* x and y */ tile_margin, tile_margin,
+ /* size */ tile_size,
+ /* radius */ radius_percent);
+ context.fill ();
+
+ context.restore ();
+ }
+
+ /*\
+ * * drawing tiles
+ \*/
+
+ internal override void draw_paused_tile (Cairo.Context context)
+ {
+ draw_tile_shadow (context, paused_color_h, paused_color_v, paused_color_h, paused_color_v);
+ 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_shadow (context, tile_shadows [tile.north], tile_shadows [tile.east], tile_shadows
[tile.south], tile_shadows [tile.west]);
+ 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_extruded, tile.north);
+ draw_number (context, text_colors [tile.south], half_tile_size, south_number_y_extruded, tile.south);
+ draw_number (context, text_colors [tile.east ], east_number_x , half_tile_size_extruded, tile.east);
+ draw_number (context, text_colors [tile.west ], west_number_x , half_tile_size_extruded, tile.west);
+ }
+
+ private void draw_tile_shadow (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 */ radius_percent);
+ context.clip_preserve ();
+
+ /* 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.rectangle (/* x and y */ west_shadow_limit, 0.0, /* width and height */
lateral_shadow_width, size);
+
+ context.set_source (east_color);
+ context.fill ();
+
+ context.restore ();
+
+ /* West */
+ context.save ();
+
+ context.rectangle (/* x and y */ 0.0, 0.0, /* width and height */ lateral_shadow_width, size);
+
+ context.set_source (west_color);
+ context.fill ();
+
+ context.restore ();
+
+ /* Draw color separation */
+ context.reset_clip ();
+ rounded_square (context,
+ /* x and y */ tile_margin, tile_margin,
+ /* size */ tile_size,
+ /* radius */ radius_percent);
+
+ context.set_source_rgba (0.0, 0.0, 0.0, 0.2);
+ context.set_line_width (0.75);
+ context.stroke_preserve ();
+ context.clip ();
+
+ context.move_to (lateral_shadow_width, 0.0);
+ context.line_to (lateral_shadow_width, size);
+ context.move_to (west_shadow_limit, 0.0);
+ context.line_to (west_shadow_limit, size);
+ context.set_source_rgba (0.4, 0.4, 0.4, 0.4);
+ context.set_line_width (1.5);
+ context.stroke ();
+
+ context.restore ();
+ }
+
+ 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 ();
+
+ context.translate (0.0, extrusion);
+
+ /* Only write in a rounded square */
+ rounded_square (context,
+ /* x and y */ tile_margin, tile_margin,
+ /* size */ tile_size,
+ /* radius */ radius_percent);
+ 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 ();
+ rounded_square (context,
+ /* x and y */ tile_margin, tile_margin,
+ /* size */ tile_size,
+ /* radius */ radius_percent);
+
+ context.set_source_rgba (0.0, 0.0, 0.0, 0.2);
+ context.set_line_width (0.75);
+ 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.set_source_rgba (0.4, 0.4, 0.4, 0.4);
+ context.set_line_width (1.5);
+ 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 ();
+ }
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]