Expand keyboard input options in Bridges, for faster entry.

- Lay bridges (crosess) with Control-arrow (Shift-arrow)
- Jump (non-orthogonally) to nearby islands with number keys, a..f
- Mark islands as done with a single tap on the space bar
This commit is contained in:
Jonas Kölker
2015-10-05 17:59:39 +02:00
committed by Simon Tatham
parent 96b6f55ec8
commit f7eb186184
2 changed files with 65 additions and 6 deletions

View File

@ -2333,6 +2333,8 @@ static char *interpret_move(const game_state *state, game_ui *ui,
int gx = FROMCOORD(x), gy = FROMCOORD(y); int gx = FROMCOORD(x), gy = FROMCOORD(y);
char buf[80], *ret; char buf[80], *ret;
grid_type ggrid = INGRID(state,gx,gy) ? GRID(state,gx,gy) : 0; grid_type ggrid = INGRID(state,gx,gy) ? GRID(state,gx,gy) : 0;
int shift = button & MOD_SHFT, control = button & MOD_CTRL;
button &= ~MOD_MASK;
if (button == LEFT_BUTTON || button == RIGHT_BUTTON) { if (button == LEFT_BUTTON || button == RIGHT_BUTTON) {
if (!INGRID(state, gx, gy)) return NULL; if (!INGRID(state, gx, gy)) return NULL;
@ -2372,6 +2374,12 @@ static char *interpret_move(const game_state *state, game_ui *ui,
return ret; return ret;
} else if (IS_CURSOR_MOVE(button)) { } else if (IS_CURSOR_MOVE(button)) {
ui->cur_visible = 1; ui->cur_visible = 1;
if (control || shift) {
ui->dragx_src = ui->cur_x;
ui->dragy_src = ui->cur_y;
ui->dragging = TRUE;
ui->drag_is_noline = !control;
}
if (ui->dragging) { if (ui->dragging) {
int nx = ui->cur_x, ny = ui->cur_y; int nx = ui->cur_x, ny = ui->cur_y;
@ -2441,7 +2449,7 @@ found:
ui->cur_visible = 1; ui->cur_visible = 1;
return ""; return "";
} }
if (ui->dragging) { if (ui->dragging || button == CURSOR_SELECT2) {
ui_cancel_drag(ui); ui_cancel_drag(ui);
if (ui->dragx_dst == -1 && ui->dragy_dst == -1) { if (ui->dragx_dst == -1 && ui->dragy_dst == -1) {
sprintf(buf, "M%d,%d", ui->cur_x, ui->cur_y); sprintf(buf, "M%d,%d", ui->cur_x, ui->cur_y);
@ -2459,6 +2467,51 @@ found:
return ""; return "";
} }
} }
} else if ((button >= '0' && button <= '9') ||
(button >= 'a' && button <= 'f') ||
(button >= 'A' && button <= 'F')) {
/* jump to island with .count == number closest to cur_{x,y} */
int best_x = -1, best_y = -1, best_sqdist = -1, number = -1, i;
if (button >= '0' && button <= '9')
number = (button == '0' ? 16 : button - '0');
else if (button >= 'a' && button <= 'f')
number = 10 + button - 'a';
else if (button >= 'A' && button <= 'F')
number = 10 + button - 'A';
if (!ui->cur_visible) {
ui->cur_visible = 1;
return "";
}
for (i = 0; i < state->n_islands; ++i) {
int x = state->islands[i].x, y = state->islands[i].y;
int dx = x - ui->cur_x, dy = y - ui->cur_y;
int sqdist = dx*dx + dy*dy;
if (state->islands[i].count != number)
continue;
if (x == ui->cur_x && y == ui->cur_y)
continue;
/* new_game() reads the islands in row-major order, so by
* breaking ties in favor of `first in state->islands' we
* also break ties by `lexicographically smallest (y, x)'.
* Thus, there's a stable pattern to how ties are broken
* which the user can learn and use to navigate faster. */
if (best_sqdist == -1 || sqdist < best_sqdist) {
best_x = x;
best_y = y;
best_sqdist = sqdist;
}
}
if (best_x != -1 && best_y != -1) {
ui->cur_x = best_x;
ui->cur_y = best_y;
return "";
} else
return NULL;
} else if (button == 'g' || button == 'G') { } else if (button == 'g' || button == 'G') {
ui->show_hints = 1 - ui->show_hints; ui->show_hints = 1 - ui->show_hints;
return ""; return "";

View File

@ -2193,12 +2193,18 @@ it and restore your ability to modify it.
You can also use the cursor keys to move around the grid: if possible You can also use the cursor keys to move around the grid: if possible
the cursor will always move orthogonally, otherwise it will move the cursor will always move orthogonally, otherwise it will move
towards the nearest island to the indicated direction. Pressing the towards the nearest island to the indicated direction. Holding Control
return key followed by a cursor key will lay a bridge in that direction and pressing a cursor key will lay a bridge in that direction (if
(if available); pressing the space bar followed by a cursor key will available); Shift and a cursor key will lay a \q{non-bridge} marker.
lay a \q{non-bridge} marker. Pressing the return key followed by a cursor key will also lay a
bridge in that direction.
You can mark an island as finished by pressing the return key twice. You can mark an island as finished by pressing the space bar or by
pressing the return key twice.
By pressing a number key, you can jump to the nearest island with that
number. Letters \q{a}, ..., \q{f} count as 10, ..., 15 and \q{0} as
16.
Violations of the puzzle rules will be marked in red: Violations of the puzzle rules will be marked in red: