[gnome-tetravex] Allow playing with keyboard.
- From: Arnaud B. <arnaudb src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-tetravex] Allow playing with keyboard.
- Date: Tue, 15 Oct 2019 15:32:43 +0000 (UTC)
commit a44cbaebb69ad38dac102067f62e37566e0d6661
Author: Arnaud Bonatti <arnaud bonatti gmail com>
Date: Sun Oct 13 04:46:40 2019 +0200
Allow playing with keyboard.
Fixes #9.
src/gnome-tetravex.vala | 9 +-
src/help-overlay.ui | 47 ++++++++
src/puzzle-view.vala | 267 ++++++++++++++++++++++++++++++++++++++++++++-
src/theme-extrusion.vala | 66 ++++++++---
src/theme-neoretro.vala | 115 ++++++++++---------
src/theme-nostalgia.vala | 36 +++++-
src/theme-synesthesia.vala | 36 +++++-
7 files changed, 500 insertions(+), 76 deletions(-)
---
diff --git a/src/gnome-tetravex.vala b/src/gnome-tetravex.vala
index 03819ef..a4959a4 100644
--- a/src/gnome-tetravex.vala
+++ b/src/gnome-tetravex.vala
@@ -214,16 +214,19 @@ private class Tetravex : Gtk.Application
MenuModel appmenu = (MenuModel) menu_builder.get_object ("app-menu");
hamburger_button = new MenuButton ();
hamburger_button.set_image (new Image.from_icon_name ("open-menu-symbolic", IconSize.BUTTON));
+ ((Widget) hamburger_button).set_focus_on_click (false);
hamburger_button.show ();
hamburger_button.set_menu_model (appmenu);
headerbar.pack_end (hamburger_button);
Button undo_button = new Button.from_icon_name ("edit-undo-symbolic");
undo_button.set_action_name ("app.undo");
+ ((Widget) undo_button).set_focus_on_click (false);
undo_button.show ();
Button redo_button = new Button.from_icon_name ("edit-redo-symbolic");
redo_button.set_action_name ("app.redo");
+ ((Widget) redo_button).set_focus_on_click (false);
redo_button.show ();
Box undo_redo_box = new Box (Orientation.HORIZONTAL, /* spacing */ 0);
@@ -238,6 +241,7 @@ private class Tetravex : Gtk.Application
view = new PuzzleView ();
view.hexpand = true;
view.vexpand = true;
+ view.can_focus = true;
view.button_release_event.connect (view_button_release_event);
settings.bind ("theme", view, "theme-id", SettingsBindFlags.GET | SettingsBindFlags.NO_SENSITIVITY);
@@ -367,7 +371,8 @@ private class Tetravex : Gtk.Application
valign: Align.CENTER,
margin_start: 35,
margin_end: 35,
- image: _image);
+ image: _image,
+ focus_on_click: false);
sizegroup.add_widget (this);
}
@@ -439,6 +444,8 @@ private class Tetravex : Gtk.Application
puzzle.paused = true;
start_paused = false;
}
+ else
+ view.grab_focus ();
update_bottom_button_states ();
}
diff --git a/src/help-overlay.ui b/src/help-overlay.ui
index ed6036c..4d18b99 100644
--- a/src/help-overlay.ui
+++ b/src/help-overlay.ui
@@ -64,6 +64,29 @@
</child>
</object>
</child>
+ <child>
+ <object class="GtkShortcutsGroup">
+ <property name="visible">True</property>
+ <!-- Translators: title of a section in the Keyboard Shortcuts dialog; contains "Select where to
play" and "Play on selected tile" -->
+ <property name="title" translatable="yes" context="shortcut window">Play with keyboard</property>
+ <child>
+ <object class="GtkShortcutsShortcut">
+ <property name="visible">True</property>
+ <!-- Translators: Left/Right/Up/Down arrows actions description in the Keyboard Shortcuts
dialog, moves highlight -->
+ <property name="title" translatable="yes" context="shortcut window">Move keyboard
highlight</property>
+ <property name="accelerator">Left Right Up Down</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkShortcutsShortcut">
+ <property name="visible">True</property>
+ <!-- Translators: Return/space actions description in the Keyboard Shortcuts dialog; depend
on context -->
+ <property name="title" translatable="yes" context="shortcut window">Select, unselect, or
move selected tile</property>
+ <property name="accelerator">Return space</property>
+ </object>
+ </child>
+ </object>
+ </child>
<child>
<object class="GtkShortcutsGroup">
<property name="visible">1</property>
@@ -163,6 +186,30 @@
<property name="title" translatable="yes" context="shortcut window">Move all the pieces in
the left box right by one</property>
</object>
</child>
+ <child>
+ <object class="GtkShortcutsShortcut">
+ <property name="visible">True</property>
+ <!-- Translators: numbers (1 to 6) actions description in the Keyboard Shortcuts dialog,
section Advanced gameplay; depending on game size, you can only use 1 to 2 or up to 1 to 6 -->
+ <property name="title" translatable="yes" context="shortcut window">Select the given row, up
to game size</property>
+ <property name="accelerator">1...6</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkShortcutsShortcut">
+ <property name="visible">True</property>
+ <!-- Translators: alphabetical chars (a to f) actions description in the Keyboard Shortcuts
dialog, section Advanced gameplay; depending on game size, you can only use a to b or up to a to f; the board
is splitted in two parts, that is for the left one -->
+ <property name="title" translatable="yes" context="shortcut window">Select the given column
in the left board, up to game size</property>
+ <property name="accelerator">a...f</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkShortcutsShortcut">
+ <property name="visible">True</property>
+ <!-- Translators: capital alphabetical chars (A to F) actions description in the Keyboard
Shortcuts dialog, section Advanced gameplay; depending on game size, you can only use A to B or up to A to F;
the board is splitted in two parts, that is for the right one -->
+ <property name="title" translatable="yes" context="shortcut window">Select the given column
in the right board, up to game size</property>
+ <property name="accelerator"><Shift>A...<Shift>F</property>
+ </object>
+ </child>
</object>
</child>
</object>
diff --git a/src/puzzle-view.vala b/src/puzzle-view.vala
index 902b9d0..00a73dc 100644
--- a/src/puzzle-view.vala
+++ b/src/puzzle-view.vala
@@ -30,8 +30,9 @@ 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_highlight (Cairo.Context context, bool has_tile);
internal abstract void draw_paused_tile (Cairo.Context context);
- internal abstract void draw_tile (Cairo.Context context, Tile tile);
+ internal abstract void draw_tile (Cairo.Context context, Tile tile, bool highlight);
internal abstract void set_animation_level (uint8 animation_level /* 0-16 */);
}
@@ -118,6 +119,8 @@ private class PuzzleView : Gtk.DrawingArea
sockets_ys = new double [2 * _puzzle.size, _puzzle.size];
}
+ clear_keyboard_highlight (/* only selection */ false);
+ _puzzle.solved.connect (() => clear_keyboard_highlight (/* only selection */ false));
_puzzle.tile_moved.connect (tile_moved_cb);
_puzzle.notify ["paused"].connect (queue_draw);
queue_resize ();
@@ -208,6 +211,14 @@ private class PuzzleView : Gtk.DrawingArea
(int) tilesize + theme.overdraw_top + theme.overdraw_bottom);
}
+ private void queue_draw_tile (uint8 x, uint8 y)
+ {
+ queue_draw_area ((int) sockets_xs [x, y] - theme.overdraw_left,
+ (int) sockets_ys [x, 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)
{
double target_x = x_offset + (double) (x * tilesize);
@@ -481,20 +492,37 @@ private class PuzzleView : Gtk.DrawingArea
else if (last_selected_tile != null)
draw_image (context, (!) last_selected_tile);
+ /* Draw highlight */
+ if (show_highlight)
+ {
+ context.save ();
+ context.translate (sockets_xs [highlight_x, highlight_y], sockets_ys [highlight_x, highlight_y]);
+ theme.draw_highlight (context, puzzle.get_tile (highlight_x, highlight_y) != null);
+ context.restore ();
+ }
+
/* Draw pause overlay */
if (puzzle.paused)
draw_pause_overlay (context);
return false;
}
- private inline void draw_image (Cairo.Context context, TileImage image)
+ private void draw_image (Cairo.Context context, TileImage image)
{
context.save ();
context.translate ((int) image.x, (int) image.y);
if (puzzle.paused)
theme.draw_paused_tile (context);
else
- theme.draw_tile (context, image.tile);
+ {
+ uint8 tile_x;
+ uint8 tile_y;
+ puzzle.get_tile_location (image.tile, out tile_x, out tile_y);
+ bool highlight = show_highlight && tile_selection
+ && kbd_selected_x == tile_x
+ && kbd_selected_y == tile_y;
+ theme.draw_tile (context, image.tile, highlight);
+ }
context.restore ();
}
private inline void draw_pause_overlay (Cairo.Context context)
@@ -621,6 +649,7 @@ private class PuzzleView : Gtk.DrawingArea
{
if (puzzle.paused || puzzle.is_solved)
return false;
+ clear_keyboard_highlight (/* only selection */ false);
if (event.button == 1 || event.button == 3)
return main_button_pressed (event);
@@ -659,7 +688,7 @@ private class PuzzleView : Gtk.DrawingArea
{
uint8 x;
uint8 y;
- if (selected_tile_is_last_tile (out x, out y))
+ if (only_one_remaining_tile (out x, out y))
{
uint8 selected_x, selected_y;
puzzle.get_tile_location (((!) selected_tile).tile, out selected_x, out selected_y);
@@ -688,7 +717,7 @@ private class PuzzleView : Gtk.DrawingArea
return false;
}
- private inline bool selected_tile_is_last_tile (out uint8 empty_x, out uint8 empty_y)
+ private inline bool only_one_remaining_tile (out uint8 empty_x, out uint8 empty_y)
{
bool empty_found = false;
empty_x = uint8.MAX; // garbage
@@ -713,6 +742,7 @@ private class PuzzleView : Gtk.DrawingArea
{
if (puzzle.paused || puzzle.is_solved)
return false;
+ clear_keyboard_highlight (/* only selection */ false);
if (event.button == 1 && selected_tile != null && selection_timeout == 0)
drop_tile (event.x, event.y);
@@ -836,4 +866,231 @@ private class PuzzleView : Gtk.DrawingArea
arrow_pattern = null;
socket_pattern = null;
}
+
+ /*\
+ * * keyboard
+ \*/
+
+ private bool show_highlight = false;
+
+ private bool highlight_set = false;
+ private uint8 highlight_x = uint8.MAX;
+ private uint8 highlight_y = uint8.MAX;
+ private uint8 old_highlight_x = uint8.MAX;
+ private uint8 old_highlight_y = uint8.MAX;
+
+ private bool tile_selection = false;
+ private uint8 kbd_selected_x = uint8.MAX;
+ private uint8 kbd_selected_y = uint8.MAX;
+
+ protected override bool key_press_event (Gdk.EventKey event)
+ {
+ if (!puzzle_init_done)
+ return false;
+
+ if (puzzle.is_solved || puzzle.paused)
+ return false;
+
+ if (tile_selected)
+ return false;
+
+ string key = (!) (Gdk.keyval_name (event.keyval) ?? "");
+ if (key == "")
+ return false;
+
+ if (highlight_set && show_highlight && (key == "space" || key == "Return" || key == "KP_Enter"))
+ {
+ if (tile_selection)
+ {
+ if (highlight_x == kbd_selected_x && highlight_y == kbd_selected_y)
+ {
+ clear_keyboard_highlight (/* only selection */ true);
+ return true;
+ }
+ if (puzzle.can_switch (highlight_x, highlight_y, kbd_selected_x, kbd_selected_y))
+ {
+ puzzle.switch_tiles (highlight_x, highlight_y, kbd_selected_x, kbd_selected_y);
+ clear_keyboard_highlight (/* only selection */ true);
+ return true;
+ }
+ if (puzzle.get_tile (highlight_x, highlight_y) != null)
+ {
+ tile_selection = false;
+ queue_draw_tile (kbd_selected_x, kbd_selected_y);
+ kbd_selected_x = highlight_x;
+ kbd_selected_y = highlight_y;
+ tile_selection = true;
+ queue_draw_tile (highlight_x, highlight_y);
+ return true;
+ }
+ }
+ else
+ {
+ Tile? tile = puzzle.get_tile (highlight_x, highlight_y);
+ if (tile == null)
+ return true;
+
+ if (highlight_x >= puzzle.size)
+ {
+ uint8 x;
+ uint8 y;
+ if (only_one_remaining_tile (out x, out y))
+ {
+ uint8 selected_x, selected_y;
+ puzzle.get_tile_location ((!) tile, out selected_x, out selected_y);
+ if (puzzle.can_switch (selected_x, selected_y, x, y))
+ {
+ puzzle.switch_tiles (selected_x, selected_y, x, y, final_animation_duration);
+ return true;
+ }
+ }
+ }
+ tile_selection = true;
+ kbd_selected_x = highlight_x;
+ kbd_selected_y = highlight_y;
+ queue_draw_tile (highlight_x, highlight_y);
+ }
+ return true;
+ }
+
+ if ((puzzle.size <= 2 && (key == "c" || key == "C" || key == "3" || key == "KP_3")) ||
+ (puzzle.size <= 3 && (key == "d" || key == "D" || key == "4" || key == "KP_4")) ||
+ (puzzle.size <= 4 && (key == "e" || key == "E" || key == "5" || key == "KP_5")) ||
+ (puzzle.size <= 5 && (key == "f" || key == "F" || key == "6" || key == "KP_6")) ||
+ (puzzle.size <= 6 && (key == "g" || key == "G" || key == "7" || key == "KP_7")) ||
+ (puzzle.size <= 7 && (key == "h" || key == "H" || key == "8" || key == "KP_8")) ||
+ (puzzle.size <= 8 && (key == "i" || key == "I" || key == "9" || key == "KP_9")) ||
+ (puzzle.size <= 9 && (key == "j" || key == "J" || key == "0" || key == "KP_0")))
+ return false;
+
+ old_highlight_x = highlight_x;
+ old_highlight_y = highlight_y;
+ switch (key)
+ {
+ case "Up":
+ case "KP_Up":
+ set_highlight_position_if_needed ();
+ if (highlight_y > 0) highlight_y--;
+ break;
+ case "Left":
+ case "KP_Left":
+ set_highlight_position_if_needed ();
+ if (highlight_x > 0) highlight_x--;
+ break;
+ case "Right":
+ case "KP_Right":
+ set_highlight_position_if_needed ();
+ if (highlight_x < puzzle.size * 2 - 1) highlight_x++;
+ break;
+ case "Down":
+ case "KP_Down":
+ set_highlight_position_if_needed ();
+ if (highlight_y < puzzle.size - 1) highlight_y++;
+ break;
+
+ case "space":
+ case "Return":
+ case "KP_Enter":
+ set_highlight_position_if_needed ();
+ break;
+
+ case "Escape": break;
+
+ case "a": set_highlight_position_if_needed (); highlight_x = 0; break;
+ case "b": set_highlight_position_if_needed (); highlight_x = 1; break;
+ case "c": set_highlight_position_if_needed (); highlight_x = 2; break;
+ case "d": set_highlight_position_if_needed (); highlight_x = 3; break;
+ case "e": set_highlight_position_if_needed (); highlight_x = 4; break;
+ case "f": set_highlight_position_if_needed (); highlight_x = 5; break;
+
+ case "A": set_highlight_position_if_needed (); highlight_x = puzzle.size ; break;
+ case "B": set_highlight_position_if_needed (); highlight_x = puzzle.size + 1; break;
+ case "C": set_highlight_position_if_needed (); highlight_x = puzzle.size + 2; break;
+ case "D": set_highlight_position_if_needed (); highlight_x = puzzle.size + 3; break;
+ case "E": set_highlight_position_if_needed (); highlight_x = puzzle.size + 4; break;
+ case "F": set_highlight_position_if_needed (); highlight_x = puzzle.size + 5; break;
+
+ case "1": case "KP_1": set_highlight_position_if_needed (); highlight_y = 0; break;
+ case "2": case "KP_2": set_highlight_position_if_needed (); highlight_y = 1; break;
+ case "3": case "KP_3": set_highlight_position_if_needed (); highlight_y = 2; break;
+ case "4": case "KP_4": set_highlight_position_if_needed (); highlight_y = 3; break;
+ case "5": case "KP_5": set_highlight_position_if_needed (); highlight_y = 4; break;
+ case "6": case "KP_6": set_highlight_position_if_needed (); highlight_y = 5; break;
+
+ case "Home":
+ case "KP_Home":
+ set_highlight_position_if_needed ();
+ highlight_x = 0;
+ break;
+ case "End":
+ case "KP_End":
+ set_highlight_position_if_needed ();
+ highlight_x = puzzle.size * 2 - 1;
+ break;
+ case "Page_Up":
+ case "KP_Page_Up":
+ set_highlight_position_if_needed ();
+ highlight_y = 0;
+ break;
+ case "Page_Down":
+ case "KP_Next": // TODO use KP_Page_Down instead of KP_Next, probably a gtk+ or vala bug;
check also KP_Prior
+ set_highlight_position_if_needed ();
+ highlight_y = puzzle.size - 1;
+ break;
+
+ // allow <Tab> and <Shift><Tab> to change focus
+ default:
+ return false;
+ }
+
+ highlight_set = true;
+
+ if (key == "Escape")
+ {
+ if (tile_selection)
+ clear_keyboard_highlight (/* only selection */ true);
+ else
+ clear_keyboard_highlight (/* only selection */ false);
+ }
+ else
+ show_highlight = true;
+
+ queue_draw_tile (old_highlight_x, old_highlight_y);
+ if ((old_highlight_x != highlight_x)
+ || (old_highlight_y != highlight_y))
+ queue_draw_tile (highlight_x, highlight_y);
+ return true;
+ }
+
+ private void set_highlight_position_if_needed ()
+ {
+ if (highlight_set)
+ /* If keyboard highlight is already set (and visible), this is good. */
+ return;
+
+ // TODO better
+ highlight_x = puzzle.size;
+ highlight_y = 0;
+ }
+
+ private void clear_keyboard_highlight (bool only_selection)
+ {
+ if (!only_selection)
+ {
+ show_highlight = false;
+ queue_draw_tile (highlight_x, highlight_y);
+ highlight_set = false;
+ highlight_x = uint8.MAX;
+ highlight_y = uint8.MAX;
+ old_highlight_x = uint8.MAX;
+ old_highlight_y = uint8.MAX;
+ }
+ if (tile_selection)
+ {
+ tile_selection = false;
+ queue_draw_tile (kbd_selected_x, kbd_selected_y);
+ kbd_selected_x = uint8.MAX;
+ kbd_selected_y = uint8.MAX;
+ }
+ }
}
diff --git a/src/theme-extrusion.vala b/src/theme-extrusion.vala
index e06b4ad..17ce04f 100644
--- a/src/theme-extrusion.vala
+++ b/src/theme-extrusion.vala
@@ -24,9 +24,11 @@ private class ExtrusionTheme : Theme
* * colors arrays
\*/
- private Cairo.Pattern tile_colors_h [10];
- private Cairo.Pattern tile_colors_v [10];
- private Cairo.Pattern tile_shadows [10];
+ private Cairo.Pattern tile_colors_h [10];
+ private Cairo.Pattern tile_colors_v [10];
+ private Cairo.Pattern tile_highlights_h [10];
+ private Cairo.Pattern tile_highlights_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);
@@ -48,14 +50,16 @@ private class ExtrusionTheme : Theme
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);
+ paused_color_h = make_dir_color_pattern ("CCCCCC", /* vertical */ false, 1.0);
+ paused_color_v = make_dir_color_pattern ("CCCCCC", /* vertical */ true , 1.0);
}
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_colors_h [position] = make_dir_color_pattern (color, /* vertical */ false, 1.00);
+ tile_colors_v [position] = make_dir_color_pattern (color, /* vertical */ true , 1.00);
+ tile_highlights_h [position] = make_dir_color_pattern (color, /* vertical */ false, 1.35);
+ tile_highlights_v [position] = make_dir_color_pattern (color, /* vertical */ true , 1.35);
tile_shadows [position] = make_shadow_color_pattern (color);
@@ -65,11 +69,11 @@ private class ExtrusionTheme : Theme
text_colors [position] = black_text_color;
}
- private static Cairo.Pattern make_dir_color_pattern (string color, bool vertical)
+ private static Cairo.Pattern make_dir_color_pattern (string color, bool vertical, double color_factor)
{
- 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 r0 = (hex_value (color [0]) * 16 + hex_value (color [1])) / 255.0 * color_factor;
+ double g0 = (hex_value (color [2]) * 16 + hex_value (color [3])) / 255.0 * color_factor;
+ double b0 = (hex_value (color [4]) * 16 + hex_value (color [5])) / 255.0 * color_factor;
double r1 = double.min (r0 + 0.01, 1.0);
double g1 = double.min (g0 + 0.01, 1.0);
@@ -128,6 +132,9 @@ private class ExtrusionTheme : Theme
private double arrow_opacity;
+ /* highlight */
+ private Cairo.Pattern highlight_tile_pattern;
+
/* tile only */
private const uint radius_percent = 8;
private Cairo.Matrix matrix;
@@ -166,12 +173,23 @@ private class ExtrusionTheme : Theme
arrow_clip_w = 2.0 * arrow_x + arrow_w;
arrow_clip_h = 2.0 * new_size;
+ /* highlight */
+ half_tile_size = new_size * 0.5; // also for tile
+ double highlight_radius = new_size * 0.45;
+ highlight_tile_pattern = new Cairo.Pattern.radial (half_tile_size, half_tile_size, 0.0,
+ half_tile_size, half_tile_size, highlight_radius);
+ highlight_tile_pattern.add_color_stop_rgba (0.0, 1.0, 1.0, 1.0, 1.0);
+ highlight_tile_pattern.add_color_stop_rgba (0.2, 1.0, 1.0, 1.0, 0.8);
+ highlight_tile_pattern.add_color_stop_rgba (0.3, 1.0, 1.0, 1.0, 0.5);
+ highlight_tile_pattern.add_color_stop_rgba (0.4, 1.0, 1.0, 1.0, 0.2);
+ highlight_tile_pattern.add_color_stop_rgba (0.5, 1.0, 1.0, 1.0, 0.1);
+ highlight_tile_pattern.add_color_stop_rgba (1.0, 1.0, 1.0, 1.0, 0.0);
+
/* 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;
@@ -232,6 +250,23 @@ private class ExtrusionTheme : Theme
context.restore ();
}
+ /*\
+ * * drawing highlight
+ \*/
+
+ internal override void draw_highlight (Cairo.Context context, bool has_tile)
+ {
+ context.save ();
+
+ if (has_tile)
+ context.translate (0.0, extrusion);
+
+ context.set_source (highlight_tile_pattern);
+ context.rectangle (0.0, 0.0, /* width and height */ size, size);
+ context.fill ();
+ context.restore ();
+ }
+
/*\
* * drawing tiles
\*/
@@ -242,7 +277,7 @@ private class ExtrusionTheme : Theme
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)
+ internal override void draw_tile (Cairo.Context context, Tile tile, bool highlight)
{
tile_colors_h [tile.north].set_matrix (matrix);
tile_colors_h [tile.east ].set_matrix (matrix);
@@ -254,7 +289,10 @@ private class ExtrusionTheme : Theme
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]);
+ if (highlight)
+ draw_tile_background (context, tile_highlights_h [tile.north], tile_highlights_v [tile.east],
tile_highlights_h [tile.south], tile_highlights_v [tile.west]);
+ else
+ 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);
diff --git a/src/theme-neoretro.vala b/src/theme-neoretro.vala
index 6f5a1ae..1900122 100644
--- a/src/theme-neoretro.vala
+++ b/src/theme-neoretro.vala
@@ -24,8 +24,10 @@ private class NeoRetroTheme : Theme
* * colors arrays
\*/
- private Cairo.Pattern tile_colors_h [10];
- private Cairo.Pattern tile_colors_v [10];
+ private Cairo.Pattern tile_colors_h [10];
+ private Cairo.Pattern tile_colors_v [10];
+ private Cairo.Pattern tile_highlights_h [10];
+ private Cairo.Pattern tile_highlights_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);
@@ -47,14 +49,16 @@ private class NeoRetroTheme : Theme
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");
+ paused_color_h = make_dir_color_pattern ("CCCCCC", /* vertical */ false, 1.0);
+ paused_color_v = make_dir_color_pattern ("CCCCCC", /* vertical */ true , 1.0);
}
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);
+ tile_colors_h [position] = make_dir_color_pattern (color, /* vertical */ false, 1.0);
+ tile_colors_v [position] = make_dir_color_pattern (color, /* vertical */ true , 1.0);
+ tile_highlights_h [position] = make_dir_color_pattern (color, /* vertical */ false, 1.4);
+ tile_highlights_v [position] = make_dir_color_pattern (color, /* vertical */ true , 1.4);
if (white_text)
text_colors [position] = white_text_color;
@@ -62,11 +66,11 @@ private class NeoRetroTheme : Theme
text_colors [position] = black_text_color;
}
- private static Cairo.Pattern make_h_color_pattern (string color)
+ private static Cairo.Pattern make_dir_color_pattern (string color, bool vertical, double color_factor)
{
- 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 r0 = (hex_value (color [0]) * 16 + hex_value (color [1])) / 255.0 * color_factor;
+ double g0 = (hex_value (color [2]) * 16 + hex_value (color [3])) / 255.0 * color_factor;
+ double b0 = (hex_value (color [4]) * 16 + hex_value (color [5])) / 255.0 * color_factor;
double r1 = double.min (r0 + 0.10, 1.0);
double g1 = double.min (g0 + 0.10, 1.0);
@@ -80,35 +84,11 @@ private class NeoRetroTheme : Theme
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);
+ 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, 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);
@@ -157,6 +137,9 @@ private class NeoRetroTheme : Theme
private Cairo.MeshPattern socket_pattern;
private Cairo.Matrix matrix; // also used for tile
+ /* highlight */
+ private Cairo.Pattern highlight_tile_pattern;
+
/* tile only */
private uint tile_margin;
private int tile_size;
@@ -195,10 +178,21 @@ private class NeoRetroTheme : Theme
init_socket_pattern ();
+ /* highlight */
+ half_tile_size = new_size * 0.5; // also for tile
+ double highlight_radius = new_size * 0.45;
+ highlight_tile_pattern = new Cairo.Pattern.radial (half_tile_size, half_tile_size, 0.0,
+ half_tile_size, half_tile_size, highlight_radius);
+ highlight_tile_pattern.add_color_stop_rgba (0.0, 1.0, 1.0, 1.0, 1.0);
+ highlight_tile_pattern.add_color_stop_rgba (0.2, 1.0, 1.0, 1.0, 0.8);
+ highlight_tile_pattern.add_color_stop_rgba (0.3, 1.0, 1.0, 1.0, 0.5);
+ highlight_tile_pattern.add_color_stop_rgba (0.4, 1.0, 1.0, 1.0, 0.2);
+ highlight_tile_pattern.add_color_stop_rgba (0.5, 1.0, 1.0, 1.0, 0.1);
+ highlight_tile_pattern.add_color_stop_rgba (1.0, 1.0, 1.0, 1.0, 0.0);
+
/* 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;
@@ -320,6 +314,17 @@ private class NeoRetroTheme : Theme
context.restore ();
}
+ /*\
+ * * drawing highlight
+ \*/
+
+ internal override void draw_highlight (Cairo.Context context, bool has_tile)
+ {
+ context.set_source (highlight_tile_pattern);
+ context.rectangle (0.0, 0.0, /* width and height */ size, size);
+ context.fill ();
+ }
+
/*\
* * drawing tiles
\*/
@@ -329,18 +334,26 @@ private class NeoRetroTheme : Theme
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)
+ internal override void draw_tile (Cairo.Context context, Tile tile, bool highlight)
{
- 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]);
+ if (highlight)
+ {
+ tile_highlights_h [tile.north].set_matrix (matrix);
+ tile_highlights_h [tile.south].set_matrix (matrix);
+ tile_highlights_v [tile.east ].set_matrix (matrix);
+ tile_highlights_v [tile.west ].set_matrix (matrix);
+
+ draw_tile_background (context, tile_highlights_h [tile.north], tile_highlights_v [tile.east],
tile_highlights_h [tile.south], tile_highlights_v [tile.west]);
+ }
+ else
+ {
+ tile_colors_h [tile.north].set_matrix (matrix);
+ tile_colors_h [tile.south].set_matrix (matrix);
+ tile_colors_v [tile.east ].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);
diff --git a/src/theme-nostalgia.vala b/src/theme-nostalgia.vala
index d3f37e0..4d71977 100644
--- a/src/theme-nostalgia.vala
+++ b/src/theme-nostalgia.vala
@@ -102,6 +102,9 @@ private class NostalgiaTheme : Theme
private double size_minus_socket_depth;
private double size_minus_two_socket_depths;
+ /* highlight */
+ private Cairo.Pattern highlight_tile_pattern;
+
/* tile only */
private double tile_depth;
private double size_minus_tile_depth;
@@ -128,13 +131,24 @@ private class NostalgiaTheme : Theme
configure_arrow (new_size);
configure_socket (new_size);
+ /* highlight */
+ half_tile_size = new_size * 0.5; // also for tile
+ double highlight_radius = new_size * 0.45;
+ highlight_tile_pattern = new Cairo.Pattern.radial (half_tile_size, half_tile_size, 0.0,
+ half_tile_size, half_tile_size, highlight_radius);
+ highlight_tile_pattern.add_color_stop_rgba (0.0, 1.0, 1.0, 1.0, 1.0);
+ highlight_tile_pattern.add_color_stop_rgba (0.2, 1.0, 1.0, 1.0, 0.8);
+ highlight_tile_pattern.add_color_stop_rgba (0.3, 1.0, 1.0, 1.0, 0.5);
+ highlight_tile_pattern.add_color_stop_rgba (0.4, 1.0, 1.0, 1.0, 0.2);
+ highlight_tile_pattern.add_color_stop_rgba (0.5, 1.0, 1.0, 1.0, 0.1);
+ highlight_tile_pattern.add_color_stop_rgba (1.0, 1.0, 1.0, 1.0, 0.0);
+
/* tiles */
tile_depth = double.min (new_size * 0.05, 4.0);
size_minus_tile_depth = (double) new_size - tile_depth;
tile_dx = (Math.SQRT2 + 1.0) * tile_depth;
tile_dy = Math.SQRT2 * tile_depth;
size_minus_tile_dx = (double) new_size - tile_dx;
- half_tile_size = new_size * 0.5;
half_tile_size_minus_dy = half_tile_size - tile_dy;
half_tile_size_plus_dy = half_tile_size + tile_dy;
size_minus_one = (double) (new_size - 1);
@@ -268,6 +282,17 @@ private class NostalgiaTheme : Theme
context.fill ();
}
+ /*\
+ * * drawing highlight
+ \*/
+
+ internal override void draw_highlight (Cairo.Context context, bool has_tile)
+ {
+ context.set_source (highlight_tile_pattern);
+ context.rectangle (0.0, 0.0, /* width and height */ size, size);
+ context.fill ();
+ }
+
/*\
* * drawing tiles
\*/
@@ -277,7 +302,7 @@ private class NostalgiaTheme : Theme
draw_tile_background (context, paused_color, paused_color, paused_color, paused_color);
}
- internal override void draw_tile (Cairo.Context context, Tile tile)
+ internal override void draw_tile (Cairo.Context context, Tile tile, bool highlight)
{
draw_tile_background (context, tile_colors [tile.north], tile_colors [tile.east], tile_colors
[tile.south], tile_colors [tile.west]);
@@ -287,6 +312,13 @@ private class NostalgiaTheme : Theme
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);
+
+ if (highlight)
+ {
+ context.set_source_rgba (1.0, 1.0, 1.0, 0.3);
+ context.rectangle (0.0, 0.0, size, size);
+ context.fill ();
+ }
}
private void draw_tile_background (Cairo.Context context, Cairo.Pattern north_color, Cairo.Pattern
east_color, Cairo.Pattern south_color, Cairo.Pattern west_color)
diff --git a/src/theme-synesthesia.vala b/src/theme-synesthesia.vala
index 74eecb4..470fe64 100644
--- a/src/theme-synesthesia.vala
+++ b/src/theme-synesthesia.vala
@@ -27,6 +27,7 @@ private class SynesthesiaTheme : Theme
private Cairo.Pattern text_colors [10];
private Cairo.Pattern paused_color;
private Cairo.Pattern tile_color;
+ private Cairo.Pattern highlight_color;
construct
{ // based on GNOME color palette
@@ -43,6 +44,7 @@ private class SynesthesiaTheme : Theme
paused_color = make_color_pattern ("CCCCCC");
tile_color = make_color_pattern ("CDCADA", /* transparency */ true);
+ highlight_color = make_color_pattern ("DACACD", /* transparency */ true);
}
private static Cairo.Pattern make_color_pattern (string color, bool transparency = false)
@@ -85,6 +87,9 @@ private class SynesthesiaTheme : Theme
private Cairo.MeshPattern socket_pattern;
private Cairo.Matrix matrix; // also used for tile
+ /* highlight */
+ private Cairo.Pattern highlight_tile_pattern;
+
/* tile only */
private uint tile_margin;
private int tile_size;
@@ -119,10 +124,21 @@ private class SynesthesiaTheme : Theme
size_minus_two_tile_depths = (double) (new_size - tile_depth * 2);
init_socket_pattern ();
+ /* highlight */
+ half_size = new_size * 0.5; // also for tile
+ double highlight_radius = new_size * 0.45;
+ highlight_tile_pattern = new Cairo.Pattern.radial (half_size, half_size, 0.0,
+ half_size, half_size, highlight_radius);
+ highlight_tile_pattern.add_color_stop_rgba (0.0, 1.0, 1.0, 1.0, 1.0);
+ highlight_tile_pattern.add_color_stop_rgba (0.2, 1.0, 1.0, 1.0, 0.8);
+ highlight_tile_pattern.add_color_stop_rgba (0.3, 1.0, 1.0, 1.0, 0.5);
+ highlight_tile_pattern.add_color_stop_rgba (0.4, 1.0, 1.0, 1.0, 0.2);
+ highlight_tile_pattern.add_color_stop_rgba (0.5, 1.0, 1.0, 1.0, 0.1);
+ highlight_tile_pattern.add_color_stop_rgba (1.0, 1.0, 1.0, 1.0, 0.0);
+
/* tile */
tile_margin = uint.min ((uint) (new_size * 0.05), 2) - 1;
tile_size = (int) new_size - (int) tile_margin * 2;
- half_size = new_size * 0.5;
half_tile_size = tile_size * 0.5;
/* numbers */
@@ -215,6 +231,17 @@ private class SynesthesiaTheme : Theme
context.restore ();
}
+ /*\
+ * * drawing highlight
+ \*/
+
+ internal override void draw_highlight (Cairo.Context context, bool has_tile)
+ {
+ context.set_source (highlight_tile_pattern);
+ context.rectangle (0.0, 0.0, /* width and height */ size, size);
+ context.fill ();
+ }
+
/*\
* * drawing tiles
\*/
@@ -224,9 +251,12 @@ private class SynesthesiaTheme : Theme
draw_tile_background (context, paused_color);
}
- internal override void draw_tile (Cairo.Context context, Tile tile)
+ internal override void draw_tile (Cairo.Context context, Tile tile, bool highlight)
{
- draw_tile_background (context, tile_color);
+ if (highlight)
+ draw_tile_background (context, highlight_color);
+ else
+ draw_tile_background (context, tile_color);
context.select_font_face ("Cantarell", Cairo.FontSlant.NORMAL, Cairo.FontWeight.BOLD);
context.set_font_size (font_size);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]