aboutsummaryrefslogtreecommitdiff
path: root/filling.c
diff options
context:
space:
mode:
authorBen Harris <bjh21@bjh21.me.uk>2022-12-05 01:13:26 +0000
committerBen Harris <bjh21@bjh21.me.uk>2022-12-09 20:48:30 +0000
commita3310ab857f088489b35ebf10733ba284a24d27f (patch)
tree6ae25aaf1bfce3151fbe17e51c49ec12d0c74538 /filling.c
parent1d91522babe41fcf7cbfb06633ae6bc5606db367 (diff)
downloadpuzzles-a3310ab857f088489b35ebf10733ba284a24d27f.zip
puzzles-a3310ab857f088489b35ebf10733ba284a24d27f.tar.gz
puzzles-a3310ab857f088489b35ebf10733ba284a24d27f.tar.bz2
puzzles-a3310ab857f088489b35ebf10733ba284a24d27f.tar.xz
New backend function: current_key_label()
This provides a way for the front end to ask how a particular key should be labelled right now (specifically, for a given game_state and game_ui). This is useful on feature phones where it's conventional to put a small caption above each soft key indicating what it currently does. The function currently provides labels only for CURSOR_SELECT and CURSOR_SELECT2. This is because these are the only keys that need labelling on KaiOS. The concept of labelling keys also turns up in the request_keys() call, but there are quite a few differences. The labels returned by current_key_label() are dynamic and likely to vary with each move, while the labels provided by request_keys() are constant for a given game_params. Also, the keys returned by request_keys() don't generally include CURSOR_SELECT and CURSOR_SELECT2, because those aren't necessary on platforms with pointing devices. It might be possible to provide a unified API covering both of this, but I think it would be quite difficult to work with. Where a key is to be unlabelled, current_key_label() is expected to return an empty string. This leaves open the possibility of NULL indicating a fallback to button2label or the label specified by request_keys() in the future. It's tempting to try to implement current_key_label() by calling interpret_move() and parsing its output. This doesn't work for two reasons. One is that interpret_move() is entitled to modify the game_ui, and there isn't really a practical way to back those changes out. The other is that the information returned by interpret_move() isn't sufficient to generate a label. For instance, in many puzzles it generates moves that toggle the state of a square, but we want the label to reflect which state the square will be toggled to. The result is that I've generally ended up pulling bits of code from interpret_move() and execute_move() together to implement current_key_label(). Alongside the back-end function, there's a midend_current_key_label() that's a thin wrapper around the back-end function. It just adds an assertion about which key's being requested and a default null implementation so that back-ends can avoid defining the function if it will do nothing useful.
Diffstat (limited to 'filling.c')
-rw-r--r--filling.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/filling.c b/filling.c
index 4b96648..879e916 100644
--- a/filling.c
+++ b/filling.c
@@ -1429,6 +1429,23 @@ static void game_changed_state(game_ui *ui, const game_state *oldstate,
ui->keydragging = false;
}
+static const char *current_key_label(const game_ui *ui,
+ const game_state *state, int button)
+{
+ const int w = state->shared->params.w;
+
+ if (IS_CURSOR_SELECT(button) && ui->cur_visible) {
+ if (button == CURSOR_SELECT) {
+ if (ui->keydragging) return "Stop";
+ return "Multiselect";
+ }
+ if (button == CURSOR_SELECT2 &&
+ !state->shared->clues[w*ui->cur_y + ui->cur_x])
+ return (ui->sel[w*ui->cur_y + ui->cur_x]) ? "Deselect" : "Select";
+ }
+ return "";
+}
+
#define PREFERRED_TILE_SIZE 32
#define TILE_SIZE (ds->tilesize)
#define BORDER (TILE_SIZE / 2)
@@ -2166,6 +2183,7 @@ const struct game thegame = {
decode_ui,
game_request_keys,
game_changed_state,
+ current_key_label,
interpret_move,
execute_move,
PREFERRED_TILE_SIZE, game_compute_size, game_set_size,