[iagno] Add keyboard support.
- From: Arnaud Bonatti <arnaudb src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [iagno] Add keyboard support.
- Date: Mon, 6 Apr 2015 18:09:51 +0000 (UTC)
commit 94dab347c2c3f81ad199172f7d99db964731f9d1
Author: Arnaud Bonatti <arnaud bonatti gmail com>
Date: Mon Apr 6 20:07:05 2015 +0200
Add keyboard support.
Based on Iulian Radu's work on a not really related bug.
https://bugzilla.gnome.org/show_bug.cgi?id=710139#c14
data/themes/adwaita.theme.in | 6 ++
data/themes/classic.theme.in | 6 ++
data/themes/high_contrast.theme.in | 6 ++
data/themes/sun_and_star.theme.in | 6 ++
src/game-view.vala | 176 +++++++++++++++++++++++++++++++++---
5 files changed, 185 insertions(+), 15 deletions(-)
---
diff --git a/data/themes/adwaita.theme.in b/data/themes/adwaita.theme.in
index 3bbf548..27119a8 100644
--- a/data/themes/adwaita.theme.in
+++ b/data/themes/adwaita.theme.in
@@ -30,6 +30,12 @@ Green=0.2
Blue=0.3
Width=2
+[Highlight]
+Red=0.1
+Green=0.2
+Blue=0.3
+Alpha=0.4
+
[Margin]
#Width=0
diff --git a/data/themes/classic.theme.in b/data/themes/classic.theme.in
index 9e9466b..a38ed84 100644
--- a/data/themes/classic.theme.in
+++ b/data/themes/classic.theme.in
@@ -30,6 +30,12 @@ Green=0.3
Blue=0.2
Width=2
+[Highlight]
+Red=0.1
+Green=0.3
+Blue=0.2
+Alpha=0.4
+
[Margin]
#Width=0
diff --git a/data/themes/high_contrast.theme.in b/data/themes/high_contrast.theme.in
index 0fb21e3..ceae514 100644
--- a/data/themes/high_contrast.theme.in
+++ b/data/themes/high_contrast.theme.in
@@ -30,6 +30,12 @@ Green=0.0
Blue=0.0
Width=3
+[Highlight]
+Red=0.7
+Green=0.7
+Blue=0.7
+Alpha=1.0
+
[Margin]
#Width=0
diff --git a/data/themes/sun_and_star.theme.in b/data/themes/sun_and_star.theme.in
index 57dec45..e345baa 100644
--- a/data/themes/sun_and_star.theme.in
+++ b/data/themes/sun_and_star.theme.in
@@ -30,6 +30,12 @@ Green=0.3
Blue=0.2
Width=2
+[Highlight]
+Red=0.1
+Green=0.3
+Blue=0.2
+Alpha=0.4
+
[Margin]
#Width=0
diff --git a/src/game-view.vala b/src/game-view.vala
index b76a602..9f94a2a 100644
--- a/src/game-view.vala
+++ b/src/game-view.vala
@@ -52,6 +52,11 @@ public class GameView : Gtk.DrawingArea
private double spacing_blue = 0.2;
private int spacing_width = 2;
+ private double highlight_red = 0.1;
+ private double highlight_green = 0.3;
+ private double highlight_blue = 0.2;
+ private double highlight_alpha = 0.4;
+
// private int margin_width = 0;
public string sound_flip { get; private set; }
@@ -60,8 +65,15 @@ public class GameView : Gtk.DrawingArea
/* Utilities, see calculate () */
private int tile_size;
private int board_size;
- private int x_offset { get { return (get_allocated_width () - board_size) / 2 + border_width; }}
- private int y_offset { get { return (get_allocated_height () - board_size) / 2 + border_width; }}
+ private int board_x { get { return (get_allocated_width () - board_size) / 2; }}
+ private int board_y { get { return (get_allocated_height () - board_size) / 2; }}
+
+ /* Keyboard */
+ private bool show_highlight;
+ private int highlight_x;
+ private int highlight_y;
+ private int highlight_state;
+ private const int HIGHLIGHT_MAX = 5;
/* Delay in milliseconds between tile flip frames */
private const int PIXMAP_FLIP_DELAY = 20;
@@ -102,6 +114,12 @@ public class GameView : Gtk.DrawingArea
for (int y = 0; y < game.size; y++)
pixmaps[x, y] = get_pixmap (_game.get_owner (x, y));
}
+
+ show_highlight = false;
+ highlight_x = 3; // TODO default on 3 3 / 4 4 (on 8×8 board) when dark and
+ highlight_y = 3; // 3 4 / 4 3 when light, depending on first key pressed
+ highlight_state = 0;
+
queue_draw ();
}
}
@@ -190,6 +208,11 @@ public class GameView : Gtk.DrawingArea
spacing_blue = key.get_double ("Spacing", "Blue");
spacing_width = key.get_integer ("Spacing", "Width");
+ highlight_red = key.get_double ("Highlight", "Red");
+ highlight_green = key.get_double ("Highlight", "Green");
+ highlight_blue = key.get_double ("Highlight", "Blue");
+ highlight_alpha = key.get_double ("Highlight", "Alpha");
+
// margin_width = key.get_integer ("Margin", "Width");
sound_flip = key.get_string ("Sound", "Flip");
@@ -212,8 +235,8 @@ public class GameView : Gtk.DrawingArea
int size = int.min (get_allocated_width (), get_allocated_height ());
/* tile_size includes a grid spacing */
tile_size = (size - 2 * border_width + spacing_width) / game.size;
- /* board_size includes its borders */
- board_size = tile_size * game.size - spacing_width + 2 * border_width;
+ /* board_size excludes its borders */
+ board_size = tile_size * game.size - spacing_width;
}
public override bool draw (Cairo.Context cr)
@@ -232,11 +255,11 @@ public class GameView : Gtk.DrawingArea
tiles_pattern = new Cairo.Pattern.for_surface (surface);
}
- cr.translate (x_offset, y_offset);
+ cr.translate (board_x, board_y);
- /* draw background; TODO save for border */
+ /* draw background */
cr.set_source_rgba (background_red, background_green, background_blue, 1.0);
- cr.rectangle (-border_width / 2.0, -border_width / 2.0, board_size - border_width, board_size -
border_width);
+ cr.rectangle (0, 0, board_size, board_size);
cr.fill ();
/* draw lines */
@@ -245,19 +268,38 @@ public class GameView : Gtk.DrawingArea
for (var i = 1; i < game.size; i++)
{
cr.move_to (i * tile_size - spacing_width / 2.0, 0);
- cr.rel_line_to (0, board_size - border_width);
+ cr.rel_line_to (0, board_size);
cr.move_to (0, i * tile_size - spacing_width / 2.0);
- cr.rel_line_to (board_size - border_width, 0);
+ cr.rel_line_to (board_size, 0);
}
cr.stroke ();
/* draw border */
cr.set_source_rgba (border_red, border_green, border_blue, 1.0);
cr.set_line_width (border_width);
- cr.rectangle (-border_width / 2.0, -border_width / 2.0, board_size - border_width, board_size -
border_width);
+ cr.rectangle (-border_width / 2.0, -border_width / 2.0, board_size + border_width, board_size +
border_width);
cr.stroke ();
+ /* draw highlight */
+ if ((show_highlight || highlight_state != 0) && !game.is_complete)
+ {
+ if (show_highlight && highlight_state != HIGHLIGHT_MAX)
+ {
+ highlight_state ++;
+ queue_draw_area (board_x + highlight_x * tile_size, board_y + highlight_y * tile_size,
tile_size, tile_size);
+ }
+ else if (!show_highlight && highlight_state != 0)
+ highlight_state = 0; // TODO highlight_state--; when mouse clicking, conflict updating
coords & showing the anim on previous place
+
+ cr.set_source_rgba (highlight_red, highlight_green, highlight_blue, highlight_alpha);
+ cr.rectangle (highlight_x * tile_size + (tile_size - spacing_width) * (HIGHLIGHT_MAX -
highlight_state) / (2 * HIGHLIGHT_MAX),
+ highlight_y * tile_size + (tile_size - spacing_width) * (HIGHLIGHT_MAX -
highlight_state) / (2 * HIGHLIGHT_MAX),
+ (tile_size - spacing_width) * highlight_state / HIGHLIGHT_MAX,
+ (tile_size - spacing_width) * highlight_state / HIGHLIGHT_MAX);
+ cr.fill ();
+ }
+
/* draw pieces */
cr.translate (-spacing_width / 2, -spacing_width / 2);
for (var x = 0; x < game.size; x++)
@@ -315,7 +357,7 @@ public class GameView : Gtk.DrawingArea
private void square_changed_cb (int x, int y)
{
- var pixmap = get_pixmap (game.get_owner (x, y));
+ int pixmap = get_pixmap (game.get_owner (x, y));
/* Show the result by laying the tiles with winning color first */
if (flip_final_result_now && game.is_complete)
@@ -378,7 +420,7 @@ public class GameView : Gtk.DrawingArea
if (animate_timeout == 0)
animate_timeout = Timeout.add (PIXMAP_FLIP_DELAY, animate_cb);
}
- queue_draw_area (x_offset + x * tile_size, y_offset + y * tile_size, tile_size, tile_size);
+ queue_draw_area (board_x + x * tile_size, board_y + y * tile_size, tile_size, tile_size);
}
private bool animate_cb ()
@@ -389,7 +431,7 @@ public class GameView : Gtk.DrawingArea
{
for (int y = 0; y < game.size; y++)
{
- var old = pixmaps[x, y];
+ int old = pixmaps[x, y];
square_changed_cb (x, y);
if (pixmaps[x, y] != old)
animating = true;
@@ -423,12 +465,116 @@ public class GameView : Gtk.DrawingArea
{
if (event.button == Gdk.BUTTON_PRIMARY || event.button == Gdk.BUTTON_SECONDARY)
{
- var x = (int) (event.x - x_offset) / tile_size;
- var y = (int) (event.y - y_offset) / tile_size;
+ int x = (int) (event.x - board_x) / tile_size;
+ int y = (int) (event.y - board_y) / tile_size;
if (x >= 0 && x < game.size && y >= 0 && y < game.size)
+ {
+ show_highlight = false;
+ queue_draw ();
+ highlight_x = x;
+ highlight_y = y;
move (x, y);
+ }
+ }
+
+ return true;
+ }
+
+ public override bool key_press_event (Gdk.EventKey event)
+ {
+ string key = Gdk.keyval_name (event.keyval);
+
+ if (show_highlight && (key == "space" || key == "Return" || key == "KP_Enter"))
+ {
+ move (highlight_x, highlight_y);
+ return true;
}
+ if ((game.size <= 4 && (key == "e" || key == "5" || key == "KP_5")) ||
+ (game.size <= 5 && (key == "f" || key == "6" || key == "KP_6")) ||
+ (game.size <= 6 && (key == "g" || key == "7" || key == "KP_7")) ||
+ (game.size <= 7 && (key == "h" || key == "8" || key == "KP_8")) ||
+ (game.size <= 8 && (key == "i" || key == "9" || key == "KP_9")) ||
+ (game.size <= 9 && (key == "j" || key == "0" || key == "KP_0")))
+ return false;
+
+ switch (key)
+ {
+ case "Left":
+ case "KP_Left":
+ if (highlight_x > 0) highlight_x --;
+ break;
+ case "Right":
+ case "KP_Right":
+ if (highlight_x < game.size - 1) highlight_x ++;
+ break;
+ case "Up":
+ case "KP_Up":
+ if (highlight_y > 0) highlight_y --;
+ break;
+ case "Down":
+ case "KP_Down":
+ if (highlight_y < game.size - 1) highlight_y ++;
+ break;
+
+ case "space":
+ case "Return":
+ case "KP_Enter":
+
+ case "Escape": break;
+
+ case "a": highlight_x = 0; break;
+ case "b": highlight_x = 1; break;
+ case "c": highlight_x = 2; break;
+ case "d": highlight_x = 3; break;
+ case "e": highlight_x = 4; break;
+ case "f": highlight_x = 5; break;
+ case "g": highlight_x = 6; break;
+ case "h": highlight_x = 7; break;
+ case "i": highlight_x = 8; break;
+ case "j": highlight_x = 9; break;
+
+ case "1": case "KP_1": highlight_y = 0; break;
+ case "2": case "KP_2": highlight_y = 1; break;
+ case "3": case "KP_3": highlight_y = 2; break;
+ case "4": case "KP_4": highlight_y = 3; break;
+ case "5": case "KP_5": highlight_y = 4; break;
+ case "6": case "KP_6": highlight_y = 5; break;
+ case "7": case "KP_7": highlight_y = 6; break;
+ case "8": case "KP_8": highlight_y = 7; break;
+ case "9": case "KP_9": highlight_y = 8; break;
+ case "0": case "KP_0": highlight_y = 9; break;
+
+ case "Home":
+ case "KP_Home":
+ highlight_x = 0;
+ break;
+ case "End":
+ case "KP_End":
+ highlight_x = game.size - 1;
+ break;
+ case "Page_Up":
+ case "KP_Page_Up":
+ 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
+ highlight_y = game.size - 1;
+ break;
+
+ // allow <Tab> and <Shift><Tab> to change focus
+ default:
+ return false;
+ }
+
+ if (key == "Escape")
+ show_highlight = false;
+ else if (show_highlight)
+ highlight_state = HIGHLIGHT_MAX;
+ else
+ show_highlight = true;
+
+ queue_draw (); // TODO is a queue_draw_area usable somehow here?
return true;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]