blob: cb4176713005806fd9e445490f2fa5a85b25e1fa [file] [view]
Project: /youtube/cobalt/_project.yaml
Book: /youtube/cobalt/_book.yaml
# Starboard Module Reference: `ui_navigation.h`
API to allow applications to take advantage of the platform's native UI engine.
This is mainly to drive the animation of visual elements and to signal which of
those elements have focus. The implementation should not render any visual
elements; instead, it will be used to guide the app in where these elements
should be drawn.
When the application creates the user interface, it will create SbUiNavItems for
interactable elements. Additionally, the app must specify the position and size
of these navigation items. As the app's user interface changes, it will create
and destroy navigation items as appropriate.
For each render frame, the app will query the local transform for each
SbUiNavItem in case the native UI engine moves individual items in response to
user interaction. If the navigation item is a container, then the content offset
will also be queried to determine the placement of its content items.
## Macros
### kSbUiNavItemInvalid
Well-defined value for an invalid navigation item.
## Enums
### SbUiNavItemType
Navigation items may be one of the following types. This must be specified upon
item creation and may not change during the item's lifespan.
#### Values
* `kSbUiNavItemTypeFocus`
This is a single focusable item.
* `kSbUiNavItemTypeContainer`
This is a container of navigation items which can also be containers
themselves or focusable items. Containers themselves cannot be focused.
## Typedefs
### SbUiNavItem
An opaque handle to an implementation-private structure representing a
navigation item.
#### Definition
```
typedef struct SbUiNavItemPrivate* SbUiNavItem
```
## Structs
### SbUiNavCallbacks
This structure specifies all the callbacks which the platform UI engine should
invoke for various interaction events on navigation items. These callbacks may
be invoked from any thread at any frequency. The `callback_context` is the value
that was passed on creation of the relevant SbUiNavItem.
#### Members
* `void(*onblur)(SbUiNavItem item, void *callback_context)`
Invoke when an item has lost focus. This is only used with focus items.
* `void(*onfocus)(SbUiNavItem item, void *callback_context)`
Invoke when an item has gained focus. This is only used with focus items.
* `void(*onscroll)(SbUiNavItem item, void *callback_context)`
Invoke when an item's content offset is changed. This is only used with
container items.
### SbUiNavInterface
This structure declares the interface to the UI navigation implementation. All
function pointers must be specified if the platform supports UI navigation.
#### Members
* `SbUiNavItem(*create_item)(SbUiNavItemType type, const SbUiNavCallbacks
*callbacks, void *callback_context)`
Create a new navigation item. When the user interacts with this item the
appropriate SbUiNavCallbacks function will be invoked with the provided
`callback_context`. An item is not interactable until it is enabled.
* `void(*destroy_item)(SbUiNavItem item)`
Destroy the given navigation item. If this is a content of another item,
then it will first be unregistered. Additionally, if this item contains
other items, then those will be unregistered as well, but they will not be
automatically destroyed.
* `void(*set_focus)(SbUiNavItem item)`
This is used to manually force focus on a navigation item of type
kSbUiNavItemTypeFocus. Any previously focused navigation item should receive
the blur event. If the item is not transitively a content of the root item,
then this does nothing.
Specifying kSbUiNavItemInvalid should remove focus from the UI navigation
system.
* `void(*set_item_enabled)(SbUiNavItem item, bool enabled)`
This is used to enable or disable user interaction with the specified
navigation item. All navigation items are disabled when created, and they
must be explicitly enabled to allow user interaction. If a container is
disabled, then all of its contents are not interactable even though they
remain enabled. If `enabled` is false, it must be guaranteed that once this
function returns, no callbacks associated with this item will be invoked
until the item is re-enabled.
* `void(*set_item_dir)(SbUiNavItem item, SbUiNavItemDir dir)`
This specifies directionality for container items. Containers within
containers do not inherit directionality. Directionality must be specified
for each container explicitly.
This should work even if `item` is disabled.
* `void(*set_item_focus_duration)(SbUiNavItem item, float seconds)`
Set the minimum amount of time the focus item should remain focused once it
becomes focused. This may be used to make important focus items harder to
navigate over. Focus may still be moved before `seconds` has elapsed by
using the set_focus() function. By default, item focus duration is 0
seconds.
* `void(*set_item_size)(SbUiNavItem item, float width, float height)`
Set the interactable size of the specified navigation item. By default, an
item's size is (0,0).
* `void(*set_item_transform)(SbUiNavItem item, const SbUiNavMatrix2x3
*transform)`
Set the transform for the navigation item and its contents if the item is a
container. This specifies the placement of the item's center within its
container. The transform origin is the center of the item. Distance is
measured in pixels with the origin being the top-left of the item's
container. By default, an item's transform is identity.
* `bool(*get_item_focus_transform)(SbUiNavItem item, SbUiNavMatrix4
*out_transform)`
Retrieve the focus transform matrix for the navigation item. The UI engine
may translate, rotate, and/or tilt focus items to reflect user interaction.
This transform should be multiplied with the item's transform to get its
position inside its container. The transform origin is the center of the
item. Return false if the item position should not be changed (i.e. the
transform should be treated as identity).
* `bool(*get_item_focus_vector)(SbUiNavItem item, float *out_x, float *out_y)`
Retrieve a vector representing the focus location within a focused item.
This is used to provide feedback about user input that is too small to
result in a focus change. If there is no focus vector for the navigation
item, then return false and leave `out_x` and `out_y` unchanged. Otherwise,
return true and set the output values in the range of [-1, +1] with (out_x,
out_y) of (-1, -1) being the top-left corner of the navigation item and (0,
0) being the center.
* `void(*set_item_container_window)(SbUiNavItem item, SbWindow window)`
This attaches the given navigation item (which must be a container) to the
specified window. Navigation items are only interactable if they are
transitively attached to a window.
The native UI engine should never change this navigation item's content
offset. It is assumed to be used as a proxy for the system window.
A navigation item may only have a SbUiNavItem or SbWindow as its direct
container. The navigation item hierarchy is established using
set_item_container_item() with the root container attached to a SbWindow
using set_item_container_window() to enable interaction with all enabled
items in the hierarchy.
If `item` is already registered with a different window, then this will
unregister it from that window then attach it to the given `window`. It is
an error to register more than one navigation item with any given window. If
`window` is kSbWindowInvalid, then this will unregister the `item` from its
current window if any. Upon destruction of `item` or `window`, the `item` is
automatically unregistered from the `window`.
* `void(*set_item_container_item)(SbUiNavItem item, SbUiNavItem container)`
A container navigation item may contain other navigation items. However, it
is an error to have circular containment or for `container` to not be of
type kSbUiNavItemTypeContainer. If `item` already has a different container,
then this first serves that connection. If `container` is
kSbUiNavItemInvalid, then this removes `item` from its current container.
Upon destruction of `item` or `container`, the `item` is automatically
removed from the `container`.
The position of items within a container are specified relative to the
container's position. The position of these content items are further
modified by the container's "content offset".
For example, consider item A with position (5,5) and content offset (0,0).
Given item B with position (10,10) is registered as a content of item A.
1) Item B should be drawn at position (15,15).
2) If item A's content offset is changed to (10,0), then item B should be
drawn at position (5,15).
Essentially, content items should be drawn at: [container position] +
[content position] - [container content offset]
Content items may overlap within a container. This can cause obscured items
to be unfocusable. The only rule that needs to be followed is that contents
which are focus items can obscure other contents which are containers, but
not vice versa. The caller must ensure that content focus items do not
overlap other content focus items and content container items do not overlap
other content container items.
* `void(*set_item_content_offset)(SbUiNavItem item, float content_offset_x,
float content_offset_y)`
Set the current content offset for the given container. This may be used to
force scrolling to make certain content items visible. A container item's
content offset helps determine where its content items should be drawn.
Essentially, a content item should be drawn at: [container position] +
[content position] - [container content offset] If `item` is not a
container, then this does nothing. By default, the content offset is (0,0).
This should update the values returned by get_item_content_offset() even if
the `item` is disabled.
* `void(*get_item_content_offset)(SbUiNavItem item, float
*out_content_offset_x, float *out_content_offset_y)`
Retrieve the current content offset for the navigation item. If `item` is
not a container, then the content offset is (0,0).
The native UI engine should not change the content offset of a container
unless one of its contents (possibly recursively) is focused. This is to
allow seamlessly disabling then re-enabling focus items without having their
containers change offsets.
* `void(*do_batch_update)(void(*update_function)(void *), void *context)`
Call `update_function` with `context` to perform a series of UI navigation
changes atomically before returning.
### SbUiNavItemDir
Navigation items of type kSbUiNavItemTypeContainer have directionality. If
directionality is not specified for a container, it should default to left-to-
right and top-to-bottom.
```
/// For left-to-right, content offset x = 0 shows the leftmost content.
/// |<--Container Size-->|
/// +--------------------+--------------------+--------------------+
/// | Not selectable. | Selectable. | Selectable. |
/// | Offscreen. | Onscreen. | Offscreen. |
/// | Negative position. | Positive position. | Positive position. |
/// +--------------------+--------------------+--------------------+
/// ^
/// Content Offset X = 0.
///
/// For right-to-left, content offset x = 0 shows the rightmost content.
/// |<--Container Size-->|
/// +--------------------+--------------------+--------------------+
/// | Selectable. | Selectable. | Not selectable. |
/// | Offscreen. | Onscreen. | Offscreen. |
/// | Negative position. | Positive position. | Positive position. |
/// +--------------------+--------------------+--------------------+
/// ^
/// Content Offset X = 0.
```
```
Top-to-bottom is similar to left-to-right, but for the Y position.
Bottom-to-top is similar to right-to-left, but for the Y position.
```
#### Members
* `bool is_left_to_right`
* `bool is_top_to_bottom`
### SbUiNavMatrix2x3
This represents a 2x3 transform matrix in row-major order.
```
/// | a b tx |
/// | c d ty |
```
#### Members
* `float m`
### SbUiNavMatrix4
This represents a 4x4 transform matrix in row-major order.
#### Members
* `float m`
## Functions
### SbUiNavGetInterface
Retrieve the platform's UI navigation implementation. If the platform does not
provide one, then return false without modifying `out_interface`. Otherwise,
initialize all members of `out_interface` and return true. The `out_interface`
pointer must not be NULL.
#### Declaration
```
bool SbUiNavGetInterface(SbUiNavInterface *out_interface)
```
### SbUiNavItemIsValid
Returns whether the given navigation item handle is valid.
#### Declaration
```
static bool SbUiNavItemIsValid(SbUiNavItem item)
```