Keyboard cursor support for Tents, from James H.

[originally from svn r8416]
This commit is contained in:
Simon Tatham
2009-01-16 18:50:22 +00:00
parent fa23fc3943
commit 28acb0ebdc
2 changed files with 73 additions and 6 deletions

View File

@ -2006,6 +2006,11 @@ blank square in the region you cover will be turned green, and no
other squares will be affected. (This is useful for clearing the other squares will be affected. (This is useful for clearing the
remainder of a row once you have placed all its tents.) remainder of a row once you have placed all its tents.)
You can also use the cursor keys to move around the grid. Pressing the
return key over an empty square will place a tent, and pressing the
space bar over an empty square will colour it green; either key will
clear an occupied square.
(All the actions described in \k{common-actions} are also available.) (All the actions described in \k{common-actions} are also available.)
\H{tents-parameters} \I{parameters, for Tents}Tents parameters \H{tents-parameters} \I{parameters, for Tents}Tents parameters

74
tents.c
View File

@ -1414,6 +1414,8 @@ struct game_ui {
int dex, dey; /* coords of drag end */ int dex, dey; /* coords of drag end */
int drag_button; /* -1 for none, or a button code */ int drag_button; /* -1 for none, or a button code */
int drag_ok; /* dragged off the window, to cancel */ int drag_ok; /* dragged off the window, to cancel */
int cx, cy, cdisp; /* cursor position, and ?display. */
}; };
static game_ui *new_ui(game_state *state) static game_ui *new_ui(game_state *state)
@ -1423,6 +1425,7 @@ static game_ui *new_ui(game_state *state)
ui->dex = ui->dey = -1; ui->dex = ui->dey = -1;
ui->drag_button = -1; ui->drag_button = -1;
ui->drag_ok = FALSE; ui->drag_ok = FALSE;
ui->cx = ui->cy = ui->cdisp = 0;
return ui; return ui;
} }
@ -1450,6 +1453,7 @@ struct game_drawstate {
int started; int started;
game_params p; game_params p;
char *drawn; char *drawn;
int cx, cy; /* last-drawn cursor pos, or (-1,-1) if absent. */
}; };
#define PREFERRED_TILESIZE 32 #define PREFERRED_TILESIZE 32
@ -1514,6 +1518,7 @@ static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
int x, int y, int button) int x, int y, int button)
{ {
int w = state->p.w, h = state->p.h; int w = state->p.w, h = state->p.h;
char tmpbuf[80];
if (button == LEFT_BUTTON || button == RIGHT_BUTTON) { if (button == LEFT_BUTTON || button == RIGHT_BUTTON) {
x = FROMCOORD(x); x = FROMCOORD(x);
@ -1525,13 +1530,14 @@ static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
ui->dsx = ui->dex = x; ui->dsx = ui->dex = x;
ui->dsy = ui->dey = y; ui->dsy = ui->dey = y;
ui->drag_ok = TRUE; ui->drag_ok = TRUE;
ui->cdisp = 0;
return ""; /* ui updated */ return ""; /* ui updated */
} }
if ((IS_MOUSE_DRAG(button) || IS_MOUSE_RELEASE(button)) && if ((IS_MOUSE_DRAG(button) || IS_MOUSE_RELEASE(button)) &&
ui->drag_button > 0) { ui->drag_button > 0) {
int xmin, ymin, xmax, ymax; int xmin, ymin, xmax, ymax;
char *buf, *sep, tmpbuf[80]; char *buf, *sep;
int buflen, bufsize, tmplen; int buflen, bufsize, tmplen;
x = FROMCOORD(x); x = FROMCOORD(x);
@ -1608,6 +1614,39 @@ static char *interpret_move(game_state *state, game_ui *ui, game_drawstate *ds,
} }
} }
if (IS_CURSOR_MOVE(button)) {
move_cursor(button, &ui->cx, &ui->cy, w, h, 0);
ui->cdisp = 1;
return "";
}
if (ui->cdisp) {
char rep = 0;
int v = state->grid[ui->cy*w+ui->cx];
if (v != TREE) {
#ifdef SINGLE_CURSOR_SELECT
if (button == CURSOR_SELECT)
/* SELECT cycles T, N, B */
rep = v == BLANK ? 'T' : v == TENT ? 'N' : 'B';
#else
if (button == CURSOR_SELECT)
rep = v == BLANK ? 'T' : 'B';
else if (button == CURSOR_SELECT2)
rep = v == BLANK ? 'N' : 'B';
else if (button == 'T' || button == 'N' || button == 'B')
rep = (char)button;
#endif
}
if (rep) {
sprintf(tmpbuf, "%c%d,%d", (int)rep, ui->cx, ui->cy);
return dupstr(tmpbuf);
}
} else if (IS_CURSOR_SELECT(button)) {
ui->cdisp = 1;
return "";
}
return NULL; return NULL;
} }
@ -1856,6 +1895,7 @@ static game_drawstate *game_new_drawstate(drawing *dr, game_state *state)
ds->p = state->p; /* structure copy */ ds->p = state->p; /* structure copy */
ds->drawn = snewn(w*h, char); ds->drawn = snewn(w*h, char);
memset(ds->drawn, MAGIC, w*h); memset(ds->drawn, MAGIC, w*h);
ds->cx = ds->cy = -1;
return ds; return ds;
} }
@ -1867,7 +1907,7 @@ static void game_free_drawstate(drawing *dr, game_drawstate *ds)
} }
static void draw_tile(drawing *dr, game_drawstate *ds, static void draw_tile(drawing *dr, game_drawstate *ds,
int x, int y, int v, int printing) int x, int y, int v, int cur, int printing)
{ {
int tx = COORD(x), ty = COORD(y); int tx = COORD(x), ty = COORD(y);
int cx = tx + TILESIZE/2, cy = ty + TILESIZE/2; int cx = tx + TILESIZE/2, cy = ty + TILESIZE/2;
@ -1911,6 +1951,12 @@ static void draw_tile(drawing *dr, game_drawstate *ds,
draw_polygon(dr, coords, 3, (printing ? -1 : COL_TENT), COL_TENT); draw_polygon(dr, coords, 3, (printing ? -1 : COL_TENT), COL_TENT);
} }
if (cur) {
int coff = TILESIZE/8;
draw_rect_outline(dr, tx + coff, ty + coff,
TILESIZE - coff*2, TILESIZE - coff*2, COL_GRID);
}
unclip(dr); unclip(dr);
draw_update(dr, tx+1, ty+1, TILESIZE-1, TILESIZE-1); draw_update(dr, tx+1, ty+1, TILESIZE-1, TILESIZE-1);
} }
@ -1924,6 +1970,13 @@ static void int_redraw(drawing *dr, game_drawstate *ds, game_state *oldstate,
{ {
int w = state->p.w, h = state->p.h; int w = state->p.w, h = state->p.h;
int x, y, flashing; int x, y, flashing;
int cx = -1, cy = -1;
int cmoved = 0;
if (ui) {
if (ui->cdisp) { cx = ui->cx; cy = ui->cy; }
if (cx != ds->cx || cy != ds->cy) cmoved = 1;
}
if (printing || !ds->started) { if (printing || !ds->started) {
if (!printing) { if (!printing) {
@ -1975,6 +2028,7 @@ static void int_redraw(drawing *dr, game_drawstate *ds, game_state *oldstate,
for (y = 0; y < h; y++) for (y = 0; y < h; y++)
for (x = 0; x < w; x++) { for (x = 0; x < w; x++) {
int v = state->grid[y*w+x]; int v = state->grid[y*w+x];
int credraw = 0;
/* /*
* We deliberately do not take drag_ok into account * We deliberately do not take drag_ok into account
@ -1988,12 +2042,18 @@ static void int_redraw(drawing *dr, game_drawstate *ds, game_state *oldstate,
if (flashing && (v == TREE || v == TENT)) if (flashing && (v == TREE || v == TENT))
v = NONTENT; v = NONTENT;
if (printing || ds->drawn[y*w+x] != v) { if (cmoved) {
draw_tile(dr, ds, x, y, v, printing); if ((x == cx && y == cy) ||
(x == ds->cx && y == ds->cy)) credraw = 1;
}
if (printing || ds->drawn[y*w+x] != v || credraw) {
draw_tile(dr, ds, x, y, v, (x == cx && y == cy), printing);
if (!printing) if (!printing)
ds->drawn[y*w+x] = v; ds->drawn[y*w+x] = v;
} }
} }
if (cmoved) { ds->cx = cx; ds->cy = cy; }
} }
static void game_redraw(drawing *dr, game_drawstate *ds, game_state *oldstate, static void game_redraw(drawing *dr, game_drawstate *ds, game_state *oldstate,
@ -2032,8 +2092,8 @@ static void game_print_size(game_params *params, float *x, float *y)
* I'll use 6mm squares by default. * I'll use 6mm squares by default.
*/ */
game_compute_size(params, 600, &pw, &ph); game_compute_size(params, 600, &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)
@ -2185,3 +2245,5 @@ int main(int argc, char **argv)
} }
#endif #endif
/* vim: set shiftwidth=4 tabstop=8: */