3static void selection_grid_process_directional_input(
SelectionGrid* selection_grid)
5 int horz_tri_input = bit_tribool(key_hit(KEY_ANY), KI_RIGHT, KI_LEFT);
7 if (horz_tri_input != 0)
16 int vert_tri_input = bit_tribool(key_hit(KEY_ANY), KI_DOWN, KI_UP);
18 if (vert_tri_input != 0)
26 if (selection_grid == NULL || selection_grid->selection.y < 0 ||
27 selection_grid->selection.y >= selection_grid->num_rows)
32 SelectionGridRow current_row = selection_grid->rows[selection_grid->selection.y];
35 Selection new_selection =
37 ? (Selection){selection_grid->selection.x, current_row.attributes.
h_exit_idx}
38 : selection_grid->selection;
40 new_selection.x += direction_tribool;
41 int row_size = selection_grid->rows[new_selection.y].get_size();
42 bool wrap_enabled = selection_grid->rows[new_selection.y].attributes.
wrap;
46 new_selection.x = wrap(new_selection.x, 0, row_size);
49 if (wrap_enabled || (new_selection.x >= 0 && new_selection.x < row_size))
51 bool proceed_selection =
52 selection_grid->rows[selection_grid->selection.y].on_selection_changed(
55 &selection_grid->selection,
59 if (proceed_selection)
61 selection_grid->selection = new_selection;
68 if (selection_grid == NULL)
71 Selection selection = selection_grid->selection;
72 Selection new_selection = selection;
73 new_selection.y += direction_tribool;
75 if (new_selection.y >= 0 && new_selection.y < selection_grid->num_rows)
77 int new_row_size = selection_grid->rows[new_selection.y].get_size();
78 if (new_row_size <= 0)
81 int old_row_size = selection_grid->rows[selection.y].get_size();
84 old_row_size += (old_row_size == 0);
88 new_selection.x = fx2int(selection.x * ((int2fx(new_row_size) / old_row_size)));
90 bool proceed_selection =
true;
92 if (selection.y >= 0 && selection.y < selection_grid->num_rows)
95 selection_grid->rows[selection.y]
96 .on_selection_changed(selection_grid, selection.y, &selection, &new_selection);
99 if (proceed_selection)
101 proceed_selection = selection_grid->rows[new_selection.y].on_selection_changed(
109 if (proceed_selection)
111 selection_grid->selection = new_selection;
118 if (selection_grid == NULL || selection_grid->rows == NULL)
121 selection_grid_process_directional_input(selection_grid);
123 u32 non_directional_key = KEY_ANY & ~KEY_DIR;
124 if (key_transit(non_directional_key))
127 Selection* selection = &selection_grid->selection;
128 if (selection_grid->rows[selection->y].on_key_transit != NULL)
130 selection_grid->rows[selection->y].on_key_transit(selection_grid, selection);
An implementation for a selection grid that handles directional selection.
void selection_grid_move_selection_vert(SelectionGrid *selection_grid, int direction_tribool)
Moves the selection vertically within the selection grid.
void selection_grid_move_selection_horz(SelectionGrid *selection_grid, int direction_tribool)
Moves the selection horizontally within the selection grid.
void selection_grid_process_input(SelectionGrid *selection_grid)
Processes user input for the selection grid.
bool has_h_exit_idx
Whether this row have a horizontal exit index (a row to process horizontal inputs from).
u8 h_exit_idx
The index of the row to exit from when a horizontal input is received.
bool wrap
Whether to wrap selection when it passes the end of the row.
The core selection grid struct, represents the grid itself and its state.