GridState Modes refactor, take 2
Status: Implemented | Jan 2024 See also: xword-state-modes.md
Summary
Supplement the GridStateMode
enum with a set of distinct
behaviors. These behaviors can be set individually on a state.
This will make grid-state.c easier to understand and debug (and test), as well as let us create modes on demand later on.
Rationale
The current grid modes have been created on demand when we need a new grid type. The modes combine some rendering options, cursor behaviors, and thematic functionality all in one. They are hard to reason about, and have proven fragile and brittle over time.
Proposal
We decompose the current modes into a set of behaviors that are independently settable. The current modes are:
typedef enum
{
GRID_STATE_SOLVE, /* @ Solve a crossword @ */
GRID_STATE_BROWSE, /* @ Browse through a board without modifying it @ */
GRID_STATE_EDIT, /* @ Edit the grid @ */
GRID_STATE_EDIT_BROWSE, /* @ Browse through an editable board without modifying it @ */
GRID_STATE_SELECT, /* @ Select cells @ */
GRID_STATE_VIEW, /* @ Display a board with no interaction @ */
} GridStateMode;
The decomposition into behaviors looks like:
USE_CURSOR |
SHOW_GUESS |
SELECTABLE |
EDIT_CELLS |
NORMAL_ONLY |
QUIRKS_ADVANCE |
|
---|---|---|---|---|---|---|
SOLVE |
true |
true |
false |
true |
true |
true |
BROWSE |
true |
true |
false |
false |
true |
false |
EDIT |
true |
false |
false |
true |
false |
false |
EDIT_BROWSE |
true |
false |
false |
false |
true |
false |
SELECT |
true |
true |
true |
false |
true |
false |
VIEW |
false |
false |
false |
false |
false |
false |
Each behavior is described below:
USE_CURSOR: The state has a valid cursor
SHOW_GUESS: The grid displays the guess instead of the solution in a cell
SELECTABLE: The grid can select cells
EDIT_CELLS: The grid allows the user to edit the cel
NORMAL_ONLT: The grid only allows the cursor to exist on normal cells. BLOCK and NULL cells can’t have a cursor set
QUIRKS_ADVANCE: Whether to honor the quirks GuessAdvance setting when going to the next cell after a guess.
This set of booleans is represented by the GridState.behavior
bitfield. Setting the mode will set the bitfield to a well known
state.
Changing the behavior afterwards is possible. We will add a
GRID_STATE_CUSTOM
mode to capture when that has happened.
NOTE: Not all combinations of behaviors are valid. Some also interact, such as CURSOR_ONLY_NORMAL and SELECTABLE
Other Considerations
Selection may need multiple selection types (like GtkEditable, for instance.)
We also want an overlay mode for things like reveal errors, or heat maps. That might factor into this design.
Once we’ve validated the behavior bitfield and fully migrated, we may remove the mode attribute from the state in order to avoid confusion. We won’t go away completely from the modes, but just use them as a short-hand for setting well-known combinations of behaviors.