chiark / gitweb /
Better mouse button handling in Mines:
authorSimon Tatham <anakin@pobox.com>
Tue, 31 May 2005 18:38:01 +0000 (18:38 +0000)
committerSimon Tatham <anakin@pobox.com>
Tue, 31 May 2005 18:38:01 +0000 (18:38 +0000)
 - middle button now also triggers the clear-around-square action
 - a special-case handler in midend_process_key() arranges that the
   left button always trumps the right button if both are pressed
   together, meaning that Windows Minesweeper players used to
   pressing L+R to clear around a square should still be able to do
   so without any strange behaviour.
(The latter touches all game backends, yet again, to add a field to
the game structure which is zero in everything except Mines.)

[originally from svn r5888]

13 files changed:
cube.c
fifteen.c
midend.c
mines.c
net.c
netslide.c
nullgame.c
pattern.c
puzzles.h
rect.c
sixteen.c
solo.c
twiddle.c

diff --git a/cube.c b/cube.c
index 671918e8cbb35a075ed1874c0daca1c4f7501f44..cb6a1f970c02cc61e26ef6712fd66ea4245f88e6 100644 (file)
--- a/cube.c
+++ b/cube.c
@@ -1645,4 +1645,5 @@ const struct game thegame = {
     game_flash_length,
     game_wants_statusbar,
     FALSE, game_timing_state,
+    0,                                /* mouse_priorities */
 };
index 49a31183dc8b18cd913476fe37ea8775de1e1dba..6749093c00807b072c5e6f58171ff7e1a290fca5 100644 (file)
--- a/fifteen.c
+++ b/fifteen.c
@@ -840,4 +840,5 @@ const struct game thegame = {
     game_flash_length,
     game_wants_statusbar,
     FALSE, game_timing_state,
+    0,                                /* mouse_priorities */
 };
index e71cd33f5ddc9d65b9d1977c038fd2cd6c6da36b..cde2729bf959d93bda162e582cdf80633de038ec 100644 (file)
--- a/midend.c
+++ b/midend.c
@@ -441,6 +441,14 @@ int midend_process_key(midend_data *me, int x, int y, int button)
      *    pressed, invent a button-up for the first one and then
      *    pass the button-down through as before.
      * 
+     * 2005-05-31: An addendum to the above. Some games might want
+     * a `priority order' among buttons, such that if one button is
+     * pressed while another is down then a fixed one of the
+     * buttons takes priority no matter what order they're pressed
+     * in. Mines, in particular, wants to treat a left+right click
+     * like a left click for the benefit of users of other
+     * implementations. So the last of the above points is modified
+     * in the presence of an (optional) button priority order.
      */
     if (IS_MOUSE_DRAG(button) || IS_MOUSE_RELEASE(button)) {
         if (me->pressed_mouse_button) {
@@ -454,6 +462,14 @@ int midend_process_key(midend_data *me, int x, int y, int button)
         } else
             return ret;                /* ignore it */
     } else if (IS_MOUSE_DOWN(button) && me->pressed_mouse_button) {
+       /*
+        * If the new button has lower priority than the old one,
+        * don't bother doing this.
+        */
+       if (me->ourgame->mouse_priorities &
+           BUTTON_BEATS(me->pressed_mouse_button, button))
+           return ret;                /* just ignore it */
+
         /*
          * Fabricate a button-up for the previously pressed button.
          */
diff --git a/mines.c b/mines.c
index d1ca4fffa8be0d11782e904137ae929effcce1a8..fcf439d6289e59d0dd732fc2f395865ac10b1d93 100644 (file)
--- a/mines.c
+++ b/mines.c
@@ -2457,7 +2457,8 @@ static game_state *make_move(game_state *from, game_ui *ui, game_drawstate *ds,
     if (cx < 0 || cx >= from->w || cy < 0 || cy > from->h)
        return NULL;
 
-    if (button == LEFT_BUTTON || button == LEFT_DRAG) {
+    if (button == LEFT_BUTTON || button == LEFT_DRAG ||
+       button == MIDDLE_BUTTON || button == MIDDLE_DRAG) {
        /*
         * Mouse-downs and mouse-drags just cause highlighting
         * updates.
@@ -2487,7 +2488,7 @@ static game_state *make_move(game_state *from, game_ui *ui, game_drawstate *ds,
        return ret;
     }
 
-    if (button == LEFT_RELEASE) {
+    if (button == LEFT_RELEASE || button == MIDDLE_RELEASE) {
        ui->hx = ui->hy = -1;
        ui->hradius = 0;
 
@@ -2501,8 +2502,9 @@ static game_state *make_move(game_state *from, game_ui *ui, game_drawstate *ds,
         * permitted if the tile is marked as a mine, for safety.
         * (Unmark it and _then_ open it.)
         */
-       if (from->grid[cy * from->w + cx] == -2 ||
-           from->grid[cy * from->w + cx] == -3) {
+       if (button == LEFT_RELEASE &&
+           (from->grid[cy * from->w + cx] == -2 ||
+            from->grid[cy * from->w + cx] == -3)) {
            ret = dup_game(from);
             ret->just_used_solve = FALSE;
            open_square(ret, cx, cy);
@@ -2512,10 +2514,10 @@ static game_state *make_move(game_state *from, game_ui *ui, game_drawstate *ds,
        }
 
        /*
-        * Left-clicking on an uncovered tile: first we check to see if
-        * the number of mine markers surrounding the tile is equal to
-        * its mine count, and if so then we open all other surrounding
-        * squares.
+        * Left-clicking or middle-clicking on an uncovered tile:
+        * first we check to see if the number of mine markers
+        * surrounding the tile is equal to its mine count, and if
+        * so then we open all other surrounding squares.
         */
        if (from->grid[cy * from->w + cx] > 0) {
            int dy, dx, n;
@@ -3006,4 +3008,5 @@ const struct game thegame = {
     game_flash_length,
     game_wants_statusbar,
     TRUE, game_timing_state,
+    BUTTON_BEATS(LEFT_BUTTON, RIGHT_BUTTON),
 };
diff --git a/net.c b/net.c
index 40f68f979cdfd70a638c346ee15b5ae7cf475709..5ef1ba77d97b2bed0f9c5b74f9541e61586f1365 100644 (file)
--- a/net.c
+++ b/net.c
@@ -2604,4 +2604,5 @@ const struct game thegame = {
     game_flash_length,
     game_wants_statusbar,
     FALSE, game_timing_state,
+    0,                                /* mouse_priorities */
 };
index 86efb2f8db9a3d0de53ad1b55e3735658b9850ae..5697b2ffaa9dcd0429799d0300ee188bc4a91803 100644 (file)
@@ -1762,4 +1762,5 @@ const struct game thegame = {
     game_flash_length,
     game_wants_statusbar,
     FALSE, game_timing_state,
+    0,                                /* mouse_priorities */
 };
index 56694de8dd3a0f9dba8e061ee87a4d78ca6fa784..49173b6d0c2fadd5025e33368d7e1421ecdfaea8 100644 (file)
@@ -254,4 +254,5 @@ const struct game thegame = {
     game_flash_length,
     game_wants_statusbar,
     FALSE, game_timing_state,
+    0,                                /* mouse_priorities */
 };
index 4cd366924b30a74cfe964e39dba735f443287f38..c7c06f141d5fd0091b36c45c1e4907475dcdbac6 100644 (file)
--- a/pattern.c
+++ b/pattern.c
@@ -1143,6 +1143,7 @@ const struct game thegame = {
     game_flash_length,
     game_wants_statusbar,
     FALSE, game_timing_state,
+    0,                                /* mouse_priorities */
 };
 
 #ifdef STANDALONE_SOLVER
index 7b35896860c41141b438fb98fff9a67f1a26dce7..b8317ee8da5654067426d2ce8c300caad64a2876 100644 (file)
--- a/puzzles.h
+++ b/puzzles.h
@@ -47,6 +47,9 @@ enum {
 #define IS_MOUSE_RELEASE(m) ( (unsigned)((m) - LEFT_RELEASE) <= \
                                (unsigned)(RIGHT_RELEASE - LEFT_RELEASE))
 
+/* Bit flags indicating mouse button priorities */
+#define BUTTON_BEATS(x,y) ( 1 << (((x)-LEFT_BUTTON)*3+(y)-LEFT_BUTTON) )
+
 #define IGNOREARG(x) ( (x) = (x) )
 
 typedef struct frontend frontend;
@@ -245,6 +248,7 @@ struct game {
     int (*wants_statusbar)(void);
     int is_timed;
     int (*timing_state)(game_state *state);
+    int mouse_priorities;
 };
 
 /*
diff --git a/rect.c b/rect.c
index 9e4204d46469fe8cb89acbe35f1e53ec531453e2..0eeb704502963252cd147d3e8821875458a95ff1 100644 (file)
--- a/rect.c
+++ b/rect.c
@@ -2553,4 +2553,5 @@ const struct game thegame = {
     game_flash_length,
     game_wants_statusbar,
     FALSE, game_timing_state,
+    0,                                /* mouse_priorities */
 };
index c202de1f129dfddb9aec946a87ec5298197cd21f..70abe13e0655e9b1bf115c6532e5dfab6ff54b65 100644 (file)
--- a/sixteen.c
+++ b/sixteen.c
@@ -1011,4 +1011,5 @@ const struct game thegame = {
     game_flash_length,
     game_wants_statusbar,
     FALSE, game_timing_state,
+    0,                                /* mouse_priorities */
 };
diff --git a/solo.c b/solo.c
index f3afb02cb687091ed425a316dcc721f42ec6e9bb..563217a93f554c331dab41be6ae8d1830bfaffeb 100644 (file)
--- a/solo.c
+++ b/solo.c
@@ -2179,6 +2179,7 @@ const struct game thegame = {
     game_flash_length,
     game_wants_statusbar,
     FALSE, game_timing_state,
+    0,                                /* mouse_priorities */
 };
 
 #ifdef STANDALONE_SOLVER
index 66e8e954086c4f8cfaf6442b3d056c9bd6fd3cc9..66c4d8b98b38723e72c4acaaefa7e39796c2b4cc 100644 (file)
--- a/twiddle.c
+++ b/twiddle.c
@@ -1179,4 +1179,5 @@ const struct game thegame = {
     game_flash_length,
     game_wants_statusbar,
     FALSE, game_timing_state,
+    0,                                /* mouse_priorities */
 };