# Menu Driver - Core Data Structures

## Page State Types

A **page state**<span style="white-space: pre-wrap;"> is:</span>

> <span style="white-space: pre-wrap;">The </span>**persistent data container**<span style="white-space: pre-wrap;"> that represents everything a UI page needs to function between frames.</span>

Not just data. It’s:

- memory of what the user did
- memory of what was rendered
- memory of external data (diagnostics, etc.)

### List Page State

```c
typedef struct {
  uint8_t num_entries;
  uint8_t selected_index;
  uint8_t entry_ids[MAX_LIST_ENTRIES];
  const uint8_t (*entry_icons)[MENU_DRIVER_ICON_BYTE_SIZE];
  bool first_render;
} page_list_state;
```

#### Responsibilities:

- track selection
- map entries → page IDs
- hold icons
- manage first render optimization

### Overview Page State

<p class="callout danger">Todo :D</p>

### State Union

```c
typedef union {
  page_list_state list;
  page_overview_state overview;
} menu_page_state;
```

### Page Type

```c
typedef enum {
  MENU_PAGE_TYPE_LIST,
  MENU_PAGE_TYPE_OVERVIEW,
} menu_page_type_t;
```

Used to interpret the union correctly.

## Page Object

```c
typedef struct {
  menu_page_state *state;
  menu_page_type_t type;
  unsigned char id;
  unsigned char parent_id;
  bool needs_render;

  char name[MAX_PAGE_NAME_LEN];

  void (*init)(menu_page_state *);
  void (*update)(menu_manager_t *);
  void (*render)(menu_manager_t *);
  void (*destruct)(menu_page_state *);
} menu_page_t;
```

<p class="callout info"><span style="white-space: pre-wrap;">This is the </span>**core abstraction**.</p>

### Definition and Role

A page object represents one logical screen within the menu system. It encapsulates:

- the data required to represent the page (via its state)
- the functions required to manage its lifecycle
- metadata used for navigation and identification

This abstraction allows the menu system to treat all pages uniformly, regardless of their internal implementation or purpose.

### Important Fields

#### Render Control

```c
bool needs_render;
```

This flag indicates whether the page requires re-rendering.

It allows the system to avoid unnecessary redraw operations, which is critical in environments where display updates are expensive.

<span style="white-space: pre-wrap;">The responsibility for managing this flag lies with the </span>**page implementation**<span style="white-space: pre-wrap;">. </span>

### Lifecycle Function Pointers

Each page defines its own behavior through four function pointers:

#### Initialization

```c
void (*init)(menu_page_state *state);
```

Responsible for preparing the page state when the page becomes active.

Typical responsibilities include:

- resetting selection indices
- initializing flags
- preparing any required data structures

#### Update

```c
void (*update)(struct menu_manager_t *manager);
```

Handles input processing and state updates.

This function is expected to:

- read input through the manager
- modify internal state accordingly
- trigger page transitions if necessary

#### Render

```c
void (*render)(struct menu_manager_t *manager);
```

Responsible for drawing the page to the display.

This function should:

- read from the page state
- issue drawing commands via the display driver
- <span style="white-space: pre-wrap;">respect the </span>`<span class="editor-theme-code">needs_render</span>`<span style="white-space: pre-wrap;"> flag when applicable</span>

#### Destruction

```c
void (*destruct)(menu_page_state *state);
```

Handles cleanup when the page is no longer active.

In embedded systems, this typically involves:

- resetting state fields
- releasing logical ownership of resources

Dynamic memory cleanup is generally not required unless explicitly used.

## Menu Manager

```c
typedef struct {
  unsigned char active_page_id;
  const menu_page_t *pages;
  menu_input (*get_input)(void);
} menu_manager_t;
```

Responsibilities:

- track active page
- provide input access
- hold page table

Does NOT:

- validate anything
- own memory
- manage concurrency