# toolbar.h ## Overview
Toolbars are things that can be docked around the edges of a rect, or float freely within the rect. The latter mode of operation is referred to as an *overlay* toolbar. The overlay toolbar can still render in the same way as a docked toolbar (as a thin menu of buttons), or display itself in a *widget* mode, which means a bigger, richer control, similar to a window. If you wish to use custom toolbars within a The Machinery tab, you do not need to use anything within `tm_toolbar_api`. The docking system will ask your tab for a list of toolbars to draw each frame. See see `tm_tab_vt->toolbars()`. **How to use toolbars outside of The Machinery tabs** Create a state struct using `tm_toolbar_api->create_state()`. This is a persistent state struct that will store the positions and drawing modes of the the toolbars between frames. You have to manually destroy it using `destroy_state()` when the thing within which you draw toolbars is ceases to exist. `tm_toolbar_api->ui()` can then be used to draw toolbars. Define your toolbars using `tm_toolbar_i` objects and, each frame, send a list of those into `ui()`. It will internally track state for the toolbars. Make sure that each `tm_toolbar_i` has a unique ID. The pointer to each `tm_toolbar_i` is not saved, it just uses the ID. So if you want, you can functionally generate the `tm_toolbar_i` objects. If a `tm_toolbar_i` object is removed from the list fed to `ui()`, then it is seen as removed and thus destroyed from the internal state. However, some state is saved in The Truth (see `enum TM_TT_PROP__TOOLBAR_SETTINGS`), so if you later add a `tm_toolbar_i` with a previously used ID back, it will fetch the saved state from The Truth.
## Index
`TM_TT_TYPE__TOOLBAR_SETTINGS`
`enum TM_TT_PROP__TOOLBAR_SETTINGS`
`enum tm_toolbar_container`
`enum tm_toolbar_anchor`
`enum tm_toolbar_flags`
`enum tm_toolbar_draw_mode`

`struct tm_toolbar_i`
`id`
`owner`
`display_name()`
`ui()`
`close()`
`custom_settings()`
`default_container`
`default_anchor`
`tool_ids`
`num_tool_ids`
`flags`
`overlay_default_size`
`fill_min_size`
`draw_mode_mask`

`tm_toolbar_rect_split_off()`
`tm_toolbar_rect_advance()`
`tm_toolbars_state_o`
`TM_TOOLBAR_API_NAME`

`struct tm_toolbar_api`
`create_state()`
`destroy_state()`
`calculate_rect()`
`ui()`

## API
### `TM_TT_TYPE__TOOLBAR_SETTINGS`
~~~c #define TM_TT_TYPE__TOOLBAR_SETTINGS "tm_toolbar_settings" #define TM_TT_TYPE_HASH__TOOLBAR_SETTINGS TM_STATIC_HASH("tm_toolbar_settings", 0xe4839373f4cd97c1ULL) ~~~
### `enum TM_TT_PROP__TOOLBAR_SETTINGS`
~~~c enum { TM_TT_PROP__TOOLBAR_SETTINGS__ID = 0, // uint64_t TM_TT_PROP__TOOLBAR_SETTINGS__CONTAINER, // uint32_t TM_TT_PROP__TOOLBAR_SETTINGS__ANCHOR, // uint32_t TM_TT_PROP__TOOLBAR_SETTINGS__ANCHOR_ORDER, // uint32_t TM_TT_PROP__TOOLBAR_SETTINGS__POSITION_X, // float TM_TT_PROP__TOOLBAR_SETTINGS__POSITION_Y, // float // Only used for overlay toolbars TM_TT_PROP__TOOLBAR_SETTINGS__WIDTH, // float TM_TT_PROP__TOOLBAR_SETTINGS__HEIGHT, // float TM_TT_PROP__TOOLBAR_SETTINGS__DRAW_MODE, // uint32_t (enum tm_toolbar_draw_mode) }; ~~~
### `enum tm_toolbar_container`
~~~c enum tm_toolbar_container { TM_TOOLBAR_CONTAINER_TOP, TM_TOOLBAR_CONTAINER_BOTTOM, TM_TOOLBAR_CONTAINER_LEFT, TM_TOOLBAR_CONTAINER_RIGHT, TM_TOOLBAR_CONTAINER_OVERLAY, TM_TOOLBAR_CONTAINER_COUNT, }; ~~~
### `enum tm_toolbar_anchor`
A toolbar anchor is a point inside a container to which the toolbar *sticks*, these are usually the beginning and end points of vertical and horizontal containers (those that appear around the edge of the rect). ~~~c enum tm_toolbar_anchor { TM_TOOLBAR_ANCHOR_NONE, TM_TOOLBAR_ANCHOR_END, TM_TOOLBAR_ANCHOR_BEGINNING, }; ~~~
### `enum tm_toolbar_flags`
~~~c enum tm_toolbar_flags { // Applies only to non-overlay toolbars. Fill the space up to the next toolbar. TM_TOOLBAR_FLAG_FILL = 1, // Applies only to overlays. Makes it resizeable in the X direction. TM_TOOLBAR_FLAG_OVERLAY_RESIZE_X = 2, // Applies only to overlays. Makes it resizeable in the Y direction. TM_TOOLBAR_FLAG_OVERLAY_RESIZE_Y = 4, // Only applies to non-overlay toolbars. The toolbar will, when being added for the first time, // spawn at the anchor rather than next to anything already anchored. TM_TOOLBAR_FLAG_FORCE_ANCHOR = 8, }; ~~~
### `enum tm_toolbar_draw_mode`
~~~c enum tm_toolbar_draw_mode { TM_TOOLBAR_DRAW_MODE_HORIZONTAL = 1, TM_TOOLBAR_DRAW_MODE_VERTICAL = 2, TM_TOOLBAR_DRAW_MODE_WIDGET = 4, TM_TOOLBAR_DRAW_MODE_ALL = 7, }; ~~~
### `struct tm_toolbar_i`
Defines a toolbar to be drawn within a tab. For each frame, pass a list of these into `ui()` of `tm_toolbar_api`. *Make sure that the `id` ID is unique* #### `id` ~~~c uint64_t id; ~~~ An application-wide unique ID for the toolbar. Cannot be zero. #### `owner` ~~~c void *owner; ~~~ A pointer that can be accessed through the `toolbar` argument to the functions of this struct. Often used to store state for the toolbar, for example if you drawing toolbars inside a tab then you might want to store a pointer to that tab here. #### `display_name()` ~~~c const char *(*display_name)(struct tm_toolbar_i *toolbar); ~~~ Optional. Returns a name used when referring to the toolbar in the UI. #### `ui()` ~~~c tm_rect_t (*ui)(struct tm_toolbar_i *toolbar, struct tm_ui_o *ui, const struct tm_ui_style_t *uistyle, tm_rect_t toolbar_r, enum tm_toolbar_draw_mode draw_mode); ~~~ Called when `ui()` of `tm_toolbar_api` wants to draw the toolbar. Make sure to respect `draw_mode` and return the rect that encompasses all the drawn controls. For toolbars inside horizontal and vertical containers, you can use `tm_toolbar_rect_split_off()` and `tm_toolbar_rect_advance()` to easily manage the rect sizes while drawing your toolbar. If you need to store state, the make sure to set `owner` when you create the `tm_toolbar_i` object and get it from the passed `toolbar` pointer. #### `close()` ~~~c void (*close)(struct tm_toolbar_i *toolbar); ~~~ Optional. If set, a close button will be shown in the corner of the toolbar when in overlay mode. The callback will have to implement the actual close operation itself, i.e. in some way make sure that the `tm_toolbar_i` object isn't fed to `ui()` of `tm_toolbar_api` the next frame. #### `custom_settings()` ~~~c void (*custom_settings)(struct tm_toolbar_i *toolbar, struct tm_ui_o *tm_ui_o); ~~~ Optional. Will add a settings button to any toolbar that is in overlay mode. The callback is free to do whatever it wants, it could for example focus a settings object in the property panel. #### `default_container` ~~~c enum tm_toolbar_container default_container; ~~~ The container in which the toolbar should be created if it doesn't already exist. #### `default_anchor` ~~~c enum tm_toolbar_anchor default_anchor; ~~~ If non-zero, the toolbar will started anchored. You can for example use this to make the toolbar stick to the right-hand side of a horizontal toolbar. #### `tool_ids` ~~~c const tm_strhash_t *tool_ids; ~~~ A list of the tool IDs available in this toolbar. The purpose of this is to make it possible for the tab to enumerate all the available tools. That way, if the currently selected tool is not available in any toolbar, we can switch to a default tool. #### `num_tool_ids` ~~~c uint32_t num_tool_ids; ~~~ #### `flags` ~~~c uint32_t flags; ~~~ Flags for misc. settings, set to a combination of `enum tm_toolbar_flags`. #### `overlay_default_size` ~~~c tm_vec2_t overlay_default_size; ~~~ The default size to use in overlay mode. #### `fill_min_size` ~~~c float fill_min_size; ~~~ The minimum size the toolbar must have when size_mode is FILL. Only applies to non-overlay toolbars. #### `draw_mode_mask` ~~~c uint32_t draw_mode_mask; ~~~ A combination of supported draw modes, ORed together values of `enum tm_toolbar_draw_mode`. The `ui` function will be passed the currently used draw mode and is expected to handle it.
### `tm_toolbar_rect_split_off()`
~~~c static inline tm_rect_t tm_toolbar_rect_split_off(tm_rect_t *r, float w, float h, float margin, enum tm_toolbar_draw_mode draw_mode) ~~~ Like tm_rect_split_off_left and tm_rect_split_off_top, but acts accordingly to `draw_mode`. Used to split off space from the toolbar's rect. The user can pass different values for w and h, because they might want to split off different sizes depending on `draw_mode`. Does nothing for overlay toolbars displayed as widgets.
### `tm_toolbar_rect_advance()`
~~~c static inline void tm_toolbar_rect_advance(tm_rect_t *r, const tm_rect_t to_remove, float margin, enum tm_toolbar_draw_mode draw_mode) ~~~ For removing the width / height of `to_remove` from the beginning or `r`. Will remove in the direction dictated by `draw_mode`. Does nothing for overlay toolbars displayed as widgets.
### `tm_toolbars_state_o`
~~~c typedef struct tm_toolbars_state_o tm_toolbars_state_o; ~~~
### `TM_TOOLBAR_API_NAME`
~~~c #define TM_TOOLBAR_API_NAME "tm_toolbar_api" ~~~
### `struct tm_toolbar_api`
#### `create_state()` ~~~c tm_toolbars_state_o *(*create_state)(struct tm_allocator_i *allocator); ~~~ If you wish to use toolbars within a tab in The Machinery, then the docking system will call this automatically for you. Creates a persistent state struct that will store the state of each toolbar. The return value should be stored and passed to `ui()` each frame. Make sure to call `destroy_state()` when whatever context that is drawing toolbars is destroyed. For example, when drawing toolbars for a tab, call this once when creating each tab and then store the return `tm_toolbars_state_o` value along with the tab. Make sure to run `destroy_state()` when the tab is destroyed. For each frame that you want to draw toolbars within your tab, call `ui()` and pass the `tm_toolbars_state_o` to it. #### `destroy_state()` ~~~c void (*destroy_state)(tm_toolbars_state_o *state); ~~~ If you wish to use toolbars within a tab in The Machinery, then the docking system will call this automatically for you. #### `calculate_rect()` ~~~c tm_rect_t (*calculate_rect)(const tm_toolbars_state_o *state, struct tm_ui_o *ui, tm_rect_t full_rect); ~~~ Given `full_rect` a new rect is returned with the area covered by toolbar containers subtracted. #### `ui()` ~~~c void (*ui)(tm_toolbar_i *toolbars, uint32_t num_toolbars, tm_toolbars_state_o *state, struct tm_ui_o *ui, const struct tm_ui_style_t *uistyle, tm_rect_t full_rect, struct tm_the_truth_o *settings_tt, tm_tt_id_t settings_obj); ~~~ Draws all the supplied toolbars and stores the state inside `state`. `full_rect` should be the full rect that the owner of the toolbar draws into, _not_ the return value of `calculate_rect`. In the case of The Machinery tabs, this function is automatically run by the docking system, it will be fed the tabs that are returned by `toolbars` of `tm_tab_vt`, see `docking.h`.