flow-website/content/docs/architecture/palette.smd
2025-11-03 22:56:17 +01:00

121 lines
No EOL
3.8 KiB
Text

---
.title = "Palettes",
.date = @date("2025-10-20T00:00:00"),
.author = "Igor Támara",
.layout = "tutorial.shtml",
.draft = false,
.custom = {
.githubedit = "docs/architecture/palette.smd",
.codepath ="src/tui/mode/overlay/clipboard_palette.zig",
},
---
Palettes are overlay menus with auto complete that allow to select an
item from the presented list, applying a command with the selected
element, optionally deleting the selected item; it's possible to
close the palette without selecting anything(a.k.a. cancel), filter
the elements, and having special elements that trigger different
actions, for example, the task palette.
Examples of palettes are `command_palette`, `clipboard_palette`, they
all are based on `src/tui/mode/overlay/palette.zig` doing all the heavy
lifting and sets the framework to create new palettes as simple as
possible.
Palettes are an special case of [minimode] and for instance a mode, they
receive inputs from the keyboard and execute the beforehand mentioned
actions in response.
To get the most of this section, it's recommended to have read about
[commands](/docs/architecture/command), and optionally,
[minimodes](/docs/architecture/minimode).
[]($section.id("anatomy"))
## Defining the palette
Palettes are under `tui/overlay` and use the facilities offered by
`palette.zig` to perform all the operations.
1. Defining the list of elements
2. Filtering the elements
3. Perform an action with the selected element
Note: Palettes are meant to show options and allowing to select the
options to execute an action on the given selection. To maintain as
readable as possible the code and thus extensible, the data to be used
should be prepared previously.
[]($section.id("basic"))
### Fields
Basic fields that give hints to the user and need to be set are:
```zig
pub const label = "Clipboard history";
pub const name = " clipboard";
pub const description = "clipboard";
pub const icon = " ";
```
[]($section.id("entries"))
### Defining the list of elements in the palette
`load_entries` is in charge of populating the visible entries, each one
with an index.
```zig
pub fn load_entries(palette: *Type) !usize
```
The index will identify the action to be taken.
When populating with each entry, there must be a relation that links the
option chosen with the required action, and this happens in
`add_menu_entry`.
```zig
pub fn add_menu_entry(palette: *Type, entry: *Entry, matches: ?[]const usize) !void {
```
The common line that will be used when registering the event to a
selected item is
```zig
try palette.menu.add_item_with_handler(value, select);
```
Which will apply the `select` function when the value is selected.
[]($section.id("select"))
### Acting on selection
When the selection happens, it is time to invoke the command with the
selection making sure to close the palette. Those actions will be
handled inside `select`, whose signature is:
```zig
fn select(menu: **Type.MenuType, button: *Type.ButtonType, pos: Type.Pos) void {
```
Other common operations in the palettes can be inspected looking at the
source code of the palettes, all of them import `palette.zig`. Once the
palette is ready, it's time to make the palette available as a command.
[]($section.id("register"))
## Registering the palette
Commands that open the palette are defined in `tui.zig` in a similar way
it is done with [minimodes](/docs/architecture/minimode). We have got
you covered if in doubt about
[how to create a command](/docs/architecture/command).
To view a complete implementation of a palette, take a look at
[clipboard history palette commit](https://github.com/neurocyte/flow/commit/634a18cb5685a3c3fcfc08301306e628d33c3256)
[]($section.id("next"))
## Next steps
* [Minimodes](/docs/architecture/minimode)
* [On commands](/docs/architecture/command)
* [Architecture](/docs/architecture)