chiark / gitweb /
Keyboard control patch for Solo, from James H.
authorSimon Tatham <anakin@pobox.com>
Mon, 19 Jan 2009 18:38:29 +0000 (18:38 +0000)
committerSimon Tatham <anakin@pobox.com>
Mon, 19 Jan 2009 18:38:29 +0000 (18:38 +0000)
[originally from svn r8418]

puzzles.but
solo.c

index 5c605702d7481c8d548cdf68d18010ccff56654a..6b75d118603b198c69a95093e59c76f9a3e6c1f7 100644 (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
 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
 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
 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.)
 
 \H{solo-parameters} \I{parameters, for Solo}Solo parameters
diff --git a/solo.c b/solo.c
index 6ccf1adf668ba7bb461b391c664364ad28a18804..cde2930221aa8d0c0132effb07c480e409b1ad18 100644 (file)
--- a/solo.c
+++ b/solo.c
@@ -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);
                }
        }
-       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++)
            assert(state->blocks->blocknames[i]);
     }
@@ -3176,9 +3176,7 @@ static char *game_text_format(game_state *state)
 struct game_ui {
     /*
      * These are the coordinates of the currently highlighted
-     * square on the grid, or -1,-1 if there isn't one. When there
-     * is, pressing a valid number or letter key or Space will
-     * enter that number or letter in the grid.
+     * square on the grid, if hshow = 1.
      */
     int hx, hy;
     /*
@@ -3186,14 +3184,28 @@ struct game_ui {
      * pencil-mark one or a real one.
      */
     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)
 {
     game_ui *ui = snew(game_ui);
 
-    ui->hx = ui->hy = -1;
-    ui->hpencil = 0;
+    ui->hx = ui->hy = 0;
+    ui->hpencil = ui->hshow = ui->hcursor = 0;
 
     return ui;
 }
@@ -3217,14 +3229,14 @@ static void game_changed_state(game_ui *ui, game_state *oldstate,
 {
     int cr = newstate->cr;
     /*
-     * We prevent pencil-mode highlighting of a filled square. So
-     * if the user has just filled in a square which we had a
-     * pencil-mode highlight in (by Undo, or by Redo, or by Solve),
-     * then we cancel the highlight.
+     * We prevent pencil-mode highlighting of a filled square, unless
+     * we're using the cursor keys. So if the user has just filled in
+     * a square which we had a pencil-mode highlight in (by Undo, or
+     * 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) {
-        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 (button == LEFT_BUTTON) {
             if (state->immutable[ty*cr+tx]) {
-                ui->hx = ui->hy = -1;
-            } else if (tx == ui->hx && ty == ui->hy && ui->hpencil == 0) {
-                ui->hx = ui->hy = -1;
+                ui->hshow = 0;
+            } else if (tx == ui->hx && ty == ui->hy &&
+                       ui->hshow && ui->hpencil == 0) {
+                ui->hshow = 0;
             } else {
                 ui->hx = tx;
                 ui->hy = ty;
+                ui->hshow = 1;
                 ui->hpencil = 0;
             }
+            ui->hcursor = 0;
             return "";                /* UI activity occurred */
         }
         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.
              */
             if (state->grid[ty*cr+tx] == 0) {
-                if (tx == ui->hx && ty == ui->hy && ui->hpencil) {
-                    ui->hx = ui->hy = -1;
+                if (tx == ui->hx && ty == ui->hy &&
+                    ui->hshow && ui->hpencil) {
+                    ui->hshow = 0;
                 } else {
                     ui->hpencil = 1;
                     ui->hx = tx;
                     ui->hy = ty;
+                    ui->hshow = 1;
                 }
             } else {
-                ui->hx = ui->hy = -1;
+                ui->hshow = 0;
             }
+            ui->hcursor = 0;
             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 &&
-       ((button >= '1' && button <= '9' && button - '0' <= cr) ||
+    if (ui->hshow &&
+       ((button >= '0' && button <= '9' && button - '0' <= 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';
        if (button >= 'A' && button <= 'Z')
            n = button - 'A' + 10;
        if (button >= 'a' && button <= 'z')
            n = button - 'a' + 10;
-       if (button == ' ' || button == '\010' || button == '\177')
+       if (button == CURSOR_SELECT2 || button == '\010' || button == '\177')
            n = 0;
 
         /*
-         * Can't overwrite this square. In principle this shouldn't
-         * happen anyway because we should never have even been
-         * able to highlight the square, but it never hurts to be
-         * careful.
+         * Can't overwrite this square. This can only happen here
+         * if we're using the cursor keys.
          */
        if (state->immutable[ui->hy*cr+ui->hx])
            return NULL;
 
         /*
-         * Can't make pencil marks in a filled square. In principle
-         * this shouldn't happen anyway because we should never
-         * have even been able to pencil-highlight the square, but
-         * it never hurts to be careful.
+         * Can't make pencil marks in a filled square. Again, this
+         * can only become highlighted if we're using cursor keys.
          */
         if (ui->hpencil && state->grid[ui->hy*cr+ui->hx])
             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",
                (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);
     }
@@ -3651,7 +3676,7 @@ static void game_redraw(drawing *dr, game_drawstate *ds, game_state *oldstate,
                 highlight = 1;
 
             /* 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;
 
            /* 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.
      */
     game_compute_size(params, 900, &pw, &ph);
-    *x = pw / 100.0;
-    *y = ph / 100.0;
+    *x = pw / 100.0F;
+    *y = ph / 100.0F;
 }
 
 static void game_print(drawing *dr, game_state *state, int tilesize)
@@ -4026,3 +4051,5 @@ int main(int argc, char **argv)
 }
 
 #endif
+
+/* vim: set shiftwidth=4 tabstop=8: */