From 93b1da3d0f613d616b930419354558365847bc7d Mon Sep 17 00:00:00 2001 From: simon Date: Tue, 31 May 2005 18:38:01 +0000 Subject: [PATCH] Better mouse button handling in Mines: - 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.) git-svn-id: svn://svn.tartarus.org/sgt/puzzles@5888 cda61777-01e9-0310-a592-d414129be87e --- cube.c | 1 + fifteen.c | 1 + midend.c | 16 ++++++++++++++++ mines.c | 19 +++++++++++-------- net.c | 1 + netslide.c | 1 + nullgame.c | 1 + pattern.c | 1 + puzzles.h | 4 ++++ rect.c | 1 + sixteen.c | 1 + solo.c | 1 + twiddle.c | 1 + 13 files changed, 41 insertions(+), 8 deletions(-) diff --git a/cube.c b/cube.c index 671918e..cb6a1f9 100644 --- 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 */ }; diff --git a/fifteen.c b/fifteen.c index 49a3118..6749093 100644 --- 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 */ }; diff --git a/midend.c b/midend.c index e71cd33..cde2729 100644 --- 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 d1ca4ff..fcf439d 100644 --- 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 40f68f9..5ef1ba7 100644 --- 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 */ }; diff --git a/netslide.c b/netslide.c index 86efb2f..5697b2f 100644 --- a/netslide.c +++ b/netslide.c @@ -1762,4 +1762,5 @@ const struct game thegame = { game_flash_length, game_wants_statusbar, FALSE, game_timing_state, + 0, /* mouse_priorities */ }; diff --git a/nullgame.c b/nullgame.c index 56694de..49173b6 100644 --- a/nullgame.c +++ b/nullgame.c @@ -254,4 +254,5 @@ const struct game thegame = { game_flash_length, game_wants_statusbar, FALSE, game_timing_state, + 0, /* mouse_priorities */ }; diff --git a/pattern.c b/pattern.c index 4cd3669..c7c06f1 100644 --- 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 diff --git a/puzzles.h b/puzzles.h index 7b35896..b8317ee 100644 --- 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 9e4204d..0eeb704 100644 --- 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 */ }; diff --git a/sixteen.c b/sixteen.c index c202de1..70abe13 100644 --- 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 f3afb02..563217a 100644 --- 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 diff --git a/twiddle.c b/twiddle.c index 66e8e95..66c4d8b 100644 --- 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 */ }; -- 2.11.0