Keyboard control patch for Solo, from James H.

[originally from svn r8418]
This commit is contained in:
Simon Tatham
2009-01-19 18:38:29 +00:00
parent 4169a54831
commit f46eceb714
2 changed files with 69 additions and 35 deletions

View File

@ -942,7 +942,8 @@ Space to clear it again (or use the Undo feature).
If you \e{right}-click in a square and then type a number, that If you \e{right}-click in a square and then type a number, that
number will be entered in the square as a \q{pencil mark}. You can number will be entered in the square as a \q{pencil mark}. You can
have pencil marks for multiple numbers in the same square. have pencil marks for multiple numbers in the same square. Squares
containing filled-in numbers cannot also contain pencil marks.
The game pays no attention to pencil marks, so exactly what you use The game pays no attention to pencil marks, so exactly what you use
them for is up to you: you can use them as reminders that a them for is up to you: you can use them as reminders that a
@ -957,6 +958,12 @@ All pencil marks in a square are erased when you left-click and type
a number, or when you left-click and press space. Right-clicking and a number, or when you left-click and press space. Right-clicking and
pressing space will also erase pencil marks. pressing space will also erase pencil marks.
Alternatively, use the cursor keys to move the mark around the grid.
Pressing the return key toggles the mark (from a normal mark to a
pencil mark), and typing a number in is entered in the square in the
appropriate way; typing in a 0 or using the space bar will clear a
filled square.
(All the actions described in \k{common-actions} are also available.) (All the actions described in \k{common-actions} are also available.)
\H{solo-parameters} \I{parameters, for Solo}Solo parameters \H{solo-parameters} \I{parameters, for Solo}Solo parameters

95
solo.c
View File

@ -2886,7 +2886,7 @@ static game_state *new_game(midend *me, game_params *params, char *desc)
p += 1 + sprintf(p, "(%d,%d)", bx+1, by+1); p += 1 + sprintf(p, "(%d,%d)", bx+1, by+1);
} }
} }
assert(p - (char *)state->blocks->blocknames < cr*(sizeof(char *)+80)); assert(p - (char *)state->blocks->blocknames < (int)(cr*(sizeof(char *)+80)));
for (i = 0; i < cr; i++) for (i = 0; i < cr; i++)
assert(state->blocks->blocknames[i]); assert(state->blocks->blocknames[i]);
} }
@ -3176,9 +3176,7 @@ static char *game_text_format(game_state *state)
struct game_ui { struct game_ui {
/* /*
* These are the coordinates of the currently highlighted * These are the coordinates of the currently highlighted
* square on the grid, or -1,-1 if there isn't one. When there * square on the grid, if hshow = 1.
* is, pressing a valid number or letter key or Space will
* enter that number or letter in the grid.
*/ */
int hx, hy; int hx, hy;
/* /*
@ -3186,14 +3184,28 @@ struct game_ui {
* pencil-mark one or a real one. * pencil-mark one or a real one.
*/ */
int hpencil; int hpencil;
/*
* This indicates whether or not we're showing the highlight
* (used to be hx = hy = -1); important so that when we're
* using the cursor keys it doesn't keep coming back at a
* fixed position. When hshow = 1, pressing a valid number
* or letter key or Space will enter that number or letter in the grid.
*/
int hshow;
/*
* This indicates whether we're using the highlight as a cursor;
* it means that it doesn't vanish on a keypress, and that it is
* allowed on immutable squares.
*/
int hcursor;
}; };
static game_ui *new_ui(game_state *state) static game_ui *new_ui(game_state *state)
{ {
game_ui *ui = snew(game_ui); game_ui *ui = snew(game_ui);
ui->hx = ui->hy = -1; ui->hx = ui->hy = 0;
ui->hpencil = 0; ui->hpencil = ui->hshow = ui->hcursor = 0;
return ui; return ui;
} }
@ -3217,14 +3229,14 @@ static void game_changed_state(game_ui *ui, game_state *oldstate,
{ {
int cr = newstate->cr; int cr = newstate->cr;
/* /*
* We prevent pencil-mode highlighting of a filled square. So * We prevent pencil-mode highlighting of a filled square, unless
* if the user has just filled in a square which we had a * we're using the cursor keys. So if the user has just filled in
* pencil-mode highlight in (by Undo, or by Redo, or by Solve), * a square which we had a pencil-mode highlight in (by Undo, or
* then we cancel the highlight. * by Redo, or by Solve), then we cancel the highlight.
*/ */
if (ui->hx >= 0 && ui->hy >= 0 && ui->hpencil && if (ui->hshow && ui->hpencil && !ui->hcursor &&
newstate->grid[ui->hy * cr + ui->hx] != 0) { newstate->grid[ui->hy * cr + ui->hx] != 0) {
ui->hx = ui->hy = -1; ui->hshow = 0;
} }
} }
@ -3254,14 +3266,17 @@ static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
if (tx >= 0 && tx < cr && ty >= 0 && ty < cr) { if (tx >= 0 && tx < cr && ty >= 0 && ty < cr) {
if (button == LEFT_BUTTON) { if (button == LEFT_BUTTON) {
if (state->immutable[ty*cr+tx]) { if (state->immutable[ty*cr+tx]) {
ui->hx = ui->hy = -1; ui->hshow = 0;
} else if (tx == ui->hx && ty == ui->hy && ui->hpencil == 0) { } else if (tx == ui->hx && ty == ui->hy &&
ui->hx = ui->hy = -1; ui->hshow && ui->hpencil == 0) {
ui->hshow = 0;
} else { } else {
ui->hx = tx; ui->hx = tx;
ui->hy = ty; ui->hy = ty;
ui->hshow = 1;
ui->hpencil = 0; ui->hpencil = 0;
} }
ui->hcursor = 0;
return ""; /* UI activity occurred */ return ""; /* UI activity occurred */
} }
if (button == RIGHT_BUTTON) { if (button == RIGHT_BUTTON) {
@ -3269,47 +3284,57 @@ static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
* Pencil-mode highlighting for non filled squares. * Pencil-mode highlighting for non filled squares.
*/ */
if (state->grid[ty*cr+tx] == 0) { if (state->grid[ty*cr+tx] == 0) {
if (tx == ui->hx && ty == ui->hy && ui->hpencil) { if (tx == ui->hx && ty == ui->hy &&
ui->hx = ui->hy = -1; ui->hshow && ui->hpencil) {
ui->hshow = 0;
} else { } else {
ui->hpencil = 1; ui->hpencil = 1;
ui->hx = tx; ui->hx = tx;
ui->hy = ty; ui->hy = ty;
ui->hshow = 1;
} }
} else { } else {
ui->hx = ui->hy = -1; ui->hshow = 0;
} }
ui->hcursor = 0;
return ""; /* UI activity occurred */ return ""; /* UI activity occurred */
} }
} }
if (IS_CURSOR_MOVE(button)) {
move_cursor(button, &ui->hx, &ui->hy, cr, cr, 0);
ui->hshow = ui->hcursor = 1;
return "";
}
if (ui->hshow &&
(button == CURSOR_SELECT)) {
ui->hpencil = 1 - ui->hpencil;
ui->hcursor = 1;
return "";
}
if (ui->hx != -1 && ui->hy != -1 && if (ui->hshow &&
((button >= '1' && button <= '9' && button - '0' <= cr) || ((button >= '0' && button <= '9' && button - '0' <= cr) ||
(button >= 'a' && button <= 'z' && button - 'a' + 10 <= cr) || (button >= 'a' && button <= 'z' && button - 'a' + 10 <= cr) ||
(button >= 'A' && button <= 'Z' && button - 'A' + 10 <= cr) || (button >= 'A' && button <= 'Z' && button - 'A' + 10 <= cr) ||
button == ' ' || button == '\010' || button == '\177')) { button == CURSOR_SELECT2 || button == '\010' || button == '\177')) {
int n = button - '0'; int n = button - '0';
if (button >= 'A' && button <= 'Z') if (button >= 'A' && button <= 'Z')
n = button - 'A' + 10; n = button - 'A' + 10;
if (button >= 'a' && button <= 'z') if (button >= 'a' && button <= 'z')
n = button - 'a' + 10; n = button - 'a' + 10;
if (button == ' ' || button == '\010' || button == '\177') if (button == CURSOR_SELECT2 || button == '\010' || button == '\177')
n = 0; n = 0;
/* /*
* Can't overwrite this square. In principle this shouldn't * Can't overwrite this square. This can only happen here
* happen anyway because we should never have even been * if we're using the cursor keys.
* able to highlight the square, but it never hurts to be
* careful.
*/ */
if (state->immutable[ui->hy*cr+ui->hx]) if (state->immutable[ui->hy*cr+ui->hx])
return NULL; return NULL;
/* /*
* Can't make pencil marks in a filled square. In principle * Can't make pencil marks in a filled square. Again, this
* this shouldn't happen anyway because we should never * can only become highlighted if we're using cursor keys.
* have even been able to pencil-highlight the square, but
* it never hurts to be careful.
*/ */
if (ui->hpencil && state->grid[ui->hy*cr+ui->hx]) if (ui->hpencil && state->grid[ui->hy*cr+ui->hx])
return NULL; return NULL;
@ -3317,7 +3342,7 @@ static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
sprintf(buf, "%c%d,%d,%d", sprintf(buf, "%c%d,%d,%d",
(char)(ui->hpencil && n > 0 ? 'P' : 'R'), ui->hx, ui->hy, n); (char)(ui->hpencil && n > 0 ? 'P' : 'R'), ui->hx, ui->hy, n);
ui->hx = ui->hy = -1; if (!ui->hcursor) ui->hshow = 0;
return dupstr(buf); return dupstr(buf);
} }
@ -3651,7 +3676,7 @@ static void game_redraw(drawing *dr, game_drawstate *ds, game_state *oldstate,
highlight = 1; highlight = 1;
/* Highlight active input areas. */ /* Highlight active input areas. */
if (x == ui->hx && y == ui->hy) if (x == ui->hx && y == ui->hy && ui->hshow)
highlight = ui->hpencil ? 2 : 1; highlight = ui->hpencil ? 2 : 1;
/* Mark obvious errors (ie, numbers which occur more than once /* Mark obvious errors (ie, numbers which occur more than once
@ -3706,8 +3731,8 @@ static void game_print_size(game_params *params, float *x, float *y)
* of pencil marks in the squares. * of pencil marks in the squares.
*/ */
game_compute_size(params, 900, &pw, &ph); game_compute_size(params, 900, &pw, &ph);
*x = pw / 100.0; *x = pw / 100.0F;
*y = ph / 100.0; *y = ph / 100.0F;
} }
static void game_print(drawing *dr, game_state *state, int tilesize) static void game_print(drawing *dr, game_state *state, int tilesize)
@ -4026,3 +4051,5 @@ int main(int argc, char **argv)
} }
#endif #endif
/* vim: set shiftwidth=4 tabstop=8: */