# Pebble Developer Documentation: /docs/c/ SDK 4.33.1. 80 pages. Index: https://developer.repebble.com/llms.txt # AccelerometerService Source: https://developer.repebble.com/docs/c/Foundation/Event_Service/AccelerometerService/ Using the Pebble accelerometer The AccelerometerService enables the Pebble accelerometer to detect taps, perform measures at a given frequency, and transmit samples in batches to save CPU time and processing. For available code samples, see the [feature-accel-discs](https://github.com/pebble-examples/feature-accel-discs/) example app. ## Function Documentation int accel\_service\_peek([AccelData](https://developer.repebble.com/docs/c/Foundation/Event_Service/AccelerometerService.md#AccelData) \* data) Peek at the last recorded reading. ##### Note Cannot be used when subscribed to accelerometer data events. #### Parameters data (out) a pointer to a pre-allocated [AccelData](https://developer.repebble.com/docs/c/Foundation/Event_Service/AccelerometerService.md#AccelData) item #### Returns -1 if the accel is not running -2 if subscribed to accelerometer events. int accel\_service\_set\_sampling\_rate([AccelSamplingRate](https://developer.repebble.com/docs/c/Foundation/Event_Service/AccelerometerService.md#AccelSamplingRate) rate) Change the accelerometer sampling rate. #### Parameters rate The sampling rate in Hz (10Hz, 25Hz, 50Hz, and 100Hz possible) int accel\_service\_set\_samples\_per\_update([uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) num\_samples) Change the number of samples buffered between each accelerometer data event. #### Parameters num\_samples the number of samples to buffer, between 0 and 25. void accel\_data\_service\_subscribe([uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) samples\_per\_update, [AccelDataHandler](https://developer.repebble.com/docs/c/Foundation/Event_Service/AccelerometerService.md#AccelDataHandler) handler) Subscribe to the accelerometer data event service. Once subscribed, the handler gets called every time there are new accelerometer samples available. ##### Note Cannot use [accel\_service\_peek()](https://developer.repebble.com/docs/c/Foundation/Event_Service/AccelerometerService.md#accel_service_peek) when subscribed to accelerometer data events. #### Parameters handler A callback to be executed on accelerometer data events samples\_per\_update the number of samples to buffer, between 0 and 25. void accel\_data\_service\_unsubscribe(void) Unsubscribe from the accelerometer data event service. Once unsubscribed, the previously registered handler will no longer be called. void accel\_tap\_service\_subscribe([AccelTapHandler](https://developer.repebble.com/docs/c/Foundation/Event_Service/AccelerometerService.md#AccelTapHandler) handler) Subscribe to the accelerometer tap event service. Once subscribed, the handler gets called on every tap event emitted by the accelerometer. #### Parameters handler A callback to be executed on tap event void accel\_tap\_service\_unsubscribe(void) Unsubscribe from the accelerometer tap event service. Once unsubscribed, the previously registered handler will no longer be called. void accel\_raw\_data\_service\_subscribe([uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) samples\_per\_update, [AccelRawDataHandler](https://developer.repebble.com/docs/c/Foundation/Event_Service/AccelerometerService.md#AccelRawDataHandler) handler) Subscribe to the accelerometer raw data event service. Once subscribed, the handler gets called every time there are new accelerometer samples available. ##### Note Cannot use [accel\_service\_peek()](https://developer.repebble.com/docs/c/Foundation/Event_Service/AccelerometerService.md#accel_service_peek) when subscribed to accelerometer data events. #### Parameters handler A callback to be executed on accelerometer data events samples\_per\_update the number of samples to buffer, between 0 and 25. ## Data Structure Documentation struct AccelData A single accelerometer sample for all three axes including timestamp and vibration rumble status. #### Data Fields int16\_t x acceleration along the x axis int16\_t y acceleration along the y axis int16\_t z acceleration along the z axis bool did\_vibrate true if the watch vibrated when this sample was collected uint64\_t timestamp timestamp, in milliseconds struct AccelRawData A single accelerometer sample for all three axes. #### Data Fields int16\_t x acceleration along the x axis int16\_t y acceleration along the y axis int16\_t z acceleration along the z axis ## Enum Documentation enum AccelAxisType Enumerated values defining the three accelerometer axes. #### Enumerators ACCEL\_AXIS\_X Accelerometer's X axis. The positive direction along the X axis goes toward the right of the watch. ACCEL\_AXIS\_Y Accelerometer's Y axis. The positive direction along the Y axis goes toward the top of the watch. ACCEL\_AXIS\_Z Accelerometer's Z axis. The positive direction along the Z axis goes vertically out of the watchface. enum AccelSamplingRate Valid accelerometer sampling rates, in Hz. #### Enumerators ACCEL\_SAMPLING\_10HZ 10 HZ sampling rate ACCEL\_SAMPLING\_25HZ 25 HZ sampling rate [Default] ACCEL\_SAMPLING\_50HZ 50 HZ sampling rate ACCEL\_SAMPLING\_100HZ 100 HZ sampling rate ## Typedef Documentation typedef void(\* AccelDataHandler)(AccelData \*data, uint32\_t num\_samples) Callback type for accelerometer data events. #### Parameters data Pointer to the collected accelerometer samples. num\_samples the number of samples stored in data. typedef void(\* AccelRawDataHandler)(AccelRawData \*data, uint32\_t num\_samples, uint64\_t timestamp) Callback type for accelerometer raw data events. #### Parameters data Pointer to the collected accelerometer samples. num\_samples the number of samples stored in data. timestamp the timestamp, in ms, of the first sample. typedef void(\* AccelTapHandler)(AccelAxisType axis, int32\_t direction) Callback type for accelerometer tap events. #### Parameters axis the axis on which a tap was registered (x, y, or z) direction the direction (-1 or +1) of the tap --- # ActionBarLayer Source: https://developer.repebble.com/docs/c/User_Interface/Layers/ActionBarLayer/ Vertical, bar-shaped control widget on the right edge of the window ![](https://developer.repebble.com/assets/images/docs/c/aplite/action_bar_layer.png) ![](https://developer.repebble.com/assets/images/docs/c/aplite/action_bar_layer.png) ![](https://developer.repebble.com/assets/images/docs/c/aplite/action_bar_layer.png) ![](https://developer.repebble.com/assets/images/docs/c/aplite/action_bar_layer.png) ![](https://developer.repebble.com/assets/images/docs/c/aplite/action_bar_layer.png) ActionBarLayer is a Layer that displays a bar on the right edge of the window. The bar can contain up to 3 icons, each corresponding with one of the buttons on the right side of the watch. The purpose of each icon is to provide a hint (feed-forward) to what action a click on the respective button will cause. The action bar is useful when there are a few (up to 3) main actions that are desirable to be able to take quickly, literally with one press of a button. ### More actions If there are more than 3 actions the user might want to take: - Try assigning the top and bottom icons of the action bar to the two most immediate actions and use the middle icon to push a Window with a MenuLayer with less immediate actions. - Secondary actions that are not vital, can be "hidden" under a long click. Try to group similar actions to one button. For example, in a Music app, a single click on the top button is tied to the action to jump to the previous track. Holding that same button means seek backwards. ### Directionality mapping When the top and bottom buttons are used to control navigating through a (potentially virtual, non-visible) list of items, follow this guideline: - Tie the top button to the action that goes to the _previous_ item in the list, for example "jump to previous track" in a Music app. - Tie the bottom button to the action that goes to the _next_ item in the list, for example "jump to next track" in a Music app. ### Geometry - The action bar's width varies per platform. 30px on most displays, 34px on Emery and Gabbro, and 40px on Chalk. Use the [ACTION\_BAR\_WIDTH](https://developer.repebble.com/docs/c/User_Interface/Layers/ActionBarLayer.md#ACTION_BAR_WIDTH) define. - Icons should not be wider than 28 pixels, or taller than 18 pixels. It is recommended to use a size of around 15 x 15 pixels for the "visual core" of the icon, and extending or contracting where needed. The code example below shows how to do the initial setup of the action bar in a window's `.load` handler. Configuring the button actions is similar to the process when using [window\_set\_click\_config\_provider()](https://developer.repebble.com/docs/c/User_Interface/Window.md#window_set_click_config_provider). See [Clicks](https://developer.repebble.com/docs/c/User_Interface/Clicks.md) for more information. ``` ActionBarLayer \*action\_bar;// The implementation of my\_next\_click\_handler and my\_previous\_click\_handler// is omitted for the sake of brevity. See the Clicks reference docs.void click\_config\_provider(void \*context) {window\_single\_click\_subscribe(BUTTON\_ID\_DOWN, (ClickHandler) my\_next\_click\_handler);window\_single\_click\_subscribe(BUTTON\_ID\_UP, (ClickHandler) my\_previous\_click\_handler);}void window\_load(Window \*window) {...// Initialize the action bar:action\_bar = action\_bar\_layer\_create();// Associate the action bar with the window:action\_bar\_layer\_add\_to\_window(action\_bar, window);// Set the click config provider:action\_bar\_layer\_set\_click\_config\_provider(action\_bar,click\_config\_provider);// Set the icons:// The loading of the icons is omitted for brevity... See gbitmap\_create\_with\_resource()action\_bar\_layer\_set\_icon\_animated(action\_bar, BUTTON\_ID\_UP, my\_icon\_previous, true);action\_bar\_layer\_set\_icon\_animated(action\_bar, BUTTON\_ID\_DOWN, my\_icon\_next, true);} ``` ## Function Documentation ActionBarLayer \* action\_bar\_layer\_create(void) Creates a new ActionBarLayer on the heap and initalizes it with the default values. - Background color: [GColorBlack](https://developer.repebble.com/docs/c/Graphics/Graphics_Types/Color_Definitions.md#GColorBlack) - No click configuration provider (`NULL`) - No icons - Not added to / associated with any window, thus not catching any button input yet. #### Returns A pointer to the ActionBarLayer. `NULL` if the ActionBarLayer could not be created void action\_bar\_layer\_destroy(ActionBarLayer \* action\_bar\_layer) Destroys a ActionBarLayer previously created by action\_bar\_layer\_create. Layer \* action\_bar\_layer\_get\_layer(ActionBarLayer \* action\_bar\_layer) Gets the "root" Layer of the action bar layer, which is the parent for the sub- layers used for its implementation. #### Parameters action\_bar\_layer Pointer to the ActionBarLayer for which to get the "root" Layer #### Returns The "root" Layer of the action bar layer. void action\_bar\_layer\_set\_context(ActionBarLayer \* action\_bar, void \* context) Sets the context parameter, which will be passed in to [ClickHandler](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#ClickHandler) callbacks and the [ClickConfigProvider](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#ClickConfigProvider) callback of the action bar. ##### Note By default, a pointer to the action bar itself is passed in, if the context has not been set or if it has been set to `NULL`. #### Parameters action\_bar The action bar for which to assign the new context context The new context #### See Also [action\_bar\_layer\_set\_click\_config\_provider()](https://developer.repebble.com/docs/c/User_Interface/Layers/ActionBarLayer.md#action_bar_layer_set_click_config_provider) [Clicks](https://developer.repebble.com/docs/c/User_Interface/Clicks.md) void action\_bar\_layer\_set\_click\_config\_provider(ActionBarLayer \* action\_bar, [ClickConfigProvider](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#ClickConfigProvider) click\_config\_provider) Sets the click configuration provider callback of the action bar. In this callback your application can associate handlers to the different types of click events for each of the buttons, see [Clicks](https://developer.repebble.com/docs/c/User_Interface/Clicks.md). ##### Notes If the action bar had already been added to a window and the window is currently on-screen, the click configuration provider will be called before this function returns. Otherwise, it will be called by the system when the window becomes on-screen. The `.raw` handlers cannot be used without breaking the automatic highlighting of the segment of the action bar that for which a button is #### Parameters action\_bar The action bar for which to assign a new click configuration provider click\_config\_provider The new click configuration provider #### See Also [action\_bar\_layer\_set\_icon()](https://developer.repebble.com/docs/c/User_Interface/Layers/ActionBarLayer.md#action_bar_layer_set_icon) void action\_bar\_layer\_set\_icon(ActionBarLayer \* action\_bar, [ButtonId](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#ButtonId) button\_id, const GBitmap \* icon) Sets an action bar icon onto one of the 3 slots as identified by `button_id`. Only BUTTON\_ID\_UP, BUTTON\_ID\_SELECT and BUTTON\_ID\_DOWN can be used. The transition will not be animated. Whenever an icon is set, the click configuration provider will be called, to give the application the opportunity to reconfigure the button interaction. #### Parameters action\_bar The action bar for which to set the new icon button\_id The identifier of the button for which to set the icon icon Pointer to the GBitmap icon #### See Also [action\_bar\_layer\_set\_icon\_animated()](https://developer.repebble.com/docs/c/User_Interface/Layers/ActionBarLayer.md#action_bar_layer_set_icon_animated) [action\_bar\_layer\_set\_icon\_press\_animation()](https://developer.repebble.com/docs/c/User_Interface/Layers/ActionBarLayer.md#action_bar_layer_set_icon_press_animation) [action\_bar\_layer\_set\_click\_config\_provider()](https://developer.repebble.com/docs/c/User_Interface/Layers/ActionBarLayer.md#action_bar_layer_set_click_config_provider) void action\_bar\_layer\_clear\_icon(ActionBarLayer \* action\_bar, [ButtonId](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#ButtonId) button\_id) Convenience function to clear out an existing icon. All it does is call `action_bar_layer_set_icon(action_bar, button_id, NULL)` #### Parameters action\_bar The action bar for which to clear an icon button\_id The identifier of the button for which to clear the icon #### See Also [action\_bar\_layer\_set\_icon()](https://developer.repebble.com/docs/c/User_Interface/Layers/ActionBarLayer.md#action_bar_layer_set_icon) void action\_bar\_layer\_add\_to\_window(ActionBarLayer \* action\_bar, struct Window \* window) Adds the action bar's layer on top of the window's root layer. It also adjusts the layout of the action bar to match the geometry of the window it gets added to. Lastly, it calls [window\_set\_click\_config\_provider\_with\_context()](https://developer.repebble.com/docs/c/User_Interface/Window.md#window_set_click_config_provider_with_context) on the window to set it up to work with the internal callback and raw click handlers of the action bar, to enable the highlighting of the section of the action bar when the user presses a button. ##### Notes After this call, do not use [window\_set\_click\_config\_provider\_with\_context()](https://developer.repebble.com/docs/c/User_Interface/Window.md#window_set_click_config_provider_with_context) with the window that the action bar has been added to (this would de-associate the action bar's click config provider and context). Instead use [action\_bar\_layer\_set\_click\_config\_provider()](https://developer.repebble.com/docs/c/User_Interface/Layers/ActionBarLayer.md#action_bar_layer_set_click_config_provider) and [action\_bar\_layer\_set\_context()](https://developer.repebble.com/docs/c/User_Interface/Layers/ActionBarLayer.md#action_bar_layer_set_context) to register the click configuration provider to configure the buttons actions. It is advised to call this is in the window's `.load` or `.appear` handler. Make sure to call [action\_bar\_layer\_remove\_from\_window()](https://developer.repebble.com/docs/c/User_Interface/Layers/ActionBarLayer.md#action_bar_layer_remove_from_window) in the window's `.unload` or `.disappear` handler. Adding additional layers to the window's root layer after this calll can occlude the action bar. #### Parameters action\_bar The action bar to associate with the window window The window with which the action bar is to be associated void action\_bar\_layer\_remove\_from\_window(ActionBarLayer \* action\_bar) Removes the action bar from the window and unconfigures the window's click configuration provider. `NULL` is set as the window's new click config provider and also as its callback context. If it has not been added to a window before, this function is a no-op. #### Parameters action\_bar The action bar to de-associate from its current window void action\_bar\_layer\_set\_background\_color(ActionBarLayer \* action\_bar, GColor background\_color) Sets the background color of the action bar. Defaults to [GColorBlack](https://developer.repebble.com/docs/c/Graphics/Graphics_Types/Color_Definitions.md#GColorBlack). The action bar's layer is automatically marked dirty. #### Parameters action\_bar The action bar of which to set the background color background\_color The new background color void action\_bar\_layer\_set\_icon\_animated(ActionBarLayer \* action\_bar, [ButtonId](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#ButtonId) button\_id, const GBitmap \* icon, bool animated) Sets an action bar icon onto one of the 3 slots as identified by `button_id`. Only BUTTON\_ID\_UP, BUTTON\_ID\_SELECT and BUTTON\_ID\_DOWN can be used. Optionally, if `animated` is `true`, the transition will be animated. Whenever an icon is set, the click configuration provider will be called, to give the application the opportunity to reconfigure the button interaction. #### Parameters action\_bar The action bar for which to set the new icon button\_id The identifier of the button for which to set the icon icon Pointer to the GBitmap icon animated True = animate the transition, False = do not animate the transition #### See Also [action\_bar\_layer\_set\_icon()](https://developer.repebble.com/docs/c/User_Interface/Layers/ActionBarLayer.md#action_bar_layer_set_icon) [action\_bar\_layer\_set\_icon\_press\_animation()](https://developer.repebble.com/docs/c/User_Interface/Layers/ActionBarLayer.md#action_bar_layer_set_icon_press_animation) [action\_bar\_layer\_set\_click\_config\_provider()](https://developer.repebble.com/docs/c/User_Interface/Layers/ActionBarLayer.md#action_bar_layer_set_click_config_provider) void action\_bar\_layer\_set\_icon\_press\_animation(ActionBarLayer \* action\_bar, [ButtonId](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#ButtonId) button\_id, ActionBarLayerIconPressAnimation animation) Sets the animation to use while a button is pressed on an ActionBarLayer. By default we use ActionBarLayerIconPressAnimationMoveLeft. #### Parameters action\_bar The action bar for which to set the press animation button\_id The button for which to set the press animation animation The animation to use. #### See Also [action\_bar\_layer\_set\_icon\_animated()](https://developer.repebble.com/docs/c/User_Interface/Layers/ActionBarLayer.md#action_bar_layer_set_icon_animated) [action\_bar\_layer\_set\_click\_config\_provider()](https://developer.repebble.com/docs/c/User_Interface/Layers/ActionBarLayer.md#action_bar_layer_set_click_config_provider) ## Enum Documentation enum ActionBarLayerIconPressAnimation #### Enumerators ActionBarLayerIconPressAnimationNoneActionBarLayerIconPressAnimationMoveLeftActionBarLayerIconPressAnimationMoveUpActionBarLayerIconPressAnimationMoveRightActionBarLayerIconPressAnimationMoveDown ## Typedef Documentation typedef struct ActionBarLayer ActionBarLayer ## Macro Definition Documentation #define ACTION\_BAR\_WIDTH [\_ACTION\_BAR\_WIDTH](https://developer.repebble.com/docs/c/User_Interface/Layers/ActionBarLayer.md#_ACTION_BAR_WIDTH)(PBL\_PLATFORM\_TYPE\_CURRENT) The width of the action bar in pixels. - [SDK 3](javascript:void(0);) - [SDK 4](javascript:void(0);) - [SDK 4.9+](javascript:void(0);) #define \_ACTION\_BAR\_WIDTH ( plat) The width of the action bar in pixels, for all platforms. #define \_ACTION\_BAR\_WIDTH ( plat) The width of the action bar in pixels, for all platforms. #define \_ACTION\_BAR\_WIDTH ( plat) The width of the action bar in pixels, for all platforms. #define NUM\_ACTION\_BAR\_ITEMS 3 The maximum number of action bar items. --- # ActionMenu Source: https://developer.repebble.com/docs/c/User_Interface/Window/ActionMenu/ ## Function Documentation char \* action\_menu\_item\_get\_label(const ActionMenuItem \* item) Getter for the label of a given ActionMenuItem. #### Parameters item the ActionMenuItem of interest #### Returns a pointer to the string label. NULL if invalid. - [SDK 3](javascript:void(0);) - [SDK 4](javascript:void(0);) - [SDK 4.9+](javascript:void(0);) void \* action\_menu\_item\_get\_action\_data(const ActionMenuItem \* item) Getter for the action\_data pointer of a given ActionMenuitem. #### Parameters item the ActionMenuItem of interest #### Returns a pointer to the data. NULL if invalid. #### See Also [action\_menu\_level\_add\_action](https://developer.repebble.com/docs/c/User_Interface/Window/ActionMenu.md#action_menu_level_add_action) void \* action\_menu\_item\_get\_action\_data(const ActionMenuItem \* item) Getter for the action\_data pointer of a given ActionMenuitem. #### Parameters item the ActionMenuItem of interest #### Returns a pointer to the data. NULL if invalid. #### See Also [action\_menu\_level\_add\_action](https://developer.repebble.com/docs/c/User_Interface/Window/ActionMenu.md#action_menu_level_add_action) void \* action\_menu\_item\_get\_action\_data(const ActionMenuItem \* item) Getter for the action\_data pointer of a given ActionMenuItem. #### Parameters item the ActionMenuItem of interest #### Returns a pointer to the data. NULL if invalid. #### See Also [action\_menu\_level\_add\_action](https://developer.repebble.com/docs/c/User_Interface/Window/ActionMenu.md#action_menu_level_add_action) ActionMenuLevel \* action\_menu\_level\_create([uint16\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint16_t) max\_items) Create a new action menu level with storage allocated for a given number of items. ##### Notes levels are freed alongside the whole hierarchy so no destroy API is provided. by default, levels are using ActionMenuLevelDisplayModeWide. Use [action\_menu\_level\_set\_display\_mode](https://developer.repebble.com/docs/c/User_Interface/Window/ActionMenu.md#action_menu_level_set_display_mode) to change it. #### Parameters max\_items the max number of items that will be displayed at that level #### See Also [action\_menu\_hierarchy\_destroy](https://developer.repebble.com/docs/c/User_Interface/Window/ActionMenu.md#action_menu_hierarchy_destroy) void action\_menu\_level\_set\_display\_mode(ActionMenuLevel \* level, [ActionMenuLevelDisplayMode](https://developer.repebble.com/docs/c/User_Interface/Window/ActionMenu.md#ActionMenuLevelDisplayMode) display\_mode) Set the action menu display mode. #### Parameters level The ActionMenuLevel whose display mode you want to change display\_mode The display mode for the action menu (3 vs. 1 item per row) ActionMenuItem \* action\_menu\_level\_add\_action(ActionMenuLevel \* level, const char \* label, [ActionMenuPerformActionCb](https://developer.repebble.com/docs/c/User_Interface/Window/ActionMenu.md#ActionMenuPerformActionCb) cb, void \* action\_data) Add an action to an ActionLevel. #### Parameters level the level to add the action to label the text to display for the action in the menu cb the callback that will be triggered when this action is actuated action\_data data to pass to the callback for this action #### Returns a reference to the new ActionMenuItem on success, NULL if the level is full ActionMenuItem \* action\_menu\_level\_add\_child(ActionMenuLevel \* level, ActionMenuLevel \* child, const char \* label) Add a child to this ActionMenuLevel. #### Parameters level the parent level child the child level label the text to display in the action menu for this level #### Returns a reference to the new ActionMenuItem on success, NULL if the level is full void action\_menu\_hierarchy\_destroy(const ActionMenuLevel \* root, [ActionMenuEachItemCb](https://developer.repebble.com/docs/c/User_Interface/Window/ActionMenu.md#ActionMenuEachItemCb) each\_cb, void \* context) Destroy a hierarchy of ActionMenuLevels. ##### Notes Typical implementations will cleanup memory allocated for the item label/data associated with each item in the callback Hierarchy is traversed in post-order. In other words, all children items are freed before their parent is freed. #### Parameters root the root level in the hierarchy each\_cb a callback to call on every ActionMenuItem in every level context a context pointer to pass to each\_cb on invocation void \* action\_menu\_get\_context(ActionMenu \* action\_menu) Get the context pointer this ActionMenu was created with. #### Parameters action\_menu A pointer to an ActionMenu #### Returns the context pointer initially provided in the [ActionMenuConfig](https://developer.repebble.com/docs/c/User_Interface/Window/ActionMenu.md#ActionMenuConfig). NULL if none exists. ActionMenuLevel \* action\_menu\_get\_root\_level(ActionMenu \* action\_menu) Get the root level of an ActionMenu. #### Parameters action\_menu the ActionMenu you want to know about #### Returns a pointer to the root ActionMenuLevel for the given ActionMenu, NULL if invalid ActionMenu \* action\_menu\_open([ActionMenuConfig](https://developer.repebble.com/docs/c/User_Interface/Window/ActionMenu.md#ActionMenuConfig) \* config) Open a new ActionMenu. The ActionMenu acts much like a window. It fills the whole screen and handles clicks. #### Parameters config the configuration info for this new ActionMenu #### Returns the new ActionMenu void action\_menu\_freeze(ActionMenu \* action\_menu) Freeze the ActionMenu. The ActionMenu will no longer respond to user input. ##### Note this API should be used when waiting for asynchronous operation. #### Parameters action\_menu the ActionMenu void action\_menu\_unfreeze(ActionMenu \* action\_menu) Unfreeze the ActionMenu previously frozen with [action\_menu\_freeze](https://developer.repebble.com/docs/c/User_Interface/Window/ActionMenu.md#action_menu_freeze). #### Parameters action\_menu the ActionMenu to unfreeze void action\_menu\_set\_result\_window(ActionMenu \* action\_menu, Window \* result\_window) Set the result window for an ActionMenu. The result window will be shown when the ActionMenu closes. ##### Note repeated call will result in only the last call to be applied, i.e. only one result window is ever set #### Parameters action\_menu the ActionMenu result\_window the window to insert, pass NULL to remove the current result window void action\_menu\_close(ActionMenu \* action\_menu, bool animated) Close the ActionMenu, whether it is frozen or not. ##### Note this API can be used on a frozen ActionMenu once the data required to build the result window has been received and the result window has been set #### Parameters action\_menu the ActionMenu to close animated whether or not show a close animation ## Data Structure Documentation struct ActionMenuConfig Configuration struct for the ActionMenu. #### Data Fields const ActionMenuLevel \* root\_level the root level of the ActionMenu void \* context a context pointer which will be accessbile when actions are performed struct [ActionMenuConfig](https://developer.repebble.com/docs/c/User_Interface/Window/ActionMenu.md#ActionMenuConfig) colors[ActionMenuDidCloseCb](https://developer.repebble.com/docs/c/User_Interface/Window/ActionMenu.md#ActionMenuDidCloseCb) will\_close Called immediately before the ActionMenu closes. [ActionMenuDidCloseCb](https://developer.repebble.com/docs/c/User_Interface/Window/ActionMenu.md#ActionMenuDidCloseCb) did\_close a callback used to cleanup memory after the menu has closed ActionMenuAlign align ## Enum Documentation enum ActionMenuAlign #### Enumerators ActionMenuAlignTopActionMenuAlignCenter enum ActionMenuLevelDisplayMode enum value that controls whether menu items are displayed in a grid (similarly to the emoji replies) or in a single column (reminiscent of [MenuLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md)) #### Enumerators ActionMenuLevelDisplayModeWide Each item gets its own row. ActionMenuLevelDisplayModeThin Grid view: multiple items per row. ## Typedef Documentation typedef struct ActionMenuItem ActionMenuItem typedef struct ActionMenuLevel ActionMenuLevel typedef struct ActionMenu ActionMenu - [SDK 3](javascript:void(0);) - [SDK 4](javascript:void(0);) - [SDK 4.9+](javascript:void(0);) typedef void(\* ActionMenuDidCloseCb)(ActionMenu \*menu, const ActionMenuItem \*performed\_action, void \*context) Callback executed after the ActionMenu has closed, so memory may be freed. #### Parameters root\_level the root level passed to the ActionMenu performed\_action the ActionMenuItem for the action that was performed, NULL if the ActionMenu is closing without an action being selected by the user context the context passed to the ActionMenu typedef void(\* ActionMenuDidCloseCb)(ActionMenu \*menu, const ActionMenuItem \*performed\_action, void \*context) Callback executed after the ActionMenu has closed, so memory may be freed. #### Parameters root\_level the root level passed to the ActionMenu performed\_action the ActionMenuItem for the action that was performed, NULL if the ActionMenu is closing without an action being selected by the user context the context passed to the ActionMenu typedef void(\* ActionMenuDidCloseCb)(ActionMenu \*menu, const ActionMenuItem \*performed\_action, void \*context) Callback executed after the ActionMenu has closed, so memory may be freed. #### Parameters menu the ActionMenu performed\_action the ActionMenuItem for the action that was performed, NULL if the ActionMenu is closing without an action being selected by the user context the context passed to the ActionMenu typedef void(\* ActionMenuPerformActionCb)(ActionMenu \*action\_menu, const ActionMenuItem \*action, void \*context) Callback executed when a given action is selected. ##### Note the action menu is closed immediately after an action is performed, unless it is frozen in the [ActionMenuPerformActionCb](https://developer.repebble.com/docs/c/User_Interface/Window/ActionMenu.md#ActionMenuPerformActionCb) #### Parameters action\_menu the action menu currently on screen action the action that was triggered context the context passed to the action menu - [SDK 3](javascript:void(0);) - [SDK 4](javascript:void(0);) - [SDK 4.9+](javascript:void(0);) typedef void(\* ActionMenuEachItemCb)(const ActionMenuItem \*item, void \*context) Callback invoked for each item in an action menu hierarchy. #### Parameters item the current action menu item a caller-provided context callback typedef void(\* ActionMenuEachItemCb)(const ActionMenuItem \*item, void \*context) Callback invoked for each item in an action menu hierarchy. #### Parameters item the current action menu item a caller-provided context callback typedef void(\* ActionMenuEachItemCb)(const ActionMenuItem \*item, void \*context) Callback invoked for each item in an action menu hierarchy. #### Parameters item the current action menu item context a caller-provided callback context --- # AlarmService Source: https://developer.repebble.com/docs/c/Foundation/Event_Service/AlarmService/ The APIs on this page will only work with SDK 4.9+. ## Function Documentation bool alarm\_service\_peek\_next([time\_t](https://developer.repebble.com/docs/c/Standard_C/Time.md#time_t) \* timestamp\_out) Peek at the next scheduled, enabled alarm. #### Parameters timestamp\_out Must point to a valid `time_t`. If an enabled alarm exists, it is set to the UTC time at which that alarm fires. #### Returns true if at least one enabled alarm is scheduled, false otherwise. --- # Alloy Source: https://developer.repebble.com/docs/c/Foundation/Alloy/ The APIs on this page will only work with SDK 4.9+. ## Function Documentation void moddable\_createMachine([ModdableCreationRecord](https://developer.repebble.com/docs/c/Foundation/Alloy.md#ModdableCreationRecord) \* creation) Create and start a Moddable XS virtual machine for an Alloy app. #### Parameters creation Configuration record, or NULL for default settings. #### See Also [ModdableCreationRecord](https://developer.repebble.com/docs/c/Foundation/Alloy.md#ModdableCreationRecord) ## Data Structure Documentation struct ModdableCreationRecord Configuration record for creating a Moddable XS virtual machine. Used with [moddable\_createMachine()](https://developer.repebble.com/docs/c/Foundation/Alloy.md#moddable_createMachine) to customize the JS runtime. Set recordSize to sizeof(ModdableCreationRecord) for version compatibility. #### Data Fields [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) recordSize Size of this struct in bytes (for versioning) [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) stack Stack size in bytes (0 for default) [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) slot Slot heap size in bytes (0 for default) [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) chunk Chunk heap size in bytes (0 for default) [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) flags Combination of kModdableCreationFlag\* values. void \* fxBuildFFI Optional pointer to an fxBuildFFI function for custom native bindings. ## Macro Definition Documentation #define kModdableCreationFlagLogInstrumentation (1 \<\< 0) Flag to enable XS instrumentation logging over Bluetooth. When set, the Moddable XS engine will log instrumentation data (e.g. memory usage, slot/chunk/stack statistics) via app\_log. Logging is only active when a Bluetooth log listener is connected; otherwise this flag has no effect. #### See Also [ModdableCreationRecord](https://developer.repebble.com/docs/c/Foundation/Alloy.md#ModdableCreationRecord) #define kModdableCreationFlagDebug (1 \<\< 1) Flag to enable XS debugging using xsbug. Should be used in combination with pebble build -debug. #### See Also [ModdableCreationRecord](https://developer.repebble.com/docs/c/Foundation/Alloy.md#ModdableCreationRecord) --- # Animation Source: https://developer.repebble.com/docs/c/User_Interface/Animation/ Abstract framework to create arbitrary animations The Animation framework provides your Pebble app with an base layer to create arbitrary animations. The simplest way to work with animations is to use the layer frame [PropertyAnimation](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md), which enables you to move a Layer around on the screen. Using [animation\_set\_implementation()](https://developer.repebble.com/docs/c/User_Interface/Animation.md#animation_set_implementation), you can implement a custom animation. Refer to the [User Interface Layers chapter in the Pebble Developer Guides](https://developer.repebble.com/guides/user-interfaces/layers.md) (chapter "Animation") for a conceptual overview of the animation framework and on how to write custom animations. ## Modules #### [PropertyAnimation](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md) A ProperyAnimation animates the value of a "property" of a "subject" over time. ## Function Documentation Animation \* animation\_create(void) Creates a new Animation on the heap and initalizes it with the default values. - Duration: 250ms, - Curve: AnimationCurveEaseInOut (ease-in-out), - Delay: 0ms, - Handlers: `{NULL, NULL}` (none), - Context: `NULL` (none), - Implementation: `NULL` (no implementation), - Scheduled: no #### Returns A pointer to the animation. `NULL` if the animation could not be created bool animation\_destroy(Animation \* animation) Destroys an Animation previously created by animation\_create. #### Returns true if successful, false on failure Animation \* animation\_clone(Animation \* from) Animation \* animation\_sequence\_create(Animation \* animation\_a, Animation \* animation\_b, Animation \* animation\_c, ...) Create a new sequence animation from a list of 2 or more other animations. The returned animation owns the animations that were provided as arguments and no further write operations on those handles are allowed. The variable length argument list must be terminated with a NULL ptr. ##### Note the maximum number of animations that can be supplied to this method is 20 #### Parameters animation\_a the first required component animation animation\_b the second required component animation animation\_c either the third component, or NULL if only adding 2 components #### Returns The newly created sequence animation Animation \* animation\_sequence\_create\_from\_array(Animation \*\* animation\_array, [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) array\_len) An alternate form of [animation\_sequence\_create()](https://developer.repebble.com/docs/c/User_Interface/Animation.md#animation_sequence_create) that accepts an array of other animations. ##### Note the maximum number of elements allowed in animation\_array is 256 #### Parameters animation\_array an array of component animations to include array\_len the number of elements in the animation\_array #### Returns The newly created sequence animation Animation \* animation\_spawn\_create(Animation \* animation\_a, Animation \* animation\_b, Animation \* animation\_c, ...) Create a new spawn animation from a list of 2 or more other animations. The returned animation owns the animations that were provided as arguments and no further write operations on those handles are allowed. The variable length argument list must be terminated with a NULL ptr. ##### Note the maximum number of animations that can be supplied to this method is 20 #### Parameters animation\_a the first required component animation animation\_b the second required component animation animation\_c either the third component, or NULL if only adding 2 components #### Returns The newly created spawn animation or NULL on failure Animation \* animation\_spawn\_create\_from\_array(Animation \*\* animation\_array, [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) array\_len) An alternate form of [animation\_spawn\_create()](https://developer.repebble.com/docs/c/User_Interface/Animation.md#animation_spawn_create) that accepts an array of other animations. ##### Note the maximum number of elements allowed in animation\_array is 256 #### Parameters animation\_array an array of component animations to include array\_len the number of elements in the animation\_array #### Returns The newly created spawn animation or NULL on failure bool animation\_set\_elapsed(Animation \* animation, [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) elapsed\_ms) Seek to a specific location in the animation. Only forward seeking is allowed. Returns true if successful, false if the passed in seek location is invalid. #### Parameters animation the animation for which to set the elapsed. elapsed\_ms the new elapsed time in milliseconds #### Returns true if successful, false if the requested elapsed is invalid. bool animation\_get\_elapsed(Animation \* animation, int32\_t \* elapsed\_ms) Get the current location in the animation. ##### Note The animation must be scheduled to get the elapsed time. If it is not schedule, this method will return false. #### Parameters animation The animation for which to fetch the elapsed. elapsed\_ms (out) pointer to variable that will contain the elapsed time in milliseconds #### Returns true if successful, false on failure bool animation\_set\_reverse(Animation \* animation, bool reverse) Set an animation to run in reverse (or forward) ##### Note Trying to set an attribute when an animation is immutable will return false (failure). An animation is immutable once it has been added to a sequence or spawn animation or has been scheduled. #### Parameters animation the animation to operate on reverse set to true to run in reverse, false to run forward #### Returns true if successful, false on failure bool animation\_get\_reverse(Animation \* animation) Get the reverse setting of an animation. #### Parameters animation The animation for which to get the setting #### Returns the reverse setting bool animation\_set\_play\_count(Animation \* animation, [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) play\_count) Set an animation to play N times. The default is 1. ##### Note Trying to set an attribute when an animation is immutable will return false (failure). An animation is immutable once it has been added to a sequence or spawn animation or has been scheduled. #### Parameters animation the animation to set the play count of play\_count number of times to play this animation. Set to ANIMATION\_PLAY\_COUNT\_INFINITE to make an animation repeat indefinitely. #### Returns true if successful, false on failure [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) animation\_get\_play\_count(Animation \* animation) Get the play count of an animation. #### Parameters animation The animation for which to get the setting #### Returns the play count bool animation\_set\_duration(Animation \* animation, [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) duration\_ms) Sets the time in milliseconds that an animation takes from start to finish. ##### Note Trying to set an attribute when an animation is immutable will return false (failure). An animation is immutable once it has been added to a sequence or spawn animation or has been scheduled. #### Parameters animation The animation for which to set the duration. duration\_ms The duration in milliseconds of the animation. This excludes any optional delay as set using [animation\_set\_delay()](https://developer.repebble.com/docs/c/User_Interface/Animation.md#animation_set_delay). #### Returns true if successful, false on failure [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) animation\_get\_duration(Animation \* animation, bool include\_delay, bool include\_play\_count) Get the static duration of an animation from start to end (ignoring how much has already played, if any). #### Parameters animation The animation for which to get the duration include\_delay if true, include the delay time include\_play\_count if true, incorporate the play\_count #### Returns the duration, in milliseconds. This includes any optional delay a set using [animation\_set\_delay](https://developer.repebble.com/docs/c/User_Interface/Animation.md#animation_set_delay). bool animation\_set\_delay(Animation \* animation, [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) delay\_ms) Sets an optional delay for the animation. ##### Note Trying to set an attribute when an animation is immutable will return false (failure). An animation is immutable once it has been added to a sequence or spawn animation or has been scheduled. #### Parameters animation The animation for which to set the delay. delay\_ms The delay in milliseconds that the animation system should wait from the moment the animation is scheduled to starting the animation. #### Returns true if successful, false on failure [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) animation\_get\_delay(Animation \* animation) Get the delay of an animation in milliseconds. #### Parameters animation The animation for which to get the setting #### Returns the delay in milliseconds bool animation\_set\_curve(Animation \* animation, [AnimationCurve](https://developer.repebble.com/docs/c/User_Interface/Animation.md#AnimationCurve) curve) Sets the animation curve for the animation. ##### Note Trying to set an attribute when an animation is immutable will return false (failure). An animation is immutable once it has been added to a sequence or spawn animation or has been scheduled. #### Parameters animation The animation for which to set the curve. curve The type of curve. #### Returns true if successful, false on failure #### See Also [AnimationCurve](https://developer.repebble.com/docs/c/User_Interface/Animation.md#AnimationCurve) [AnimationCurve](https://developer.repebble.com/docs/c/User_Interface/Animation.md#AnimationCurve) animation\_get\_curve(Animation \* animation) Gets the animation curve for the animation. #### Parameters animation The animation for which to get the curve. #### Returns The type of curve. bool animation\_set\_custom\_curve(Animation \* animation, [AnimationCurveFunction](https://developer.repebble.com/docs/c/User_Interface/Animation.md#AnimationCurveFunction) curve\_function) Sets a custom animation curve function. ##### Note Trying to set an attribute when an animation is immutable will return false (failure). An animation is immutable once it has been added to a sequence or spawn animation or has been scheduled. #### Parameters animation The animation for which to set the curve. curve\_function The custom animation curve function. #### Returns true if successful, false on failure #### See Also [AnimationCurveFunction](https://developer.repebble.com/docs/c/User_Interface/Animation.md#AnimationCurveFunction) [AnimationCurveFunction](https://developer.repebble.com/docs/c/User_Interface/Animation.md#AnimationCurveFunction) animation\_get\_custom\_curve(Animation \* animation) Gets the custom animation curve function for the animation. #### Parameters animation The animation for which to get the curve. #### Returns The custom animation curve function for the given animation. NULL if not set. bool animation\_set\_handlers(Animation \* animation, [AnimationHandlers](https://developer.repebble.com/docs/c/User_Interface/Animation.md#AnimationHandlers) callbacks, void \* context) Sets the callbacks for the animation. Often an application needs to run code at the start or at the end of an animation. Using this function is possible to register callback functions with an animation, that will get called at the start and end of the animation. ##### Note Trying to set an attribute when an animation is immutable will return false (failure). An animation is immutable once it has been added to a sequence or spawn animation or has been scheduled. #### Parameters animation The animation for which to set up the callbacks. callbacks The callbacks. context A pointer to application specific data, that will be passed as an argument by the animation subsystem when a callback is called. #### Returns true if successful, false on failure void \* animation\_get\_context(Animation \* animation) Gets the application-specific callback context of the animation. This `void` pointer is passed as an argument when the animation system calls [AnimationHandlers](https://developer.repebble.com/docs/c/User_Interface/Animation.md#AnimationHandlers) callbacks. The context pointer can be set to point to any application specific data using [animation\_set\_handlers()](https://developer.repebble.com/docs/c/User_Interface/Animation.md#animation_set_handlers). #### Parameters animation The animation. #### See Also [animation\_set\_handlers](https://developer.repebble.com/docs/c/User_Interface/Animation.md#animation_set_handlers) bool animation\_schedule(Animation \* animation) Schedules the animation. Call this once after configuring an animation to get it to start running. If the animation's implementation has a `.setup` callback it will get called before this function returns. ##### Note If the animation was already scheduled, it will first unschedule it and then re-schedule it again. Note that in that case, the animation's `.stopped` handler, the implementation's `.teardown` and `.setup` will get called, due to the unscheduling and scheduling. #### Parameters animation The animation to schedule. #### Returns true if successful, false on failure #### See Also [animation\_unschedule()](https://developer.repebble.com/docs/c/User_Interface/Animation.md#animation_unschedule) bool animation\_unschedule(Animation \* animation) Unschedules the animation, which in effect stops the animation. ##### Notes If the animation was not yet finished, unscheduling it will cause its `.stopped` handler to get called, with the "finished" argument set to false. If the animation is not scheduled or NULL, calling this routine is effectively a no-op #### Parameters animation The animation to unschedule. #### Returns true if successful, false on failure #### See Also [animation\_schedule()](https://developer.repebble.com/docs/c/User_Interface/Animation.md#animation_schedule) void animation\_unschedule\_all(void) Unschedules all animations of the application. #### See Also [animation\_unschedule](https://developer.repebble.com/docs/c/User_Interface/Animation.md#animation_unschedule) bool animation\_is\_scheduled(Animation \* animation) ##### Note An animation will be scheduled when it is running and not finished yet. An animation that has finished is automatically unscheduled. For convenience, passing in a NULL animation argument will simply return false #### Parameters animation The animation for which to get its scheduled state. #### Returns True if the animation was scheduled, or false if it was not. #### See Also [animation\_schedule](https://developer.repebble.com/docs/c/User_Interface/Animation.md#animation_schedule) [animation\_unschedule](https://developer.repebble.com/docs/c/User_Interface/Animation.md#animation_unschedule) bool animation\_set\_implementation(Animation \* animation, const [AnimationImplementation](https://developer.repebble.com/docs/c/User_Interface/Animation.md#AnimationImplementation) \* implementation) Sets the implementation of the custom animation. When implementing custom animations, use this function to specify what functions need to be called to for the setup, frame update and teardown of the animation. ##### Note Trying to set an attribute when an animation is immutable will return false (failure). An animation is immutable once it has been added to a sequence or spawn animation or has been scheduled. #### Parameters animation The animation for which to set the implementation. implementation The structure with function pointers to the implementation of the setup, update and teardown functions. #### Returns true if successful, false on failure #### See Also [AnimationImplementation](https://developer.repebble.com/docs/c/User_Interface/Animation.md#AnimationImplementation) const [AnimationImplementation](https://developer.repebble.com/docs/c/User_Interface/Animation.md#AnimationImplementation) \* animation\_get\_implementation(Animation \* animation) Gets the implementation of the custom animation. #### Parameters animation The animation for which to get the implementation. #### Returns NULL if animation implementation has not been setup. #### See Also [AnimationImplementation](https://developer.repebble.com/docs/c/User_Interface/Animation.md#AnimationImplementation) ## Data Structure Documentation struct AnimationHandlers The handlers that will get called when an animation starts and stops. See documentation with the function pointer types for more information. #### Data Fields [AnimationStartedHandler](https://developer.repebble.com/docs/c/User_Interface/Animation.md#AnimationStartedHandler) started The handler that will be called when an animation is started. [AnimationStoppedHandler](https://developer.repebble.com/docs/c/User_Interface/Animation.md#AnimationStoppedHandler) stopped The handler that will be called when an animation is stopped. #### See Also [animation\_set\_handlers](https://developer.repebble.com/docs/c/User_Interface/Animation.md#animation_set_handlers) struct AnimationImplementation The 3 callbacks that implement a custom animation. Only the `.update` callback is mandatory, `.setup` and `.teardown` are optional. See the documentation with the function pointer typedefs for more information. The diagram below illustrates the order in which callbacks can be expected to get called over the life cycle of an animation. It also illustrates where the implementation of different animation callbacks are intended to be “living”. ![](https://developer.repebble.com/assets/images/docs/c/aplite/animations.png) ![](https://developer.repebble.com/assets/images/docs/c/aplite/animations.png) ![](https://developer.repebble.com/assets/images/docs/c/aplite/animations.png) ![](https://developer.repebble.com/assets/images/docs/c/aplite/animations.png) ![](https://developer.repebble.com/assets/images/docs/c/aplite/animations.png) ##### Note The `.setup` callback is called immediately after scheduling the animation, regardless if there is a delay set for that animation using [animation\_set\_delay()](https://developer.repebble.com/docs/c/User_Interface/Animation.md#animation_set_delay). #### Data Fields [AnimationSetupImplementation](https://developer.repebble.com/docs/c/User_Interface/Animation.md#AnimationSetupImplementation) setup Called by the animation system when an animation is scheduled, to prepare it for running. This callback is optional and can be left `NULL` when not needed. [AnimationUpdateImplementation](https://developer.repebble.com/docs/c/User_Interface/Animation.md#AnimationUpdateImplementation) update Called by the animation system when the animation needs to calculate the next animation frame. This callback is mandatory and should not be left `NULL`. [AnimationTeardownImplementation](https://developer.repebble.com/docs/c/User_Interface/Animation.md#AnimationTeardownImplementation) teardown Called by the animation system when an animation is unscheduled, to clean up after it has run. This callback is optional and can be left `NULL` when not needed. #### See Also [AnimationSetupImplementation](https://developer.repebble.com/docs/c/User_Interface/Animation.md#AnimationSetupImplementation) [AnimationUpdateImplementation](https://developer.repebble.com/docs/c/User_Interface/Animation.md#AnimationUpdateImplementation) [AnimationTeardownImplementation](https://developer.repebble.com/docs/c/User_Interface/Animation.md#AnimationTeardownImplementation) ## Enum Documentation enum AnimationCurve Values that are used to indicate the different animation curves, which determine the speed at which the animated value(s) change(s). #### Enumerators AnimationCurveLinear Linear curve: the velocity is constant. AnimationCurveEaseIn Bicubic ease-in: accelerate from zero velocity. AnimationCurveEaseOut Bicubic ease-in: decelerate to zero velocity. AnimationCurveEaseInOut Bicubic ease-in-out: accelerate from zero velocity, decelerate to zero velocity. AnimationCurveDefaultAnimationCurveCustomFunction Custom (user-provided) animation curve. AnimationCurveCustomInterpolationFunction User-provided interpolation function. AnimationCurve\_Reserved1AnimationCurve\_Reserved2 ## Typedef Documentation typedef struct Animation Animation typedef int32\_t AnimationProgress The type used to represent how far an animation has progressed. This is passed to the animation's update handler. typedef [AnimationProgress](https://developer.repebble.com/docs/c/User_Interface/Animation.md#AnimationProgress)(\* AnimationCurveFunction)(AnimationProgress linear\_distance) The function pointer type of a custom animation curve. #### Parameters linear\_distance The linear normalized animation distance to be curved. #### See Also [animation\_set\_custom\_curve](https://developer.repebble.com/docs/c/User_Interface/Animation.md#animation_set_custom_curve) typedef void(\* AnimationStartedHandler)(Animation \*animation, void \*context) The function pointer type of the handler that will be called when an animation is started, just before updating the first frame of the animation. ##### Note This is called after any optional delay as set by [animation\_set\_delay()](https://developer.repebble.com/docs/c/User_Interface/Animation.md#animation_set_delay) has expired. #### Parameters animation The animation that was started. context The pointer to custom, application specific data, as set using [animation\_set\_handlers()](https://developer.repebble.com/docs/c/User_Interface/Animation.md#animation_set_handlers) #### See Also [animation\_set\_handlers](https://developer.repebble.com/docs/c/User_Interface/Animation.md#animation_set_handlers) typedef void(\* AnimationStoppedHandler)(Animation \*animation, bool finished, void \*context) The function pointer type of the handler that will be called when the animation is stopped. ##### Note This animation (i.e.: the `animation` parameter) may be destroyed here. It is not recommended to unschedule or destroy a **different** Animation within this Animation's `stopped` handler. #### Parameters animation The animation that was stopped. finished True if the animation was stopped because it was finished normally, or False if the animation was stopped prematurely, because it was unscheduled before finishing. context The pointer to custom, application specific data, as set using [animation\_set\_handlers()](https://developer.repebble.com/docs/c/User_Interface/Animation.md#animation_set_handlers) #### See Also [animation\_set\_handlers](https://developer.repebble.com/docs/c/User_Interface/Animation.md#animation_set_handlers) typedef void(\* AnimationSetupImplementation)(Animation \*animation) Pointer to function that (optionally) prepares the animation for running. This callback is called when the animation is added to the scheduler. #### Parameters animation The animation that needs to be set up. #### See Also [animation\_schedule](https://developer.repebble.com/docs/c/User_Interface/Animation.md#animation_schedule) [AnimationTeardownImplementation](https://developer.repebble.com/docs/c/User_Interface/Animation.md#AnimationTeardownImplementation) typedef void(\* AnimationUpdateImplementation)(Animation \*animation, const AnimationProgress progress) Pointer to function that updates the animation according to the given normalized progress. This callback will be called repeatedly by the animation scheduler whenever the animation needs to be updated. #### Parameters animation The animation that needs to update; gets passed in by the animation framework. progress The current normalized progress; gets passed in by the animation framework for each animation frame. The value [ANIMATION\_NORMALIZED\_MIN](https://developer.repebble.com/docs/c/User_Interface/Animation.md#ANIMATION_NORMALIZED_MIN) represents the start and [ANIMATION\_NORMALIZED\_MAX](https://developer.repebble.com/docs/c/User_Interface/Animation.md#ANIMATION_NORMALIZED_MAX) represents the end. Values outside this range (generated by a custom curve function) can be used to implement features like a bounce back effect, where the progress exceeds the desired final value before returning to complete the animation. When using a system provided curve function, each frame during the animation will have a progress value between [ANIMATION\_NORMALIZED\_MIN](https://developer.repebble.com/docs/c/User_Interface/Animation.md#ANIMATION_NORMALIZED_MIN) and [ANIMATION\_NORMALIZED\_MAX](https://developer.repebble.com/docs/c/User_Interface/Animation.md#ANIMATION_NORMALIZED_MAX) based on the animation duration and the [AnimationCurve](https://developer.repebble.com/docs/c/User_Interface/Animation.md#AnimationCurve). For example, say an animation was scheduled at t = 1.0s, has a delay of 1.0s, a duration of 2.0s and a curve of AnimationCurveLinear. Then the .update callback will get called on t = 2.0s with distance\_normalized = [ANIMATION\_NORMALIZED\_MIN](https://developer.repebble.com/docs/c/User_Interface/Animation.md#ANIMATION_NORMALIZED_MIN). For each frame thereafter until t = 4.0s, the update callback will get called where distance\_normalized is ([ANIMATION\_NORMALIZED\_MIN](https://developer.repebble.com/docs/c/User_Interface/Animation.md#ANIMATION_NORMALIZED_MIN) - ((([ANIMATION\_NORMALIZED\_MAX](https://developer.repebble.com/docs/c/User_Interface/Animation.md#ANIMATION_NORMALIZED_MAX) - [ANIMATION\_NORMALIZED\_MIN](https://developer.repebble.com/docs/c/User_Interface/Animation.md#ANIMATION_NORMALIZED_MIN)) \* t) / duration)). Other system animation curve functions will result in a non-linear relation between distance\_normalized and time. typedef void(\* AnimationTeardownImplementation)(Animation \*animation) Pointer to function that (optionally) cleans up the animation. This callback is called when the animation is removed from the scheduler. In case the `.setup` implementation allocated any memory, this is a good place to release that memory again. #### Parameters animation The animation that needs to be teared down. #### See Also [animation\_unschedule](https://developer.repebble.com/docs/c/User_Interface/Animation.md#animation_unschedule) [AnimationSetupImplementation](https://developer.repebble.com/docs/c/User_Interface/Animation.md#AnimationSetupImplementation) ## Macro Definition Documentation #define ANIMATION\_DURATION\_INFINITE UINT32\_MAX Constant to indicate "infinite" duration. This can be used with [animation\_set\_duration()](https://developer.repebble.com/docs/c/User_Interface/Animation.md#animation_set_duration) to indicate that the animation should run indefinitely. This is useful when implementing for example a frame-by-frame simulation that does not have a clear ending (e.g. a game). ##### Notes Note that `distance_normalized` parameter that is passed into the `.update` implementation is meaningless in when an infinite duration is used. This can be returned by animation\_get\_duration (if the play count is infinite) #define ANIMATION\_PLAY\_COUNT\_INFINITE UINT32\_MAX Constant to indicate infinite play count. Can be passed to [animation\_set\_play\_count()](https://developer.repebble.com/docs/c/User_Interface/Animation.md#animation_set_play_count) to repeat indefinitely. ##### Note This can be returned by [animation\_get\_play\_count()](https://developer.repebble.com/docs/c/User_Interface/Animation.md#animation_get_play_count). #define ANIMATION\_NORMALIZED\_MIN 0 The normalized distance at the start of the animation. #define ANIMATION\_NORMALIZED\_MAX 65535 The normalized distance at the end of the animation. --- # App Source: https://developer.repebble.com/docs/c/Foundation/App/ App entry point and event loop. App is a module that provides you with an event loop for your Pebble app. All interaction between Pebble apps and the underlying Pebble OS takes place through an event loop. Before calling the [app\_event\_loop()](https://developer.repebble.com/docs/c/Foundation/App.md#app_event_loop) function, you subscribe to event services and implement event handlers. Each handler receives specific types of Events dispatched throughout the life of the Pebble watchapp. The [app\_event\_loop()](https://developer.repebble.com/docs/c/Foundation/App.md#app_event_loop) function takes care of both waiting for new events to become available on the watchapp event bus and routing new events to the appropriate handler. [Event Service](https://developer.repebble.com/docs/c/Foundation/Event_Service.md) allows an app to directly register for different types of events. This function will block until the watchapp is ready to exit, and should be placed in the app's main() function. A watchapp typically configures and uses the [app\_event\_loop()](https://developer.repebble.com/docs/c/Foundation/App.md#app_event_loop) as follows: ``` int main(void) {// do set up here// Enter the main event loop. This will block until the app is ready to exit.app\_event\_loop();// do clean up here} ``` ## Function Documentation void app\_event\_loop(void) The event loop for C apps, to be used in app's main(). Will block until the app is ready to exit. --- # App Communication Source: https://developer.repebble.com/docs/c/Foundation/App_Communication/ API for interacting with the Pebble communication subsystem. ## Function Documentation void app\_comm\_set\_sniff\_interval(const [SniffInterval](https://developer.repebble.com/docs/c/Foundation/App_Communication.md#SniffInterval) interval) Set the Bluetooth module's sniff interval. The sniff interval will be restored to normal by the OS after the app's de-init handler is called. Set the sniff interval to normal whenever possible. [SniffInterval](https://developer.repebble.com/docs/c/Foundation/App_Communication.md#SniffInterval) app\_comm\_get\_sniff\_interval(void) Get the Bluetooth module's sniff interval. #### Returns The [SniffInterval](https://developer.repebble.com/docs/c/Foundation/App_Communication.md#SniffInterval) value corresponding to the current interval ## Enum Documentation enum SniffInterval Intervals during which the Bluetooth module may enter a low power mode. The sniff interval defines the period during which the Bluetooth module may not exchange (ACL) packets. The longer the sniff interval, the more time the Bluetooth module may spend in a low power mode. It may be necessary to reduce the sniff interval if an app requires reduced latency when sending messages. These settings have a dramatic effect on the Pebble's energy consumption. Use the normal sniff interval whenever possible. Note, however, that switching between modes increases power consumption during the process. Frequent switching between modes is thus discouraged. Ensure you do not drop to normal frequently. The Bluetooth module is a major consumer of the Pebble's energy. #### Enumerators SNIFF\_INTERVAL\_NORMAL Set the sniff interval to normal (power-saving) mode. SNIFF\_INTERVAL\_REDUCED Reduce the sniff interval to increase the responsiveness of the radio at the expense of increasing Bluetooth energy consumption by a multiple of 2-5 (very significant) --- # App Glance Source: https://developer.repebble.com/docs/c/Foundation/App_Glance/ API for the application to modify its "glance" i.e. app menu subtitle. Apps have the ability to show a temporary icon and subtitle in the app selection menu; this is known as a "glance". For example, the app might use it to display a preview of its current state such as the currently playing song or the number of pending notifications. The glance is loaded with a stack of [AppGlanceSlice](https://developer.repebble.com/docs/c/Foundation/App_Glance.md#AppGlanceSlice) structs; only the latest slice is shown, and they are set to expire at a certain time to show the next slice in the stack. To update the glance with a stack of slices, you must define an [AppGlanceReloadCallback](https://developer.repebble.com/docs/c/Foundation/App_Glance.md#AppGlanceReloadCallback) and give it to [app\_glance\_reload](https://developer.repebble.com/docs/c/Foundation/App_Glance.md#app_glance_reload). The implementation of your [AppGlanceReloadCallback](https://developer.repebble.com/docs/c/Foundation/App_Glance.md#AppGlanceReloadCallback) should call [app\_glance\_add\_slice](https://developer.repebble.com/docs/c/Foundation/App_Glance.md#app_glance_add_slice) to add slices to the glance. The main window's unload handler is usually a good place to call [app\_glance\_reload](https://developer.repebble.com/docs/c/Foundation/App_Glance.md#app_glance_reload). PBL\_PLATFORM\_APLITE does not support App Glance. Example code: ``` #if !PBL\_PLATFORM\_APLITEstatic void glance\_reload\_callback(AppGlanceReloadSession \*session, size\_t limit, void \*context) {AppGlanceSlice slice = {.expiration\_time = APP\_GLANCE\_SLICE\_NO\_EXPIRATION,.layout.icon = APP\_GLANCE\_SLICE\_DEFAULT\_ICON,.layout.subtitle\_template\_string = "hello!",};AppGlanceResult result = app\_glance\_add\_slice(session, slice);if (result != APP\_GLANCE\_RESULT\_SUCCESS){APP\_LOG(APP\_LOG\_LEVEL\_ERROR, "app\_glance\_add\_slice() returned %d", result);}}#endif // !PBL\_PLATFORM\_APLITEstatic void main\_window\_unload(Window \*window) {#if !PBL\_PLATFORM\_APLITEapp\_glance\_reload(glance\_reload\_callback, NULL);#endif // !PBL\_PLATFORM\_APLITE} ``` ## Function Documentation [AppGlanceResult](https://developer.repebble.com/docs/c/Foundation/App_Glance.md#AppGlanceResult) app\_glance\_add\_slice(AppGlanceReloadSession \* session, [AppGlanceSlice](https://developer.repebble.com/docs/c/Foundation/App_Glance.md#AppGlanceSlice) slice) Add a slice to the app's glance. This function will only succeed if called with a valid AppGlanceReloadSession that is provided in an [AppGlanceReloadCallback](https://developer.repebble.com/docs/c/Foundation/App_Glance.md#AppGlanceReloadCallback). #### Parameters session The session variable provided in an [AppGlanceReloadCallback](https://developer.repebble.com/docs/c/Foundation/App_Glance.md#AppGlanceReloadCallback) slice The slice to add to the app's glance #### Returns The result of trying to add the slice to the app's glance void app\_glance\_reload([AppGlanceReloadCallback](https://developer.repebble.com/docs/c/Foundation/App_Glance.md#AppGlanceReloadCallback) callback, void \* context) Clear any existing slices in the app's glance and trigger a reload via the provided callback. #### Parameters callback A function that will be called to add new slices to the app's glance; even if the provided callback is NULL, any existing slices will still be cleared from the app's glance context User-provided context that will be passed to the callback ## Data Structure Documentation - [SDK 3](javascript:void(0);) - [SDK 4](javascript:void(0);) - [SDK 4.9+](javascript:void(0);) struct AppGlanceSlice An app's glance can change over time as defined by zero or more app glance slices that each describe the state of the app glance at a particular point in time. Slices are displayed in the order they are added, and they are removed at the specified expiration time. #### Data Fields struct [AppGlanceSlice](https://developer.repebble.com/docs/c/Foundation/App_Glance.md#AppGlanceSlice) layout Describes how the slice should be visualized in the app's glance in the launcher. [time\_t](https://developer.repebble.com/docs/c/Standard_C/Time.md#time_t) expiration\_time The UTC time after which this slice should no longer be shown in the app's glance. Use [APP\_GLANCE\_SLICE\_NO\_EXPIRATION](https://developer.repebble.com/docs/c/Foundation/App_Glance.md#APP_GLANCE_SLICE_NO_EXPIRATION) if the slice should never expire. struct AppGlanceSlice An app's glance can change over time as defined by zero or more app glance slices that each describe the state of the app glance at a particular point in time. Slices are displayed in the order they are added, and they are removed at the specified expiration time. #### Data Fields struct [AppGlanceSlice](https://developer.repebble.com/docs/c/Foundation/App_Glance.md#AppGlanceSlice) layout Describes how the slice should be visualized in the app's glance in the launcher. [time\_t](https://developer.repebble.com/docs/c/Standard_C/Time.md#time_t) expiration\_time The UTC time after which this slice should no longer be shown in the app's glance. Use [APP\_GLANCE\_SLICE\_NO\_EXPIRATION](https://developer.repebble.com/docs/c/Foundation/App_Glance.md#APP_GLANCE_SLICE_NO_EXPIRATION) if the slice should never expire. struct AppGlanceSlice An app's glance can change over time as defined by zero or more app glance slices that each describe the state of the app glance at a particular point in time. Slices are displayed in the order they are added, and they are removed at the specified expiration time. #### Data Fields [AppGlanceSliceLayout](https://developer.repebble.com/docs/c/Foundation/App_Glance.md#AppGlanceSliceLayout) layout Describes how the slice should be visualized in the app's glance in the launcher. [time\_t](https://developer.repebble.com/docs/c/Standard_C/Time.md#time_t) expiration\_time The UTC time after which this slice should no longer be shown in the app's glance. Use [APP\_GLANCE\_SLICE\_NO\_EXPIRATION](https://developer.repebble.com/docs/c/Foundation/App_Glance.md#APP_GLANCE_SLICE_NO_EXPIRATION) if the slice should never expire. struct AppGlanceSliceLayout Describes how the slice should be visualized in the app's glance in the launcher. #### Data Fields [PublishedId](https://developer.repebble.com/docs/c/Foundation/App_Glance.md#PublishedId) icon The published resource ID of the bitmap icon to display in the app's glance. Use [APP\_GLANCE\_SLICE\_DEFAULT\_ICON](https://developer.repebble.com/docs/c/Foundation/App_Glance.md#APP_GLANCE_SLICE_DEFAULT_ICON) to use the app's default bitmap icon. const char \* subtitle\_template\_string A template string to visualize in the app's glance. The string will be copied, so it is safe to destroy after adding the slice to the glance. Use NULL if no string should be displayed. ## Enum Documentation enum AppGlanceResult Bitfield enum describing the result of trying to add an [AppGlanceSlice](https://developer.repebble.com/docs/c/Foundation/App_Glance.md#AppGlanceSlice) to an app's glance. #### Enumerators APP\_GLANCE\_RESULT\_SUCCESS The slice was successfully added to the app's glance. APP\_GLANCE\_RESULT\_INVALID\_TEMPLATE\_STRING The subtitle\_template\_string provided in the slice was invalid. APP\_GLANCE\_RESULT\_TEMPLATE\_STRING\_TOO\_LONG The subtitle\_template\_string provided in the slice was longer than 150 bytes. APP\_GLANCE\_RESULT\_INVALID\_ICON The icon provided in the slice was invalid. APP\_GLANCE\_RESULT\_SLICE\_CAPACITY\_EXCEEDED The provided slice would exceed the app glance's slice capacity. APP\_GLANCE\_RESULT\_EXPIRES\_IN\_THE\_PAST The expiration\_time provided in the slice expires in the past. APP\_GLANCE\_RESULT\_INVALID\_SESSION The AppGlanceReloadSession provided was invalid. ## Typedef Documentation typedef [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) PublishedId The ID of a published app resource defined within the publishedMedia section of package.json. typedef struct AppGlanceReloadSession AppGlanceReloadSession typedef void(\* AppGlanceReloadCallback)(AppGlanceReloadSession \*session, size\_t limit, void \*context) User-provided callback for reloading the slices in the app's glance. #### Parameters session A session variable that must be passed to [app\_glance\_add\_slice](https://developer.repebble.com/docs/c/Foundation/App_Glance.md#app_glance_add_slice) when adding slices to the app's glance; it becomes invalid when the [AppGlanceReloadCallback](https://developer.repebble.com/docs/c/Foundation/App_Glance.md#AppGlanceReloadCallback) returns limit The number of entries that can be added to the app's glance context User-provided context provided when calling [app\_glance\_reload()](https://developer.repebble.com/docs/c/Foundation/App_Glance.md#app_glance_reload) ## Macro Definition Documentation #define APP\_GLANCE\_SLICE\_NO\_EXPIRATION (([time\_t](https://developer.repebble.com/docs/c/Standard_C/Time.md#time_t))0) Can be used for the expiration\_time of an [AppGlanceSlice](https://developer.repebble.com/docs/c/Foundation/App_Glance.md#AppGlanceSlice) so that the slice never expires. #define APP\_GLANCE\_SLICE\_DEFAULT\_ICON (([PublishedId](https://developer.repebble.com/docs/c/Foundation/App_Glance.md#PublishedId))0) Can be used for the icon of an [AppGlanceSlice](https://developer.repebble.com/docs/c/Foundation/App_Glance.md#AppGlanceSlice) so that the slice displays the app's default icon. --- # AppFocusService Source: https://developer.repebble.com/docs/c/Foundation/Event_Service/AppFocusService/ Handling app focus The AppFocusService allows developers to be notified when their apps become visible on the screen. Common reasons your app may be running but not be on screen are: it's still in the middle of launching and being revealed by a system animation, or it is being covered by a system window such as a notification. This service is useful for apps that require a high degree of user interactivity, like a game where you'll want to pause when a notification covers your app window. It can be also used for apps that want to sync up an intro animation to the end of the system animation that occurs before your app is visible. ## Function Documentation - [SDK 3](javascript:void(0);) - [SDK 4](javascript:void(0);) - [SDK 4.9+](javascript:void(0);) void app\_focus\_service\_subscribe\_handlers([AppFocusHandlers](https://developer.repebble.com/docs/c/Foundation/Event_Service/AppFocusService.md#AppFocusHandlers) handlers) Subscribe to the focus event service. Once subscribed, the handlers get called every time the app gains or loses focus. #### Parameters handler Handlers which will be called on will-focus and did-focus events. #### See Also [AppFocusHandlers](https://developer.repebble.com/docs/c/Foundation/Event_Service/AppFocusService.md#AppFocusHandlers) void app\_focus\_service\_subscribe\_handlers([AppFocusHandlers](https://developer.repebble.com/docs/c/Foundation/Event_Service/AppFocusService.md#AppFocusHandlers) handlers) Subscribe to the focus event service. Once subscribed, the handlers get called every time the app gains or loses focus. #### Parameters handler Handlers which will be called on will-focus and did-focus events. #### See Also [AppFocusHandlers](https://developer.repebble.com/docs/c/Foundation/Event_Service/AppFocusService.md#AppFocusHandlers) void app\_focus\_service\_subscribe\_handlers([AppFocusHandlers](https://developer.repebble.com/docs/c/Foundation/Event_Service/AppFocusService.md#AppFocusHandlers) handlers) Subscribe to the focus event service. Once subscribed, the handlers get called every time the app gains or loses focus. #### Parameters handlers Handlers which will be called on will-focus and did-focus events. #### See Also [AppFocusHandlers](https://developer.repebble.com/docs/c/Foundation/Event_Service/AppFocusService.md#AppFocusHandlers) void app\_focus\_service\_subscribe([AppFocusHandler](https://developer.repebble.com/docs/c/Foundation/Event_Service/AppFocusService.md#AppFocusHandler) handler) Subscribe to the focus event service. Once subscribed, the handler gets called every time the app focus changes. ##### Notes Calling this function is equivalent to ``` app\_focus\_service\_subscribe\_handlers((AppFocusHandlers){.will\_focus = handler,}); ``` Out focus events are triggered when a modal window is about to open and cover the app. In focus events are triggered when a modal window which is covering the app is about to close. #### Parameters handler A callback to be called on will-focus events. void app\_focus\_service\_unsubscribe(void) Unsubscribe from the focus event service. Once unsubscribed, the previously registered handlers will no longer be called. ## Data Structure Documentation struct AppFocusHandlers There are two different focus events which take place when transitioning to and from an app being in focus. Below is an example of when these events will occur: 1) The app is launched. Once the system animation to the app has completed and the app is completely in focus, the did\_focus handler is called with in\_focus set to true. 2) A notification comes in and the animation to show the notification starts. The will\_focus handler is called with in\_focus set to false. 3) The animation completes and the notification is in focus, with the app being completely covered. The did\_focus hander is called with in\_focus set to false. 4) The notification is dismissed and the animation to return to the app starts. The will\_focus handler is called with in\_focus set to true. 5) The animation completes and the app is in focus. The did\_focus handler is called with in\_focus set to true. #### Data Fields [AppFocusHandler](https://developer.repebble.com/docs/c/Foundation/Event_Service/AppFocusService.md#AppFocusHandler) will\_focus Handler which will be called right before an app will lose or gain focus. ##### Notes This will be called with in\_focus set to true when a window which is covering the app is about to close and return focus to the app. This will be called with in\_focus set to false when a window which will cover the app is about to open, causing the app to lose focus. [AppFocusHandler](https://developer.repebble.com/docs/c/Foundation/Event_Service/AppFocusService.md#AppFocusHandler) did\_focus Handler which will be called when an animation finished which has put the app into focus or taken the app out of focus. ##### Notes This will be called with in\_focus set to true when a window which was covering the app has closed and the app has gained focus. This will be called with in\_focus set to false when a window has opened which is now covering the app, causing the app to lose focus. ## Typedef Documentation typedef void(\* AppFocusHandler)(bool in\_focus) Callback type for focus events. #### Parameters in\_focus True if the app is gaining focus, false otherwise. --- # AppMessage Source: https://developer.repebble.com/docs/c/Foundation/AppMessage/ Bi-directional communication between phone apps and Pebble watchapps AppMessage is a bi-directional messaging subsystem that enables communication between phone apps and Pebble watchapps. This is accomplished by allowing phone and watchapps to exchange arbitrary sets of key/value pairs. The key/value pairs are stored in the form of a Dictionary, the layout of which is left for the application developer to define. AppMessage implements a push-oriented messaging protocol, enabling your app to call functions and methods to push messages from Pebble to phone and vice versa. The protocol is symmetric: both Pebble and the phone can send messages. All messages are acknowledged. In this context, there is no client-server model, as such. During the sending phase, one side initiates the communication by transferring a dictionary over the air. The other side then receives this message and is given an opportunity to perform actions on that data. As soon as possible, the other side is expected to reply to the message with a simple acknowledgment that the message was received successfully. PebbleKit JavaScript provides you with a set of standard JavaScript APIs that let your app receive messages from the watch, make HTTP requests, and send new messages to the watch. AppMessage APIs are used to send and receive data. A Pebble watchapp can use the resources of the connected phone to fetch information from web services, send information to web APIs, or store login credentials. On the JavaScript side, you communicate with Pebble via a Pebble object exposed in the namespace. Messages always need to get either ACKnowledged or "NACK'ed," that is, not acknowledged. If not, messages will result in a time-out failure. The AppMessage subsystem takes care of this implicitly. In the phone libraries, this step is a bit more explicit. The Pebble watch interfaces make a distinction between the Inbox and the Outbox calls. The Inbox receives messages from the phone on the watch; the Outbox sends messages from the watch to the phone. These two buffers can be managed separately. #### Warning A critical constraint of AppMessage is that messages are limited in size. An ingoing (outgoing) message larger than the inbox (outbox) will not be transmitted and will generate an error. You can choose your inbox and outbox size when you call [app\_message\_open()](https://developer.repebble.com/docs/c/Foundation/AppMessage.md#app_message_open). Pebble SDK provides a static minimum guaranteed size (APP\_MESSAGE\_INBOX\_SIZE\_MINIMUM and APP\_MESSAGE\_OUTBOX\_SIZE\_MINIMUM). Requesting a buffer of the minimum guaranteed size (or smaller) is always guaranteed to succeed on all Pebbles in this SDK version or higher, and with every phone. In some context, Pebble might be able to provide your application with larger inbox/outbox. You can call [app\_message\_inbox\_size\_maximum()](https://developer.repebble.com/docs/c/Foundation/AppMessage.md#app_message_inbox_size_maximum) and [app\_message\_outbox\_size\_maximum()](https://developer.repebble.com/docs/c/Foundation/AppMessage.md#app_message_outbox_size_maximum) in your code to get the largest possible value you can use. To always get the largest buffer available, follow this best practice: app\_message\_open([app\_message\_inbox\_size\_maximum()](https://developer.repebble.com/docs/c/Foundation/AppMessage.md#app_message_inbox_size_maximum), [app\_message\_outbox\_size\_maximum()](https://developer.repebble.com/docs/c/Foundation/AppMessage.md#app_message_outbox_size_maximum)) AppMessage uses your application heap space. That means that the sizes you pick for the AppMessage inbox and outbox buffers are important in optimizing your app’s performance. The more you use for AppMessage, the less space you’ll have for the rest of your app. To register callbacks, you should call [app\_message\_register\_inbox\_received()](https://developer.repebble.com/docs/c/Foundation/AppMessage.md#app_message_register_inbox_received), [app\_message\_register\_inbox\_dropped()](https://developer.repebble.com/docs/c/Foundation/AppMessage.md#app_message_register_inbox_dropped), [app\_message\_register\_outbox\_sent()](https://developer.repebble.com/docs/c/Foundation/AppMessage.md#app_message_register_outbox_sent), [app\_message\_register\_outbox\_failed()](https://developer.repebble.com/docs/c/Foundation/AppMessage.md#app_message_register_outbox_failed). Pebble recommends that you call them before [app\_message\_open()](https://developer.repebble.com/docs/c/Foundation/AppMessage.md#app_message_open) to ensure you do not miss a message arriving between starting AppMessage and registering the callback. You can set a context that will be passed to all the callbacks with [app\_message\_set\_context()](https://developer.repebble.com/docs/c/Foundation/AppMessage.md#app_message_set_context). In circumstances that may not be ideal, when using AppMessage several types of errors may occur. For example: - The send can’t start because the system state won't allow for a success. Several reasons you're unable to perform a send: A send() is already occurring (only one is possible at a time) or Bluetooth is not enabled or connected. - The send and receive occur, but the receiver can’t accept the message. For instance, there is no app that receives such a message. - The send occurs, but the receiver either does not actually receive the message or can’t handle it in a timely fashion. - In the case of a dropped message, the phone sends a message to the watchapp, while there is still an unprocessed message in the Inbox. Other errors are possible and described by [AppMessageResult](https://developer.repebble.com/docs/c/Foundation/AppMessage.md#AppMessageResult). A client of the AppMessage interface should use the result codes to be more robust in the face of communication problems either in the field or while debugging. Refer to the [App Communication in the Pebble Developer Guides](https://developer.repebble.com/guides/pebble-apps/communications/) for a conceptual overview and code usage. For code examples, refer to the SDK Examples that directly use App Message. These include: - [pebblekit-js-weather](https://github.com/pebble-examples/pebblekit-js-weather) - [pebblekit-js-quotes](https://github.com/pebble-examples/pebblekit-js-quotes) ## Function Documentation [AppMessageResult](https://developer.repebble.com/docs/c/Foundation/AppMessage.md#AppMessageResult) app\_message\_open(const [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) size\_inbound, const [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) size\_outbound) Open AppMessage to transfers. Use [dict\_calc\_buffer\_size\_from\_tuplets()](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#dict_calc_buffer_size_from_tuplets) or [dict\_calc\_buffer\_size()](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#dict_calc_buffer_size) to estimate the size you need. ##### Note It is recommended that if the Inbox will be used, that at least the Inbox callbacks should be registered before this call. Otherwise it is possible for an Inbox message to be NACK'ed without being seen by the application. #### Parameters size\_inbound (in) The required size for the Inbox buffer size\_outbound (in) The required size for the Outbox buffer #### Returns A result code such as APP\_MSG\_OK or APP\_MSG\_OUT\_OF\_MEMORY. void app\_message\_deregister\_callbacks(void) Deregisters all callbacks and their context. void \* app\_message\_get\_context(void) Gets the context that will be passed to all AppMessage callbacks. #### Returns The current context on record. void \* app\_message\_set\_context(void \* context) Sets the context that will be passed to all AppMessage callbacks. #### Parameters context (in) The context that will be passed to all AppMessage callbacks. #### Returns The previous context that was on record. [AppMessageInboxReceived](https://developer.repebble.com/docs/c/Foundation/AppMessage.md#AppMessageInboxReceived) app\_message\_register\_inbox\_received([AppMessageInboxReceived](https://developer.repebble.com/docs/c/Foundation/AppMessage.md#AppMessageInboxReceived) received\_callback) Registers a function that will be called after any Inbox message is received successfully. Only one callback may be registered at a time. Each subsequent call to this function will replace the previous callback. The callback is optional; setting it to NULL will deregister the current callback and no function will be called anymore. #### Parameters received\_callback (in) The callback that will be called going forward; NULL to not have a callback. #### Returns The previous callback (or NULL) that was on record. [AppMessageInboxDropped](https://developer.repebble.com/docs/c/Foundation/AppMessage.md#AppMessageInboxDropped) app\_message\_register\_inbox\_dropped([AppMessageInboxDropped](https://developer.repebble.com/docs/c/Foundation/AppMessage.md#AppMessageInboxDropped) dropped\_callback) Registers a function that will be called after any Inbox message is received but dropped by the system. Only one callback may be registered at a time. Each subsequent call to this function will replace the previous callback. The callback is optional; setting it to NULL will deregister the current callback and no function will be called anymore. #### Parameters dropped\_callback (in) The callback that will be called going forward; NULL to not have a callback. #### Returns The previous callback (or NULL) that was on record. [AppMessageOutboxSent](https://developer.repebble.com/docs/c/Foundation/AppMessage.md#AppMessageOutboxSent) app\_message\_register\_outbox\_sent([AppMessageOutboxSent](https://developer.repebble.com/docs/c/Foundation/AppMessage.md#AppMessageOutboxSent) sent\_callback) Registers a function that will be called after any Outbox message is sent and an ACK reply occurs in a timely fashion. Only one callback may be registered at a time. Each subsequent call to this function will replace the previous callback. The callback is optional; setting it to NULL will deregister the current callback and no function will be called anymore. #### Parameters sent\_callback (in) The callback that will be called going forward; NULL to not have a callback. #### Returns The previous callback (or NULL) that was on record. [AppMessageOutboxFailed](https://developer.repebble.com/docs/c/Foundation/AppMessage.md#AppMessageOutboxFailed) app\_message\_register\_outbox\_failed([AppMessageOutboxFailed](https://developer.repebble.com/docs/c/Foundation/AppMessage.md#AppMessageOutboxFailed) failed\_callback) Registers a function that will be called after any Outbox message is not sent with a timely ACK reply. The call to [app\_message\_outbox\_send()](https://developer.repebble.com/docs/c/Foundation/AppMessage.md#app_message_outbox_send) must have succeeded. Only one callback may be registered at a time. Each subsequent call to this function will replace the previous callback. The callback is optional; setting it to NULL will deregister the current callback and no function will be called anymore. #### Parameters failed\_callback (in) The callback that will be called going forward; NULL to not have a callback. #### Returns The previous callback (or NULL) that was on record. [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) app\_message\_inbox\_size\_maximum(void) Programatically determine the inbox size maximum in the current configuration. #### Returns The inbox size maximum on this firmware. #### See Also [APP\_MESSAGE\_INBOX\_SIZE\_MINIMUM](https://developer.repebble.com/docs/c/Foundation/AppMessage.md#APP_MESSAGE_INBOX_SIZE_MINIMUM) [app\_message\_outbox\_size\_maximum()](https://developer.repebble.com/docs/c/Foundation/AppMessage.md#app_message_outbox_size_maximum) [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) app\_message\_outbox\_size\_maximum(void) Programatically determine the outbox size maximum in the current configuration. #### Returns The outbox size maximum on this firmware. #### See Also [APP\_MESSAGE\_OUTBOX\_SIZE\_MINIMUM](https://developer.repebble.com/docs/c/Foundation/AppMessage.md#APP_MESSAGE_OUTBOX_SIZE_MINIMUM) [app\_message\_inbox\_size\_maximum()](https://developer.repebble.com/docs/c/Foundation/AppMessage.md#app_message_inbox_size_maximum) [AppMessageResult](https://developer.repebble.com/docs/c/Foundation/AppMessage.md#AppMessageResult) app\_message\_outbox\_begin([DictionaryIterator](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#DictionaryIterator) \*\* iterator) Begin writing to the Outbox's Dictionary buffer. ##### Note After a successful call, one can add values to the dictionary using functions like [dict\_write\_data()](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#dict_write_data) and friends. #### Parameters iterator (out) Location to write the [DictionaryIterator](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#DictionaryIterator) pointer. This will be NULL on failure. #### Returns A result code, including but not limited to APP\_MSG\_OK, APP\_MSG\_INVALID\_ARGS or APP\_MSG\_BUSY. #### See Also [Dictionary](https://developer.repebble.com/docs/c/Foundation/Dictionary.md) [AppMessageResult](https://developer.repebble.com/docs/c/Foundation/AppMessage.md#AppMessageResult) app\_message\_outbox\_send(void) Sends the outbound dictionary. #### Returns A result code, including but not limited to APP\_MSG\_OK or APP\_MSG\_BUSY. The APP\_MSG\_OK code does not mean that the message was sent successfully, but only that the start of processing was successful. Since this call is asynchronous, callbacks provide the final result instead. #### See Also [AppMessageOutboxSent](https://developer.repebble.com/docs/c/Foundation/AppMessage.md#AppMessageOutboxSent) [AppMessageOutboxFailed](https://developer.repebble.com/docs/c/Foundation/AppMessage.md#AppMessageOutboxFailed) ## Enum Documentation enum AppMessageResult AppMessage result codes. #### Enumerators APP\_MSG\_OK (0) All good, operation was successful. APP\_MSG\_SEND\_TIMEOUT (2) The other end did not confirm receiving the sent data with an (n)ack in time. APP\_MSG\_SEND\_REJECTED (4) The other end rejected the sent data, with a "nack" reply. APP\_MSG\_NOT\_CONNECTED (8) The other end was not connected. APP\_MSG\_APP\_NOT\_RUNNING (16) The local application was not running. APP\_MSG\_INVALID\_ARGS (32) The function was called with invalid arguments. APP\_MSG\_BUSY (64) There are pending (in or outbound) messages that need to be processed first before new ones can be received or sent. APP\_MSG\_BUFFER\_OVERFLOW (128) The buffer was too small to contain the incoming message. APP\_MSG\_ALREADY\_RELEASED (512) The resource had already been released. APP\_MSG\_CALLBACK\_ALREADY\_REGISTERED (1024) The callback was already registered. APP\_MSG\_CALLBACK\_NOT\_REGISTERED (2048) The callback could not be deregistered, because it had not been registered before. APP\_MSG\_OUT\_OF\_MEMORY (4096) The system did not have sufficient application memory to perform the requested operation. APP\_MSG\_CLOSED (8192) App message was closed. APP\_MSG\_INTERNAL\_ERROR (16384) An internal OS error prevented AppMessage from completing an operation. APP\_MSG\_INVALID\_STATE (32768) The function was called while App Message was not in the appropriate state. ## Typedef Documentation typedef void(\* AppMessageInboxReceived)(DictionaryIterator \*iterator, void \*context) Called after an incoming message is received. #### Parameters iterator (in) The dictionary iterator to the received message. Never NULL. Note that the iterator cannot be modified or saved off. The library may need to re-use the buffered space where this message is supplied. Returning from the callback indicates to the library that the received message contents are no longer needed or have already been externalized outside its buffering space and iterator. context (in) Pointer to application data as specified when registering the callback. - [SDK 3](javascript:void(0);) - [SDK 4](javascript:void(0);) - [SDK 4.9+](javascript:void(0);) typedef void(\* AppMessageInboxDropped)(AppMessageResult reason, void \*context) Called after an incoming message is dropped. Note that you can call [app\_message\_outbox\_begin()](https://developer.repebble.com/docs/c/Foundation/AppMessage.md#app_message_outbox_begin) from this handler to prepare a new message. This will invalidate the previous dictionary iterator; do not use it after calling [app\_message\_outbox\_begin()](https://developer.repebble.com/docs/c/Foundation/AppMessage.md#app_message_outbox_begin). #### Parameters result (in) The reason why the message was dropped. Some possibilities include APP\_MSG\_BUSY and APP\_MSG\_BUFFER\_OVERFLOW. context (in) Pointer to application data as specified when registering the callback. typedef void(\* AppMessageInboxDropped)(AppMessageResult reason, void \*context) Called after an incoming message is dropped. Note that you can call [app\_message\_outbox\_begin()](https://developer.repebble.com/docs/c/Foundation/AppMessage.md#app_message_outbox_begin) from this handler to prepare a new message. This will invalidate the previous dictionary iterator; do not use it after calling [app\_message\_outbox\_begin()](https://developer.repebble.com/docs/c/Foundation/AppMessage.md#app_message_outbox_begin). #### Parameters result (in) The reason why the message was dropped. Some possibilities include APP\_MSG\_BUSY and APP\_MSG\_BUFFER\_OVERFLOW. context (in) Pointer to application data as specified when registering the callback. typedef void(\* AppMessageInboxDropped)(AppMessageResult reason, void \*context) Called after an incoming message is dropped. Note that you can call [app\_message\_outbox\_begin()](https://developer.repebble.com/docs/c/Foundation/AppMessage.md#app_message_outbox_begin) from this handler to prepare a new message. This will invalidate the previous dictionary iterator; do not use it after calling [app\_message\_outbox\_begin()](https://developer.repebble.com/docs/c/Foundation/AppMessage.md#app_message_outbox_begin). #### Parameters reason (in) The reason why the message was dropped. Some possibilities include APP\_MSG\_BUSY and APP\_MSG\_BUFFER\_OVERFLOW. context (in) Pointer to application data as specified when registering the callback. typedef void(\* AppMessageOutboxSent)(DictionaryIterator \*iterator, void \*context) Called after an outbound message has been sent and the reply has been received. #### Parameters iterator (in) The dictionary iterator to the sent message. The iterator will be in the final state that was sent. Note that the iterator cannot be modified or saved off as the library will re-open the dictionary with dict\_begin() after this callback returns. context (in) Pointer to application data as specified when registering the callback. - [SDK 3](javascript:void(0);) - [SDK 4](javascript:void(0);) - [SDK 4.9+](javascript:void(0);) typedef void(\* AppMessageOutboxFailed)(DictionaryIterator \*iterator, AppMessageResult reason, void \*context) Called after an outbound message has not been sent successfully. Note that you can call [app\_message\_outbox\_begin()](https://developer.repebble.com/docs/c/Foundation/AppMessage.md#app_message_outbox_begin) from this handler to prepare a new message. This will invalidate the previous dictionary iterator; do not use it after calling [app\_message\_outbox\_begin()](https://developer.repebble.com/docs/c/Foundation/AppMessage.md#app_message_outbox_begin). #### Parameters iterator (in) The dictionary iterator to the sent message. The iterator will be in the final state that was sent. Note that the iterator cannot be modified or saved off as the library will re-open the dictionary with dict\_begin() after this callback returns. result (in) The result of the operation. Some possibilities for the value include APP\_MSG\_SEND\_TIMEOUT, APP\_MSG\_SEND\_REJECTED, APP\_MSG\_NOT\_CONNECTED, APP\_MSG\_APP\_NOT\_RUNNING, and the combination `(APP_MSG_NOT_CONNECTED | APP_MSG_APP_NOT_RUNNING)`. context Pointer to application data as specified when registering the callback. typedef void(\* AppMessageOutboxFailed)(DictionaryIterator \*iterator, AppMessageResult reason, void \*context) Called after an outbound message has not been sent successfully. Note that you can call [app\_message\_outbox\_begin()](https://developer.repebble.com/docs/c/Foundation/AppMessage.md#app_message_outbox_begin) from this handler to prepare a new message. This will invalidate the previous dictionary iterator; do not use it after calling [app\_message\_outbox\_begin()](https://developer.repebble.com/docs/c/Foundation/AppMessage.md#app_message_outbox_begin). #### Parameters iterator (in) The dictionary iterator to the sent message. The iterator will be in the final state that was sent. Note that the iterator cannot be modified or saved off as the library will re-open the dictionary with dict\_begin() after this callback returns. result (in) The result of the operation. Some possibilities for the value include APP\_MSG\_SEND\_TIMEOUT, APP\_MSG\_SEND\_REJECTED, APP\_MSG\_NOT\_CONNECTED, APP\_MSG\_APP\_NOT\_RUNNING, and the combination `(APP_MSG_NOT_CONNECTED | APP_MSG_APP_NOT_RUNNING)`. context Pointer to application data as specified when registering the callback. typedef void(\* AppMessageOutboxFailed)(DictionaryIterator \*iterator, AppMessageResult reason, void \*context) Called after an outbound message has not been sent successfully. Note that you can call [app\_message\_outbox\_begin()](https://developer.repebble.com/docs/c/Foundation/AppMessage.md#app_message_outbox_begin) from this handler to prepare a new message. This will invalidate the previous dictionary iterator; do not use it after calling [app\_message\_outbox\_begin()](https://developer.repebble.com/docs/c/Foundation/AppMessage.md#app_message_outbox_begin). #### Parameters iterator (in) The dictionary iterator to the sent message. The iterator will be in the final state that was sent. Note that the iterator cannot be modified or saved off as the library will re-open the dictionary with dict\_begin() after this callback returns. reason (in) The result of the operation. Some possibilities for the value include APP\_MSG\_SEND\_TIMEOUT, APP\_MSG\_SEND\_REJECTED, APP\_MSG\_NOT\_CONNECTED, APP\_MSG\_APP\_NOT\_RUNNING, and the combination `(APP_MSG_NOT_CONNECTED | APP_MSG_APP_NOT_RUNNING)`. context Pointer to application data as specified when registering the callback. ## Macro Definition Documentation #define APP\_MESSAGE\_INBOX\_SIZE\_MINIMUM 124 As long as the firmware maintains its current major version, inboxes of this size or smaller will be allowed. #### See Also [app\_message\_inbox\_size\_maximum()](https://developer.repebble.com/docs/c/Foundation/AppMessage.md#app_message_inbox_size_maximum) [APP\_MESSAGE\_OUTBOX\_SIZE\_MINIMUM](https://developer.repebble.com/docs/c/Foundation/AppMessage.md#APP_MESSAGE_OUTBOX_SIZE_MINIMUM) #define APP\_MESSAGE\_OUTBOX\_SIZE\_MINIMUM 636 As long as the firmware maintains its current major version, outboxes of this size or smaller will be allowed. #### See Also [app\_message\_outbox\_size\_maximum()](https://developer.repebble.com/docs/c/Foundation/AppMessage.md#app_message_outbox_size_maximum) [APP\_MESSAGE\_INBOX\_SIZE\_MINIMUM](https://developer.repebble.com/docs/c/Foundation/AppMessage.md#APP_MESSAGE_INBOX_SIZE_MINIMUM) --- # AppSync Source: https://developer.repebble.com/docs/c/Foundation/AppSync/ UI synchronization layer for AppMessage AppSync is a convenience layer that resides on top of [AppMessage](https://developer.repebble.com/docs/c/Foundation/AppMessage.md), and serves as a UI synchronization layer for AppMessage. In so doing, AppSync makes it easier to drive the information displayed in the watchapp UI with messages sent by a phone app. AppSync maintains and updates a Dictionary, and provides your app with a callback ([AppSyncTupleChangedCallback](https://developer.repebble.com/docs/c/Foundation/AppSync.md#AppSyncTupleChangedCallback)) routine that is called whenever the Dictionary changes and the app's UI is updated. Note that the app UI is not updated automatically. To update the UI, you need to implement the callback. Pebble OS provides support for data serialization utilities, like Dictionary, [Tuple](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#Tuple) and [Tuplet](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#Tuplet) data structures and their accompanying functions. You use Tuplets to create a Dictionary with [Tuple](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#Tuple) structures. AppSync manages the storage and bookkeeping chores of the current [Tuple](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#Tuple) values. AppSync copies incoming AppMessage Tuples into this "current" Dictionary, so that the key/values remain available for the UI to use. For example, it is safe to use a C-string value provided by AppSync and use it directly in a [text\_layer\_set\_text()](https://developer.repebble.com/docs/c/User_Interface/Layers/TextLayer.md#text_layer_set_text) call. Your app needs to supply the buffer that AppSync uses for the "current" Dictionary when initializing AppSync. Refer to the [Synchronizing App UI](https://developer.repebble.com/guides/pebble-apps/communications/appsync/) guide for a conceptual overview and code usage. ## Function Documentation void app\_sync\_init(struct AppSync \* s, uint8\_t \* buffer, const [uint16\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint16_t) buffer\_size, const [Tuplet](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#Tuplet) \*const keys\_and\_initial\_values, const uint8\_t count, [AppSyncTupleChangedCallback](https://developer.repebble.com/docs/c/Foundation/AppSync.md#AppSyncTupleChangedCallback) tuple\_changed\_callback, [AppSyncErrorCallback](https://developer.repebble.com/docs/c/Foundation/AppSync.md#AppSyncErrorCallback) error\_callback, void \* context) Initialized an AppSync system with specific buffer size and initial keys and values. The `callback.value_changed` callback will be called **asynchronously** with the initial keys and values, as to avoid duplicating code to update your app's UI. ##### Note Only updates for the keys specified in this initial array will be accepted by AppSync, updates for other keys that might come in will just be ignored. #### Parameters s The AppSync context to initialize buffer The buffer that AppSync should use buffer\_size The size of the backing storage of the "current" dictionary. Use [dict\_calc\_buffer\_size\_from\_tuplets()](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#dict_calc_buffer_size_from_tuplets) to estimate the size you need. keys\_and\_initial\_values An array of Tuplets with the initial keys and values. count The number of Tuplets in the `keys_and_initial_values` array. tuple\_changed\_callback The callback that will handle changed key/value pairs error\_callback The callback that will handle errors context Pointer to app specific data that will get passed into calls to the callbacks void app\_sync\_deinit(struct AppSync \* s) Cleans up an AppSync system. It frees the buffer allocated by an [app\_sync\_init()](https://developer.repebble.com/docs/c/Foundation/AppSync.md#app_sync_init) call and deregisters itself from the [AppMessage](https://developer.repebble.com/docs/c/Foundation/AppMessage.md) subsystem. #### Parameters s The AppSync context to deinit. [AppMessageResult](https://developer.repebble.com/docs/c/Foundation/AppMessage.md#AppMessageResult) app\_sync\_set(struct AppSync \* s, const [Tuplet](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#Tuplet) \*const keys\_and\_values\_to\_update, const uint8\_t count) Updates key/value pairs using an array of Tuplets. ##### Note The call will attempt to send the updated keys and values to the application on the other end. Only after the other end has acknowledged the update, the `.value_changed` callback will be called to confirm the update has completed and your application code can update its user interface. #### Parameters s The AppSync context keys\_and\_values\_to\_update An array of Tuplets with the keys and values to update. The data in the Tuplets are copied during the call, so the array can be stack-allocated. count The number of Tuplets in the `keys_and_values_to_update` array. #### Returns The result code from the [AppMessage](https://developer.repebble.com/docs/c/Foundation/AppMessage.md) subsystem. Can be APP\_MSG\_OK, APP\_MSG\_BUSY or APP\_MSG\_INVALID\_ARGS const [Tuple](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#Tuple) \* app\_sync\_get(const struct AppSync \* s, const [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) key) Finds and gets a tuple in the "current" dictionary. #### Parameters s The AppSync context key The key for which to find a [Tuple](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#Tuple) #### Returns Pointer to a found [Tuple](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#Tuple), or NULL if there was no [Tuple](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#Tuple) with the specified key. ## Data Structure Documentation struct AppSync #### Data Fields [DictionaryIterator](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#DictionaryIterator) current\_iterunion AppSync [uint16\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint16_t) buffer\_sizestruct AppSync callback ## Typedef Documentation typedef void(\* AppSyncTupleChangedCallback)(const uint32\_t key, const Tuple \*new\_tuple, const Tuple \*old\_tuple, void \*context) Called whenever a [Tuple](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#Tuple) changes. This does not necessarily mean the value in the [Tuple](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#Tuple) has changed. When the internal "current" dictionary gets updated, existing Tuples might get shuffled around in the backing buffer, even though the values stay the same. In this callback, the client code gets the chance to remove the old reference and start using the new one. In this callback, your application MUST clean up any references to the `old_tuple` of a PREVIOUS call to this callback (and replace it with the `new_tuple` that is passed in with the current call). #### Parameters key The key for which the [Tuple](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#Tuple) was changed. new\_tuple The new tuple. The tuple points to the actual, updated "current" dictionary, as backed by the buffer internal to the AppSync struct. Therefore the [Tuple](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#Tuple) can be used after the callback returns, until the AppSync is deinited. In case there was an error (e.g. storage shortage), this `new_tuple` can be `NULL_TUPLE`. old\_tuple The values that will be replaced with `new_tuple`. The key, value and type will be equal to the previous tuple in the old destination dictionary; however, the `old_tuple` points to a stack-allocated copy of the old data. This value will be `NULL_TUPLE` when the initial values are being set. context Pointer to application specific data, as set using [app\_sync\_init()](https://developer.repebble.com/docs/c/Foundation/AppSync.md#app_sync_init) #### See Also [app\_sync\_init()](https://developer.repebble.com/docs/c/Foundation/AppSync.md#app_sync_init) typedef void(\* AppSyncErrorCallback)(DictionaryResult dict\_error, AppMessageResult app\_message\_error, void \*context) Called whenever there was an error. #### Parameters dict\_error The dictionary result error code, if the error was dictionary related. app\_message\_error The app\_message result error code, if the error was app\_message related. context Pointer to application specific data, as set using [app\_sync\_init()](https://developer.repebble.com/docs/c/Foundation/AppSync.md#app_sync_init) #### See Also [app\_sync\_init()](https://developer.repebble.com/docs/c/Foundation/AppSync.md#app_sync_init) --- # AppWorker Source: https://developer.repebble.com/docs/c/Foundation/AppWorker/ Runs in the background, and can communicate with the foreground app. ## Function Documentation bool app\_worker\_is\_running(void) Determine if the worker for the current app is running. #### Returns true if running [AppWorkerResult](https://developer.repebble.com/docs/c/Foundation/AppWorker.md#AppWorkerResult) app\_worker\_launch(void) Launch the worker for the current app. Note that this is an asynchronous operation, a result code of APP\_WORKER\_RESULT\_SUCCESS merely means that the request was successfully queued up. #### Returns result code [AppWorkerResult](https://developer.repebble.com/docs/c/Foundation/AppWorker.md#AppWorkerResult) app\_worker\_kill(void) Kill the worker for the current app. Note that this is an asynchronous operation, a result code of APP\_WORKER\_RESULT\_SUCCESS merely means that the request was successfully queued up. #### Returns result code bool app\_worker\_message\_subscribe([AppWorkerMessageHandler](https://developer.repebble.com/docs/c/Foundation/AppWorker.md#AppWorkerMessageHandler) handler) Subscribe to worker messages. Once subscribed, the handler gets called on every message emitted by the other task (either worker or app). #### Parameters handler A callback to be executed when the event is received #### Returns true on success bool app\_worker\_message\_unsubscribe(void) Unsubscribe from worker messages. Once unsubscribed, the previously registered handler will no longer be called. #### Returns true on success void app\_worker\_send\_message(uint8\_t type, [AppWorkerMessage](https://developer.repebble.com/docs/c/Foundation/AppWorker.md#AppWorkerMessage) \* data) Send a message to the other task (either worker or app). #### Parameters type An application defined message type data the message data structure ## Data Structure Documentation struct AppWorkerMessage Generic structure of a worker message that can be sent between an app and its worker. #### Data Fields [uint16\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint16_t) data0[uint16\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint16_t) data1[uint16\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint16_t) data2 ## Enum Documentation enum AppWorkerResult Possible error codes from app\_worker\_launch, app\_worker\_kill. #### Enumerators APP\_WORKER\_RESULT\_SUCCESS Success. APP\_WORKER\_RESULT\_NO\_WORKER No worker found for the current app. APP\_WORKER\_RESULT\_DIFFERENT\_APP A worker for a different app is already running. APP\_WORKER\_RESULT\_NOT\_RUNNING The worker is not running. APP\_WORKER\_RESULT\_ALREADY\_RUNNING The worker is already running. APP\_WORKER\_RESULT\_ASKING\_CONFIRMATION The user will be asked for confirmation. ## Typedef Documentation typedef void(\* AppWorkerMessageHandler)(uint16\_t type, AppWorkerMessage \*data) Callback type for worker messages. Messages can be sent from worker to app or vice versa. #### Parameters type An application defined message type data pointer to message data. The receiver must know the structure of the data provided by the sender. --- # BacklightService Source: https://developer.repebble.com/docs/c/Foundation/Event_Service/BacklightService/ The APIs on this page will only work with SDK 4.9+. Notifies your app when the backlight turns on or off. The BacklightService lets your app react to the backlight turning on. The handler is invoked whenever the backlight transitions between off and on (any non-off state — fully on, on with timeout, or fading out is treated as "on"). This means you get a single edge per wake, not one event per fade step. ## Function Documentation void backlight\_service\_subscribe([BacklightHandler](https://developer.repebble.com/docs/c/Foundation/Event_Service/BacklightService.md#BacklightHandler) handler) Subscribe to the backlight event service. Once subscribed, the handler is called every time the backlight transitions between off and on. #### Parameters handler A callback to be executed on backlight on/off events. void backlight\_service\_unsubscribe(void) Unsubscribe from the backlight event service. Once unsubscribed, the previously registered handler will no longer be called. To read the current backlight state at any time, use [light\_is\_on()](https://developer.repebble.com/docs/c/User_Interface/Light.md#light_is_on). ## Typedef Documentation typedef void(\* BacklightHandler)(bool on) Callback type for backlight on/off events. #### Parameters on true when the backlight has just turned on, false when it has just turned fully off. --- # BatteryStateService Source: https://developer.repebble.com/docs/c/Foundation/Event_Service/BatteryStateService/ Determines when the battery state changes The BatteryStateService API lets you know when the battery state changes, that is, its current charge level, whether it is plugged and charging. It uses the [BatteryChargeState](https://developer.repebble.com/docs/c/Foundation/Event_Service/BatteryStateService.md#BatteryChargeState) structure to describe the current power state of Pebble. Refer to the [classio-battery-connection](https://github.com/pebble-examples/classio-battery-connection) example, which demonstrates using the battery state service in a watchface. ## Function Documentation void battery\_state\_service\_subscribe([BatteryStateHandler](https://developer.repebble.com/docs/c/Foundation/Event_Service/BatteryStateService.md#BatteryStateHandler) handler) Subscribe to the battery state event service. Once subscribed, the handler gets called on every battery state change. #### Parameters handler A callback to be executed on battery state change event void battery\_state\_service\_unsubscribe(void) Unsubscribe from the battery state event service. Once unsubscribed, the previously registered handler will no longer be called. [BatteryChargeState](https://developer.repebble.com/docs/c/Foundation/Event_Service/BatteryStateService.md#BatteryChargeState) battery\_state\_service\_peek(void) Peek at the last known battery state. #### Returns a [BatteryChargeState](https://developer.repebble.com/docs/c/Foundation/Event_Service/BatteryStateService.md#BatteryChargeState) containing the last known data ## Data Structure Documentation struct BatteryChargeState Structure for retrieval of the battery charge state. #### Data Fields uint8\_t charge\_percent A percentage (0-100) of how full the battery is. bool is\_charging True if the battery is currently being charged. False if not. bool is\_plugged True if the charger cable is connected. False if not. ## Typedef Documentation typedef void(\* BatteryStateHandler)(BatteryChargeState charge) Callback type for battery state change events. #### Parameters charge the state of the battery [BatteryChargeState](https://developer.repebble.com/docs/c/Foundation/Event_Service/BatteryStateService.md#BatteryChargeState) --- # BitmapLayer Source: https://developer.repebble.com/docs/c/User_Interface/Layers/BitmapLayer/ Layer that displays a bitmap image. ![](https://developer.repebble.com/assets/images/docs/c/aplite/bitmap_layer.png) ![](https://developer.repebble.com/assets/images/docs/c/aplite/bitmap_layer.png) ![](https://developer.repebble.com/assets/images/docs/c/aplite/bitmap_layer.png) ![](https://developer.repebble.com/assets/images/docs/c/aplite/bitmap_layer.png) ![](https://developer.repebble.com/assets/images/docs/c/aplite/bitmap_layer.png) BitmapLayer is a Layer subtype that draws a GBitmap within its frame. It uses an alignment property to specify how to position the bitmap image within its frame. Optionally, when the background color is not GColorClear, it draws a solid background color behind the bitmap image, filling areas of the frame that are not covered by the bitmap image. Lastly, using the compositing mode property of the BitmapLayer, determines the way the bitmap image is drawn on top of what is underneath it (either the background color, or the layers beneath it). ### Inside the Implementation The implementation of BitmapLayer is fairly straightforward and relies heavily on the functionality as exposed by the core drawing functions (see [Drawing Primitives](https://developer.repebble.com/docs/c/Graphics/Drawing_Primitives.md)). [BitmapLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/BitmapLayer.md)'s drawing callback uses [graphics\_draw\_bitmap\_in\_rect()](https://developer.repebble.com/docs/c/Graphics/Drawing_Primitives.md#graphics_draw_bitmap_in_rect) to perform the actual drawing of the GBitmap. It uses [grect\_align()](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#grect_align) to perform the layout of the image and it uses [graphics\_fill\_rect()](https://developer.repebble.com/docs/c/Graphics/Drawing_Primitives.md#graphics_fill_rect) to draw the background plane. ## Function Documentation BitmapLayer \* bitmap\_layer\_create([GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) frame) Creates a new bitmap layer on the heap and initalizes it the default values. - Bitmap: `NULL` (none) - Background color: GColorClear - Compositing mode: GCompOpAssign - Clips: `true` #### Returns A pointer to the BitmapLayer. `NULL` if the BitmapLayer could not be created void bitmap\_layer\_destroy(BitmapLayer \* bitmap\_layer) Destroys a window previously created by bitmap\_layer\_create. Layer \* bitmap\_layer\_get\_layer(const BitmapLayer \* bitmap\_layer) Gets the "root" Layer of the bitmap layer, which is the parent for the sub- layers used for its implementation. #### Parameters bitmap\_layer Pointer to the BitmapLayer for which to get the "root" Layer #### Returns The "root" Layer of the bitmap layer. const GBitmap \* bitmap\_layer\_get\_bitmap(BitmapLayer \* bitmap\_layer) Gets the pointer to the bitmap image that the BitmapLayer is using. #### Parameters bitmap\_layer The BitmapLayer for which to get the bitmap image #### Returns A pointer to the bitmap image that the BitmapLayer is using void bitmap\_layer\_set\_bitmap(BitmapLayer \* bitmap\_layer, const GBitmap \* bitmap) Sets the bitmap onto the BitmapLayer. The bitmap is set by reference (no deep copy), thus the caller of this function has to make sure the bitmap is kept in memory. The bitmap layer is automatically marked dirty after this operation. #### Parameters bitmap\_layer The BitmapLayer for which to set the bitmap image bitmap The new GBitmap to set onto the BitmapLayer void bitmap\_layer\_set\_alignment(BitmapLayer \* bitmap\_layer, [GAlign](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GAlign) alignment) Sets the alignment of the image to draw with in frame of the BitmapLayer. The aligment parameter specifies which edges of the bitmap should overlap with the frame of the BitmapLayer. If the bitmap is smaller than the frame of the BitmapLayer, the background is filled with the background color. The bitmap layer is automatically marked dirty after this operation. #### Parameters bitmap\_layer The BitmapLayer for which to set the aligment alignment The new alignment for the image inside the BitmapLayer - [SDK 3](javascript:void(0);) - [SDK 4](javascript:void(0);) - [SDK 4.9+](javascript:void(0);) void bitmap\_layer\_set\_background\_color(BitmapLayer \* bitmap\_layer, GColor color) Sets the background color of bounding box that will be drawn behind the image of the BitmapLayer. The bitmap layer is automatically marked dirty after this operation. #### Parameters bitmap\_layer The BitmapLayer for which to set the background color color The new GColor to set the background to void bitmap\_layer\_set\_background\_color(BitmapLayer \* bitmap\_layer, GColor color) Sets the background color of bounding box that will be drawn behind the image of the BitmapLayer. The bitmap layer is automatically marked dirty after this operation. #### Parameters bitmap\_layer The BitmapLayer for which to set the background color color The new GColor to set the background to void bitmap\_layer\_set\_background\_color(BitmapLayer \* bitmap\_layer, GColor color) Sets the background color of bounding box that will be drawn behind the image of the BitmapLayer. The bitmap layer is automatically marked dirty after this operation. #### Parameters bitmap\_layer The BitmapLayer for which to set the background color color The new GColor to set the background to #### See Also [bitmap\_layer\_set\_compositing\_mode](https://developer.repebble.com/docs/c/User_Interface/Layers/BitmapLayer.md#bitmap_layer_set_compositing_mode) - [SDK 3](javascript:void(0);) - [SDK 4](javascript:void(0);) - [SDK 4.9+](javascript:void(0);) void bitmap\_layer\_set\_compositing\_mode(BitmapLayer \* bitmap\_layer, [GCompOp](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GCompOp) mode) Sets the compositing mode of how the bitmap image is composited onto the BitmapLayer's background plane, or how it is composited onto what has been drawn beneath the BitmapLayer. The compositing mode only affects the drawing of the bitmap and not the drawing of the background color. For Aplite, there is no notion of "transparency" in the graphics system. However, the effect of transparency can be created by masking and using compositing modes. For Basalt, when drawing GBitmap images, GCompOpSet will be required to apply any transparency. The bitmap layer is automatically marked dirty after this operation. #### Parameters bitmap\_layer The BitmapLayer for which to set the compositing mode mode The compositing mode to set #### See Also [GCompOp](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GCompOp) void bitmap\_layer\_set\_compositing\_mode(BitmapLayer \* bitmap\_layer, [GCompOp](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GCompOp) mode) Sets the compositing mode of how the bitmap image is composited onto the BitmapLayer's background plane, or how it is composited onto what has been drawn beneath the BitmapLayer. The compositing mode only affects the drawing of the bitmap and not the drawing of the background color. For Aplite, there is no notion of "transparency" in the graphics system. However, the effect of transparency can be created by masking and using compositing modes. For Basalt, when drawing GBitmap images, GCompOpSet will be required to apply any transparency. The bitmap layer is automatically marked dirty after this operation. #### Parameters bitmap\_layer The BitmapLayer for which to set the compositing mode mode The compositing mode to set #### See Also [GCompOp](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GCompOp) void bitmap\_layer\_set\_compositing\_mode(BitmapLayer \* bitmap\_layer, [GCompOp](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GCompOp) mode) Sets the compositing mode of how the bitmap image is composited onto the BitmapLayer's background plane, or how it is composited onto what has been drawn beneath the BitmapLayer. The compositing mode only affects the drawing of the bitmap and not the drawing of the background color. For black&white platforms, there is no notion of "transparency" in the graphics system. However, the effect of transparency can be created by masking and using compositing modes. For color platforms, when drawing GBitmap images, GCompOpSet is required to apply any transparency. The bitmap layer is automatically marked dirty after this operation. #### Parameters bitmap\_layer The BitmapLayer for which to set the compositing mode mode The compositing mode to set #### See Also [GCompOp](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GCompOp) ## Typedef Documentation typedef struct BitmapLayer BitmapLayer --- # C SDK Documentation Source: https://developer.repebble.com/docs/c/ This is the contents page for the [Pebble C SDK](https://developer.repebble.com/sdk.md). Here you will find information on all the available modules, functions and objects that can be used to create watchapps and watchfaces for Pebble. The C SDK is broken down into these 5 top level modules. Click on them to browse around the rest of the SDK. You can also use the search bar at the top of the page to find what you are looking for. #### [Foundation](https://developer.repebble.com/docs/c/Foundation.md) The core of the Pebble SDK. #### [Graphics](https://developer.repebble.com/docs/c/Graphics.md) Low-level drawing routines. #### [User Interface](https://developer.repebble.com/docs/c/User_Interface.md) Everything related to user interface. #### [Worker](https://developer.repebble.com/docs/c/Worker.md) Run a background worker alongside the foreground app to collect data or respond to events while the app is not running. See the [Background Worker](https://developer.repebble.com/guides/events-and-services/background-worker.md) guide. #### [Standard C](https://developer.repebble.com/docs/c/Standard_C.md)   --- # Clicks Source: https://developer.repebble.com/docs/c/User_Interface/Clicks/ Handling button click interactions Each Pebble window handles Pebble's buttons while it is displayed. Raw button down and button up events are transformed into click events that can be transferred to your app: - Single-click. Detects a single click, that is, a button down event followed by a button up event. It also offers hold-to-repeat functionality (repeated click). - Multi-click. Detects double-clicking, triple-clicking and other arbitrary click counts. It can fire its event handler on all of the matched clicks, or just the last. - Long-click. Detects long clicks, that is, press-and-hold. - Raw. Simply forwards the raw button events. It is provided as a way to use both the higher level "clicks" processing and the raw button events at the same time. To receive click events when a window is displayed, you must register a [ClickConfigProvider](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#ClickConfigProvider) for this window with [window\_set\_click\_config\_provider()](https://developer.repebble.com/docs/c/User_Interface/Window.md#window_set_click_config_provider). Your [ClickConfigProvider](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#ClickConfigProvider) will be called every time the window becomes visible with one context argument. By default this context is a pointer to the window but you can change this with [window\_set\_click\_config\_provider\_with\_context()](https://developer.repebble.com/docs/c/User_Interface/Window.md#window_set_click_config_provider_with_context). In your [ClickConfigProvider](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#ClickConfigProvider) you call the [window\_single\_click\_subscribe()](https://developer.repebble.com/docs/c/User_Interface/Window.md#window_single_click_subscribe), [window\_single\_repeating\_click\_subscribe()](https://developer.repebble.com/docs/c/User_Interface/Window.md#window_single_repeating_click_subscribe), [window\_multi\_click\_subscribe()](https://developer.repebble.com/docs/c/User_Interface/Window.md#window_multi_click_subscribe), [window\_long\_click\_subscribe()](https://developer.repebble.com/docs/c/User_Interface/Window.md#window_long_click_subscribe) and [window\_raw\_click\_subscribe()](https://developer.repebble.com/docs/c/User_Interface/Window.md#window_raw_click_subscribe) functions to register a handler for each event you wish to receive. For convenience, click handlers are provided with a [ClickRecognizerRef](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#ClickRecognizerRef) and a user-specified context. The [ClickRecognizerRef](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#ClickRecognizerRef) can be used in combination with [click\_number\_of\_clicks\_counted()](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#click_number_of_clicks_counted), [click\_recognizer\_get\_button\_id()](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#click_recognizer_get_button_id) and [click\_recognizer\_is\_repeating()](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#click_recognizer_is_repeating) to get more information about the click. This is useful if you want different buttons or event types to share the same handler. The user-specified context is the context of your [ClickConfigProvider](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#ClickConfigProvider) (see above). By default it points to the window. You can override it for all handlers with [window\_set\_click\_config\_provider\_with\_context()](https://developer.repebble.com/docs/c/User_Interface/Window.md#window_set_click_config_provider_with_context) or for a specific button with [window\_set\_click\_context()](https://developer.repebble.com/docs/c/User_Interface/Window.md#window_set_click_context). ### User interaction in watchfaces Watchfaces cannot use the buttons to interact with the user. Instead, you can use the [AccelerometerService](https://developer.repebble.com/docs/c/Foundation/Event_Service/AccelerometerService.md). ### About the Back button By default, the Back button will always pop to the previous window on the [Window Stack](https://developer.repebble.com/docs/c/User_Interface/Window_Stack.md) (and leave the app if the current window is the only window). You can override the default back button behavior with [window\_single\_click\_subscribe()](https://developer.repebble.com/docs/c/User_Interface/Window.md#window_single_click_subscribe) and [window\_multi\_click\_subscribe()](https://developer.repebble.com/docs/c/User_Interface/Window.md#window_multi_click_subscribe) but you cannot set a repeating, long or raw click handler on the back button because a long press will always terminate the app and return to the main menu. ### Usage example First associate a click config provider callback with your window: ``` void app\_init(void) {...window\_set\_click\_config\_provider(&window, (ClickConfigProvider) config\_provider);...} ``` Then in the callback, you set your desired configuration for each button: ``` void config\_provider(Window \*window) { // single click / repeat-on-hold config:window\_single\_click\_subscribe(BUTTON\_ID\_DOWN, down\_single\_click\_handler);window\_single\_repeating\_click\_subscribe(BUTTON\_ID\_SELECT, 1000, select\_single\_click\_handler);// multi click config:window\_multi\_click\_subscribe(BUTTON\_ID\_SELECT, 2, 10, 0, true, select\_multi\_click\_handler);// long click config:window\_long\_click\_subscribe(BUTTON\_ID\_SELECT, 700, select\_long\_click\_handler, select\_long\_click\_release\_handler);} ``` Now you implement the handlers for each click you've subscribed to and set up: ``` void down\_single\_click\_handler(ClickRecognizerRef recognizer, void \*context) {... called on single click ...Window \*window = (Window \*)context;}void select\_single\_click\_handler(ClickRecognizerRef recognizer, void \*context) {... called on single click, and every 1000ms of being held ...Window \*window = (Window \*)context;}void select\_multi\_click\_handler(ClickRecognizerRef recognizer, void \*context) {... called for multi-clicks ...Window \*window = (Window \*)context;const uint16\_t count = click\_number\_of\_clicks\_counted(recognizer);}void select\_long\_click\_handler(ClickRecognizerRef recognizer, void \*context) {... called on long click start ...Window \*window = (Window \*)context;}void select\_long\_click\_release\_handler(ClickRecognizerRef recognizer, void \*context) {... called when long click is released ...Window \*window = (Window \*)context;} ``` ### See also Refer to the [User Interface Layers chapter in the Pebble Developer Guides](https://developer.repebble.com/guides/user-interfaces/layers.md) (chapter "Clicks") for a conceptual overview of clicks and relevant code examples. ## Function Documentation uint8\_t click\_number\_of\_clicks\_counted([ClickRecognizerRef](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#ClickRecognizerRef) recognizer) Gets the click count. You can use this inside a click handler implementation to get the click count for multi\_click and (repeated) click events. #### Parameters recognizer The click recognizer for which to get the click count #### Returns The number of consecutive clicks, and for auto-repeating the number of repetitions. [ButtonId](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#ButtonId) click\_recognizer\_get\_button\_id([ClickRecognizerRef](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#ClickRecognizerRef) recognizer) Gets the button identifier. You can use this inside a click handler implementation to get the button id for the click event. #### Parameters recognizer The click recognizer for which to get the button id that caused the click event #### Returns the [ButtonId](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#ButtonId) of the click recognizer bool click\_recognizer\_is\_repeating([ClickRecognizerRef](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#ClickRecognizerRef) recognizer) Is this a repeating click. You can use this inside a click handler implementation to find out whether this is a repeating click or not. #### Parameters recognizer The click recognizer for which to find out whether this is a repeating click. #### Returns true if this is a repeating click. ## Enum Documentation enum ButtonId Button ID values. click\_recognizer\_get\_button\_id() #### Enumerators BUTTON\_ID\_BACK Back button. BUTTON\_ID\_UP Up button. BUTTON\_ID\_SELECT Select (middle) button. BUTTON\_ID\_DOWN Down button. NUM\_BUTTONS Total number of buttons. ## Typedef Documentation typedef void \* ClickRecognizerRef Reference to opaque click recognizer When a [ClickHandler](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#ClickHandler) callback is called, the recognizer that fired the handler is passed in. #### See Also [ClickHandler](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#ClickHandler) [click\_number\_of\_clicks\_counted()](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#click_number_of_clicks_counted) [click\_recognizer\_get\_button\_id()](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#click_recognizer_get_button_id) [click\_recognizer\_is\_repeating()](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#click_recognizer_is_repeating) typedef void(\* ClickHandler)(ClickRecognizerRef recognizer, void \*context) Function signature of the callback that handles a recognized click pattern. #### Parameters recognizer The click recognizer that detected a "click" pattern context Pointer to application specified data (see [window\_set\_click\_config\_provider\_with\_context()](https://developer.repebble.com/docs/c/User_Interface/Window.md#window_set_click_config_provider_with_context) and [window\_set\_click\_context()](https://developer.repebble.com/docs/c/User_Interface/Window.md#window_set_click_context)). This defaults to the window. #### See Also [ClickConfigProvider](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#ClickConfigProvider) typedef void(\* ClickConfigProvider)(void \*context) This callback is called every time the window becomes visible (and when you call [window\_set\_click\_config\_provider()](https://developer.repebble.com/docs/c/User_Interface/Window.md#window_set_click_config_provider) if the window is already visible). Subscribe to click events using [window\_single\_click\_subscribe()](https://developer.repebble.com/docs/c/User_Interface/Window.md#window_single_click_subscribe) [window\_single\_repeating\_click\_subscribe()](https://developer.repebble.com/docs/c/User_Interface/Window.md#window_single_repeating_click_subscribe) [window\_multi\_click\_subscribe()](https://developer.repebble.com/docs/c/User_Interface/Window.md#window_multi_click_subscribe) [window\_long\_click\_subscribe()](https://developer.repebble.com/docs/c/User_Interface/Window.md#window_long_click_subscribe) [window\_raw\_click\_subscribe()](https://developer.repebble.com/docs/c/User_Interface/Window.md#window_raw_click_subscribe) These subscriptions will get used by the click recognizers of each of the 4 buttons. #### Parameters context Pointer to application specific data (see [window\_set\_click\_config\_provider\_with\_context()](https://developer.repebble.com/docs/c/User_Interface/Window.md#window_set_click_config_provider_with_context)). --- # Color Definitions Source: https://developer.repebble.com/docs/c/Graphics/Graphics_Types/Color_Definitions/ A list of all of the named colors available with links to the color map on the Pebble Developer website. ## Macro Definition Documentation #define GColorBlackARGB8 ((uint8\_t)0b11000000) #define GColorOxfordBlueARGB8 ((uint8\_t)0b11000001) #define GColorDukeBlueARGB8 ((uint8\_t)0b11000010) #define GColorBlueARGB8 ((uint8\_t)0b11000011) #define GColorDarkGreenARGB8 ((uint8\_t)0b11000100) #define GColorMidnightGreenARGB8 ((uint8\_t)0b11000101) #define GColorCobaltBlueARGB8 ((uint8\_t)0b11000110) #define GColorBlueMoonARGB8 ((uint8\_t)0b11000111) #define GColorIslamicGreenARGB8 ((uint8\_t)0b11001000) #define GColorJaegerGreenARGB8 ((uint8\_t)0b11001001) #define GColorTiffanyBlueARGB8 ((uint8\_t)0b11001010) #define GColorVividCeruleanARGB8 ((uint8\_t)0b11001011) #define GColorGreenARGB8 ((uint8\_t)0b11001100) #define GColorMalachiteARGB8 ((uint8\_t)0b11001101) #define GColorMediumSpringGreenARGB8 ((uint8\_t)0b11001110) #define GColorCyanARGB8 ((uint8\_t)0b11001111) #define GColorBulgarianRoseARGB8 ((uint8\_t)0b11010000) #define GColorImperialPurpleARGB8 ((uint8\_t)0b11010001) #define GColorIndigoARGB8 ((uint8\_t)0b11010010) #define GColorElectricUltramarineARGB8 ((uint8\_t)0b11010011) #define GColorArmyGreenARGB8 ((uint8\_t)0b11010100) #define GColorDarkGrayARGB8 ((uint8\_t)0b11010101) #define GColorLibertyARGB8 ((uint8\_t)0b11010110) #define GColorVeryLightBlueARGB8 ((uint8\_t)0b11010111) #define GColorKellyGreenARGB8 ((uint8\_t)0b11011000) #define GColorMayGreenARGB8 ((uint8\_t)0b11011001) #define GColorCadetBlueARGB8 ((uint8\_t)0b11011010) #define GColorPictonBlueARGB8 ((uint8\_t)0b11011011) #define GColorBrightGreenARGB8 ((uint8\_t)0b11011100) #define GColorScreaminGreenARGB8 ((uint8\_t)0b11011101) #define GColorMediumAquamarineARGB8 ((uint8\_t)0b11011110) #define GColorElectricBlueARGB8 ((uint8\_t)0b11011111) #define GColorDarkCandyAppleRedARGB8 ((uint8\_t)0b11100000) #define GColorJazzberryJamARGB8 ((uint8\_t)0b11100001) #define GColorPurpleARGB8 ((uint8\_t)0b11100010) #define GColorVividVioletARGB8 ((uint8\_t)0b11100011) #define GColorWindsorTanARGB8 ((uint8\_t)0b11100100) #define GColorRoseValeARGB8 ((uint8\_t)0b11100101) #define GColorPurpureusARGB8 ((uint8\_t)0b11100110) #define GColorLavenderIndigoARGB8 ((uint8\_t)0b11100111) #define GColorLimerickARGB8 ((uint8\_t)0b11101000) #define GColorBrassARGB8 ((uint8\_t)0b11101001) #define GColorLightGrayARGB8 ((uint8\_t)0b11101010) #define GColorBabyBlueEyesARGB8 ((uint8\_t)0b11101011) #define GColorSpringBudARGB8 ((uint8\_t)0b11101100) #define GColorInchwormARGB8 ((uint8\_t)0b11101101) #define GColorMintGreenARGB8 ((uint8\_t)0b11101110) #define GColorCelesteARGB8 ((uint8\_t)0b11101111) #define GColorRedARGB8 ((uint8\_t)0b11110000) #define GColorFollyARGB8 ((uint8\_t)0b11110001) #define GColorFashionMagentaARGB8 ((uint8\_t)0b11110010) #define GColorMagentaARGB8 ((uint8\_t)0b11110011) #define GColorOrangeARGB8 ((uint8\_t)0b11110100) #define GColorSunsetOrangeARGB8 ((uint8\_t)0b11110101) #define GColorBrilliantRoseARGB8 ((uint8\_t)0b11110110) #define GColorShockingPinkARGB8 ((uint8\_t)0b11110111) #define GColorChromeYellowARGB8 ((uint8\_t)0b11111000) #define GColorRajahARGB8 ((uint8\_t)0b11111001) #define GColorMelonARGB8 ((uint8\_t)0b11111010) #define GColorRichBrilliantLavenderARGB8 ((uint8\_t)0b11111011) #define GColorYellowARGB8 ((uint8\_t)0b11111100) #define GColorIcterineARGB8 ((uint8\_t)0b11111101) #define GColorPastelYellowARGB8 ((uint8\_t)0b11111110) #define GColorWhiteARGB8 ((uint8\_t)0b11111111) #define GColorBlack (GColor8){.argb=GColorBlackARGB8} [GColorBlack](https://developer.repebble.com/tools/color-picker/#000000) #define GColorOxfordBlue (GColor8){.argb=GColorOxfordBlueARGB8} [GColorOxfordBlue](https://developer.repebble.com/tools/color-picker/#000055) #define GColorDukeBlue (GColor8){.argb=GColorDukeBlueARGB8} [GColorDukeBlue](https://developer.repebble.com/tools/color-picker/#0000AA) #define GColorBlue (GColor8){.argb=GColorBlueARGB8} [GColorBlue](https://developer.repebble.com/tools/color-picker/#0000FF) #define GColorDarkGreen (GColor8){.argb=GColorDarkGreenARGB8} [GColorDarkGreen](https://developer.repebble.com/tools/color-picker/#005500) #define GColorMidnightGreen (GColor8){.argb=GColorMidnightGreenARGB8} [GColorMidnightGreen](https://developer.repebble.com/tools/color-picker/#005555) #define GColorCobaltBlue (GColor8){.argb=GColorCobaltBlueARGB8} [GColorCobaltBlue](https://developer.repebble.com/tools/color-picker/#0055AA) #define GColorBlueMoon (GColor8){.argb=GColorBlueMoonARGB8} [GColorBlueMoon](https://developer.repebble.com/tools/color-picker/#0055FF) #define GColorIslamicGreen (GColor8){.argb=GColorIslamicGreenARGB8} [GColorIslamicGreen](https://developer.repebble.com/tools/color-picker/#00AA00) #define GColorJaegerGreen (GColor8){.argb=GColorJaegerGreenARGB8} [GColorJaegerGreen](https://developer.repebble.com/tools/color-picker/#00AA55) #define GColorTiffanyBlue (GColor8){.argb=GColorTiffanyBlueARGB8} [GColorTiffanyBlue](https://developer.repebble.com/tools/color-picker/#00AAAA) #define GColorVividCerulean (GColor8){.argb=GColorVividCeruleanARGB8} [GColorVividCerulean](https://developer.repebble.com/tools/color-picker/#00AAFF) #define GColorGreen (GColor8){.argb=GColorGreenARGB8} [GColorGreen](https://developer.repebble.com/tools/color-picker/#00FF00) #define GColorMalachite (GColor8){.argb=GColorMalachiteARGB8} [GColorMalachite](https://developer.repebble.com/tools/color-picker/#00FF55) #define GColorMediumSpringGreen (GColor8){.argb=GColorMediumSpringGreenARGB8} [GColorMediumSpringGreen](https://developer.repebble.com/tools/color-picker/#00FFAA) #define GColorCyan (GColor8){.argb=GColorCyanARGB8} [GColorCyan](https://developer.repebble.com/tools/color-picker/#00FFFF) #define GColorBulgarianRose (GColor8){.argb=GColorBulgarianRoseARGB8} [GColorBulgarianRose](https://developer.repebble.com/tools/color-picker/#550000) #define GColorImperialPurple (GColor8){.argb=GColorImperialPurpleARGB8} [GColorImperialPurple](https://developer.repebble.com/tools/color-picker/#550055) #define GColorIndigo (GColor8){.argb=GColorIndigoARGB8} [GColorIndigo](https://developer.repebble.com/tools/color-picker/#5500AA) #define GColorElectricUltramarine (GColor8){.argb=GColorElectricUltramarineARGB8} [GColorElectricUltramarine](https://developer.repebble.com/tools/color-picker/#5500FF) #define GColorArmyGreen (GColor8){.argb=GColorArmyGreenARGB8} [GColorArmyGreen](https://developer.repebble.com/tools/color-picker/#555500) #define GColorDarkGray (GColor8){.argb=GColorDarkGrayARGB8} [GColorDarkGray](https://developer.repebble.com/tools/color-picker/#555555) #define GColorLiberty (GColor8){.argb=GColorLibertyARGB8} [GColorLiberty](https://developer.repebble.com/tools/color-picker/#5555AA) #define GColorVeryLightBlue (GColor8){.argb=GColorVeryLightBlueARGB8} [GColorVeryLightBlue](https://developer.repebble.com/tools/color-picker/#5555FF) #define GColorKellyGreen (GColor8){.argb=GColorKellyGreenARGB8} [GColorKellyGreen](https://developer.repebble.com/tools/color-picker/#55AA00) #define GColorMayGreen (GColor8){.argb=GColorMayGreenARGB8} [GColorMayGreen](https://developer.repebble.com/tools/color-picker/#55AA55) #define GColorCadetBlue (GColor8){.argb=GColorCadetBlueARGB8} [GColorCadetBlue](https://developer.repebble.com/tools/color-picker/#55AAAA) #define GColorPictonBlue (GColor8){.argb=GColorPictonBlueARGB8} [GColorPictonBlue](https://developer.repebble.com/tools/color-picker/#55AAFF) #define GColorBrightGreen (GColor8){.argb=GColorBrightGreenARGB8} [GColorBrightGreen](https://developer.repebble.com/tools/color-picker/#55FF00) #define GColorScreaminGreen (GColor8){.argb=GColorScreaminGreenARGB8} [GColorScreaminGreen](https://developer.repebble.com/tools/color-picker/#55FF55) #define GColorMediumAquamarine (GColor8){.argb=GColorMediumAquamarineARGB8} [GColorMediumAquamarine](https://developer.repebble.com/tools/color-picker/#55FFAA) #define GColorElectricBlue (GColor8){.argb=GColorElectricBlueARGB8} [GColorElectricBlue](https://developer.repebble.com/tools/color-picker/#55FFFF) #define GColorDarkCandyAppleRed (GColor8){.argb=GColorDarkCandyAppleRedARGB8} [GColorDarkCandyAppleRed](https://developer.repebble.com/tools/color-picker/#AA0000) #define GColorJazzberryJam (GColor8){.argb=GColorJazzberryJamARGB8} [GColorJazzberryJam](https://developer.repebble.com/tools/color-picker/#AA0055) #define GColorPurple (GColor8){.argb=GColorPurpleARGB8} [GColorPurple](https://developer.repebble.com/tools/color-picker/#AA00AA) #define GColorVividViolet (GColor8){.argb=GColorVividVioletARGB8} [GColorVividViolet](https://developer.repebble.com/tools/color-picker/#AA00FF) #define GColorWindsorTan (GColor8){.argb=GColorWindsorTanARGB8} [GColorWindsorTan](https://developer.repebble.com/tools/color-picker/#AA5500) #define GColorRoseVale (GColor8){.argb=GColorRoseValeARGB8} [GColorRoseVale](https://developer.repebble.com/tools/color-picker/#AA5555) #define GColorPurpureus (GColor8){.argb=GColorPurpureusARGB8} [GColorPurpureus](https://developer.repebble.com/tools/color-picker/#AA55AA) #define GColorLavenderIndigo (GColor8){.argb=GColorLavenderIndigoARGB8} [GColorLavenderIndigo](https://developer.repebble.com/tools/color-picker/#AA55FF) #define GColorLimerick (GColor8){.argb=GColorLimerickARGB8} [GColorLimerick](https://developer.repebble.com/tools/color-picker/#AAAA00) #define GColorBrass (GColor8){.argb=GColorBrassARGB8} [GColorBrass](https://developer.repebble.com/tools/color-picker/#AAAA55) #define GColorLightGray (GColor8){.argb=GColorLightGrayARGB8} [GColorLightGray](https://developer.repebble.com/tools/color-picker/#AAAAAA) #define GColorBabyBlueEyes (GColor8){.argb=GColorBabyBlueEyesARGB8} [GColorBabyBlueEyes](https://developer.repebble.com/tools/color-picker/#AAAAFF) #define GColorSpringBud (GColor8){.argb=GColorSpringBudARGB8} [GColorSpringBud](https://developer.repebble.com/tools/color-picker/#AAFF00) #define GColorInchworm (GColor8){.argb=GColorInchwormARGB8} [GColorInchworm](https://developer.repebble.com/tools/color-picker/#AAFF55) #define GColorMintGreen (GColor8){.argb=GColorMintGreenARGB8} [GColorMintGreen](https://developer.repebble.com/tools/color-picker/#AAFFAA) #define GColorCeleste (GColor8){.argb=GColorCelesteARGB8} [GColorCeleste](https://developer.repebble.com/tools/color-picker/#AAFFFF) #define GColorRed (GColor8){.argb=GColorRedARGB8} [GColorRed](https://developer.repebble.com/tools/color-picker/#FF0000) #define GColorFolly (GColor8){.argb=GColorFollyARGB8} [GColorFolly](https://developer.repebble.com/tools/color-picker/#FF0055) #define GColorFashionMagenta (GColor8){.argb=GColorFashionMagentaARGB8} [GColorFashionMagenta](https://developer.repebble.com/tools/color-picker/#FF00AA) #define GColorMagenta (GColor8){.argb=GColorMagentaARGB8} [GColorMagenta](https://developer.repebble.com/tools/color-picker/#FF00FF) #define GColorOrange (GColor8){.argb=GColorOrangeARGB8} [GColorOrange](https://developer.repebble.com/tools/color-picker/#FF5500) #define GColorSunsetOrange (GColor8){.argb=GColorSunsetOrangeARGB8} [GColorSunsetOrange](https://developer.repebble.com/tools/color-picker/#FF5555) #define GColorBrilliantRose (GColor8){.argb=GColorBrilliantRoseARGB8} [GColorBrilliantRose](https://developer.repebble.com/tools/color-picker/#FF55AA) #define GColorShockingPink (GColor8){.argb=GColorShockingPinkARGB8} [GColorShockingPink](https://developer.repebble.com/tools/color-picker/#FF55FF) #define GColorChromeYellow (GColor8){.argb=GColorChromeYellowARGB8} [GColorChromeYellow](https://developer.repebble.com/tools/color-picker/#FFAA00) #define GColorRajah (GColor8){.argb=GColorRajahARGB8} [GColorRajah](https://developer.repebble.com/tools/color-picker/#FFAA55) #define GColorMelon (GColor8){.argb=GColorMelonARGB8} [GColorMelon](https://developer.repebble.com/tools/color-picker/#FFAAAA) #define GColorRichBrilliantLavender (GColor8){.argb=GColorRichBrilliantLavenderARGB8} [GColorRichBrilliantLavender](https://developer.repebble.com/tools/color-picker/#FFAAFF) #define GColorYellow (GColor8){.argb=GColorYellowARGB8} [GColorYellow](https://developer.repebble.com/tools/color-picker/#FFFF00) #define GColorIcterine (GColor8){.argb=GColorIcterineARGB8} [GColorIcterine](https://developer.repebble.com/tools/color-picker/#FFFF55) #define GColorPastelYellow (GColor8){.argb=GColorPastelYellowARGB8} [GColorPastelYellow](https://developer.repebble.com/tools/color-picker/#FFFFAA) #define GColorWhite (GColor8){.argb=GColorWhiteARGB8} [GColorWhite](https://developer.repebble.com/tools/color-picker/#FFFFFF) #define GColorClearARGB8 ((uint8\_t)0b00000000) #define GColorClear ((GColor8){.argb=GColorClearARGB8}) --- # CompassService Source: https://developer.repebble.com/docs/c/Foundation/Event_Service/CompassService/ The Compass Service combines information from Pebble's accelerometer and magnetometer to automatically calibrate the compass and transform the raw magnetic field information into a [CompassHeading](https://developer.repebble.com/docs/c/Foundation/Event_Service/CompassService.md#CompassHeading), that is an angle to north. It also provides magnetic north and information about its status and accuracy through the [CompassHeadingData](https://developer.repebble.com/docs/c/Foundation/Event_Service/CompassService.md#CompassHeadingData) structure. The API is designed to also provide true north in a future release. Note that not all platforms have compasses. To check for the presence of a compass at compile time for the current platform use the `PBL_COMPASS` define. To learn more about the Compass Service and how to use it, read the [Determining Direction](https://developer.repebble.com/guides/pebble-apps/sensors/magnetometer/) guide. For available code samples, see the [feature-compass](https://github.com/pebble-examples/feature-compass) example. ## Function Documentation int compass\_service\_set\_heading\_filter([CompassHeading](https://developer.repebble.com/docs/c/Foundation/Event_Service/CompassService.md#CompassHeading) filter) Set the minimum angular change required to generate new compass heading events. The angular distance is measured relative to the last delivered heading event. Use 0 to be notified of all movements. Negative values and values \> TRIG\_MAX\_ANGLE / 2 are not valid. The default value of this property is TRIG\_MAX\_ANGLE / 360. #### Returns 0, success. Non-Zero, if filter is invalid. #### See Also [compass\_service\_subscribe](https://developer.repebble.com/docs/c/Foundation/Event_Service/CompassService.md#compass_service_subscribe) void compass\_service\_subscribe([CompassHeadingHandler](https://developer.repebble.com/docs/c/Foundation/Event_Service/CompassService.md#CompassHeadingHandler) handler) Subscribe to the compass heading event service. Once subscribed, the handler gets called every time the angular distance relative to the previous value exceeds the configured filter. #### Parameters handler A callback to be executed on heading events #### See Also [compass\_service\_set\_heading\_filter](https://developer.repebble.com/docs/c/Foundation/Event_Service/CompassService.md#compass_service_set_heading_filter) [compass\_service\_unsubscribe](https://developer.repebble.com/docs/c/Foundation/Event_Service/CompassService.md#compass_service_unsubscribe) void compass\_service\_unsubscribe(void) Unsubscribe from the compass heading event service. Once unsubscribed, the previously registered handler will no longer be called. #### See Also [compass\_service\_subscribe](https://developer.repebble.com/docs/c/Foundation/Event_Service/CompassService.md#compass_service_subscribe) int compass\_service\_peek([CompassHeadingData](https://developer.repebble.com/docs/c/Foundation/Event_Service/CompassService.md#CompassHeadingData) \* data) Peek at the last recorded reading. #### Parameters data (out) a pointer to a pre-allocated [CompassHeadingData](https://developer.repebble.com/docs/c/Foundation/Event_Service/CompassService.md#CompassHeadingData) #### Returns Always returns 0 to indicate success. ## Data Structure Documentation struct CompassHeadingData Structure containing a single heading towards magnetic and true north. #### Data Fields [CompassHeading](https://developer.repebble.com/docs/c/Foundation/Event_Service/CompassService.md#CompassHeading) magnetic\_heading Measured angle that increases counter-clockwise from magnetic north (use `int clockwise_heading = TRIG_MAX_ANGLE - heading_data.magnetic_heading;` for example to find your heading clockwise from magnetic north). [CompassHeading](https://developer.repebble.com/docs/c/Foundation/Event_Service/CompassService.md#CompassHeading) true\_heading Currently same value as magnetic\_heading (reserved for future implementation). [CompassStatus](https://developer.repebble.com/docs/c/Foundation/Event_Service/CompassService.md#CompassStatus) compass\_status Indicates the current state of the Compass Service calibration. bool is\_declination\_valid Currently always false (reserved for future implementation). ## Enum Documentation enum CompassStatus Enum describing the current state of the Compass Service. #### Enumerators CompassStatusUnavailable The Compass Service is unavailable. CompassStatusDataInvalid Compass is calibrating: data is invalid and should not be used Data will become valid once calibration is complete. CompassStatusCalibrating Compass is calibrating: the data is valid but the calibration is still being refined. CompassStatusCalibrated Compass data is valid and the calibration has completed. ## Typedef Documentation typedef int32\_t CompassHeading Represents an angle relative to get to a reference direction, e.g. (magnetic) north. The angle value is scaled linearly, such that a value of TRIG\_MAX\_ANGLE corresponds to 360 degrees or 2 PI radians. Thus, if heading towards north, north is 0, west is TRIG\_MAX\_ANGLE/4, south is TRIG\_MAX\_ANGLE/2, and so on. typedef void(\* CompassHeadingHandler)(CompassHeadingData heading) Callback type for compass heading events. #### Parameters heading copy of last recorded heading --- # ConnectionService Source: https://developer.repebble.com/docs/c/Foundation/Event_Service/ConnectionService/ Determine what the Pebble watch is connected to The ConnectionService allows your app to learn about the apps the Pebble watch is connected to. You can ask the system for this information at a given time or you can register to receive events every time connection or disconnection events occur. It allows you to determine whether the watch is connected to the Pebble mobile app by subscribing to the pebble\_app\_connection\_handler or by calling the connection\_service\_peek\_pebble\_app\_connection function. Note that when the Pebble app is connected, you can assume PebbleKit JS apps will also be running correctly. The service also allows you to determine if the Pebble watch can establish a connection to a PebbleKit companion app by subscribing to the pebblekit\_connection\_handler or by calling the connection\_service\_peek\_pebblekit\_connection function. Today, due to architectural differences between iOS and Android, this will return true for Android anytime a connection with the Pebble mobile app is established (since PebbleKit messages are routed through the Android app). For iOS, this will return true when any PebbleKit companion app has established a connection with the Pebble watch (since companion app messages are routed directly to the watch) ## Function Documentation bool connection\_service\_peek\_pebble\_app\_connection(void) Query the bluetooth connection service for the current Pebble app connection status. #### Returns true if the Pebble app is connected, false otherwise bool connection\_service\_peek\_pebblekit\_connection(void) Query the bluetooth connection service for the current PebbleKit connection status. #### Returns true if a PebbleKit companion app is connected, false otherwise - [SDK 3](javascript:void(0);) - [SDK 4](javascript:void(0);) - [SDK 4.9+](javascript:void(0);) void connection\_service\_subscribe(ConnectionHandlers conn\_handlers) Subscribe to the connection event service. Once subscribed, the appropriate handler gets called based on the type of connection event and user provided handlers. #### Parameters ConnectionHandlers A struct populated with the handlers to be called when the specified connection event occurs. If a given handler is NULL, no function will be called. void connection\_service\_subscribe(ConnectionHandlers conn\_handlers) Subscribe to the connection event service. Once subscribed, the appropriate handler gets called based on the type of connection event and user provided handlers. #### Parameters ConnectionHandlers A struct populated with the handlers to be called when the specified connection event occurs. If a given handler is NULL, no function will be called. void connection\_service\_subscribe(ConnectionHandlers conn\_handlers) Subscribe to the connection event service. Once subscribed, the appropriate handler gets called based on the type of connection event and user provided handlers. #### Parameters conn\_handlers A struct populated with the handlers to be called when the specified connection event occurs. If a given handler is NULL, no function will be called. void connection\_service\_unsubscribe(void) Unsubscribe from the bluetooth event service. Once unsubscribed, the previously registered handler will no longer be called. bool bluetooth\_connection\_service\_peek(void) DeprecatedBackward compatibility function for connection\_service\_peek\_pebble\_app\_connection. New code should use connection\_service\_peek\_pebble\_app\_connection directly. This will be removed in a future version of the Pebble SDK void bluetooth\_connection\_service\_subscribe(ConnectionHandler handler) DeprecatedBackward compatibility function for connection\_service\_subscribe. New code should use connection\_service\_subscribe directly. This will be removed in a future version of the Pebble SDK void bluetooth\_connection\_service\_unsubscribe(void) DeprecatedBackward compatibility function for connection\_service\_unsubscribe. New code should use connection\_service\_unsubscribe directly. This will be removed in a future version of the Pebble SDK ## Data Structure Documentation struct ConnectionHandlers #### Data Fields ConnectionHandler pebble\_app\_connection\_handler callback to be executed when the connection state between the watch and the phone app has changed. Note, if the phone App is connected, PebbleKit JS apps will also be working correctly ConnectionHandler pebblekit\_connection\_handler ID for callback to be executed on PebbleKit connection event. ## Typedef Documentation typedef void(\* ConnectionHandler)(bool connected) typedef ConnectionHandler BluetoothConnectionHandler DeprecatedBackwards compatibility typedef for ConnectionHandler. New code should use ConnectionHandler directly. This will be removed in a future version of the Pebble SDK. --- # DataLogging Source: https://developer.repebble.com/docs/c/Foundation/DataLogging/ Enables logging data asynchronously to a mobile app In Pebble OS, data logging is a data storage and transfer subsystem that allows watchapps to save data on non-volatile storage devices when the phone is not available to process it. The API provides your watchapp with a mechanism for short-term data buffering for asynchronous data transmission to a mobile app. Using this API, your Pebble watchapp can create an arbitrary number of logs, but you’re limited in the amount of storage space you can use. Note that approximately 640K is available for data logging, which is shared among all watchapps that use it. This value is subject to change in the future. When the data spool is full, an app will start overwriting its own data. An app cannot overwrite another apps's data. However, the other app might have 0 bytes for data logging. Your app can log data to a session. Every new block of data is appended to the session. The data is then sent to the associated phone application at the earliest convenience. If a phone is available, the data is sent directly to the phone. Otherwise, it is saved to the watch storage until the watch is connected to a phone. For example: To create a data logging session for 4-byte unsigned integers with a tag of 0x1234, you would do this: ``` DataLoggingSessionRef logging\_session = data\_logging\_create(0x1234, DATA\_LOGGING\_UINT, 4,false);// Fake creating some data and logging it to the session.uint32\_t data[] = { 1, 2, 3};data\_logging\_log(logging\_session, &data, 3);// Fake creating more data and logging that as well.uint32\_t data2[] = { 1, 2 };data\_logging\_log(logging\_session, &data, 2);// When we don't need to log anything else, we can close off the session.data\_logging\_finish(logging\_session); ``` ## Function Documentation DataLoggingSessionRef data\_logging\_create([uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) tag, [DataLoggingItemType](https://developer.repebble.com/docs/c/Foundation/DataLogging.md#DataLoggingItemType) item\_type, [uint16\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint16_t) item\_length, bool resume) Create a new data logging session. #### Parameters tag A tag associated with the logging session. item\_type The type of data stored in this logging session item\_length The size of a single data item in bytes resume True if we want to look for a logging session of the same tag and resume logging to it. If this is false and a session with the specified tag exists, that session will be closed and a new session will be opened. #### Returns An opaque reference to the data logging session void data\_logging\_finish(DataLoggingSessionRef logging\_session) Finish up a data logging\_session. Logging data is kept until it has successfully been transferred over to the phone, but no data may be added to the session after this function is called. #### Parameters logging\_session a reference to the data logging session previously allocated using data\_logging\_create [DataLoggingResult](https://developer.repebble.com/docs/c/Foundation/DataLogging.md#DataLoggingResult) data\_logging\_log(DataLoggingSessionRef logging\_session, const void \* data, [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) num\_items) Add data to the data logging session. If a phone is available, the data is sent directly to the phone. Otherwise, it is saved to the watch storage until the watch is connected to a phone. #### Parameters logging\_session a reference to the data logging session you want to add the data to data a pointer to the data buffer that contains multiple items num\_items the number of items to log. This means data must be at least (num\_items \* item\_length) long in bytes #### Returns DATA\_LOGGING\_SUCCESS on success DATA\_LOGGING\_NOT\_FOUND if the logging session is invalid DATA\_LOGGING\_CLOSED if the sesion is not active DATA\_LOGGING\_BUSY if the sesion is not available for writing DATA\_LOGGING\_INVALID\_PARAMS if num\_items is 0 or data is NULL ## Enum Documentation enum DataLoggingItemType The different types of session data that Pebble supports. This type describes the type of a singular item in the data session. Every item in a given session is the same type and size. #### Enumerators DATA\_LOGGING\_BYTE\_ARRAY Array of bytes. Remember that this is the type of a single item in the logging session, so using this type means you'll be logging multiple byte arrays (each a fixed length described by item\_length) for the duration of the session. DATA\_LOGGING\_UINT Unsigned integer. This may be a 1, 2, or 4 byte integer depending on the item\_length parameter. DATA\_LOGGING\_INT Signed integer. This may be a 1, 2, or 4 byte integer depending on the item\_length parameter. enum DataLoggingResult Enumerated values describing the possible outcomes of data logging operations. #### Enumerators DATA\_LOGGING\_SUCCESS Successful operation. DATA\_LOGGING\_BUSY Someone else is writing to this logging session. DATA\_LOGGING\_FULL No more space to save data. DATA\_LOGGING\_NOT\_FOUND The logging session does not exist. DATA\_LOGGING\_CLOSED The logging session was made inactive. DATA\_LOGGING\_INVALID\_PARAMS An invalid parameter was passed to one of the functions. DATA\_LOGGING\_INTERNAL\_ERR An internal error occurred. ## Typedef Documentation typedef void \* DataLoggingSessionRef --- # Dictation Source: https://developer.repebble.com/docs/c/Foundation/Dictation/ ## Function Documentation - [SDK 3](javascript:void(0);) - [SDK 4](javascript:void(0);) - [SDK 4.9+](javascript:void(0);) DictationSession \* dictation\_session\_create([uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) buffer\_size, [DictationSessionStatusCallback](https://developer.repebble.com/docs/c/Foundation/Dictation.md#DictationSessionStatusCallback) callback, void \* callback\_context) Create a dictation session. The session object can be used more than once to get a transcription. When a transcription is received a buffer will be allocated to store the text in with a maximum size specified by buffer\_size. When a transcription and accepted by the user or a failure of some sort occurs, the callback specified will be called with the status and the transcription if one was accepted. #### Parameters buffer\_size size of buffer to allocate for the transcription text; text will be truncated if it is longer than the maximum size specified; a size of 0 will allow the session to allocate as much as it needs and text will not be truncated callback dictation session status handler (must be valid) callback\_context context pointer for status handler #### Returns handle to the dictation session or NULL if the phone app is not connected or does not support voice dictation, if this is called on a platform that doesn't support voice dictation, or if an internal error occurs. DictationSession \* dictation\_session\_create([uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) buffer\_size, [DictationSessionStatusCallback](https://developer.repebble.com/docs/c/Foundation/Dictation.md#DictationSessionStatusCallback) callback, void \* callback\_context) Create a dictation session. The session object can be used more than once to get a transcription. When a transcription is received a buffer will be allocated to store the text in with a maximum size specified by buffer\_size. When a transcription and accepted by the user or a failure of some sort occurs, the callback specified will be called with the status and the transcription if one was accepted. #### Parameters buffer\_size size of buffer to allocate for the transcription text; text will be truncated if it is longer than the maximum size specified; a size of 0 will allow the session to allocate as much as it needs and text will not be truncated callback dictation session status handler (must be valid) callback\_context context pointer for status handler #### Returns handle to the dictation session or NULL if the phone app is not connected or does not support voice dictation, if this is called on a platform that doesn't support voice dictation, or if an internal error occurs. DictationSession \* dictation\_session\_create([uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) buffer\_size, [DictationSessionStatusCallback](https://developer.repebble.com/docs/c/Foundation/Dictation.md#DictationSessionStatusCallback) callback, void \* callback\_context) Create a dictation session. The session object can be used more than once to get a transcription. When a transcription is received a buffer will be allocated to store the text in with a maximum size specified by `buffer_size`. When a transcription is accepted by the user or a failure of some sort occurs, the callback specified will be called with the status and the transcription if one was accepted. #### Parameters buffer\_size size of buffer to allocate for the transcription text; text will be truncated if it is longer than the maximum size specified; a size of 0 will allow the session to allocate as much as it needs and text will not be truncated callback dictation session status handler (must be valid) callback\_context context pointer for status handler #### Returns handle to the dictation session or NULL if the phone app is not connected or does not support voice dictation, if this is called on a platform that doesn't support voice dictation, or if an internal error occurs. void dictation\_session\_destroy(DictationSession \* session) Destroy the dictation session and free its memory. Will terminate a session in progress. #### Parameters session dictation session to be destroyed [DictationSessionStatus](https://developer.repebble.com/docs/c/Foundation/Dictation.md#DictationSessionStatus) dictation\_session\_start(DictationSession \* session) Start the dictation session. The dictation UI will be shown. When the user accepts a transcription or exits the UI, or, when the confirmation dialog is disabled and a status is received, the status callback will be called. Can only be called when no session is in progress. The session can be restarted multiple times after the UI is exited or the session is stopped. #### Parameters session dictation session to start or restart #### Returns true if session was started, false if session is already in progress or is invalid. [DictationSessionStatus](https://developer.repebble.com/docs/c/Foundation/Dictation.md#DictationSessionStatus) dictation\_session\_stop(DictationSession \* session) Stop the current dictation session. The UI will be hidden and no status callbacks will be received after the session is stopped. #### Parameters session dictation session to stop #### Returns true if session was stopped, false if session was not started or is invalid void dictation\_session\_enable\_confirmation(DictationSession \* session, bool is\_enabled) Enable or disable user confirmation of transcribed text, which allows the user to accept or reject (and restart) the transcription. Must be called before the session is started. #### Parameters session dictation session to modify is\_enabled set to true to enable user confirmation of transcriptions (default), false to disable void dictation\_session\_enable\_error\_dialogs(DictationSession \* session, bool is\_enabled) Enable or disable error dialogs when transcription fails. Must be called before the session is started. Disabling error dialogs will also disable automatic retries if transcription fails. #### Parameters session dictation session to modify is\_enabled set to true to enable error dialogs (default), false to disable ## Enum Documentation enum DictationSessionStatus #### Enumerators DictationSessionStatusSuccess Transcription successful, with a valid result. DictationSessionStatusFailureTranscriptionRejected User rejected transcription and exited UI. DictationSessionStatusFailureTranscriptionRejectedWithError User exited UI after transcription error. DictationSessionStatusFailureSystemAborted Too many errors occurred during transcription and the UI exited. DictationSessionStatusFailureNoSpeechDetected No speech was detected and UI exited. DictationSessionStatusFailureConnectivityError No BT or internet connection. DictationSessionStatusFailureDisabled Voice transcription disabled for this user. DictationSessionStatusFailureInternalError Voice transcription failed due to internal error. DictationSessionStatusFailureRecognizerError Cloud recognizer failed to transcribe speech (only possible if error dialogs disabled) ## Typedef Documentation typedef struct DictationSession DictationSession typedef void(\* DictationSessionStatusCallback)(DictationSession \*session, DictationSessionStatus status, char \*transcription, void \*context) Dictation status callback. Indicates success or failure of the dictation session and, if successful, passes the transcribed string to the user of the dictation session. The transcribed string will be freed after this call returns, so the string should be copied if it needs to be retained afterwards. #### Parameters session dictation session from which the status was received status dictation status transcription transcribed string context callback context specified when starting the session ## Macro Definition Documentation - [SDK 3](javascript:void(0);) - [SDK 4](javascript:void(0);) - [SDK 4.9+](javascript:void(0);) #define PBL\_IF\_MICROPHONE\_ELSE ( if\_true, if\_false) Convenience macro to switch between two expressions depending on mic support. On platforms with a mic the first expression will be chosen, the second otherwise. #define PBL\_IF\_MICROPHONE\_ELSE ( if\_true, if\_false) Convenience macro to switch between two expressions depending on mic support. On platforms with a mic the first expression will be chosen, the second otherwise. #define PBL\_IF\_MICROPHONE\_ELSE ( if\_true, if\_false) Convenience macro to switch between two expressions depending on mic support. On platforms with a mic the first expression will be chosen, the second otherwise. --- # Dictionary Source: https://developer.repebble.com/docs/c/Foundation/Dictionary/ Data serialization utilities Data residing in different parts of Pebble memory (RAM) may need to be gathered and assembled into a single continuous block for transport over the network via Bluetooth. The process of gathering and assembling this continuous block of data is called serialization. You use data serialization utilities, like Dictionary, [Tuple](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#Tuple) and [Tuplet](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#Tuplet) data structures and accompanying functions, to accomplish this task. No transformations are performed on the actual data, however. These Pebble utilities simply help assemble the data into one continuous buffer according to a specific format. [AppMessage](https://developer.repebble.com/docs/c/Foundation/AppMessage.md) uses these utilities-in particular, Dictionary-to send information between mobile and Pebble watchapps. ### Writing key/value pairs To write two key/value pairs, without using Tuplets, you would do this: ``` // Byte array + key:static const uint32\_t SOME\_DATA\_KEY = 0xb00bf00b;static const uint8\_t data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};// CString + key:static const uint32\_t SOME\_STRING\_KEY = 0xabbababe;static const char \*string = "Hello World";// Calculate the buffer size that is needed for the final Dictionary:const uint8\_t key\_count = 2;const uint32\_t size = dict\_calc\_buffer\_size(key\_count, sizeof(data),strlen(string) + 1);// Stack-allocated buffer in which to create the Dictionary:uint8\_t buffer[size];// Iterator variable, keeps the state of the creation serialization process:DictionaryIterator iter;// Begin:dict\_write\_begin(&iter, buffer, sizeof(buffer));// Write the Data:dict\_write\_data(&iter, SOME\_DATA\_KEY, data, sizeof(data));// Write the CString:dict\_write\_cstring(&iter, SOME\_STRING\_KEY, string);// End:const uint32\_t final\_size = dict\_write\_end(&iter);// buffer now contains the serialized information ``` ### Reading key/value pairs To iterate over the key/value pairs in the dictionary that was created in the previous example code, you would do this: ``` Tuple \*tuple = dict\_read\_begin\_from\_buffer(&iter, buffer, final\_size);while (tuple) {switch (tuple-\>key) {case SOME\_DATA\_KEY:foo(tuple-\>value-\>data, tuple-\>length);break;case SOME\_STRING\_KEY:bar(tuple-\>value-\>cstring);break;}tuple = dict\_read\_next(&iter);} ``` ### Tuple and Tuplet data structures To understand the difference between [Tuple](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#Tuple) and [Tuplet](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#Tuplet) data structures: [Tuple](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#Tuple) is the header for a serialized key/value pair, while [Tuplet](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#Tuplet) is a helper data structure that references the value you want to serialize. This data structure exists to make the creation of a Dictionary easier to write. Use this mnemonic to remember the difference: TupleT(emplate), the [Tuplet](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#Tuplet) being a template to create a Dictionary with [Tuple](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#Tuple) structures. For example: ``` Tuplet pairs[] = {TupletInteger(WEATHER\_ICON\_KEY, (uint8\_t) 1),TupletCString(WEATHER\_TEMPERATURE\_KEY, "1234 Fahrenheit"),};uint8\_t buffer[256];uint32\_t size = sizeof(buffer);dict\_serialize\_tuplets\_to\_buffer(pairs, ARRAY\_LENGTH(pairs), buffer, &size);// buffer now contains the serialized information ``` ## Function Documentation [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) dict\_calc\_buffer\_size(const uint8\_t tuple\_count, ...) Calculates the number of bytes that a dictionary will occupy, given one or more value lengths that need to be stored in the dictionary. ##### Note The formula to calculate the size of a Dictionary in bytes is: ``` 1 + (n * 7) + D1 + ... + Dn ``` Where `n` is the number of Tuples in the Dictionary and `Dx` are the sizes of the values in the Tuples. The size of the Dictionary header is 1 byte. The size of the header for each [Tuple](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#Tuple) is 7 bytes. #### Parameters tuple\_count The total number of key/value pairs in the dictionary. ... The sizes of each of the values that need to be stored in the dictionary. #### Returns The total number of bytes of storage needed. [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) dict\_size([DictionaryIterator](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#DictionaryIterator) \* iter) Calculates the size of data that has been written to the dictionary. AKA, the "dictionary size". Note that this is most likely different than the size of the backing storage/backing buffer. #### Parameters iter The dictionary iterator #### Returns The total number of bytes which have been written to the dictionary. [DictionaryResult](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#DictionaryResult) dict\_write\_begin([DictionaryIterator](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#DictionaryIterator) \* iter, uint8\_t \*const buffer, const [uint16\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint16_t) size) Initializes the dictionary iterator with a given buffer and size, resets and empties it, in preparation of writing key/value tuples. #### Parameters iter The dictionary iterator buffer The storage of the dictionary size The storage size of the dictionary #### Returns DICT\_OK, DICT\_NOT\_ENOUGH\_STORAGE or DICT\_INVALID\_ARGS #### See Also [dict\_calc\_buffer\_size](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#dict_calc_buffer_size) [dict\_write\_end](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#dict_write_end) [DictionaryResult](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#DictionaryResult) dict\_write\_data([DictionaryIterator](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#DictionaryIterator) \* iter, const [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) key, const uint8\_t \*const data, const [uint16\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint16_t) size) Adds a key with a byte array value pair to the dictionary. ##### Notes The data will be copied into the backing storage of the dictionary. There is _no_ checking for duplicate keys. #### Parameters iter The dictionary iterator key The key data Pointer to the byte array size Length of the byte array #### Returns DICT\_OK, DICT\_NOT\_ENOUGH\_STORAGE or DICT\_INVALID\_ARGS [DictionaryResult](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#DictionaryResult) dict\_write\_cstring([DictionaryIterator](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#DictionaryIterator) \* iter, const [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) key, const char \*const cstring) Adds a key with a C string value pair to the dictionary. ##### Notes The string will be copied into the backing storage of the dictionary. There is _no_ checking for duplicate keys. #### Parameters iter The dictionary iterator key The key cstring Pointer to the zero-terminated C string #### Returns DICT\_OK, DICT\_NOT\_ENOUGH\_STORAGE or DICT\_INVALID\_ARGS [DictionaryResult](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#DictionaryResult) dict\_write\_int([DictionaryIterator](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#DictionaryIterator) \* iter, const [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) key, const void \* integer, const uint8\_t width\_bytes, const bool is\_signed) Adds a key with an integer value pair to the dictionary. ##### Note There is _no_ checking for duplicate keys. [dict\_write\_int()](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#dict_write_int) is only for serializing a single integer. width\_bytes can only be 1, 2, or 4. #### Parameters iter The dictionary iterator key The key integer Pointer to the integer value width\_bytes The width of the integer value is\_signed Whether the integer's type is signed or not #### Returns DICT\_OK, DICT\_NOT\_ENOUGH\_STORAGE or DICT\_INVALID\_ARGS [DictionaryResult](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#DictionaryResult) dict\_write\_uint8([DictionaryIterator](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#DictionaryIterator) \* iter, const [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) key, const uint8\_t value) Adds a key with an unsigned, 8-bit integer value pair to the dictionary. ##### Notes There is _no_ checking for duplicate keys. There are counterpart functions for different signedness and widths, `dict_write_uint16()`, `dict_write_uint32()`, `dict_write_int8()`, `dict_write_int16()` and `dict_write_int32()`. The documentation is not repeated for brevity's sake. #### Parameters iter The dictionary iterator key The key value The unsigned, 8-bit integer value #### Returns DICT\_OK, DICT\_NOT\_ENOUGH\_STORAGE or DICT\_INVALID\_ARGS [DictionaryResult](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#DictionaryResult) dict\_write\_uint16([DictionaryIterator](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#DictionaryIterator) \* iter, const [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) key, const [uint16\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint16_t) value) [DictionaryResult](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#DictionaryResult) dict\_write\_uint32([DictionaryIterator](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#DictionaryIterator) \* iter, const [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) key, const [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) value) [DictionaryResult](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#DictionaryResult) dict\_write\_int8([DictionaryIterator](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#DictionaryIterator) \* iter, const [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) key, const int8\_t value) [DictionaryResult](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#DictionaryResult) dict\_write\_int16([DictionaryIterator](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#DictionaryIterator) \* iter, const [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) key, const int16\_t value) [DictionaryResult](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#DictionaryResult) dict\_write\_int32([DictionaryIterator](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#DictionaryIterator) \* iter, const [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) key, const int32\_t value) [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) dict\_write\_end([DictionaryIterator](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#DictionaryIterator) \* iter) End a series of writing operations to a dictionary. This must be called before reading back from the dictionary. #### Parameters iter The dictionary iterator #### Returns The size in bytes of the finalized dictionary, or 0 if the parameters were invalid. [Tuple](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#Tuple) \* dict\_read\_begin\_from\_buffer([DictionaryIterator](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#DictionaryIterator) \* iter, const uint8\_t \*const buffer, const [uint16\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint16_t) size) Initializes the dictionary iterator with a given buffer and size, in preparation of reading key/value tuples. #### Parameters iter The dictionary iterator buffer The storage of the dictionary size The storage size of the dictionary #### Returns The first tuple in the dictionary, or NULL in case the dictionary was empty or if there was a parsing error. [Tuple](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#Tuple) \* dict\_read\_next([DictionaryIterator](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#DictionaryIterator) \* iter) Progresses the iterator to the next key/value pair. #### Parameters iter The dictionary iterator #### Returns The next tuple in the dictionary, or NULL in case the end has been reached or if there was a parsing error. [Tuple](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#Tuple) \* dict\_read\_first([DictionaryIterator](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#DictionaryIterator) \* iter) Resets the iterator back to the same state as a call to [dict\_read\_begin\_from\_buffer()](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#dict_read_begin_from_buffer) would do. #### Parameters iter The dictionary iterator #### Returns The first tuple in the dictionary, or NULL in case the dictionary was empty or if there was a parsing error. [DictionaryResult](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#DictionaryResult) dict\_serialize\_tuplets([DictionarySerializeCallback](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#DictionarySerializeCallback) callback, void \* context, const [Tuplet](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#Tuplet) \*const tuplets, const uint8\_t tuplets\_count) Utility function that takes a list of Tuplets from which a dictionary will be serialized, ready to transmit or store. ##### Note The callback will be called before the function returns, so the data that that `context` points to, can be stack allocated. #### Parameters callback The callback that will be called with the serialized data of the generated dictionary. context Pointer to any application specific data that gets passed into the callback. tuplets An array of Tuplets that need to be serialized into the dictionary. tuplets\_count The number of tuplets that follow. #### Returns DICT\_OK, DICT\_NOT\_ENOUGH\_STORAGE or DICT\_INVALID\_ARGS - [SDK 3](javascript:void(0);) - [SDK 4](javascript:void(0);) - [SDK 4.9+](javascript:void(0);) [DictionaryResult](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#DictionaryResult) dict\_serialize\_tuplets\_to\_buffer(const [Tuplet](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#Tuplet) \*const tuplets, const uint8\_t tuplets\_count, uint8\_t \* buffer, [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) \* size\_in\_out) Utility function that takes an array of Tuplets and serializes them into a dictionary with a given buffer and size. #### Parameters tuplets The array of tuplets tuplets\_count The number of tuplets in the array buffer The buffer in which to write the serialized dictionary size\_in\_out (in) The available buffer size in bytes size\_in\_out (out) The number of bytes written #### Returns DICT\_OK, DICT\_NOT\_ENOUGH\_STORAGE or DICT\_INVALID\_ARGS [DictionaryResult](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#DictionaryResult) dict\_serialize\_tuplets\_to\_buffer(const [Tuplet](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#Tuplet) \*const tuplets, const uint8\_t tuplets\_count, uint8\_t \* buffer, [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) \* size\_in\_out) Utility function that takes an array of Tuplets and serializes them into a dictionary with a given buffer and size. #### Parameters tuplets The array of tuplets tuplets\_count The number of tuplets in the array buffer The buffer in which to write the serialized dictionary size\_in\_out (in) The available buffer size in bytes size\_in\_out (out) The number of bytes written #### Returns DICT\_OK, DICT\_NOT\_ENOUGH\_STORAGE or DICT\_INVALID\_ARGS [DictionaryResult](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#DictionaryResult) dict\_serialize\_tuplets\_to\_buffer(const [Tuplet](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#Tuplet) \*const tuplets, const uint8\_t tuplets\_count, uint8\_t \* buffer, [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) \* size\_in\_out) Utility function that takes an array of Tuplets and serializes them into a dictionary with a given buffer and size. #### Parameters tuplets The array of tuplets tuplets\_count The number of tuplets in the array buffer The buffer in which to write the serialized dictionary size\_in\_out (inout) In: the available buffer size in bytes. Out: the number of bytes written. #### Returns DICT\_OK, DICT\_NOT\_ENOUGH\_STORAGE or DICT\_INVALID\_ARGS - [SDK 3](javascript:void(0);) - [SDK 4](javascript:void(0);) - [SDK 4.9+](javascript:void(0);) [DictionaryResult](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#DictionaryResult) dict\_serialize\_tuplets\_to\_buffer\_with\_iter([DictionaryIterator](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#DictionaryIterator) \* iter, const [Tuplet](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#Tuplet) \*const tuplets, const uint8\_t tuplets\_count, uint8\_t \* buffer, [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) \* size\_in\_out) Serializes an array of Tuplets into a dictionary with a given buffer and size. #### Parameters iter The dictionary iterator tuplets The array of tuplets tuplets\_count The number of tuplets in the array buffer The buffer in which to write the serialized dictionary size\_in\_out (in) The available buffer size in bytes size\_in\_out (out) The number of bytes written #### Returns DICT\_OK, DICT\_NOT\_ENOUGH\_STORAGE or DICT\_INVALID\_ARGS [DictionaryResult](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#DictionaryResult) dict\_serialize\_tuplets\_to\_buffer\_with\_iter([DictionaryIterator](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#DictionaryIterator) \* iter, const [Tuplet](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#Tuplet) \*const tuplets, const uint8\_t tuplets\_count, uint8\_t \* buffer, [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) \* size\_in\_out) Serializes an array of Tuplets into a dictionary with a given buffer and size. #### Parameters iter The dictionary iterator tuplets The array of tuplets tuplets\_count The number of tuplets in the array buffer The buffer in which to write the serialized dictionary size\_in\_out (in) The available buffer size in bytes size\_in\_out (out) The number of bytes written #### Returns DICT\_OK, DICT\_NOT\_ENOUGH\_STORAGE or DICT\_INVALID\_ARGS [DictionaryResult](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#DictionaryResult) dict\_serialize\_tuplets\_to\_buffer\_with\_iter([DictionaryIterator](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#DictionaryIterator) \* iter, const [Tuplet](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#Tuplet) \*const tuplets, const uint8\_t tuplets\_count, uint8\_t \* buffer, [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) \* size\_in\_out) Serializes an array of Tuplets into a dictionary with a given buffer and size. #### Parameters iter The dictionary iterator tuplets The array of tuplets tuplets\_count The number of tuplets in the array buffer The buffer in which to write the serialized dictionary size\_in\_out (inout) In: the available buffer size in bytes. Out: the number of bytes written. #### Returns DICT\_OK, DICT\_NOT\_ENOUGH\_STORAGE or DICT\_INVALID\_ARGS [DictionaryResult](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#DictionaryResult) dict\_write\_tuplet([DictionaryIterator](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#DictionaryIterator) \* iter, const [Tuplet](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#Tuplet) \*const tuplet) Serializes a [Tuplet](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#Tuplet) and writes the resulting [Tuple](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#Tuple) into a dictionary. #### Parameters iter The dictionary iterator tuplet The [Tuplet](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#Tuplet) describing the key/value pair to write #### Returns DICT\_OK, DICT\_NOT\_ENOUGH\_STORAGE or DICT\_INVALID\_ARGS [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) dict\_calc\_buffer\_size\_from\_tuplets(const [Tuplet](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#Tuplet) \*const tuplets, const uint8\_t tuplets\_count) Calculates the number of bytes that a dictionary will occupy, given one or more Tuplets that need to be stored in the dictionary. ##### Note See [dict\_calc\_buffer\_size()](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#dict_calc_buffer_size) for the formula for the calculation. #### Parameters tuplets An array of Tuplets that need to be stored in the dictionary. tuplets\_count The total number of Tuplets that follow. #### Returns The total number of bytes of storage needed. #### See Also [Tuplet](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#Tuplet) [DictionaryResult](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#DictionaryResult) dict\_merge([DictionaryIterator](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#DictionaryIterator) \* dest, [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) \* dest\_max\_size\_in\_out, [DictionaryIterator](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#DictionaryIterator) \* source, const bool update\_existing\_keys\_only, const [DictionaryKeyUpdatedCallback](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#DictionaryKeyUpdatedCallback) key\_callback, void \* context) Merges entries from another "source" dictionary into a "destination" dictionary. All Tuples from the source are written into the destination dictionary, while updating the exsting Tuples with matching keys. #### Parameters dest The destination dictionary to update dest\_max\_size\_in\_out (inout) In: the maximum size of buffer backing `dest`. Out: the final size of the updated dictionary. source The source dictionary of which its Tuples will be used to update dest. update\_existing\_keys\_only Specify True if only the existing keys in `dest` should be updated. key\_callback The callback that will be called for each [Tuple](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#Tuple) in the merged destination dictionary. context Pointer to app specific data that will get passed in when `update_key_callback` is called. #### Returns DICT\_OK, DICT\_INVALID\_ARGS, DICT\_NOT\_ENOUGH\_STORAGE [Tuple](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#Tuple) \* dict\_find(const [DictionaryIterator](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#DictionaryIterator) \* iter, const [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) key) Tries to find a [Tuple](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#Tuple) with specified key in a dictionary. #### Parameters iter Iterator to the dictionary to search in. key The key for which to find a [Tuple](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#Tuple) #### Returns Pointer to a found [Tuple](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#Tuple), or NULL if there was no [Tuple](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#Tuple) with the specified key. ## Data Structure Documentation struct DictionaryIterator An iterator can be used to iterate over the key/value tuples in an existing dictionary, using [dict\_read\_begin\_from\_buffer()](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#dict_read_begin_from_buffer), [dict\_read\_first()](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#dict_read_first) and [dict\_read\_next()](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#dict_read_next). An iterator can also be used to append key/value tuples to a dictionary, for example using [dict\_write\_data()](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#dict_write_data) or [dict\_write\_cstring()](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#dict_write_cstring). #### Data Fields Dictionary \* dictionary The dictionary being iterated. const void \* end Points to the first memory address after the last byte of the dictionary Points to the next [Tuple](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#Tuple) in the dictionary. Given the end of the Dictionary has not yet been reached: when writing, the next key/value pair will be written at the cursor. When reading, the next call to [dict\_read\_next()](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#dict_read_next) will return the cursor. [Tuple](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#Tuple) \* cursor struct Tuple Data structure for one serialized key/value tuple. ##### Note The structure is variable length! The length depends on the value data that the tuple contains. #### Data Fields [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) key The key. [TupleType](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#TupleType) type The type of data that the `.value` fields contains. [uint16\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint16_t) length The length of `.value` in bytes. union [Tuple](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#Tuple) value The value itself. The different union fields are provided for convenience, avoiding the need for manual casts. ##### Notes The array length is of incomplete length on purpose, to facilitate variable length data and because a data length of zero is valid. **Important: The integers are little endian!** struct Tuplet Non-serialized, template data structure for a key/value pair. For strings and byte arrays, it only has a pointer to the actual data. For integers, it provides storage for integers up to 32-bits wide. The [Tuplet](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#Tuplet) data structure is useful when creating dictionaries from values that are already stored in arbitrary buffers. See also [Tuple](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#Tuple), with is the header of a serialized key/value pair. #### Data Fields [TupleType](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#TupleType) type The type of the [Tuplet](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#Tuplet). This determines which of the struct fields in the anonymomous union are valid. [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) key The key. union [Tuplet](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#Tuplet) Anonymous union containing the reference to the [Tuplet](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#Tuplet)'s value, being either a byte array, c-string or integer. See documentation of `.bytes`, `.cstring` and `.integer` fields. See documentation of `.bytes`, `.cstring` and `.integer` fields. ## Enum Documentation enum DictionaryResult Return values for dictionary write/conversion functions. #### Enumerators DICT\_OK The operation returned successfully. DICT\_NOT\_ENOUGH\_STORAGE There was not enough backing storage to complete the operation. DICT\_INVALID\_ARGS One or more arguments were invalid or uninitialized. DICT\_INTERNAL\_INCONSISTENCY The lengths and/or count of the dictionary its tuples are inconsistent. DICT\_MALLOC\_FAILED A requested operation required additional memory to be allocated, but the allocation failed, likely due to insufficient remaining heap memory. enum TupleType Values representing the type of data that the `value` field of a [Tuple](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#Tuple) contains. #### Enumerators TUPLE\_BYTE\_ARRAY The value is an array of bytes. TUPLE\_CSTRING The value is a zero-terminated, UTF-8 C-string. TUPLE\_UINT The value is an unsigned integer. The tuple's `.length` field is used to determine the size of the integer (1, 2, or 4 bytes). TUPLE\_INT The value is a signed integer. The tuple's `.length` field is used to determine the size of the integer (1, 2, or 4 bytes). ## Typedef Documentation typedef struct Dictionary Dictionary typedef void(\* DictionarySerializeCallback)(const uint8\_t \*const data, const uint16\_t size, void \*context) Callback for [dict\_serialize\_tuplets()](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#dict_serialize_tuplets) utility. #### Parameters data The data of the serialized dictionary size The size of data context The context pointer as passed in to [dict\_serialize\_tuplets()](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#dict_serialize_tuplets) #### See Also [dict\_serialize\_tuplets](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#dict_serialize_tuplets) - [SDK 3](javascript:void(0);) - [SDK 4](javascript:void(0);) - [SDK 4.9+](javascript:void(0);) typedef void(\* DictionaryKeyUpdatedCallback)(const uint32\_t key, const Tuple \*new\_tuple, const Tuple \*old\_tuple, void \*context) Type of the callback used in [dict\_merge()](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#dict_merge) #### Parameters key The key that is being updated. new\_tuple The new tuple. The tuple points to the actual, updated destination dictionary or NULL\_TUPLE in case there was an error (e.g. backing buffer was too small). Therefore the [Tuple](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#Tuple) can be used after the callback returns, until the destination dictionary storage is free'd (by the application itself). old\_tuple The values that will be replaced with `new_tuple`. The key, value and type will be equal to the previous tuple in the old destination dictionary, however the `old_tuple points to a stack-allocated copy of the old data. @param context Pointer to application specific data The storage backing `old\_tuple` can only be used during the callback and will no longer be valid after the callback returns. #### See Also [dict\_merge](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#dict_merge) typedef void(\* DictionaryKeyUpdatedCallback)(const uint32\_t key, const Tuple \*new\_tuple, const Tuple \*old\_tuple, void \*context) Type of the callback used in [dict\_merge()](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#dict_merge) #### Parameters key The key that is being updated. new\_tuple The new tuple. The tuple points to the actual, updated destination dictionary or NULL\_TUPLE in case there was an error (e.g. backing buffer was too small). Therefore the [Tuple](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#Tuple) can be used after the callback returns, until the destination dictionary storage is free'd (by the application itself). old\_tuple The values that will be replaced with `new_tuple`. The key, value and type will be equal to the previous tuple in the old destination dictionary, however the `old_tuple points to a stack-allocated copy of the old data. @param context Pointer to application specific data The storage backing `old\_tuple` can only be used during the callback and will no longer be valid after the callback returns. #### See Also [dict\_merge](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#dict_merge) typedef void(\* DictionaryKeyUpdatedCallback)(const uint32\_t key, const Tuple \*new\_tuple, const Tuple \*old\_tuple, void \*context) Type of the callback used in [dict\_merge()](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#dict_merge) #### Parameters key The key that is being updated. new\_tuple The new tuple. The tuple points to the actual, updated destination dictionary or NULL\_TUPLE in case there was an error (e.g. backing buffer was too small). Therefore the [Tuple](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#Tuple) can be used after the callback returns, until the destination dictionary storage is free'd (by the application itself). old\_tuple The values that will be replaced with `new_tuple`. The key, value and type will be equal to the previous tuple in the old destination dictionary, however the `old_tuple` points to a stack-allocated copy of the old data. context Pointer to application specific data The storage backing `old_tuple` can only be used during the callback and will no longer be valid after the callback returns. #### See Also [dict\_merge](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#dict_merge) ## Macro Definition Documentation #define TupletBytes ( \_key, \_data, \_length) Macro to create a [Tuplet](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#Tuplet) with a byte array value. #### Parameters \_key The key \_data Pointer to the bytes \_length Length of the buffer #define TupletCString ( \_key, \_cstring) Macro to create a [Tuplet](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#Tuplet) with a c-string value. #### Parameters \_key The key \_cstring The c-string value #define TupletInteger ( \_key, \_integer) Macro to create a [Tuplet](https://developer.repebble.com/docs/c/Foundation/Dictionary.md#Tuplet) with an integer value. #### Parameters \_key The key \_integer The integer value --- # Draw Commands Source: https://developer.repebble.com/docs/c/Graphics/Draw_Commands/ Pebble Draw Commands are a way to encode arbitrary path draw and fill calls in binary format, so that vector-like graphics can be represented on the watch. These draw commands can be loaded from resources, manipulated in place and drawn to the current graphics context. Each [GDrawCommand](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommand) can be an arbitrary path or a circle with optional fill or stroke. The stroke width and color of the stroke and fill are also encoded within the [GDrawCommand](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommand). Paths can can be drawn open or closed. All aspects of a draw command can be modified, except for the number of points in a path (a circle only has one point, the center). Draw commands are grouped into a [GDrawCommandList](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandList), which can be drawn all at once. Each individual [GDrawCommand](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommand) can be accessed from a [GDrawCommandList](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandList) for modification. A [GDrawCommandList](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandList) forms the basis for [GDrawCommandImage](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandImage) and [GDrawCommandFrame](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandFrame) objects. A [GDrawCommandImage](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandImage) represents a static image and can be represented by the PDC file format and can be loaded as a resource. Once you have a [GDrawCommandImage](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandImage) loaded in memory you can draw it on the screen in a [LayerUpdateProc](https://developer.repebble.com/docs/c/User_Interface/Layers.md#LayerUpdateProc) with the [gdraw\_command\_image\_draw()](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#gdraw_command_image_draw). A [GDrawCommandFrame](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandFrame) represents a single frame of an animated sequence, with multiple frames making up a single [GDrawCommandSequence](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandSequence), which can also be stored as a PDC and loaded as a resource. To draw a [GDrawCommandSequence](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandSequence), use the [gdraw\_command\_sequence\_get\_frame\_by\_elapsed()](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#gdraw_command_sequence_get_frame_by_elapsed) to obtain the current [GDrawCommandFrame](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandFrame) and [gdraw\_command\_frame\_draw()](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#gdraw_command_frame_draw) to draw it. Draw commands also allow access to drawing with sub-pixel precision. The points are treated as Fixed point types in the format 13.3, so that 1/8th of a pixel precision is possible. Only the points in draw commands of the type GDrawCommandTypePrecisePath will be treated as higher precision. ## Function Documentation void gdraw\_command\_draw(GContext \* ctx, [GDrawCommand](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommand) \* command) Draw a command. #### Parameters ctx The destination graphics context in which to draw command [GDrawCommand](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommand) to draw [GDrawCommandType](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandType) gdraw\_command\_get\_type([GDrawCommand](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommand) \* command) Get the command type. #### Parameters command [GDrawCommand](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommand) from which to get the type #### Returns The type of the given [GDrawCommand](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommand) void gdraw\_command\_set\_fill\_color([GDrawCommand](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommand) \* command, GColor fill\_color) Set the fill color of a command. #### Parameters command ref DrawCommand for which to set the fill color fill\_color GColor to set for the fill GColor gdraw\_command\_get\_fill\_color([GDrawCommand](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommand) \* command) Get the fill color of a command. #### Parameters command [GDrawCommand](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommand) from which to get the fill color #### Returns fill color of the given [GDrawCommand](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommand) void gdraw\_command\_set\_stroke\_color([GDrawCommand](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommand) \* command, GColor stroke\_color) Set the stroke color of a command. #### Parameters command [GDrawCommand](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommand) for which to set the stroke color stroke\_color GColor to set for the stroke GColor gdraw\_command\_get\_stroke\_color([GDrawCommand](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommand) \* command) Get the stroke color of a command. #### Parameters command [GDrawCommand](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommand) from which to get the stroke color #### Returns The stroke color of the given [GDrawCommand](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommand) void gdraw\_command\_set\_stroke\_width([GDrawCommand](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommand) \* command, uint8\_t stroke\_width) Set the stroke width of a command. #### Parameters command [GDrawCommand](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommand) for which to set the stroke width stroke\_width stroke width to set for the command uint8\_t gdraw\_command\_get\_stroke\_width([GDrawCommand](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommand) \* command) Get the stroke width of a command. #### Parameters command [GDrawCommand](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommand) from which to get the stroke width #### Returns The stroke width of the given [GDrawCommand](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommand) [uint16\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint16_t) gdraw\_command\_get\_num\_points([GDrawCommand](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommand) \* command) Get the number of points in a command. void gdraw\_command\_set\_point([GDrawCommand](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommand) \* command, [uint16\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint16_t) point\_idx, [GPoint](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPoint) point) Set the value of the point in a command at the specified index. #### Parameters command [GDrawCommand](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommand) for which to set the value of a point point\_idx Index of the point to set the value for point new point value to set [GPoint](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPoint) gdraw\_command\_get\_point([GDrawCommand](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommand) \* command, [uint16\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint16_t) point\_idx) Get the value of a point in a command from the specified index. ##### Note The index **must** be less than the number of points #### Parameters command [GDrawCommand](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommand) from which to get a point point\_idx The index to get the point for #### Returns The point in the [GDrawCommand](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommand) specified by point\_idx - [SDK 3](javascript:void(0);) - [SDK 4](javascript:void(0);) - [SDK 4.9+](javascript:void(0);) void gdraw\_command\_set\_radius([GDrawCommand](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommand) \* command, [uint16\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint16_t) radius) Set the radius of a circle command. ##### Note This only works for commands of type GDrawCommandCircle #### Parameters command [GDrawCommand](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommand) from which to set the circle radius radius The radius to set for the circle. void gdraw\_command\_set\_radius([GDrawCommand](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommand) \* command, [uint16\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint16_t) radius) Set the radius of a circle command. ##### Note This only works for commands of type GDrawCommandCircle #### Parameters command [GDrawCommand](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommand) from which to set the circle radius radius The radius to set for the circle. void gdraw\_command\_set\_radius([GDrawCommand](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommand) \* command, [uint16\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint16_t) radius) Set the radius of a circle command. ##### Note This only works for commands of type GDrawCommandTypeCircle #### Parameters command [GDrawCommand](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommand) from which to set the circle radius radius The radius to set for the circle. - [SDK 3](javascript:void(0);) - [SDK 4](javascript:void(0);) - [SDK 4.9+](javascript:void(0);) [uint16\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint16_t) gdraw\_command\_get\_radius([GDrawCommand](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommand) \* command) Get the radius of a circle command. ##### Note this only works for commands of typeGDrawCommandCircle. #### Parameters command [GDrawCommand](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommand) from which to get the circle radius #### Returns The radius in pixels if command is of type GDrawCommandCircle [uint16\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint16_t) gdraw\_command\_get\_radius([GDrawCommand](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommand) \* command) Get the radius of a circle command. ##### Note this only works for commands of typeGDrawCommandCircle. #### Parameters command [GDrawCommand](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommand) from which to get the circle radius #### Returns The radius in pixels if command is of type GDrawCommandCircle [uint16\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint16_t) gdraw\_command\_get\_radius([GDrawCommand](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommand) \* command) Get the radius of a circle command. ##### Note this only works for commands of type GDrawCommandTypeCircle. #### Parameters command [GDrawCommand](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommand) from which to get the circle radius #### Returns The radius in pixels if command is of type GDrawCommandTypeCircle - [SDK 3](javascript:void(0);) - [SDK 4](javascript:void(0);) - [SDK 4.9+](javascript:void(0);) void gdraw\_command\_set\_path\_open([GDrawCommand](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommand) \* command, bool path\_open) Set the path of a stroke command to be open. ##### Note This only works for commands of type GDrawCommandPath and GDrawCommandPrecisePath #### Parameters command [GDrawCommand](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommand) for which to set the path open status path\_open true if path should be hidden void gdraw\_command\_set\_path\_open([GDrawCommand](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommand) \* command, bool path\_open) Set the path of a stroke command to be open. ##### Note This only works for commands of type GDrawCommandPath and GDrawCommandPrecisePath #### Parameters command [GDrawCommand](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommand) for which to set the path open status path\_open true if path should be hidden void gdraw\_command\_set\_path\_open([GDrawCommand](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommand) \* command, bool path\_open) Set the path of a stroke command to be open. ##### Note This only works for commands of type GDrawCommandTypePath and GDrawCommandTypePrecisePath #### Parameters command [GDrawCommand](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommand) for which to set the path open status path\_open true if path should be hidden - [SDK 3](javascript:void(0);) - [SDK 4](javascript:void(0);) - [SDK 4.9+](javascript:void(0);) bool gdraw\_command\_get\_path\_open([GDrawCommand](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommand) \* command) Return whether a stroke command path is open. ##### Note This only works for commands of type GDrawCommandPath and GDrawCommandPrecisePath #### Parameters command [GDrawCommand](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommand) from which to get the path open status #### Returns true if the path is open bool gdraw\_command\_get\_path\_open([GDrawCommand](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommand) \* command) Return whether a stroke command path is open. ##### Note This only works for commands of type GDrawCommandPath and GDrawCommandPrecisePath #### Parameters command [GDrawCommand](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommand) from which to get the path open status #### Returns true if the path is open bool gdraw\_command\_get\_path\_open([GDrawCommand](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommand) \* command) Return whether a stroke command path is open. ##### Note This only works for commands of type GDrawCommandTypePath and GDrawCommandTypePrecisePath #### Parameters command [GDrawCommand](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommand) from which to get the path open status #### Returns true if the path is open void gdraw\_command\_set\_hidden([GDrawCommand](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommand) \* command, bool hidden) Set a command as hidden. This command will not be drawn when [gdraw\_command\_draw](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#gdraw_command_draw) is called with this command. #### Parameters command [GDrawCommand](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommand) for which to set the hidden status hidden true if command should be hidden bool gdraw\_command\_get\_hidden([GDrawCommand](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommand) \* command) Return whether a command is hidden. #### Parameters command [GDrawCommand](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommand) from which to get the hidden status #### Returns true if command is hidden void gdraw\_command\_frame\_draw(GContext \* ctx, [GDrawCommandSequence](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandSequence) \* sequence, [GDrawCommandFrame](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandFrame) \* frame, [GPoint](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPoint) offset) Draw a frame. #### Parameters ctx The destination graphics context in which to draw sequence The sequence from which the frame comes from (this is required) frame Frame to draw offset Offset from draw context origin to draw the frame void gdraw\_command\_frame\_set\_duration([GDrawCommandFrame](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandFrame) \* frame, [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) duration) Set the duration of the frame. #### Parameters frame [GDrawCommandFrame](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandFrame) for which to set the duration duration duration of the frame in milliseconds [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) gdraw\_command\_frame\_get\_duration([GDrawCommandFrame](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandFrame) \* frame) Get the duration of the frame. #### Parameters frame [GDrawCommandFrame](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandFrame) from which to get the duration #### Returns duration of the frame in milliseconds [GDrawCommandImage](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandImage) \* gdraw\_command\_image\_create\_with\_resource([uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) resource\_id) Creates a [GDrawCommandImage](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandImage) from the specified resource (PDC file) #### Parameters resource\_id Resource containing data to load and create [GDrawCommandImage](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandImage) from. #### Returns [GDrawCommandImage](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandImage) pointer if the resource was loaded, NULL otherwise [GDrawCommandImage](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandImage) \* gdraw\_command\_image\_clone([GDrawCommandImage](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandImage) \* image) Creates a [GDrawCommandImage](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandImage) as a copy from a given image. #### Parameters image Image to copy. #### Returns cloned image or NULL if the operation failed void gdraw\_command\_image\_destroy([GDrawCommandImage](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandImage) \* image) Deletes the [GDrawCommandImage](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandImage) structure and frees associated data. #### Parameters image Pointer to the image to free (delete) void gdraw\_command\_image\_draw(GContext \* ctx, [GDrawCommandImage](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandImage) \* image, [GPoint](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPoint) offset) Draw an image. #### Parameters ctx The destination graphics context in which to draw image Image to draw offset Offset from draw context origin to draw the image [GSize](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GSize) gdraw\_command\_image\_get\_bounds\_size([GDrawCommandImage](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandImage) \* image) Get size of the bounding box surrounding all draw commands in the image. This bounding box can be used to set the graphics context or layer bounds when drawing the image. #### Parameters image [GDrawCommandImage](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandImage) from which to get the bounding box size #### Returns bounding box size void gdraw\_command\_image\_set\_bounds\_size([GDrawCommandImage](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandImage) \* image, [GSize](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GSize) size) Set size of the bounding box surrounding all draw commands in the image. This bounding box can be used to set the graphics context or layer bounds when drawing the image. #### Parameters image [GDrawCommandImage](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandImage) for which to set the bounding box size size bounding box size [GDrawCommandList](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandList) \* gdraw\_command\_image\_get\_command\_list([GDrawCommandImage](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandImage) \* image) Get the command list of the image. #### Parameters image [GDrawCommandImage](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandImage) from which to get the command list #### Returns command list void gdraw\_command\_list\_iterate([GDrawCommandList](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandList) \* command\_list, [GDrawCommandListIteratorCb](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandListIteratorCb) handle\_command, void \* callback\_context) Iterate over all commands in a command list. #### Parameters command\_list [GDrawCommandList](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandList) over which to iterate handle\_command iterator callback callback\_context context pointer to be passed into the iterator callback void gdraw\_command\_list\_draw(GContext \* ctx, [GDrawCommandList](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandList) \* command\_list) Draw all commands in a command list. #### Parameters ctx The destination graphics context in which to draw command\_list list of commands to draw [GDrawCommand](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommand) \* gdraw\_command\_list\_get\_command([GDrawCommandList](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandList) \* command\_list, [uint16\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint16_t) command\_idx) Get the command at the specified index. ##### Note the specified index must be less than the number of commands in the list #### Parameters command\_list [GDrawCommandList](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandList) from which to get a command command\_idx index of the command to get #### Returns pointer to [GDrawCommand](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommand) at the specified index [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) gdraw\_command\_list\_get\_num\_commands([GDrawCommandList](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandList) \* command\_list) Get the number of commands in the list. #### Parameters command\_list [GDrawCommandList](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandList) from which to get the number of commands #### Returns number of commands in command list [GDrawCommandSequence](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandSequence) \* gdraw\_command\_sequence\_create\_with\_resource([uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) resource\_id) Creates a [GDrawCommandSequence](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandSequence) from the specified resource (PDC file) #### Parameters resource\_id Resource containing data to load and create [GDrawCommandSequence](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandSequence) from. #### Returns [GDrawCommandSequence](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandSequence) pointer if the resource was loaded, NULL otherwise [GDrawCommandSequence](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandSequence) \* gdraw\_command\_sequence\_clone([GDrawCommandSequence](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandSequence) \* sequence) Creates a [GDrawCommandSequence](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandSequence) as a copy from a given sequence. #### Parameters sequence Sequence to copy #### Returns cloned sequence or NULL if the operation failed - [SDK 3](javascript:void(0);) - [SDK 4](javascript:void(0);) - [SDK 4.9+](javascript:void(0);) void gdraw\_command\_sequence\_destroy([GDrawCommandSequence](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandSequence) \* sequence) Deletes the [GDrawCommandSequence](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandSequence) structure and frees associated data. #### Parameters image Pointer to the sequence to destroy void gdraw\_command\_sequence\_destroy([GDrawCommandSequence](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandSequence) \* sequence) Deletes the [GDrawCommandSequence](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandSequence) structure and frees associated data. #### Parameters image Pointer to the sequence to destroy void gdraw\_command\_sequence\_destroy([GDrawCommandSequence](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandSequence) \* sequence) Deletes the [GDrawCommandSequence](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandSequence) structure and frees associated data. #### Parameters sequence Pointer to the sequence to destroy [GDrawCommandFrame](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandFrame) \* gdraw\_command\_sequence\_get\_frame\_by\_elapsed([GDrawCommandSequence](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandSequence) \* sequence, [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) elapsed\_ms) Get the frame that should be shown after the specified amount of elapsed time The last frame will be returned if the elapsed time exceeds the total time. #### Parameters sequence [GDrawCommandSequence](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandSequence) from which to get the frame elapsed\_ms elapsed time in milliseconds #### Returns pointer to [GDrawCommandFrame](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandFrame) that should be displayed at the elapsed time [GDrawCommandFrame](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandFrame) \* gdraw\_command\_sequence\_get\_frame\_by\_index([GDrawCommandSequence](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandSequence) \* sequence, [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) index) Get the frame at the specified index. #### Parameters sequence [GDrawCommandSequence](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandSequence) from which to get the frame index Index of frame to get #### Returns pointer to [GDrawCommandFrame](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandFrame) at the specified index [GSize](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GSize) gdraw\_command\_sequence\_get\_bounds\_size([GDrawCommandSequence](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandSequence) \* sequence) Get the size of the bounding box surrounding all draw commands in the sequence. This bounding box can be used to set the graphics context or layer bounds when drawing the frames in the sequence. #### Parameters sequence [GDrawCommandSequence](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandSequence) from which to get the bounds #### Returns bounding box size void gdraw\_command\_sequence\_set\_bounds\_size([GDrawCommandSequence](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandSequence) \* sequence, [GSize](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GSize) size) Set size of the bounding box surrounding all draw commands in the sequence. This bounding box can be used to set the graphics context or layer bounds when drawing the frames in the sequence. #### Parameters sequence [GDrawCommandSequence](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandSequence) for which to set the bounds size bounding box size [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) gdraw\_command\_sequence\_get\_play\_count([GDrawCommandSequence](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandSequence) \* sequence) Get the play count of the sequence. #### Parameters sequence [GDrawCommandSequence](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandSequence) from which to get the play count #### Returns play count of sequence void gdraw\_command\_sequence\_set\_play\_count([GDrawCommandSequence](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandSequence) \* sequence, [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) play\_count) Set the play count of the sequence. #### Parameters sequence [GDrawCommandSequence](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandSequence) for which to set the play count play\_count play count [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) gdraw\_command\_sequence\_get\_total\_duration([GDrawCommandSequence](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandSequence) \* sequence) Get the total duration of the sequence. #### Parameters sequence [GDrawCommandSequence](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandSequence) from which to get the total duration #### Returns total duration of the sequence in milliseconds [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) gdraw\_command\_sequence\_get\_num\_frames([GDrawCommandSequence](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandSequence) \* sequence) Get the number of frames in the sequence. #### Parameters sequence [GDrawCommandSequence](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandSequence) from which to get the number of frames #### Returns number of frames in the sequence [GDrawCommandList](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandList) \* gdraw\_command\_frame\_get\_command\_list([GDrawCommandFrame](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandFrame) \* frame) Get the command list of the frame. #### Parameters frame [GDrawCommandFrame](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandFrame) from which to get the command list #### Returns command list ## Enum Documentation enum GDrawCommandType #### Enumerators GDrawCommandTypeInvalid Invalid draw command type. GDrawCommandTypePath Arbitrary path draw command type. GDrawCommandTypeCircle Circle draw command type. GDrawCommandTypePrecisePath Arbitrary path drawn with sub-pixel precision (1/8th precision) ## Typedef Documentation typedef struct [GDrawCommand](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommand) GDrawCommand Draw commands are the basic building block of the draw command system, encoding the type of command to draw, the stroke width and color, fill color, and points that define the path (or center of a circle. typedef struct [GDrawCommandFrame](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandFrame) GDrawCommandFrame Draw command frames contain a list of commands to draw for that frame and a duration, indicating the length of time for which the frame should be drawn in an animation sequence. Frames form the building blocks of a [GDrawCommandSequence](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandSequence), which consists of multiple frames. typedef struct [GDrawCommandImage](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandImage) GDrawCommandImage Draw command images contain a list of commands that can be drawn. An image can be loaded from PDC file data. typedef struct [GDrawCommandList](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandList) GDrawCommandList Draw command lists contain a list of commands that can be iterated over and drawn all at once. typedef bool(\* GDrawCommandListIteratorCb)(GDrawCommand \*command, uint32\_t index, void \*context) Callback for iterating over draw command list. #### Parameters command current [GDrawCommand](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommand) in iteration index index of the current command in the list context context pointer for the iteration operation #### Returns true if the iteration should continue after this command is processed typedef struct [GDrawCommandSequence](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md#GDrawCommandSequence) GDrawCommandSequence Draw command sequences allow the animation of frames over time. Each sequence has a list of frames that can be accessed by the elapsed duration of the animation (not maintained internally) or by index. Sequences can be loaded from PDC file data. --- # Drawing Paths Source: https://developer.repebble.com/docs/c/Graphics/Drawing_Paths/ Functions to draw polygons into a graphics context Code example: ``` static GPath \*s\_my\_path\_ptr = NULL;static const GPathInfo BOLT\_PATH\_INFO = {.num\_points = 6,.points = (GPoint []) {{21, 0}, {14, 26}, {28, 26}, {7, 60}, {14, 34}, {0, 34}}};// .update\_proc of my\_layer:void my\_layer\_update\_proc(Layer \*my\_layer, GContext\* ctx) {// Fill the path:graphics\_context\_set\_fill\_color(ctx, GColorWhite);gpath\_draw\_filled(ctx, s\_my\_path\_ptr);// Stroke the path:graphics\_context\_set\_stroke\_color(ctx, GColorBlack);gpath\_draw\_outline(ctx, s\_my\_path\_ptr);}void setup\_my\_path(void) {s\_my\_path\_ptr = gpath\_create(&BOLT\_PATH\_INFO);// Rotate 15 degrees:gpath\_rotate\_to(s\_my\_path\_ptr, TRIG\_MAX\_ANGLE / 360 \* 15);// Translate by (5, 5):gpath\_move\_to(s\_my\_path\_ptr, GPoint(5, 5));}// For brevity, the setup of my\_layer is not written out... ``` ## Function Documentation [GPath](https://developer.repebble.com/docs/c/Graphics/Drawing_Paths.md#GPath) \* gpath\_create(const [GPathInfo](https://developer.repebble.com/docs/c/Graphics/Drawing_Paths.md#GPathInfo) \* init) Creates a new [GPath](https://developer.repebble.com/docs/c/Graphics/Drawing_Paths.md#GPath) on the heap based on a series of points described by a [GPathInfo](https://developer.repebble.com/docs/c/Graphics/Drawing_Paths.md#GPathInfo). Values after initialization: - `num_points` and `points` pointer: copied from the [GPathInfo](https://developer.repebble.com/docs/c/Graphics/Drawing_Paths.md#GPathInfo). - `rotation`: 0 - `offset`: (0, 0) #### Returns A pointer to the [GPath](https://developer.repebble.com/docs/c/Graphics/Drawing_Paths.md#GPath). `NULL` if the [GPath](https://developer.repebble.com/docs/c/Graphics/Drawing_Paths.md#GPath) could not be created void gpath\_destroy([GPath](https://developer.repebble.com/docs/c/Graphics/Drawing_Paths.md#GPath) \* gpath) Free a dynamically allocated gpath created with [gpath\_create()](https://developer.repebble.com/docs/c/Graphics/Drawing_Paths.md#gpath_create) void gpath\_draw\_filled(GContext \* ctx, [GPath](https://developer.repebble.com/docs/c/Graphics/Drawing_Paths.md#GPath) \* path) Draws the fill of a path into a graphics context, using the current fill color, relative to the drawing area as set up by the layering system. #### Parameters ctx The graphics context to draw into path The path to fill #### See Also [graphics\_context\_set\_fill\_color()](https://developer.repebble.com/docs/c/Graphics/Graphics_Context.md#graphics_context_set_fill_color) void gpath\_draw\_outline(GContext \* ctx, [GPath](https://developer.repebble.com/docs/c/Graphics/Drawing_Paths.md#GPath) \* path) Draws the outline of a path into a graphics context, using the current stroke color and width, relative to the drawing area as set up by the layering system. The first and last points in the path do have a line between them. #### Parameters ctx The graphics context to draw into path The path to draw #### See Also [graphics\_context\_set\_stroke\_color()](https://developer.repebble.com/docs/c/Graphics/Graphics_Context.md#graphics_context_set_stroke_color) [gpath\_draw\_outline\_open()](https://developer.repebble.com/docs/c/Graphics/Drawing_Paths.md#gpath_draw_outline_open) void gpath\_rotate\_to([GPath](https://developer.repebble.com/docs/c/Graphics/Drawing_Paths.md#GPath) \* path, int32\_t angle) Sets the absolute rotation of the path. The current rotation will be replaced by the specified angle. ##### Note Setting a rotation does not affect the points in the path directly. The rotation is applied on-the-fly during drawing, either using [gpath\_draw\_filled()](https://developer.repebble.com/docs/c/Graphics/Drawing_Paths.md#gpath_draw_filled) or [gpath\_draw\_outline()](https://developer.repebble.com/docs/c/Graphics/Drawing_Paths.md#gpath_draw_outline). #### Parameters path The path onto which to set the rotation angle The absolute angle of the rotation. The angle is represented in the same way that is used with [sin\_lookup()](https://developer.repebble.com/docs/c/Foundation/Math.md#sin_lookup). See [TRIG\_MAX\_ANGLE](https://developer.repebble.com/docs/c/Foundation/Math.md#TRIG_MAX_ANGLE) for more information. void gpath\_move\_to([GPath](https://developer.repebble.com/docs/c/Graphics/Drawing_Paths.md#GPath) \* path, [GPoint](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPoint) point) Sets the absolute offset of the path. The current translation will be replaced by the specified offset. ##### Note Setting a translation does not affect the points in the path directly. The translation is applied on-the-fly during drawing, either using [gpath\_draw\_filled()](https://developer.repebble.com/docs/c/Graphics/Drawing_Paths.md#gpath_draw_filled) or [gpath\_draw\_outline()](https://developer.repebble.com/docs/c/Graphics/Drawing_Paths.md#gpath_draw_outline). #### Parameters path The path onto which to set the translation point The point which is used as the vector for the translation. void gpath\_draw\_outline\_open(GContext \* ctx, [GPath](https://developer.repebble.com/docs/c/Graphics/Drawing_Paths.md#GPath) \* path) Draws an open outline of a path into a graphics context, using the current stroke color and width, relative to the drawing area as set up by the layering system. The first and last points in the path do not have a line between them. #### Parameters ctx The graphics context to draw into path The path to draw #### See Also [graphics\_context\_set\_stroke\_color()](https://developer.repebble.com/docs/c/Graphics/Graphics_Context.md#graphics_context_set_stroke_color) [gpath\_draw\_outline()](https://developer.repebble.com/docs/c/Graphics/Drawing_Paths.md#gpath_draw_outline) ## Data Structure Documentation struct GPath Data structure describing a path, plus its rotation and translation. ##### Note See the remark with [GPathInfo](https://developer.repebble.com/docs/c/Graphics/Drawing_Paths.md#GPathInfo) #### Data Fields [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) num\_points The number of points in the `points` array. [GPoint](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPoint) \* points Pointer to an array of points. int32\_t rotation The rotation that will be used when drawing the path with [gpath\_draw\_filled()](https://developer.repebble.com/docs/c/Graphics/Drawing_Paths.md#gpath_draw_filled) or [gpath\_draw\_outline()](https://developer.repebble.com/docs/c/Graphics/Drawing_Paths.md#gpath_draw_outline) [GPoint](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPoint) offset The translation that will to be used when drawing the path with [gpath\_draw\_filled()](https://developer.repebble.com/docs/c/Graphics/Drawing_Paths.md#gpath_draw_filled) or [gpath\_draw\_outline()](https://developer.repebble.com/docs/c/Graphics/Drawing_Paths.md#gpath_draw_outline) struct GPathInfo Data structure describing a naked path. ##### Note Note that this data structure only refers to an array of points; the points are not stored inside this data structure itself. In most cases, one cannot use a stack-allocated array of GPoints. Instead one often needs to provide longer-lived (static or "global") storage for the points. #### Data Fields [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) num\_points The number of points in the `points` array. [GPoint](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPoint) \* points Pointer to an array of points. --- # Drawing Primitives Source: https://developer.repebble.com/docs/c/Graphics/Drawing_Primitives/ Functions to draw into a graphics context Use these drawing functions inside a Layer's `.update_proc` drawing callback. A `GContext` is passed into this callback as an argument. This `GContext` can then be used with all of the drawing functions which are documented below. See [Graphics Context](https://developer.repebble.com/docs/c/Graphics/Graphics_Context.md) for more information about the graphics context. Refer to [User Interface Layers chapter in the Pebble Developer Guides](https://developer.repebble.com/guides/user-interfaces/layers.md) (chapter "Layers") for a conceptual overview of the drawing system, Layers and relevant code examples. Other drawing functions and related documentation: - [Drawing Text](https://developer.repebble.com/docs/c/Graphics/Drawing_Text.md) - [Drawing Paths](https://developer.repebble.com/docs/c/Graphics/Drawing_Paths.md) - [Graphics Types](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md) ## Function Documentation void graphics\_draw\_pixel(GContext \* ctx, [GPoint](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPoint) point) Draws a pixel at given point in the current stroke color. #### Parameters ctx The destination graphics context in which to draw point The point at which to draw the pixel void graphics\_draw\_line(GContext \* ctx, [GPoint](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPoint) p0, [GPoint](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPoint) p1) Draws line in the current stroke color, current stroke width and AA flag. #### Parameters ctx The destination graphics context in which to draw p0 The starting point of the line p1 The ending point of the line void graphics\_draw\_rect(GContext \* ctx, [GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) rect) Draws a 1-pixel wide rectangle outline in the current stroke color. #### Parameters ctx The destination graphics context in which to draw rect The rectangle for which to draw the outline void graphics\_fill\_rect(GContext \* ctx, [GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) rect, [uint16\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint16_t) corner\_radius, [GCornerMask](https://developer.repebble.com/docs/c/Graphics/Drawing_Primitives.md#GCornerMask) corner\_mask) Fills a rectangle with the current fill color, optionally rounding all or a selection of its corners. #### Parameters ctx The destination graphics context in which to draw rect The rectangle to fill corner\_radius The rounding radius of the corners in pixels (maximum is 8 pixels) corner\_mask Bitmask of the corners that need to be rounded. #### See Also [GCornerMask](https://developer.repebble.com/docs/c/Graphics/Drawing_Primitives.md#GCornerMask) void graphics\_draw\_circle(GContext \* ctx, [GPoint](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPoint) p, [uint16\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint16_t) radius) Draws the outline of a circle in the current stroke color. #### Parameters ctx The destination graphics context in which to draw p The center point of the circle radius The radius in pixels void graphics\_fill\_circle(GContext \* ctx, [GPoint](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPoint) p, [uint16\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint16_t) radius) Fills a circle in the current fill color. #### Parameters ctx The destination graphics context in which to draw p The center point of the circle radius The radius in pixels void graphics\_draw\_round\_rect(GContext \* ctx, [GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) rect, [uint16\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint16_t) radius) Draws the outline of a rounded rectangle in the current stroke color. #### Parameters ctx The destination graphics context in which to draw rect The rectangle defining the dimensions of the rounded rectangle to draw radius The corner radius in pixels void graphics\_draw\_bitmap\_in\_rect(GContext \* ctx, const GBitmap \* bitmap, [GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) rect) Draws a bitmap into the graphics context, inside the specified rectangle. ##### Note If the size of `rect` is smaller than the size of the bitmap, the bitmap will be clipped on right and bottom edges. If the size of `rect` is larger than the size of the bitmap, the bitmap will be tiled automatically in both horizontal and vertical directions, effectively drawing a repeating pattern. #### Parameters ctx The destination graphics context in which to draw the bitmap bitmap The bitmap to draw rect The rectangle in which to draw the bitmap #### See Also GBitmap GContext GBitmap \* graphics\_capture\_frame\_buffer(GContext \* ctx) A shortcut to capture the framebuffer in the native format of the watch. #### See Also [graphics\_capture\_frame\_buffer\_format](https://developer.repebble.com/docs/c/Graphics/Drawing_Primitives.md#graphics_capture_frame_buffer_format) GBitmap \* graphics\_capture\_frame\_buffer\_format(GContext \* ctx, [GBitmapFormat](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GBitmapFormat) format) Captures the frame buffer for direct access, using the given format. Graphics functions will not affect the frame buffer while it is captured. The frame buffer is released when `graphics_release_frame_buffer` is called. The frame buffer must be released before the end of a layer's `.update_proc` for the layer to be drawn properly. While the frame buffer is captured calling `graphics_capture_frame_buffer` will fail and return `NULL`. ##### Note When writing to the frame buffer, you should respect the visible boundaries of a window on the screen. Use layer\_get\_frame(window\_get\_root\_layer(window)).origin to obtain its position relative to the frame buffer. For example, drawing to (5, 5) in the frame buffer while the window is transitioning to the left with its origin at (-20, 0) would effectively draw that point at (25, 5) relative to the window. For this reason you should consider the window's root layer frame when calculating drawing coordinates. #### Parameters ctx The graphics context providing the frame buffer format The format in which the framebuffer should be captured. Supported formats are GBitmapFormat1Bit and GBitmapFormat8Bit. #### Returns A pointer to the frame buffer. `NULL` if failed. #### See Also GBitmap [GBitmapFormat](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GBitmapFormat) [layer\_get\_frame](https://developer.repebble.com/docs/c/User_Interface/Layers.md#layer_get_frame) [window\_get\_root\_layer](https://developer.repebble.com/docs/c/User_Interface/Window.md#window_get_root_layer) bool graphics\_release\_frame\_buffer(GContext \* ctx, GBitmap \* buffer) Releases the frame buffer. Must be called before the end of a layer's `.update_proc` for the layer to be drawn properly. If `buffer` does not point to the address previously returned by `graphics_capture_frame_buffer` the frame buffer will not be released. #### Parameters ctx The graphics context providing the frame buffer buffer The pointer to frame buffer #### Returns True if the frame buffer was released successfully bool graphics\_frame\_buffer\_is\_captured(GContext \* ctx) Whether or not the frame buffer has been captured by `graphics_capture_frame_buffer`. Graphics functions will not affect the frame buffer until it has been released by `graphics_release_frame_buffer`. #### Parameters ctx The graphics context providing the frame buffer #### Returns True if the frame buffer has been captured void graphics\_draw\_rotated\_bitmap(GContext \* ctx, GBitmap \* src, [GPoint](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPoint) src\_ic, int rotation, [GPoint](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPoint) dest\_ic) Draws a rotated bitmap with a memory-sensitive 2x anti-aliasing technique (using ray-finding instead of super-sampling), which is thresholded into a b/w bitmap for 1-bit and color blended for 8-bit. ##### Note This API has performance limitations that can degrade user experience. Use sparingly. #### Parameters ctx The destination graphics context in which to draw src The source bitmap to draw src\_ic Instance center (single point unaffected by rotation) relative to source bitmap rotation Angle of rotation. Rotation is an integer between 0 (no rotation) and TRIG\_MAX\_ANGLE (360 degree rotation). Use [DEG\_TO\_TRIGANGLE](https://developer.repebble.com/docs/c/Foundation/Math.md#DEG_TO_TRIGANGLE) to easily convert degrees to the appropriate value. dest\_ic Where to draw the instance center of the rotated bitmap in the context. void graphics\_draw\_arc(GContext \* ctx, [GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) rect, [GOvalScaleMode](https://developer.repebble.com/docs/c/Graphics/Drawing_Primitives.md#GOvalScaleMode) scale\_mode, int32\_t angle\_start, int32\_t angle\_end) Draws a line arc clockwise between `angle_start` and `angle_end`, where 0° is the top of the circle. If the difference between `angle_start` and `angle_end` is greater than 360°, a full circle will be drawn. #### Parameters ctx The destination graphics context in which to draw using the current stroke color and antialiasing setting. rect The reference rectangle to derive the center point and radius (see scale\_mode). scale\_mode Determines how rect will be used to derive the center point and radius. angle\_start Radial starting angle. Use [DEG\_TO\_TRIGANGLE](https://developer.repebble.com/docs/c/Foundation/Math.md#DEG_TO_TRIGANGLE) to easily convert degrees to the appropriate value. angle\_end Radial finishing angle. If smaller than `angle_start`, nothing will be drawn. void graphics\_fill\_radial(GContext \* ctx, [GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) rect, [GOvalScaleMode](https://developer.repebble.com/docs/c/Graphics/Drawing_Primitives.md#GOvalScaleMode) scale\_mode, [uint16\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint16_t) inset\_thickness, int32\_t angle\_start, int32\_t angle\_end) Fills a circle clockwise between `angle_start` and `angle_end`, where 0° is the top of the circle. If the difference between `angle_start` and `angle_end` is greater than 360°, a full circle will be drawn and filled. If `angle_start` is greater than `angle_end` nothing will be drawn. ##### Note A simple example is drawing a 'Pacman' shape, with a starting angle of -225°, and ending angle of 45°. By setting `inset_thickness` to a non-zero value (such as 30) this example will produce the letter C. #### Parameters ctx The destination graphics context in which to draw using the current fill color and antialiasing setting. rect The reference rectangle to derive the center point and radius (see scale). scale\_mode Determines how rect will be used to derive the center point and radius. inset\_thickness Describes how thick in pixels the radial will be drawn towards its center measured from the outside. angle\_start Radial starting angle. Use [DEG\_TO\_TRIGANGLE](https://developer.repebble.com/docs/c/Foundation/Math.md#DEG_TO_TRIGANGLE) to easily convert degrees to the appropriate value. angle\_end Radial finishing angle. If smaller than `angle_start`, nothing will be drawn. [GPoint](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPoint) gpoint\_from\_polar([GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) rect, [GOvalScaleMode](https://developer.repebble.com/docs/c/Graphics/Drawing_Primitives.md#GOvalScaleMode) scale\_mode, int32\_t angle) Calculates a [GPoint](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPoint) located at the angle provided on the perimeter of a circle defined by the provided [GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect). #### Parameters rect The reference rectangle to derive the center point and radius (see scale\_mode). scale\_mode Determines how rect will be used to derive the center point and radius. angle The angle at which the point on the circle's perimeter should be calculated. Use [DEG\_TO\_TRIGANGLE](https://developer.repebble.com/docs/c/Foundation/Math.md#DEG_TO_TRIGANGLE) to easily convert degrees to the appropriate value. #### Returns The point on the circle's perimeter. [GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) grect\_centered\_from\_polar([GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) rect, [GOvalScaleMode](https://developer.repebble.com/docs/c/Graphics/Drawing_Primitives.md#GOvalScaleMode) scale\_mode, int32\_t angle, [GSize](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GSize) size) Calculates a rectangle centered on the perimeter of a circle at a given angle. Use this to construct rectangles that follow the perimeter of a circle as an input for graphics\_fill\_radial\_internal or graphics\_draw\_arc\_internal, e.g. to draw circles every 30 degrees on a watchface. #### Parameters rect The reference rectangle to derive the circle's center point and radius (see scale\_mode). scale\_mode Determines how rect will be used to derive the circle's center point and radius. angle The angle at which the point on the circle's perimeter should be calculated. Use [DEG\_TO\_TRIGANGLE](https://developer.repebble.com/docs/c/Foundation/Math.md#DEG_TO_TRIGANGLE) to easily convert degrees to the appropriate value. size Width and height of the desired rectangle. #### Returns The rectangle centered on the circle's perimeter. ## Enum Documentation enum GCornerMask Bit mask values to specify the corners of a rectangle. The values can be combines using binary OR (`|`), For example: the mask to indicate top left and bottom right corners can: be created as follows: `(GCornerTopLeft | GCornerBottomRight)` #### Enumerators GCornerNone No corners. GCornerTopLeft Top-Left corner. GCornerTopRight Top-Right corner. GCornerBottomLeft Bottom-Left corner. GCornerBottomRight Bottom-Right corner. GCornersAll All corners. GCornersTop Top corners. GCornersBottom Bottom corners. GCornersLeft Left corners. GCornersRight Right corners. enum GOvalScaleMode Values to specify how a given rectangle should be used to derive an oval shape. graphics\_fill\_radial\_internal graphics\_draw\_arc\_internal gpoint\_from\_polar\_internal grect\_centered\_from\_polar #### Enumerators GOvalScaleModeFitCircle Places a circle at the center of the rectangle, with a diameter that matches the rectangle's shortest side. GOvalScaleModeFillCircle Places a circle at the center of the rectangle, with a diameter that matches the rectangle's longest side. The circle may overflow the bounds of the rectangle. --- # Drawing Text Source: https://developer.repebble.com/docs/c/Graphics/Drawing_Text/ Functions to draw text into a graphics context See [Graphics Context](https://developer.repebble.com/docs/c/Graphics/Graphics_Context.md) for more information about the graphics context. Other drawing functions and related documentation: - [Drawing Primitives](https://developer.repebble.com/docs/c/Graphics/Drawing_Primitives.md) - [Drawing Paths](https://developer.repebble.com/docs/c/Graphics/Drawing_Paths.md) - [Graphics Types](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md) ## Function Documentation GTextAttributes \* graphics\_text\_attributes\_create(void) Creates an instance of GTextAttributes for advanced control when rendering text. #### Returns New instance of GTextAttributes #### See Also [graphics\_draw\_text](https://developer.repebble.com/docs/c/Graphics/Drawing_Text.md#graphics_draw_text) void graphics\_text\_attributes\_destroy(GTextAttributes \* text\_attributes) Destroys a previously created instance of GTextAttributes. void graphics\_text\_attributes\_restore\_default\_text\_flow(GTextAttributes \* text\_attributes) Restores text flow to the rectangular default. #### Parameters text\_attributes The attributes for which to disable text flow #### See Also [graphics\_text\_attributes\_enable\_screen\_text\_flow](https://developer.repebble.com/docs/c/Graphics/Drawing_Text.md#graphics_text_attributes_enable_screen_text_flow) [text\_layer\_restore\_default\_text\_flow\_and\_paging](https://developer.repebble.com/docs/c/User_Interface/Layers/TextLayer.md#text_layer_restore_default_text_flow_and_paging) void graphics\_text\_attributes\_enable\_screen\_text\_flow(GTextAttributes \* text\_attributes, uint8\_t inset) Enables text flow that follows the boundaries of the screen. #### Parameters text\_attributes The attributes for which text flow should be enabled inset Additional amount of pixels to inset to the inside of the screen for text flow calculation. Can be zero. #### See Also [graphics\_text\_attributes\_restore\_default\_text\_flow](https://developer.repebble.com/docs/c/Graphics/Drawing_Text.md#graphics_text_attributes_restore_default_text_flow) [text\_layer\_enable\_screen\_text\_flow\_and\_paging](https://developer.repebble.com/docs/c/User_Interface/Layers/TextLayer.md#text_layer_enable_screen_text_flow_and_paging) void graphics\_text\_attributes\_restore\_default\_paging(GTextAttributes \* text\_attributes) Restores paging and locked content origin to the defaults. #### Parameters text\_attributes The attributes for which to restore paging and locked content origin #### See Also [graphics\_text\_attributes\_enable\_paging](https://developer.repebble.com/docs/c/Graphics/Drawing_Text.md#graphics_text_attributes_enable_paging) [text\_layer\_restore\_default\_text\_flow\_and\_paging](https://developer.repebble.com/docs/c/User_Interface/Layers/TextLayer.md#text_layer_restore_default_text_flow_and_paging) void graphics\_text\_attributes\_enable\_paging(GTextAttributes \* text\_attributes, [GPoint](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPoint) content\_origin\_on\_screen, [GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) paging\_on\_screen) Enables paging and locks the text flow calculation to a fixed point on the screen. #### Parameters text\_attributes Attributes for which to enable paging and locked content origin content\_origin\_on\_screen Absolute coordinate on the screen where the text content starts before an animation or scrolling takes place. Usually the frame's origin of a layer in screen coordinates. paging\_on\_screen Rectangle in absolute coordinates on the screen that describes where text content pages. Usually the container's absolute frame in screen coordinates. #### See Also [graphics\_text\_attributes\_restore\_default\_paging](https://developer.repebble.com/docs/c/Graphics/Drawing_Text.md#graphics_text_attributes_restore_default_paging) [graphics\_text\_attributes\_enable\_screen\_text\_flow](https://developer.repebble.com/docs/c/Graphics/Drawing_Text.md#graphics_text_attributes_enable_screen_text_flow) [text\_layer\_enable\_screen\_text\_flow\_and\_paging](https://developer.repebble.com/docs/c/User_Interface/Layers/TextLayer.md#text_layer_enable_screen_text_flow_and_paging) [layer\_convert\_point\_to\_screen](https://developer.repebble.com/docs/c/User_Interface/Layers.md#layer_convert_point_to_screen) void graphics\_draw\_text(GContext \* ctx, const char \* text, [GFont](https://developer.repebble.com/docs/c/Graphics/Fonts.md#GFont) const font, const [GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) box, const [GTextOverflowMode](https://developer.repebble.com/docs/c/Graphics/Drawing_Text.md#GTextOverflowMode) overflow\_mode, const [GTextAlignment](https://developer.repebble.com/docs/c/Graphics/Drawing_Text.md#GTextAlignment) alignment, GTextAttributes \* text\_attributes) Draw text into the current graphics context, using the context's current text color. The text will be drawn inside a box with the specified dimensions and configuration, with clipping occuring automatically. #### Parameters ctx The destination graphics context in which to draw text The zero terminated UTF-8 string to draw font The font in which the text should be set box The bounding box in which to draw the text. The first line of text will be drawn against the top of the box. overflow\_mode The overflow behavior, in case the text is larger than what fits inside the box. alignment The horizontal alignment of the text text\_attributes Optional text attributes to describe the characteristics of the text [GSize](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GSize) graphics\_text\_layout\_get\_content\_size(const char \* text, [GFont](https://developer.repebble.com/docs/c/Graphics/Fonts.md#GFont) const font, const [GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) box, const [GTextOverflowMode](https://developer.repebble.com/docs/c/Graphics/Drawing_Text.md#GTextOverflowMode) overflow\_mode, const [GTextAlignment](https://developer.repebble.com/docs/c/Graphics/Drawing_Text.md#GTextAlignment) alignment) Obtain the maximum size that a text with given font, overflow mode and alignment occupies within a given rectangular constraint. #### Parameters text The zero terminated UTF-8 string for which to calculate the size font The font in which the text should be set while calculating the size box The bounding box in which the text should be constrained overflow\_mode The overflow behavior, in case the text is larger than what fits inside the box. alignment The horizontal alignment of the text #### Returns The maximum size occupied by the text #### See Also app\_graphics\_text\_layout\_get\_content\_size\_with\_attributes [GSize](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GSize) graphics\_text\_layout\_get\_content\_size\_with\_attributes(const char \* text, [GFont](https://developer.repebble.com/docs/c/Graphics/Fonts.md#GFont) const font, const [GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) box, const [GTextOverflowMode](https://developer.repebble.com/docs/c/Graphics/Drawing_Text.md#GTextOverflowMode) overflow\_mode, const [GTextAlignment](https://developer.repebble.com/docs/c/Graphics/Drawing_Text.md#GTextAlignment) alignment, GTextAttributes \* text\_attributes) Obtain the maximum size that a text with given font, overflow mode and alignment occupies within a given rectangular constraint. #### Parameters text The zero terminated UTF-8 string for which to calculate the size font The font in which the text should be set while calculating the size box The bounding box in which the text should be constrained overflow\_mode The overflow behavior, in case the text is larger than what fits inside the box. alignment The horizontal alignment of the text text\_attributes Optional text attributes to describe the characteristics of the text #### Returns The maximum size occupied by the text #### See Also app\_graphics\_text\_layout\_get\_content\_size ## Enum Documentation enum GTextOverflowMode Text overflow mode controls the way text overflows when the string that is drawn does not fit inside the area constraint. graphics\_draw\_text text\_layer\_set\_overflow\_mode #### Enumerators GTextOverflowModeWordWrap On overflow, wrap words to a new line below the current one. Once vertical space is consumed, the last line may be clipped. GTextOverflowModeTrailingEllipsis On overflow, wrap words to a new line below the current one. Once vertical space is consumed, truncate as needed to fit a trailing ellipsis (...). Clipping may occur if the vertical space cannot accomodate the first line of text. GTextOverflowModeFill Acts like GTextOverflowModeTrailingEllipsis, plus trims leading and trailing newlines, while treating all other newlines as spaces. enum GTextAlignment Text aligment controls the way the text is aligned inside the box the text is drawn into. graphics\_draw\_text text\_layer\_set\_text\_alignment #### Enumerators GTextAlignmentLeft Aligns the text to the left of the drawing box. GTextAlignmentCenter Aligns the text centered inside the drawing box. GTextAlignmentRight Aligns the text to the right of the drawing box. ## Typedef Documentation typedef struct GTextAttributes GTextAttributes --- # Event Service Source: https://developer.repebble.com/docs/c/Foundation/Event_Service/ APIs to handle event services. Pebble OS provides you with a set of APIs for handling event services, like accelerometer taps, app focus for interactivity, battery states, Bluetooth connections, and tick timers to call when a time component has changed. You use event services to be notified, for example, when something happens on Pebble, like losing the connection to the phone or when a notification covers the screen and requires your Pebble game to pause. ## Modules #### [AccelerometerService](https://developer.repebble.com/docs/c/Foundation/Event_Service/AccelerometerService.md)   #### [AlarmService](https://developer.repebble.com/docs/c/Foundation/Event_Service/AlarmService.md)   #### [AppFocusService](https://developer.repebble.com/docs/c/Foundation/Event_Service/AppFocusService.md)   #### [BacklightService](https://developer.repebble.com/docs/c/Foundation/Event_Service/BacklightService.md)   #### [BatteryStateService](https://developer.repebble.com/docs/c/Foundation/Event_Service/BatteryStateService.md)   #### [CompassService](https://developer.repebble.com/docs/c/Foundation/Event_Service/CompassService.md)   #### [ConnectionService](https://developer.repebble.com/docs/c/Foundation/Event_Service/ConnectionService.md) Determine what the Pebble watch is connected to #### [HealthService](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md)   #### [TickTimerService](https://developer.repebble.com/docs/c/Foundation/Event_Service/TickTimerService.md) Handling time components #### [TouchService](https://developer.repebble.com/docs/c/Foundation/Event_Service/TouchService.md)   --- # Exit Reason Source: https://developer.repebble.com/docs/c/Foundation/Exit_Reason/ API for the application to notify the system of the reason it will exit. If the application has not specified an exit reason before it exits, then the exit reason will default to APP\_EXIT\_NOT\_SPECIFIED. Only an application can set its exit reason. The system will not modify it. ## Function Documentation - [SDK 3](javascript:void(0);) - [SDK 4](javascript:void(0);) - [SDK 4.9+](javascript:void(0);) void exit\_reason\_set([AppExitReason](https://developer.repebble.com/docs/c/Foundation/Exit_Reason.md#AppExitReason) exit\_reason) Set the app exit reason to a new reason. #### Parameters reason The new app exit reason void exit\_reason\_set([AppExitReason](https://developer.repebble.com/docs/c/Foundation/Exit_Reason.md#AppExitReason) exit\_reason) Set the app exit reason to a new reason. #### Parameters reason The new app exit reason void exit\_reason\_set([AppExitReason](https://developer.repebble.com/docs/c/Foundation/Exit_Reason.md#AppExitReason) exit\_reason) Set the app exit reason to a new reason. #### Parameters exit\_reason The new app exit reason ## Enum Documentation enum AppExitReason [AppExitReason](https://developer.repebble.com/docs/c/Foundation/Exit_Reason.md#AppExitReason) is used to notify the system of the reason of an application exiting, which may affect the part of the system UI that is presented after the application terminates. #### Enumerators APP\_EXIT\_NOT\_SPECIFIED Exit reason not specified. APP\_EXIT\_ACTION\_PERFORMED\_SUCCESSFULLY Application performed an action when it exited. NUM\_EXIT\_REASONS Number of [AppExitReason](https://developer.repebble.com/docs/c/Foundation/Exit_Reason.md#AppExitReason) options. --- # File Formats Source: https://developer.repebble.com/docs/c/Foundation/Resources/File_Formats/ ## Modules #### [PBI File Format](https://developer.repebble.com/docs/c/Foundation/Resources/File_Formats/PBI_File_Format.md)   #### [PNG8 File Format](https://developer.repebble.com/docs/c/Foundation/Resources/File_Formats/PNG8_File_Format.md)   --- # Fonts Source: https://developer.repebble.com/docs/c/Graphics/Fonts/ Custom and system fonts. Pebble OS provides you with a wide range of system fonts that you can use when you need to display and render text or numbers in your Pebble watchface or watchapp. If you want to use a system font, you call [fonts\_get\_system\_font()](https://developer.repebble.com/docs/c/Graphics/Fonts.md#fonts_get_system_font) and simply pass it the name of the system font you want. To use a custom font, call [fonts\_load\_custom\_font()](https://developer.repebble.com/docs/c/Graphics/Fonts.md#fonts_load_custom_font). The sample code feature\_custom\_font shows how you can do this programmatically, using a font resource to convert a TrueType font into a rasterized version of that font at a specified font size. For example: ``` GFont custom\_font = fonts\_load\_custom\_font(resource\_get\_handle(RESOURCE\_ID\_FONT\_OSP\_DIN\_44)); ``` Raster Gothic Condensed is the font used throughout the Pebble system, largely because it is optimized for monochromatic displays. Pebble selected this font because it allows a relatively large number of characters to be displayed on a single line, also because the font has an excellent readability vs. size ratio. Refer to the chapter [App Resources in the Pebble Developer Guides](https://developer.repebble.com/guides/pebble-apps/resources/) which explains how to work with font resources and embed a font into your app. ## Function Documentation [GFont](https://developer.repebble.com/docs/c/Graphics/Fonts.md#GFont) fonts\_get\_system\_font(const char \* font\_key) Loads a system font corresponding to the specified font key. ##### Note This may load a font from the flash peripheral into RAM. #### Parameters font\_key The string key of the font to load. See [System Fonts](https://developer.repebble.com/guides/app-resources/system-fonts.md) guide for a list of system fonts. #### Returns An opaque pointer to the loaded font, or, a pointer to the default (fallback) font if the specified font cannot be loaded. [GFont](https://developer.repebble.com/docs/c/Graphics/Fonts.md#GFont) fonts\_load\_custom\_font([ResHandle](https://developer.repebble.com/docs/c/Foundation/Resources.md#ResHandle) handle) Loads a custom font. ##### Note this may load a font from the flash peripheral into RAM. #### Parameters handle The resource handle of the font to load. See resource\_ids.auto.h for a list of resource IDs, and use `resource_get_handle()` to obtain the resource handle. #### Returns An opaque pointer to the loaded font, or a pointer to the default (fallback) font if the specified font cannot be loaded. #### See Also Read the [App Resources](https://developer.repebble.com/guides/pebble-apps/resources/) guide on how to embed a font into your app. void fonts\_unload\_custom\_font([GFont](https://developer.repebble.com/docs/c/Graphics/Fonts.md#GFont) font) Unloads the specified custom font and frees the memory that is occupied by it. ##### Note When an application exits, the system automatically unloads all fonts that have been loaded. #### Parameters font The font to unload. ## Typedef Documentation typedef struct FontInfo FontInfo typedef FontInfo \* GFont Pointer to opaque font data structure. #### See Also [fonts\_load\_custom\_font()](https://developer.repebble.com/docs/c/Graphics/Fonts.md#fonts_load_custom_font) [text\_layer\_set\_font()](https://developer.repebble.com/docs/c/User_Interface/Layers/TextLayer.md#text_layer_set_font) [graphics\_draw\_text()](https://developer.repebble.com/docs/c/Graphics/Drawing_Text.md#graphics_draw_text) --- # Format Source: https://developer.repebble.com/docs/c/Standard_C/Format/ Standard formatting. If you're looking for input/output functions, check out the [Logging](https://developer.repebble.com/docs/c/Foundation/Logging.md) API. ## Function Documentation int snprintf(char \* str, [size\_t](https://developer.repebble.com/docs/c/Standard_C/Memory.md#size_t) n, const \* fmt, ...) Format a string into a buffer. The Pebble-supported format specifiers are displayed below. | Specifier | Output | Example | | --- | --- | --- | | d or i | Signed decimal integer | 294 | | u | Unsigned decimal integer | 7235 | | o | Unsigned octal | 610 | | x | Unsigned hexadecimal integer | 8b2 | | X | Unsigned hexadecimal integer (uppercase) | 8B2 | | c | Character | h | | s | Null-terminated string of characters | pebble | | p | Pointer address | 0xb8000000 | | % | A % followed by another % character will write a single % to the stream. | % | Length specifiers can also be combined with the format specifiers above: | | u o x X | c | s | p | n | | --- | --- | --- | --- | --- | --- | | (none) | unsigned int | int | char\* | void\* | int\* | | h | unsigned short int | | | | short int\* | | l | unsigned long int | wint\_t | wchar\_t\* | | long int\* | #### Parameters str The string buffer to write the formatted string into n The maximum size of the buffer fmt The C formatting string #### Returns The number of bytes written --- # Foundation Source: https://developer.repebble.com/docs/c/Foundation/ The core of the Pebble SDK. The Pebble SDK consists of different frameworks that are organized by functionality. Each framework includes an API and provides access to the software libraries supported natively by Pebble OS. You use these interfaces (APIs) in the C programming language to write software for the Pebble platform. Frameworks are grouped hierarchically into Foundation, Graphics, Standard C and User Interface. The Foundation framework is the core of the Pebble OS. ## Modules #### [Alloy](https://developer.repebble.com/docs/c/Foundation/Alloy.md)   #### [App](https://developer.repebble.com/docs/c/Foundation/App.md) App entry point and event loop. #### [App Communication](https://developer.repebble.com/docs/c/Foundation/App_Communication.md) API for interacting with the Pebble communication subsystem. #### [App Glance](https://developer.repebble.com/docs/c/Foundation/App_Glance.md) API for the application to modify its "glance" i.e. app menu subtitle. #### [AppMessage](https://developer.repebble.com/docs/c/Foundation/AppMessage.md)   #### [AppSync](https://developer.repebble.com/docs/c/Foundation/AppSync.md) UI synchronization layer for AppMessage #### [AppWorker](https://developer.repebble.com/docs/c/Foundation/AppWorker.md) Runs in the background, and can communicate with the foreground app. #### [DataLogging](https://developer.repebble.com/docs/c/Foundation/DataLogging.md) Enables logging data asynchronously to a mobile app #### [DataStructures](https://developer.repebble.com/docs/c/Foundation/DataStructures/)   #### [Dictation](https://developer.repebble.com/docs/c/Foundation/Dictation.md)   #### [Dictionary](https://developer.repebble.com/docs/c/Foundation/Dictionary.md) Data serialization utilities #### [Event Service](https://developer.repebble.com/docs/c/Foundation/Event_Service.md) APIs to handle event services. #### [Exit Reason](https://developer.repebble.com/docs/c/Foundation/Exit_Reason.md) API for the application to notify the system of the reason it will exit. #### [Internationalization](https://developer.repebble.com/docs/c/Foundation/Internationalization.md) Internationalization & Localization APIs #### [Launch Reason](https://developer.repebble.com/docs/c/Foundation/Launch_Reason.md) API for checking what caused the application to launch. #### [Logging](https://developer.repebble.com/docs/c/Foundation/Logging.md) Functions related to logging from apps. #### [Math](https://developer.repebble.com/docs/c/Foundation/Math.md) Math routines. #### [Memory Management](https://developer.repebble.com/docs/c/Foundation/Memory_Management.md) Utility functions for managing an application's memory. #### [Platform](https://developer.repebble.com/docs/c/Foundation/Platform.md)   #### [Resources](https://developer.repebble.com/docs/c/Foundation/Resources.md) Managing application resources #### [Storage](https://developer.repebble.com/docs/c/Foundation/Storage.md) A mechanism to store persistent application data and state #### [Timer](https://developer.repebble.com/docs/c/Foundation/Timer.md) Can be used to execute some code at some point in the future. #### [Wakeup](https://developer.repebble.com/docs/c/Foundation/Wakeup.md) Allows applications to schedule to be launched even if they are not running. #### [Wall Time](https://developer.repebble.com/docs/c/Foundation/Wall_Time.md) Functions, data structures and other things related to wall clock time. #### [WatchInfo](https://developer.repebble.com/docs/c/Foundation/WatchInfo.md) Provides information about the watch itself. --- # Gesture Recognizers Source: https://developer.repebble.com/docs/c/User_Interface/Gesture_Recognizers/ The APIs on this page will only work with SDK 4.9+. Low-level touch-gesture recognizers for building fully custom touch interactions on touch-capable hardware. A recognizer watches the raw touch stream for one gesture — a tap, a pan (single-axis drag) or a swipe — and calls a [RecognizerEventCb](https://developer.repebble.com/docs/c/User_Interface/Gesture_Recognizers.md#RecognizerEventCb) as the gesture progresses. Create one with a per-gesture constructor ([tap\_recognizer\_create](https://developer.repebble.com/docs/c/User_Interface/Gesture_Recognizers.md#tap_recognizer_create), [pan\_recognizer\_create](https://developer.repebble.com/docs/c/User_Interface/Gesture_Recognizers.md#pan_recognizer_create), [swipe\_recognizer\_create](https://developer.repebble.com/docs/c/User_Interface/Gesture_Recognizers.md#swipe_recognizer_create)), attach it to a [Window](https://developer.repebble.com/docs/c/User_Interface/Window.md), and read the current gesture data from the event callback. Recognizers are the building block for a custom scroll or drag. For an ordinary scrollable list you do not need recognizers at all: on touch hardware [MenuLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md) already scrolls by touch. Reach for recognizers to build an interaction the built-in list does not give you — a custom menu, a drag, or acting on a raw tap or swipe. Note that a bare [ScrollLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/ScrollLayer.md) does not scroll by touch on its own; you drive it with a pan recognizer, as below. ### Usage example: scrolling a custom menu A [ScrollLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/ScrollLayer.md) holds your own content but does not scroll by touch by itself. Attach a vertical pan recognizer to the window and feed its delta into [scroll\_layer\_set\_content\_offset()](https://developer.repebble.com/docs/c/User_Interface/Layers/ScrollLayer.md#scroll_layer_set_content_offset) to scroll the content by finger: ``` static ScrollLayer \*s\_scroll;static int16\_t s\_base;// content offset committed on Completestatic void pan\_handler(const Recognizer \*recognizer, RecognizerEvent event) {switch (event) {case RecognizerEvent\_Updated: {// delta\_since\_start is (0, 0) at Start, so the content does not jump.GPoint d = pan\_recognizer\_get\_delta\_since\_start(recognizer);scroll\_layer\_set\_content\_offset(s\_scroll, GPoint(0, s\_base + d.y), false);break;}case RecognizerEvent\_Completed:s\_base = scroll\_layer\_get\_content\_offset(s\_scroll).y;// commitbreak;case RecognizerEvent\_Cancelled:scroll\_layer\_set\_content\_offset(s\_scroll, GPoint(0, s\_base), true);// roll backbreak;default:break;}}static void window\_load(Window \*window) {Layer \*root = window\_get\_root\_layer(window);s\_scroll = scroll\_layer\_create(layer\_get\_bounds(root));scroll\_layer\_set\_content\_size(s\_scroll, GSize(layer\_get\_bounds(root).size.w,total\_content\_height));// Add your custom row layers as children of s\_scroll here.layer\_add\_child(root, scroll\_layer\_get\_layer(s\_scroll));// The window owns the recognizer and destroys it when the window unloads.Recognizer \*pan = pan\_recognizer\_create(pan\_handler, NULL, PanAxis\_Vertical);window\_attach\_recognizer(window, pan);} ``` While the global system recognizer set is live, attaching alone is not enough: a window opts out of it with [window\_set\_touch\_bridge\_disabled()](https://developer.repebble.com/docs/c/User_Interface/Window.md#window_set_touch_bridge_disabled) (added by the touch-bridge change) so its own recognizers receive the touch stream. ## Function Documentation Recognizer \* tap\_recognizer\_create([RecognizerEventCb](https://developer.repebble.com/docs/c/User_Interface/Gesture_Recognizers.md#RecognizerEventCb) event\_cb, void \* user\_data) Create a tap recognizer. The default recognizer recognizes a single tap from a single finger. #### Parameters event\_cb event callback user\_data user data associated with recognizer #### Returns recognizer reference Recognizer \* pan\_recognizer\_create([RecognizerEventCb](https://developer.repebble.com/docs/c/User_Interface/Gesture_Recognizers.md#RecognizerEventCb) event\_cb, void \* user\_data, [PanAxis](https://developer.repebble.com/docs/c/User_Interface/Gesture_Recognizers.md#PanAxis) axis) Create a pan recognizer locked to a single axis. The recognizer stays in the Possible state until the finger moves unambiguously along _axis_ and crosses the start threshold, at which point it Starts. It Fails if the finger instead moves unambiguously along the foreign axis. #### Parameters event\_cb event callback user\_data user data associated with recognizer axis axis to which the pan is locked #### Returns recognizer reference Recognizer \* swipe\_recognizer\_create([RecognizerEventCb](https://developer.repebble.com/docs/c/User_Interface/Gesture_Recognizers.md#RecognizerEventCb) event\_cb, void \* user\_data, uint8\_t direction\_mask) Create a swipe recognizer that accepts the directions set in _direction\_mask_. The recognizer stays Possible while tracking the path and Completes on liftoff if the path is a fast, straight, long-enough flick whose direction is in the mask; otherwise it Fails. #### Parameters event\_cb event callback user\_data user data associated with recognizer direction\_mask bitwise-OR of the [SwipeDirection](https://developer.repebble.com/docs/c/User_Interface/Gesture_Recognizers.md#SwipeDirection) values to accept #### Returns recognizer reference [GPoint](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPoint) tap\_recognizer\_get\_tap\_point(const Recognizer \* recognizer) Get the coordinate of the recognized tap. The coordinate is taken from the last position update, not the liftoff. Valid once the recognizer has completed. #### Parameters recognizer recognizer from which to get the tap coordinate #### Returns tap coordinate [GPoint](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPoint) pan\_recognizer\_get\_total\_delta(const Recognizer \* recognizer) Get the total movement of the pan since the touchdown point. Component-wise. #### Parameters recognizer recognizer from which to get the delta #### Returns total delta from touchdown [GPoint](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPoint) pan\_recognizer\_get\_delta\_since\_start(const Recognizer \* recognizer) Get the movement of the pan since it Started (i.e. since the start threshold was crossed). This is exactly (0, 0) at the instant the recognizer transitions to Started, so live scroll that consumes this value does not jump at gesture start. Component-wise. #### Parameters recognizer recognizer from which to get the delta #### Returns delta since the pan started [GPoint](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPoint) pan\_recognizer\_get\_delta\_since\_prev(const Recognizer \* recognizer) Get the movement of the pan since the previous position update. Component-wise. #### Parameters recognizer recognizer from which to get the delta #### Returns delta since the previous event [GPoint](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPoint) pan\_recognizer\_get\_velocity(const Recognizer \* recognizer) Get the current velocity of the pan, in pixels per second, component-wise. Computed over the most-recent events within a short time window (see PAN\_VELOCITY\_WINDOW\_MS). Zero when the elapsed time across the sampled events is zero. #### Parameters recognizer recognizer from which to get the velocity #### Returns velocity in px/s [SwipeDirection](https://developer.repebble.com/docs/c/User_Interface/Gesture_Recognizers.md#SwipeDirection) swipe\_recognizer\_get\_direction(const Recognizer \* recognizer) Get the recognized swipe direction. Valid once the recognizer has Completed; otherwise SwipeDirection\_None. #### Parameters recognizer recognizer from which to get the direction #### Returns recognized swipe direction [GPoint](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPoint) swipe\_recognizer\_get\_velocity(const Recognizer \* recognizer) Get the velocity of the swipe, in pixels per second, component-wise. Computed over the most-recent events within a short time window. Zero when the elapsed time is zero. #### Parameters recognizer recognizer from which to get the velocity #### Returns velocity in px/s void recognizer\_destroy(Recognizer \* recognizer) Destroy an un-owned recognizer. If a recognizer is not owned, this will destroy the recognizer freeing it's data and calling the destructor (see recognizer\_set\_on\_destroy), if set. If it is owned, this will do nothing. #### Parameters recognizer [Gesture Recognizers](https://developer.repebble.com/docs/c/User_Interface/Gesture_Recognizers.md) to destroy void recognizer\_set\_simultaneous\_with(Recognizer \* recognizer, [RecognizerSimultaneousWithCb](https://developer.repebble.com/docs/c/User_Interface/Gesture_Recognizers.md#RecognizerSimultaneousWithCb) simultaneous\_with\_cb) Specify a callback to determine whether a recognizer should be evaluated simultaneously with another recognizer. #### Parameters recognizer recognizer to modify simultaneous\_with\_cb callback that determines whether this recognizer will be evaluated simultaneous with another recognizer void recognizer\_set\_fail\_after(Recognizer \* recognizer, Recognizer \* fail\_after) Tell a recognizer to only evaluate after the another recognizer fails. #### Parameters recognizer recognizer to modify fail\_after recognizer after which the modified gesture will be evaluated ## Enum Documentation enum RecognizerEvent #### Enumerators RecognizerEvent\_StartedRecognizerEvent\_UpdatedRecognizerEvent\_CompletedRecognizerEvent\_Cancelled enum PanAxis Axis to which a pan recognizer is locked. A pan is only recognized when the finger moves unambiguously along this axis. #### Enumerators PanAxis\_HorizontalPanAxis\_Vertical enum SwipeDirection Swipe direction, also used as a bitmask when configuring which directions a swipe recognizer accepts. Screen coordinates grow downward, so a positive y delta is a downward swipe. #### Enumerators SwipeDirection\_NoneSwipeDirection\_UpSwipeDirection\_DownSwipeDirection\_LeftSwipeDirection\_Right ## Typedef Documentation typedef struct Recognizer Recognizer typedef void(\* RecognizerEventCb)(const Recognizer \*recognizer, RecognizerEvent event\_type) User event callback. When a recognizer changes state to any state other than the failed state the user callback of this type will be called. #### Parameters recognizer recognizer affected by the event event\_type event that occurred typedef bool(\* RecognizerSimultaneousWithCb)(const Recognizer \*recognizer, const Recognizer \*simultaneous\_with) This function is called to determine whether _recognizer_ should be evaluated simultaneously with _simultaneous\_with_. #### Parameters recognizer recognizer to be tested simultaneous\_with recognizer with which _recognizer_ would be evaluated simultaneously should this test pass #### Returns true if recognizers should be evaluated simultaneously --- # Graphics Source: https://developer.repebble.com/docs/c/Graphics/ Low-level drawing routines. The Graphics framework defines a set of APIs that can be used to draw paths, primitives and text, as well as handle the loading of fonts and the setting of graphics contexts for compositing, fill color and text color. ## Modules #### [Draw Commands](https://developer.repebble.com/docs/c/Graphics/Draw_Commands.md) Pebble Draw Commands are a way to encode arbitrary path draw and fill calls in binary format, so that vector-like graphics can be represented on the watch. #### [Drawing Paths](https://developer.repebble.com/docs/c/Graphics/Drawing_Paths.md) Functions to draw polygons into a graphics context #### [Drawing Primitives](https://developer.repebble.com/docs/c/Graphics/Drawing_Primitives.md) Functions to draw into a graphics context #### [Drawing Text](https://developer.repebble.com/docs/c/Graphics/Drawing_Text.md) Functions to draw text into a graphics context #### [Fonts](https://developer.repebble.com/docs/c/Graphics/Fonts.md) Custom and system fonts. #### [Graphics Context](https://developer.repebble.com/docs/c/Graphics/Graphics_Context.md) The "canvas" into which an application draws #### [Graphics Types](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md) Basic graphics types (point, rect, size, color, bitmaps, etc.) and utility functions. --- # Graphics Context Source: https://developer.repebble.com/docs/c/Graphics/Graphics_Context/ The "canvas" into which an application draws The Pebble OS graphics engine, inspired by several notable graphics systems, including Apple’s Quartz 2D and its predecessor QuickDraw, provides your app with a canvas into which to draw, namely, the graphics context. A graphics context is the target into which graphics functions can paint, using Pebble drawing routines (see [Drawing Primitives](https://developer.repebble.com/docs/c/Graphics/Drawing_Primitives.md), [Drawing Paths](https://developer.repebble.com/docs/c/Graphics/Drawing_Paths.md) and [Drawing Text](https://developer.repebble.com/docs/c/Graphics/Drawing_Text.md)). A graphics context holds a reference to the bitmap into which to paint. It also holds the current drawing state, like the current fill color, stroke color, clipping box, drawing box, compositing mode, and so on. The GContext struct is the type representing the graphics context. For drawing in your Pebble watchface or watchapp, you won't need to create a GContext yourself. In most cases, it is provided by Pebble OS as an argument passed into a render callback (the .update\_proc of a Layer). Your app can’t call drawing functions at any given point in time: Pebble OS will request your app to render. Typically, your app will be calling out to graphics functions in the .update\_proc callback of a Layer. ## Function Documentation void graphics\_context\_set\_stroke\_color(GContext \* ctx, GColor color) Sets the current stroke color of the graphics context. #### Parameters ctx The graphics context onto which to set the stroke color color The new stroke color void graphics\_context\_set\_fill\_color(GContext \* ctx, GColor color) Sets the current fill color of the graphics context. #### Parameters ctx The graphics context onto which to set the fill color color The new fill color void graphics\_context\_set\_text\_color(GContext \* ctx, GColor color) Sets the current text color of the graphics context. #### Parameters ctx The graphics context onto which to set the text color color The new text color - [SDK 3](javascript:void(0);) - [SDK 4](javascript:void(0);) - [SDK 4.9+](javascript:void(0);) void graphics\_context\_set\_compositing\_mode(GContext \* ctx, [GCompOp](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GCompOp) mode) Sets the current bitmap compositing mode of the graphics context. ##### Note At the moment, this only affects the bitmaps drawing operations - [graphics\_draw\_bitmap\_in\_rect()](https://developer.repebble.com/docs/c/Graphics/Drawing_Primitives.md#graphics_draw_bitmap_in_rect), [graphics\_draw\_rotated\_bitmap](https://developer.repebble.com/docs/c/Graphics/Drawing_Primitives.md#graphics_draw_rotated_bitmap), and anything that uses those APIs -, but it currently does not affect the filling or stroking operations. #### Parameters ctx The graphics context onto which to set the compositing mode mode The new compositing mode #### See Also [GCompOp](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GCompOp) [bitmap\_layer\_set\_compositing\_mode()](https://developer.repebble.com/docs/c/User_Interface/Layers/BitmapLayer.md#bitmap_layer_set_compositing_mode) void graphics\_context\_set\_compositing\_mode(GContext \* ctx, [GCompOp](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GCompOp) mode) Sets the current bitmap compositing mode of the graphics context. ##### Note At the moment, this only affects the bitmaps drawing operations - [graphics\_draw\_bitmap\_in\_rect()](https://developer.repebble.com/docs/c/Graphics/Drawing_Primitives.md#graphics_draw_bitmap_in_rect), [graphics\_draw\_rotated\_bitmap](https://developer.repebble.com/docs/c/Graphics/Drawing_Primitives.md#graphics_draw_rotated_bitmap), and anything that uses those APIs -, but it currently does not affect the filling or stroking operations. #### Parameters ctx The graphics context onto which to set the compositing mode mode The new compositing mode #### See Also [GCompOp](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GCompOp) [bitmap\_layer\_set\_compositing\_mode()](https://developer.repebble.com/docs/c/User_Interface/Layers/BitmapLayer.md#bitmap_layer_set_compositing_mode) void graphics\_context\_set\_compositing\_mode(GContext \* ctx, [GCompOp](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GCompOp) mode) Sets the current bitmap compositing mode of the graphics context. The default mode is GCompOpAssign i.e. bitmap transparency disabled. ##### Note At the moment, this only affects the bitmaps drawing operations - [graphics\_draw\_bitmap\_in\_rect()](https://developer.repebble.com/docs/c/Graphics/Drawing_Primitives.md#graphics_draw_bitmap_in_rect), [graphics\_draw\_rotated\_bitmap](https://developer.repebble.com/docs/c/Graphics/Drawing_Primitives.md#graphics_draw_rotated_bitmap), and anything that uses those APIs -, but it currently does not affect the filling or stroking operations. #### Parameters ctx The graphics context onto which to set the compositing mode mode The new compositing mode #### See Also [GCompOp](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GCompOp) [bitmap\_layer\_set\_compositing\_mode()](https://developer.repebble.com/docs/c/User_Interface/Layers/BitmapLayer.md#bitmap_layer_set_compositing_mode) void graphics\_context\_set\_antialiased(GContext \* ctx, bool enable) Sets whether antialiasing is applied to stroke drawing. ##### Note Default value is true. #### Parameters ctx The graphics context onto which to set the antialiasing enable True = antialiasing enabled, False = antialiasing disabled void graphics\_context\_set\_stroke\_width(GContext \* ctx, uint8\_t stroke\_width) Sets the width of the stroke for drawing routines. ##### Note If stroke width of zero is passed, it will be ignored and will not change the value stored in GContext. Currently, only odd stroke\_width values are supported. If an even value is passed in, the value will be stored as is, but the drawing routines will round down to the previous integral value when drawing. Default value is 1. #### Parameters ctx The graphics context onto which to set the stroke width stroke\_width Width in pixels of the stroke. --- # Graphics Types Source: https://developer.repebble.com/docs/c/Graphics/Graphics_Types/ Basic graphics types (point, rect, size, color, bitmaps, etc.) and utility functions. ## Modules #### [Color Definitions](https://developer.repebble.com/docs/c/Graphics/Graphics_Types/Color_Definitions.md) A list of all of the named colors available with links to the color map on the Pebble Developer website. ## Function Documentation bool gcolor\_equal(GColor8 x, GColor8 y) True if both colors are identical or both are invisible (i.e. both have alpha values of .a=0). GColor8 gcolor\_legible\_over(GColor8 background\_color) This method assists in improving the legibility of text on various background colors. It takes the background color for the region in question and computes a color for maximum legibility. #### Parameters background\_color Background color for the region in question #### Returns A legible color for the given background color bool gpoint\_equal(const [GPoint](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPoint) \*const point\_a, const [GPoint](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPoint) \*const point\_b) Tests whether 2 points are equal. #### Parameters point\_a Pointer to the first point point\_b Pointer to the second point #### Returns `true` if both points are equal, `false` if not. bool gsize\_equal(const [GSize](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GSize) \* size\_a, const [GSize](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GSize) \* size\_b) Tests whether 2 sizes are equal. #### Parameters size\_a Pointer to the first size size\_b Pointer to the second size #### Returns `true` if both sizes are equal, `false` if not. bool grect\_equal(const [GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) \*const rect\_a, const [GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) \*const rect\_b) Tests whether 2 rectangles are equal. #### Parameters rect\_a Pointer to the first rectangle rect\_b Pointer to the second rectangle #### Returns `true` if both rectangles are equal, `false` if not. bool grect\_is\_empty(const [GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) \*const rect) Tests whether the size of the rectangle is (0, 0). ##### Note If the width and/or height of a rectangle is negative, this function will return `true`! #### Parameters rect Pointer to the rectangle #### Returns `true` if the rectangle its size is (0, 0), or `false` if not. - [SDK 3](javascript:void(0);) - [SDK 4](javascript:void(0);) - [SDK 4.9+](javascript:void(0);) void grect\_standardize([GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) \* rect) Converts a rectangle's values so that the components of its size (width and/or height) are both positive. In the width and/or height are negative, the origin will offset, so that the final rectangle overlaps with the original. For example, a [GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) with size (-10, -5) and origin (20, 20), will be standardized to size (10, 5) and origin (10, 15). #### Parameters rect (in) The rectangle to convert. rect (out) The standardized rectangle. void grect\_standardize([GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) \* rect) Converts a rectangle's values so that the components of its size (width and/or height) are both positive. In the width and/or height are negative, the origin will offset, so that the final rectangle overlaps with the original. For example, a [GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) with size (-10, -5) and origin (20, 20), will be standardized to size (10, 5) and origin (10, 15). #### Parameters rect (in) The rectangle to convert. rect (out) The standardized rectangle. void grect\_standardize([GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) \* rect) Converts a rectangle's values so that the components of its size (width and/or height) are both positive. In the width and/or height are negative, the origin will offset, so that the final rectangle overlaps with the original. For example, a [GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) with size (-10, -5) and origin (20, 20), will be standardized to size (10, 5) and origin (10, 15). #### Parameters rect (inout) The rectangle to convert, set to the standardized rectangle. - [SDK 3](javascript:void(0);) - [SDK 4](javascript:void(0);) - [SDK 4.9+](javascript:void(0);) void grect\_clip([GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) \*const rect\_to\_clip, const [GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) \*const rect\_clipper) Trim one rectangle using the edges of a second rectangle. #### Parameters rect\_to\_clip (in) The rectangle that needs to be clipped (in place). rect\_to\_clip (out) The clipped rectangle. rect\_clipper The rectangle of which the edges will serve as "scissors" in order to trim `rect_to_clip`. void grect\_clip([GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) \*const rect\_to\_clip, const [GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) \*const rect\_clipper) Trim one rectangle using the edges of a second rectangle. #### Parameters rect\_to\_clip (in) The rectangle that needs to be clipped (in place). rect\_to\_clip (out) The clipped rectangle. rect\_clipper The rectangle of which the edges will serve as "scissors" in order to trim `rect_to_clip`. void grect\_clip([GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) \*const rect\_to\_clip, const [GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) \*const rect\_clipper) Trim one rectangle using the edges of a second rectangle. #### Parameters rect\_to\_clip (inout) The rectangle that needs to be clipped (in place). rect\_clipper The rectangle of which the edges will serve as "scissors" in order to trim `rect_to_clip`. bool grect\_contains\_point(const [GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) \* rect, const [GPoint](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPoint) \* point) Tests whether a rectangle contains a point. #### Parameters rect The rectangle point The point #### Returns `true` if the rectangle contains the point, or `false` if it does not. [GPoint](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPoint) grect\_center\_point(const [GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) \* rect) Convenience function to compute the center-point of a given rectangle. This is equal to `(rect->x + rect->width / 2, rect->y + rect->height / 2)`. #### Parameters rect The rectangle for which to calculate the center point. #### Returns The point at the center of `rect` [GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) grect\_crop([GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) rect, const int32\_t crop\_size\_px) Reduce the width and height of a rectangle by insetting each of the edges with a fixed inset. The returned rectangle will be centered relative to the input rectangle. ##### Note The function will trip an assertion if the crop yields a rectangle with negative width or height. #### Parameters rect The rectangle that will be inset crop\_size\_px The inset by which each of the rectangle will be inset. A positive inset value results in a smaller rectangle, while negative inset value results in a larger rectangle. #### Returns The cropped rectangle. [uint16\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint16_t) gbitmap\_get\_bytes\_per\_row(const GBitmap \* bitmap) Get the number of bytes per row in the bitmap data for the given GBitmap. On rectangular displays, this can be used as a safe way of iterating over the rows in the bitmap, since bytes per row should be set according to format. On circular displays with pixel format of GBitmapFormat8BitCircular this will return 0, and should not be used for iteration over frame buffer pixels. Instead, use [GBitmapDataRowInfo](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GBitmapDataRowInfo), which provides safe minimum and maximum x values for a given row's y value. #### Parameters bitmap A pointer to the GBitmap to get the bytes per row #### Returns The number of bytes per row of the GBitmap #### See Also [gbitmap\_get\_data](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#gbitmap_get_data) [GBitmapFormat](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GBitmapFormat) gbitmap\_get\_format(const GBitmap \* bitmap) Get the [GBitmapFormat](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GBitmapFormat) for the GBitmap. #### Parameters bitmap A pointer to the GBitmap to get the format #### Returns The format of the given GBitmap. uint8\_t \* gbitmap\_get\_data(const GBitmap \* bitmap) Get a pointer to the raw image data section of the given GBitmap as specified by the format of the bitmap. #### Parameters bitmap A pointer to the GBitmap to get the data #### Returns pointer to the raw image data for the GBitmap #### See Also [gbitmap\_get\_bytes\_per\_row](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#gbitmap_get_bytes_per_row) GBitmap void gbitmap\_set\_data(GBitmap \* bitmap, uint8\_t \* data, [GBitmapFormat](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GBitmapFormat) format, [uint16\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint16_t) row\_size\_bytes, bool free\_on\_destroy) Set the bitmap data for the given GBitmap. #### Parameters bitmap A pointer to the GBitmap to set data to data A pointer to the bitmap data format the format of the bitmap data. If this is a palettized format, make sure that there is an accompanying call to [gbitmap\_set\_palette](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#gbitmap_set_palette). row\_size\_bytes How many bytes a single row takes. For example, bitmap data of format GBitmapFormat1Bit must have a row size as a multiple of 4 bytes. free\_on\_destroy Set whether the data should be freed when the GBitmap is destroyed. #### See Also [gbitmap\_destroy](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#gbitmap_destroy) [GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) gbitmap\_get\_bounds(const GBitmap \* bitmap) Gets the bounds of the content for the GBitmap. This is set when loading the image or if changed by [gbitmap\_set\_bounds](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#gbitmap_set_bounds). #### Parameters bitmap A pointer to the GBitmap to get the bounding box from. #### Returns The bounding box for the GBitmap. #### See Also [gbitmap\_set\_bounds](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#gbitmap_set_bounds) void gbitmap\_set\_bounds(GBitmap \* bitmap, [GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) bounds) Set the bounds of the given GBitmap. #### Parameters bitmap A pointer to the GBitmap to set the bounding box. bounds The bounding box to set. #### See Also [gbitmap\_get\_bounds](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#gbitmap_get_bounds) GColor \* gbitmap\_get\_palette(const GBitmap \* bitmap) Get the palette for the given GBitmap. #### Parameters bitmap A pointer to the GBitmap to get the palette from. #### Returns Pointer to a GColor array containing the palette colors. #### See Also [gbitmap\_set\_palette](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#gbitmap_set_palette) void gbitmap\_set\_palette(GBitmap \* bitmap, GColor \* palette, bool free\_on\_destroy) Set the palette for the given GBitmap. #### Parameters bitmap A pointer to the GBitmap to set the palette to palette The palette to be used. Make sure that the palette is large enough for the bitmap's format. free\_on\_destroy Set whether the palette data should be freed when the GBitmap is destroyed or when another palette is set. #### See Also [gbitmap\_get\_format](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#gbitmap_get_format) [gbitmap\_destroy](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#gbitmap_destroy) [gbitmap\_set\_palette](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#gbitmap_set_palette) GBitmap \* gbitmap\_create\_with\_resource([uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) resource\_id) Creates a new GBitmap on the heap using a Pebble image file stored as a resource. The resulting GBitmap must be destroyed using [gbitmap\_destroy()](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#gbitmap_destroy). #### Parameters resource\_id The ID of the bitmap resource to load #### Returns A pointer to the GBitmap. `NULL` if the GBitmap could not be created GBitmap \* gbitmap\_create\_with\_data(const uint8\_t \* data) Creates a new GBitmap on the heap initialized with the provided Pebble image data. The resulting GBitmap must be destroyed using [gbitmap\_destroy()](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#gbitmap_destroy) but the image data will not be freed automatically. The developer is responsible for keeping the image data in memory as long as the bitmap is used and releasing it after the bitmap is destroyed. ##### Note One way to generate Pebble image data is to use bitmapgen.py in the Pebble SDK to generate a .pbi file. #### Parameters data The Pebble image data. Must not be NULL. The function assumes the data to be correct; there are no sanity checks performed on the data. The data will not be copied and the pointer must remain valid for the lifetime of this GBitmap. #### Returns A pointer to the GBitmap. `NULL` if the GBitmap could not be created GBitmap \* gbitmap\_create\_as\_sub\_bitmap(const GBitmap \* base\_bitmap, [GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) sub\_rect) Create a new GBitmap on the heap as a sub-bitmap of a 'base' GBitmap, using a [GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) to indicate what portion of the base to use. The sub-bitmap will just reference the image data and palette of the base bitmap. No deep-copying occurs as a result of calling this function, thus the caller is responsible for making sure the base bitmap and palette will remain available when using the sub-bitmap. Note that you should not destroy the parent bitmap until the sub\_bitmap has been destroyed. The resulting GBitmap must be destroyed using [gbitmap\_destroy()](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#gbitmap_destroy). #### Parameters base\_bitmap (in) The bitmap that the sub-bitmap of which the image data will be used by the sub-bitmap sub\_rect The rectangle within the image data of the base bitmap. The bounds of the base bitmap will be used to clip `sub_rect`. #### Returns A pointer to the GBitmap. `NULL` if the GBitmap could not be created GBitmap \* gbitmap\_create\_from\_png\_data(const uint8\_t \* png\_data, [size\_t](https://developer.repebble.com/docs/c/Standard_C/Memory.md#size_t) png\_data\_size) Create a GBitmap based on raw PNG data. The resulting GBitmap must be destroyed using [gbitmap\_destroy()](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#gbitmap_destroy). The developer is responsible for freeing png\_data following this call. ##### Note PNG decoding currently supports 1,2,4 and 8 bit palettized and grayscale images. #### Parameters png\_data PNG image data. png\_data\_size PNG image size in bytes. #### Returns A pointer to the GBitmap. `NULL` if the GBitmap could not be created GBitmap \* gbitmap\_create\_blank([GSize](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GSize) size, [GBitmapFormat](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GBitmapFormat) format) Creates a new blank GBitmap on the heap initialized to zeroes. In the case that the format indicates a palettized bitmap, a palette of appropriate size will also be allocated on the heap. The resulting GBitmap must be destroyed using [gbitmap\_destroy()](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#gbitmap_destroy). #### Parameters size The Pebble image dimensions as a [GSize](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GSize). format The [GBitmapFormat](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GBitmapFormat) the created image should be in. #### Returns A pointer to the GBitmap. `NULL` if the GBitmap could not be created GBitmap \* gbitmap\_create\_blank\_with\_palette([GSize](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GSize) size, [GBitmapFormat](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GBitmapFormat) format, GColor \* palette, bool free\_on\_destroy) Creates a new blank GBitmap on the heap, initialized to zeroes, and assigns it the given palette. No deep-copying of the palette occurs, so the caller is responsible for making sure the palette remains available when using the resulting bitmap. Management of that memory can be handed off to the system with the free\_on\_destroy argument. #### Parameters size The Pebble image dimensions as a [GSize](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GSize). format the [GBitmapFormat](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GBitmapFormat) the created image and palette should be in. palette a pointer to a palette that is to be used for this GBitmap. The palette should be large enough to hold enough colors for the specified format. For example, GBitmapFormat2BitPalette should have 4 colors, since 2^2 = 4. free\_on\_destroy Set whether the palette data should be freed along with the bitmap data when the GBitmap is destroyed. #### Returns A Pointer to the GBitmap. `NULL` if the GBitmap could not be created. GBitmap \* gbitmap\_create\_palettized\_from\_1bit(const GBitmap \* src\_bitmap) Given a 1-bit GBitmap, create a new bitmap of format GBitmapFormat1BitPalette. The new data buffer is allocated on the heap, and a 2-color palette is allocated as well. ##### Note The new bitmap does not depend on any data from src\_bitmap, so src\_bitmap can be freed without worry. #### Parameters src\_bitmap A GBitmap of format GBitmapFormat1Bit which is to be copied into a newly created GBitmap of format GBitmapFormat1BitPalettized. #### Returns The newly created 1-bit palettized GBitmap, or NULL if there is not sufficient space. void gbitmap\_destroy(GBitmap \* bitmap) Destroy a GBitmap. This must be called for every bitmap that's been created with gbitmap\_create\_\*. This function will also free the memory of the bitmap data (bitmap-\>addr) if the bitmap was created with [gbitmap\_create\_blank()](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#gbitmap_create_blank) or [gbitmap\_create\_with\_resource()](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#gbitmap_create_with_resource). If the GBitmap was created with [gbitmap\_create\_with\_data()](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#gbitmap_create_with_data), you must release the memory after calling [gbitmap\_destroy()](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#gbitmap_destroy). GBitmapSequence \* gbitmap\_sequence\_create\_with\_resource([uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) resource\_id) Creates a GBitmapSequence from the specified resource (APNG/PNG files) #### Parameters resource\_id Resource to load and create GBitmapSequence from. #### Returns GBitmapSequence pointer if the resource was loaded, NULL otherwise bool gbitmap\_sequence\_update\_bitmap\_next\_frame(GBitmapSequence \* bitmap\_sequence, GBitmap \* bitmap, [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) \* delay\_ms) Updates the contents of the bitmap sequence to the next frame and optionally returns the delay in milliseconds until the next frame. ##### Note GBitmap must be large enough to accommodate the bitmap\_sequence image [gbitmap\_sequence\_get\_bitmap\_size](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#gbitmap_sequence_get_bitmap_size) #### Parameters bitmap\_sequence Pointer to loaded bitmap sequence bitmap Pointer to the initialized GBitmap in which to render the bitmap sequence delay\_ms (out) If not NULL, returns the delay in milliseconds until the next frame. #### Returns True if frame was rendered. False if all frames (and loops) have been rendered for the sequence. Will also return false if frame could not be rendered (includes out of memory errors). bool gbitmap\_sequence\_update\_bitmap\_by\_elapsed(GBitmapSequence \* bitmap\_sequence, GBitmap \* bitmap, [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) elapsed\_ms) Updates the contents of the bitmap sequence to the frame at elapsed in the sequence. For looping animations this accounts for the loop, for example an animation of 1 second that is configured to loop 2 times updated to 1500 ms elapsed time will display the sequence frame at 500 ms. Elapsed time is the time from the start of the animation, and will be ignored if it is for a time earlier than the last rendered frame. ##### Notes GBitmap must be large enough to accommodate the bitmap\_sequence image [gbitmap\_sequence\_get\_bitmap\_size](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#gbitmap_sequence_get_bitmap_size) This function is disabled for play\_count 0 #### Parameters bitmap\_sequence Pointer to loaded bitmap sequence bitmap Pointer to the initialized GBitmap in which to render the bitmap sequence elapsed\_ms Elapsed time in milliseconds in the sequence relative to start #### Returns True if a frame was rendered. False if all frames (and loops) have already been rendered for the sequence. Will also return false if frame could not be rendered (includes out of memory errors). void gbitmap\_sequence\_destroy(GBitmapSequence \* bitmap\_sequence) Deletes the GBitmapSequence structure and frees any allocated memory/decoder\_data. #### Parameters bitmap\_sequence Pointer to the bitmap sequence to free (delete) bool gbitmap\_sequence\_restart(GBitmapSequence \* bitmap\_sequence) Restarts the GBitmapSequence to the first frame [gbitmap\_sequence\_update\_bitmap\_next\_frame](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#gbitmap_sequence_update_bitmap_next_frame). #### Parameters bitmap\_sequence Pointer to loaded bitmap sequence #### Returns True if sequence was restarted, false otherwise int32\_t gbitmap\_sequence\_get\_current\_frame\_idx(GBitmapSequence \* bitmap\_sequence) This function gets the current frame number for the bitmap sequence. #### Parameters bitmap\_sequence Pointer to loaded bitmap sequence #### Returns index of current frame in the current loop of the bitmap sequence [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) gbitmap\_sequence\_get\_total\_num\_frames(GBitmapSequence \* bitmap\_sequence) This function sets the total number of frames for the bitmap sequence. #### Parameters bitmap\_sequence Pointer to loaded bitmap sequence #### Returns number of frames contained in a single loop of the bitmap sequence [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) gbitmap\_sequence\_get\_play\_count(GBitmapSequence \* bitmap\_sequence) This function gets the play count (number of times to repeat) the bitmap sequence. ##### Note This value is initialized by the bitmap sequence data, and is modified by [gbitmap\_sequence\_set\_play\_count](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#gbitmap_sequence_set_play_count) #### Parameters bitmap\_sequence Pointer to loaded bitmap sequence #### Returns Play count of bitmap sequence, PLAY\_COUNT\_INFINITE for infinite looping void gbitmap\_sequence\_set\_play\_count(GBitmapSequence \* bitmap\_sequence, [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) play\_count) This function sets the play count (number of times to repeat) the bitmap sequence. #### Parameters bitmap\_sequence Pointer to loaded bitmap sequence play\_count Number of times to repeat the bitmap sequence with 0 disabling update\_by\_elapsed and update\_next\_frame, and PLAY\_COUNT\_INFINITE for infinite looping of the animation [GSize](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GSize) gbitmap\_sequence\_get\_bitmap\_size(GBitmapSequence \* bitmap\_sequence) This function gets the minimum required size (dimensions) necessary to render the bitmap sequence to a GBitmap using the /ref gbitmap\_sequence\_update\_bitmap\_next\_frame. #### Parameters bitmap\_sequence Pointer to loaded bitmap sequence #### Returns Dimensions required to render the bitmap sequence to a GBitmap [GBitmapDataRowInfo](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GBitmapDataRowInfo) gbitmap\_get\_data\_row\_info(const GBitmap \* bitmap, [uint16\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint16_t) y) Provides information about a pixel data row. ##### Note This function does not respect the bitmap's bounds but purely operates on the pixel data. This function works with every bitmap format including GBitmapFormat1Bit. The result of the function for invalid rows is undefined. #### Parameters bitmap A pointer to the GBitmap to get row info y Absolute row number in the pixel data, independent from the bitmap's bounds #### Returns Description of the row #### See Also [gbitmap\_get\_data](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#gbitmap_get_data) - [SDK 3](javascript:void(0);) - [SDK 4](javascript:void(0);) - [SDK 4.9+](javascript:void(0);) void grect\_align([GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) \* rect, const [GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) \* inside\_rect, const [GAlign](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GAlign) alignment, const bool clip) Aligns one rectangle within another rectangle, using an alignment parameter. The relative coordinate systems of both rectangles are assumed to be the same. When clip is true, `rect` is also clipped by the constraint. #### Parameters rect (in) The rectangle to align (in place) rect (out) The aligned and optionally clipped rectangle inside\_rect The rectangle in which to align `rect` alignment Determines the alignment of `rect` within `inside_rect` by specifying what edges of should overlap. clip Determines whether `rect` should be trimmed using the edges of `inside_rect` in case `rect` extends outside of the area that `inside_rect` covers after the alignment. void grect\_align([GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) \* rect, const [GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) \* inside\_rect, const [GAlign](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GAlign) alignment, const bool clip) Aligns one rectangle within another rectangle, using an alignment parameter. The relative coordinate systems of both rectangles are assumed to be the same. When clip is true, `rect` is also clipped by the constraint. #### Parameters rect (in) The rectangle to align (in place) rect (out) The aligned and optionally clipped rectangle inside\_rect The rectangle in which to align `rect` alignment Determines the alignment of `rect` within `inside_rect` by specifying what edges of should overlap. clip Determines whether `rect` should be trimmed using the edges of `inside_rect` in case `rect` extends outside of the area that `inside_rect` covers after the alignment. void grect\_align([GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) \* rect, const [GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) \* inside\_rect, const [GAlign](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GAlign) alignment, const bool clip) Aligns one rectangle within another rectangle, using an alignment parameter. The relative coordinate systems of both rectangles are assumed to be the same. When clip is true, `rect` is also clipped by the constraint. #### Parameters rect (inout) The rectangle to align (in place), set to the aligned and optionally clipped rectangle inside\_rect The rectangle in which to align `rect` alignment Determines the alignment of `rect` within `inside_rect` by specifying what edges of should overlap. clip Determines whether `rect` should be trimmed using the edges of `inside_rect` in case `rect` extends outside of the area that `inside_rect` covers after the alignment. [GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) grect\_inset([GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) rect, [GEdgeInsets](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GEdgeInsets) insets) Returns a rectangle that is shrinked or expanded by the given edge insets. ##### Notes The rectangle is standardized and then the inset parameters are applied. If the resulting rectangle would have a negative height or width, a GRectZero is returned. Use this function in together with the [GEdgeInsets](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GEdgeInsets) macro ``` GRect r\_inset\_all\_sides = grect\_inset(r, GEdgeInsets(10));GRect r\_inset\_vertical\_horizontal = grect\_inset(r, GEdgeInsets(10, 20));GRect r\_expand\_top\_right\_shrink\_bottom\_left = grect\_inset(r, GEdgeInsets(-10, -10, 10, 10)); ``` #### Parameters rect The rectangle that will be inset insets The insets that will be applied #### Returns The resulting rectangle ## Data Structure Documentation struct GBitmapDataRowInfo Description of a single data row in the pixel data of a bitmap. ##### Note This data type describes the actual pixel data of a bitmap and does not respect the bitmap's bounds. #### Data Fields uint8\_t \* data Address of the byte at column 0 of a given data row in a bitmap. Use this to calculate the memory address of a pixel. For GBitmapFormat8BitCircular or GBitmapFormat8Bit this would be: `uint8_t *pixel_addr = row_info.addr + x`. Note that this byte can be outside of the valid range for this row. For example: The first valid pixel (`min_x=76`) of a row might start at 76 bytes after the given data pointer (assuming that 1 pixel is represented as 1 byte as in GBitmapFormat8BitCircular or GBitmapFormat8Bit). int16\_t min\_x The absolute column of a first valid pixel for a given data row. int16\_t max\_x The absolute column of the last valid pixel for a given data row. For optimization reasons the result can be anywhere between grect\_get\_max\_x(bitmap\_bounds) - 1 and the physical data boundary. #### See Also [gbitmap\_get\_data\_row\_info](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#gbitmap_get_data_row_info) [gbitmap\_get\_data](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#gbitmap_get_data) [gbitmap\_get\_bounds](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#gbitmap_get_bounds) struct GEdgeInsets Represents insets for four sides. Negative values mean a side extends. #### Data Fields int16\_t top The inset at the top of an object. int16\_t right The inset at the right of an object. int16\_t bottom The inset at the bottom of an object. int16\_t left The inset at the left of an object. #### See Also [grect\_inset](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#grect_inset) struct GPoint Represents a point in a 2-dimensional coordinate system. ##### Note Conventionally, the origin of Pebble's 2D coordinate system is in the upper, lefthand corner its x-axis extends to the right and its y-axis extends to the bottom of the screen. #### Data Fields int16\_t x The x-coordinate. int16\_t y The y-coordinate. struct GRect Represents a rectangle and defining it using the origin of the upper-lefthand corner and its size. #### Data Fields [GPoint](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPoint) origin The coordinate of the upper-lefthand corner point of the rectangle. [GSize](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GSize) size The size of the rectangle. struct GSize Represents a 2-dimensional size. #### Data Fields int16\_t w The width. int16\_t h The height. ## Union Documentation struct GColor8 #### Data Fields uint8\_t argbstruct GColor8 ## Enum Documentation enum GBitmapFormat The format of a GBitmap can either be 1-bit or 8-bit. #### Enumerators GBitmapFormat1BitGBitmapFormat8BitGBitmapFormat1BitPaletteGBitmapFormat2BitPaletteGBitmapFormat4BitPaletteGBitmapFormat8BitCircular enum GAlign Values to specify how two things should be aligned relative to each other. ![](https://developer.repebble.com/assets/images/docs/c/aplite/galign.png) ![](https://developer.repebble.com/assets/images/docs/c/aplite/galign.png) ![](https://developer.repebble.com/assets/images/docs/c/aplite/galign.png) ![](https://developer.repebble.com/assets/images/docs/c/aplite/galign.png) ![](https://developer.repebble.com/assets/images/docs/c/aplite/galign.png) bitmap\_layer\_set\_alignment() #### Enumerators GAlignCenter Align by centering. GAlignTopLeft Align by making the top edges overlap and left edges overlap. GAlignTopRight Align by making the top edges overlap and left edges overlap. GAlignTop Align by making the top edges overlap and centered horizontally. GAlignLeft Align by making the left edges overlap and centered vertically. GAlignBottom Align by making the bottom edges overlap and centered horizontally. GAlignRight Align by making the right edges overlap and centered vertically. GAlignBottomRight Align by making the bottom edges overlap and right edges overlap. GAlignBottomLeft Align by making the bottom edges overlap and left edges overlap. enum GCompOp Values to specify how the source image should be composited onto the destination image. ![](https://developer.repebble.com/assets/images/docs/c/aplite/compops.png) ![](https://developer.repebble.com/assets/images/docs/c/aplite/compops.png) ![](https://developer.repebble.com/assets/images/docs/c/aplite/compops.png) ![](https://developer.repebble.com/assets/images/docs/c/aplite/compops.png) ![](https://developer.repebble.com/assets/images/docs/c/aplite/compops.png) Contrived example of how the different compositing modes affect drawing. Often, the "destination image" is the render buffer and thus contains the image of what has been drawn before or "underneath". For color displays, only two compositing modes are supported, GCompOpAssign and GCompOpSet. The behavior of other compositing modes are undefined and may change in the future. Transparency can be achieved using GCompOpSet and requires pixel values with alpha value .a \< 3. bitmap\_layer\_set\_compositing\_mode() graphics\_context\_set\_compositing\_mode() graphics\_draw\_bitmap\_in\_rect() graphics\_draw\_rotated\_bitmap() #### Enumerators GCompOpAssign Assign the pixel values of the source image to the destination pixels, effectively replacing the previous values for those pixels. For color displays, when drawing a palettized or 8-bit GBitmap image, the opacity value is ignored. GCompOpAssignInverted ##### Note For bitmaps with a format different from GBitmapFormat1Bit, this mode is not supported and the resulting behavior is undefined. Assign the **inverted** pixel values of the source image to the destination pixels, effectively replacing the previous values for those pixels. GCompOpOr ##### Note For bitmaps with a format different from GBitmapFormat1Bit, this mode is not supported and the resulting behavior is undefined. Use the boolean operator `OR` to composite the source and destination pixels. The visual result of this compositing mode is the source's white pixels are painted onto the destination and the source's black pixels are treated as clear. GCompOpAnd ##### Note For bitmaps with a format different from GBitmapFormat1Bit, this mode is not supported and the resulting behavior is undefined. Use the boolean operator `AND` to composite the source and destination pixels. The visual result of this compositing mode is the source's black pixels are painted onto the destination and the source's white pixels are treated as clear. GCompOpClear ##### Note For bitmaps with a format different from GBitmapFormat1Bit, this mode is not supported and the resulting behavior is undefined. Clears the bits in the destination image, using the source image as mask. The visual result of this compositing mode is that for the parts where the source image is white, the destination image will be painted black. Other parts will be left untouched. GCompOpSet ##### Note For bitmaps of the format GBitmapFormat1Bit, the visual result of this compositing mode is that for the parts where the source image is black, the destination image will be painted white. Other parts will be left untouched. Sets the bits in the destination image, using the source image as mask. This mode is required to apply any transparency of your bitmap. ## Typedef Documentation typedef GColor8 GColor typedef struct GBitmap GBitmap typedef struct GBitmapSequence GBitmapSequence typedef struct GContext GContext ## Macro Definition Documentation - [SDK 3](javascript:void(0);) - [SDK 4](javascript:void(0);) - [SDK 4.9+](javascript:void(0);) #define GColorFromRGBA ( red, green, blue, alpha) Convert RGBA to GColor. #### Parameters red Red value from 0 - 255 green Green value from 0 - 255 blue Blue value from 0 - 255 alpha Alpha value from 0 - 255 #### Returns GColor created from the RGB values #define GColorFromRGBA ( red, green, blue, alpha) Convert RGBA to GColor. #### Parameters red Red value from 0 - 255 green Green value from 0 - 255 blue Blue value from 0 - 255 alpha Alpha value from 0 - 255 #### Returns GColor created from the RGB values #define GColorFromRGBA ( red, green, blue, alpha) Convert RGBA to GColor. #### Parameters red Red value from 0 - 255 green Green value from 0 - 255 blue Blue value from 0 - 255 alpha Alpha value from 0 - 255 #### Returns GColor created from the RGBA values #define GColorFromRGB ( red, green, blue) Convert RGB to GColor. #### Parameters red Red value from 0 - 255 green Green value from 0 - 255 blue Blue value from 0 - 255 #### Returns GColor created from the RGB values #define GColorFromHEX ( v) Convert hex integer to GColor. #### Parameters v Integer hex value (e.g. 0x64ff46) #### Returns GColor created from the hex value - [SDK 3](javascript:void(0);) - [SDK 4](javascript:void(0);) - [SDK 4.9+](javascript:void(0);) #define COLOR\_FALLBACK ( color, bw) Convenience macro allowing use of a fallback color for black and white platforms. On color platforms, the first expression will be chosen, the second otherwise. #define COLOR\_FALLBACK ( color, bw) Convenience macro allowing use of a fallback color for black and white platforms. On color platforms, the first expression will be chosen, the second otherwise. #define COLOR\_FALLBACK ( color, bw) Convenience macro allowing use of a fallback color for black and white platforms. On color platforms, the first expression will be chosen, the second otherwise. #define PBL\_IF\_RECT\_ELSE ( if\_true, if\_false) Convenience macro to switch between two expression depending on the screen of the platform. On platforms with rectangular screen, the first expression will be chosen, the second otherwise. #define PBL\_IF\_ROUND\_ELSE ( if\_true, if\_false) Convenience macro to switch between two expression depending on the screen of the platform. On platforms with round screen, the first expression will be chosen, the second otherwise. - [SDK 3](javascript:void(0);) - [SDK 4](javascript:void(0);) - [SDK 4.9+](javascript:void(0);) #define PBL\_IF\_BW\_ELSE ( if\_true, if\_false) Convenience macro to switch between two expression depending on the screen of the platform. On black& white platforms, the first expression will be chosen, the second otherwise. #define PBL\_IF\_BW\_ELSE ( if\_true, if\_false) Convenience macro to switch between two expression depending on the screen of the platform. On black& white platforms, the first expression will be chosen, the second otherwise. #define PBL\_IF\_BW\_ELSE ( if\_true, if\_false) Convenience macro to switch between two expression depending on the screen of the platform. On black& white platforms, the first expression will be chosen, the second otherwise. - [SDK 3](javascript:void(0);) - [SDK 4](javascript:void(0);) - [SDK 4.9+](javascript:void(0);) #define PBL\_IF\_COLOR\_ELSE ( if\_true, if\_false) Convenience macro to switch between two expression depending on the screen of the platform. On color platforms, the first expression will be chosen, the second otherwise. #define PBL\_IF\_COLOR\_ELSE ( if\_true, if\_false) Convenience macro to switch between two expression depending on the screen of the platform. On color platforms, the first expression will be chosen, the second otherwise. #define PBL\_IF\_COLOR\_ELSE ( if\_true, if\_false) Convenience macro to switch between two expression depending on the screen of the platform. On color platforms, the first expression will be chosen, the second otherwise. #define GPoint ( x, y) Convenience macro to make a [GPoint](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPoint). #define GPointZero [GPoint](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPoint)(0, 0) Convenience macro to make a [GPoint](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPoint) at (0, 0). #define GSize ( w, h) Convenience macro to make a [GSize](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GSize). #define GSizeZero [GSize](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GSize)(0, 0) Convenience macro to make a [GSize](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GSize) of (0, 0). #define GRect ( x, y, w, h) Convenience macro to make a [GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect). #define GRectZero [GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect)(0, 0, 0, 0) Convenience macro to make a [GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) of ((0, 0), (0, 0)). #define PLAY\_COUNT\_INFINITE UINT32\_MAX Repeat Sequence or animation indefinitely. #define PLAY\_DURATION\_INFINITE UINT32\_MAX Duration of Sequence or animation is infinite. #define GEdgeInsets4 ( t, r, b, l) helper for [GEdgeInsets](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GEdgeInsets) macro #define GEdgeInsets3 ( t, rl, b) helper for [GEdgeInsets](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GEdgeInsets) macro #define GEdgeInsets2 ( tb, rl) helper for [GEdgeInsets](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GEdgeInsets) macro #define GEdgeInsets1 ( trbl) helper for [GEdgeInsets](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GEdgeInsets) macro #define GEdgeInsetsN ( \_1, \_2, \_3, \_4, NAME, ...) helper for [GEdgeInsets](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GEdgeInsets) macro - [SDK 3](javascript:void(0);) - [SDK 4](javascript:void(0);) - [SDK 4.9+](javascript:void(0);) #define GEdgeInsets ( ...) Convenience macro to make a [GEdgeInsets](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GEdgeInsets) This macro follows the CSS shorthand notation where you can call it with. - just one value [GEdgeInsets(v1)](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GEdgeInsets) to configure all edges with v1 ([GEdgeInsets](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GEdgeInsets)){.top = v1, .right = v1, .bottom = v1, .left = v1} - two values v1, v2 to configure a vertical and horizontal inset as ([GEdgeInsets](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GEdgeInsets)){.top = v1, .right = v2, .bottom = v1, .left = v2} - three values v1, v2, v3 to configure it with ([GEdgeInsets](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GEdgeInsets)){.top = v1, .right = v2, .bottom = v3, .left = v2} - four values v1, v2, v3, v4 to configure it with ([GEdgeInsets](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GEdgeInsets)){.top = v1, .right = v2, .bottom = v3, .left = v4} #### See Also grect\_insets #define GEdgeInsets ( ...) Convenience macro to make a [GEdgeInsets](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GEdgeInsets) This macro follows the CSS shorthand notation where you can call it with. - just one value [GEdgeInsets(v1)](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GEdgeInsets) to configure all edges with v1 ([GEdgeInsets](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GEdgeInsets)){.top = v1, .right = v1, .bottom = v1, .left = v1} - two values v1, v2 to configure a vertical and horizontal inset as ([GEdgeInsets](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GEdgeInsets)){.top = v1, .right = v2, .bottom = v1, .left = v2} - three values v1, v2, v3 to configure it with ([GEdgeInsets](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GEdgeInsets)){.top = v1, .right = v2, .bottom = v3, .left = v2} - four values v1, v2, v3, v4 to configure it with ([GEdgeInsets](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GEdgeInsets)){.top = v1, .right = v2, .bottom = v3, .left = v4} #### See Also grect\_insets #define GEdgeInsets ( ...) Convenience macro to make a [GEdgeInsets](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GEdgeInsets) This macro follows the CSS shorthand notation where you can call it with. - just one value [GEdgeInsets(v1)](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GEdgeInsets) to configure all edges with v1 ([GEdgeInsets](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GEdgeInsets)){.top = v1, .right = v1, .bottom = v1, .left = v1} - two values v1, v2 to configure a vertical and horizontal inset as ([GEdgeInsets](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GEdgeInsets)){.top = v1, .right = v2, .bottom = v1, .left = v2} - three values v1, v2, v3 to configure it with ([GEdgeInsets](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GEdgeInsets)){.top = v1, .right = v2, .bottom = v3, .left = v2} - four values v1, v2, v3, v4 to configure it with ([GEdgeInsets](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GEdgeInsets)){.top = v1, .right = v2, .bottom = v3, .left = v4} #### See Also [grect\_inset](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#grect_inset) --- # HealthService Source: https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService/ Get access to health information like step count, sleep totals, etc. The HealthService provides your app access to the step count and sleep activity of the user. ## Function Documentation [HealthValue](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthValue) health\_service\_sum([HealthMetric](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthMetric) metric, [time\_t](https://developer.repebble.com/docs/c/Standard_C/Time.md#time_t) time\_start, [time\_t](https://developer.repebble.com/docs/c/Standard_C/Time.md#time_t) time\_end) Return the sum of a [HealthMetric](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthMetric)'s values over a time range. The `time_start` and `time_end` parameters define the range of time you want the sum for. ##### Note The value returned will be based on daily totals, weighted for the length of the specified time range. This may change in the future. #### Parameters metric The metric to query for data. time\_start UTC time of the earliest data item to incorporate into the sum. time\_end UTC time of the most recent data item to incorporate into the sum. #### Returns The sum of that metric over the given time range, if available. [HealthValue](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthValue) health\_service\_sum\_today([HealthMetric](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthMetric) metric) Convenience wrapper for [health\_service\_sum()](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#health_service_sum) that returns the sum for today. #### Parameters metric The metric to query. #### Returns The sum of that metric's data for today, if available. [HealthValue](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthValue) health\_service\_peek\_current\_value([HealthMetric](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthMetric) metric) Convenience function for peeking at the current value of a metric. This is useful for metrics like HealthMetricHeartRateBPM that represent instantaneous values. It is NOT applicable for metrics like HealthMetricStepCount that must be accumulated over time (it will return 0 if passed that type of metric). This call is equivalent to calling `health_service_aggregate_averaged(metric, time(NULL), time(NULL), HealthAggregationAvg, HealthServiceTimeScopeOnce)` #### Parameters metric The metric to query. #### Returns The current value of that metric, if available. [HealthValue](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthValue) health\_service\_sum\_averaged([HealthMetric](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthMetric) metric, [time\_t](https://developer.repebble.com/docs/c/Standard_C/Time.md#time_t) time\_start, [time\_t](https://developer.repebble.com/docs/c/Standard_C/Time.md#time_t) time\_end, [HealthServiceTimeScope](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthServiceTimeScope) scope) Return the value of a metric's sum over a given time range between `time_start` and `time_end`. Using this call you can specify the time range that you are interested in getting the average for, as well as a `scope` specifier on how to compute an average of the sum. For example, if you want to get the average number of steps taken from 12 AM (midnight) to 9 AM across all days you would specify: ``` time\_t time\_start = time\_start\_of\_today();time\_t time\_end = time\_start + (9 \* SECONDS\_PER\_HOUR);HealthValue value = health\_service\_sum\_averaged(HealthMetricStepCount, time\_start,time\_end, HealthServiceTimeScopeDaily); ``` If you want the average number of steps taken on a weekday (Monday to Friday) and today is a Monday (in the local timezone) you would specify: ``` time\_start = time\_start\_of\_today();time\_end = time\_start + SECONDS\_PER\_DAY;HealthValue value = health\_service\_sum\_averaged(HealthMetricStepCount, time\_start,time\_end, HealthServiceTimeScopeDailyWeekdayOrWeekend); ``` Note that this call is the same as calling `health_service_aggregate_averaged(metric, time_start, time_end, HealthAggregationSum, scope)` #### Parameters metric Which [HealthMetric](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthMetric) to query. time\_start UTC time of the start of the query interval. time\_end UTC time of the end of the query interval. scope [HealthServiceTimeScope](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthServiceTimeScope) value describing how the average should be computed. #### Returns The average of the sum of the given metric over the given time range, if available. [HealthValue](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthValue) health\_service\_aggregate\_averaged([HealthMetric](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthMetric) metric, [time\_t](https://developer.repebble.com/docs/c/Standard_C/Time.md#time_t) time\_start, [time\_t](https://developer.repebble.com/docs/c/Standard_C/Time.md#time_t) time\_end, [HealthAggregation](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthAggregation) aggregation, [HealthServiceTimeScope](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthServiceTimeScope) scope) Return the value of an aggregated metric over a given time range. This call is more flexible than health\_service\_sum\_averaged because it lets you specify which aggregation function to perform. The aggregation function `aggregation` is applied to the metric `metric` over the given time range `time_start` to `time_end` first, and then an average is computed based on the passed in `scope`. For example, if you want to get the average number of steps taken from 12 AM (midnight) to 9 AM across all days you would specify: ``` time\_t time\_start = time\_start\_of\_today();time\_t time\_end = time\_start + (9 \* SECONDS\_PER\_HOUR);HealthValue value = health\_service\_aggregate\_averaged(HealthMetricStepCount, time\_start,time\_end, HealthAggregationSum, HealthServiceTimeScopeDaily); ``` If you want to compute the average heart rate on Mondays and today is a Monday, you would specify: ``` time\_t time\_start = time\_start\_of\_today(),time\_t time\_end = time\_start + SECONDS\_PER\_DAY,HealthValue value = health\_service\_aggregate\_averaged(HealthMetricHeartRateBPM, time\_start,time\_end, HealthAggregationAvg, HealthServiceTimeScopeWeekly); ``` To get the average of the minimum heart rate seen on Mondays for example, you would instead pass in `HealthAggregationMin` Certain [HealthAggregation](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthAggregation) operations are only applicable to certain types of metrics. See the notes above on [HealthAggregation](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthAggregation) for details. Use [health\_service\_metric\_aggregate\_averaged\_accessible](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#health_service_metric_aggregate_averaged_accessible) to check for applicability at run time. #### Parameters metric Which [HealthMetric](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthMetric) to query. time\_start UTC time of the start of the query interval. time\_end UTC time of the end of the query interval. aggregation the aggregation function to perform on the metric. This operation is performed across the passed in time range `time_start` to `time_end`. scope [HealthServiceTimeScope](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthServiceTimeScope) value describing how the average should be computed. Use `HealthServiceTimeScopeOnce` to not compute an average. #### Returns The average of the aggregation performed on the given metric over the given time range, if available. [HealthActivityMask](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthActivityMask) health\_service\_peek\_current\_activities(void) Return a [HealthActivityMask](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthActivityMask) containing a set of bits, one set for each activity that is currently active. #### Returns A bitmask with zero or more [HealthActivityMask](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthActivityMask) bits set as appropriate. void health\_service\_activities\_iterate([HealthActivityMask](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthActivityMask) activity\_mask, [time\_t](https://developer.repebble.com/docs/c/Standard_C/Time.md#time_t) time\_start, [time\_t](https://developer.repebble.com/docs/c/Standard_C/Time.md#time_t) time\_end, [HealthIterationDirection](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthIterationDirection) direction, [HealthActivityIteratorCB](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthActivityIteratorCB) callback, void \* context) Iterates backwards or forward within a given time span to list all recorded activities. For example, this can be used to find the last recorded sleep phase or all deep sleep phases in a given time range. Any activity that overlaps with `time_start` and `time_end` will be included, even if the start time starts before `time_start` or end time ends after `time_end`. #### Parameters activity\_mask A bitmask containing set of activities you are interested in. time\_start UTC time of the earliest time you are interested in. time\_end UTC time of the latest time you are interested in. direction The direction in which to iterate. callback Developer-supplied callback that is called for each activity iterated over. context Developer-supplied context pointer that is passed to the callback. [HealthServiceAccessibilityMask](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthServiceAccessibilityMask) health\_service\_metric\_accessible([HealthMetric](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthMetric) metric, [time\_t](https://developer.repebble.com/docs/c/Standard_C/Time.md#time_t) time\_start, [time\_t](https://developer.repebble.com/docs/c/Standard_C/Time.md#time_t) time\_end) Check if a certain combination of metric and time span is accessible using [health\_service\_sum](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#health_service_sum) by returning a value of [HealthServiceAccessibilityMask](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthServiceAccessibilityMask). Developers should check if the return value is HealthServiceAccessibilityMaskAvailable before calling [health\_service\_sum](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#health_service_sum). Note that this call is the same as calling `health_service_metric_averaged_accessible(metric, time_start, time_end, HealthServiceTimeScopeOnce)` #### Parameters metric The metric to query for data. time\_start Earliest UTC time you are interested in. time\_end Latest UTC time you are interested in. #### Returns A [HealthServiceAccessibilityMask](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthServiceAccessibilityMask) representing the accessible metrics in this time range. - [SDK 3](javascript:void(0);) - [SDK 4](javascript:void(0);) - [SDK 4.9+](javascript:void(0);) [HealthServiceAccessibilityMask](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthServiceAccessibilityMask) health\_service\_metric\_averaged\_accessible([HealthMetric](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthMetric) metric, [time\_t](https://developer.repebble.com/docs/c/Standard_C/Time.md#time_t) time\_start, [time\_t](https://developer.repebble.com/docs/c/Standard_C/Time.md#time_t) time\_end, [HealthServiceTimeScope](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthServiceTimeScope) scope) Check if a certain combination of metric, time span, and scope is accessible for calculating summed, averaged data by returning a value of [HealthServiceAccessibilityMask](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthServiceAccessibilityMask). Developers should check if the return value is HealthServiceAccessibilityMaskAvailable before calling [health\_service\_sum\_averaged](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#health_service_sum_averaged). Note that this call is the same as calling `health_service_metric_aggregate_averaged_accessible(metric, time_start, time_end, HealthAggregationSum, HealthServiceTimeScopeOnce)` #### Parameters metric The metric to query for averaged data. time\_start Earliest UTC time you are interested in. time\_end Latest UTC time you are interested in. scope [HealthServiceTimeScope](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthServiceTimeScope) value describing how the average should be computed. #### Returns A \HealthServiceAccessibilityMask value decribing whether averaged data is available. [HealthServiceAccessibilityMask](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthServiceAccessibilityMask) health\_service\_metric\_averaged\_accessible([HealthMetric](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthMetric) metric, [time\_t](https://developer.repebble.com/docs/c/Standard_C/Time.md#time_t) time\_start, [time\_t](https://developer.repebble.com/docs/c/Standard_C/Time.md#time_t) time\_end, [HealthServiceTimeScope](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthServiceTimeScope) scope) Check if a certain combination of metric, time span, and scope is accessible for calculating summed, averaged data by returning a value of [HealthServiceAccessibilityMask](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthServiceAccessibilityMask). Developers should check if the return value is HealthServiceAccessibilityMaskAvailable before calling [health\_service\_sum\_averaged](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#health_service_sum_averaged). Note that this call is the same as calling `health_service_metric_aggregate_averaged_accessible(metric, time_start, time_end, HealthAggregationSum, HealthServiceTimeScopeOnce)` #### Parameters metric The metric to query for averaged data. time\_start Earliest UTC time you are interested in. time\_end Latest UTC time you are interested in. scope [HealthServiceTimeScope](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthServiceTimeScope) value describing how the average should be computed. #### Returns A \HealthServiceAccessibilityMask value decribing whether averaged data is available. [HealthServiceAccessibilityMask](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthServiceAccessibilityMask) health\_service\_metric\_averaged\_accessible([HealthMetric](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthMetric) metric, [time\_t](https://developer.repebble.com/docs/c/Standard_C/Time.md#time_t) time\_start, [time\_t](https://developer.repebble.com/docs/c/Standard_C/Time.md#time_t) time\_end, [HealthServiceTimeScope](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthServiceTimeScope) scope) Check if a certain combination of metric, time span, and scope is accessible for calculating summed, averaged data by returning a value of [HealthServiceAccessibilityMask](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthServiceAccessibilityMask). Developers should check if the return value is HealthServiceAccessibilityMaskAvailable before calling [health\_service\_sum\_averaged](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#health_service_sum_averaged). Note that this call is the same as calling `health_service_metric_aggregate_averaged_accessible(metric, time_start, time_end, HealthAggregationSum, HealthServiceTimeScopeOnce)` #### Parameters metric The metric to query for averaged data. time\_start Earliest UTC time you are interested in. time\_end Latest UTC time you are interested in. scope [HealthServiceTimeScope](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthServiceTimeScope) value describing how the average should be computed. #### Returns A [HealthServiceAccessibilityMask](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthServiceAccessibilityMask) value decribing whether averaged data is available. - [SDK 3](javascript:void(0);) - [SDK 4](javascript:void(0);) - [SDK 4.9+](javascript:void(0);) [HealthServiceAccessibilityMask](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthServiceAccessibilityMask) health\_service\_metric\_aggregate\_averaged\_accessible([HealthMetric](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthMetric) metric, [time\_t](https://developer.repebble.com/docs/c/Standard_C/Time.md#time_t) time\_start, [time\_t](https://developer.repebble.com/docs/c/Standard_C/Time.md#time_t) time\_end, [HealthAggregation](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthAggregation) aggregation, [HealthServiceTimeScope](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthServiceTimeScope) scope) Check if a certain combination of metric, time span, aggregation operation, and scope is accessible for calculating aggregated, averaged data by returning a value of [HealthServiceAccessibilityMask](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthServiceAccessibilityMask). Developers should check if the return value is HealthServiceAccessibilityMaskAvailable before calling [health\_service\_aggregate\_averaged](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#health_service_aggregate_averaged). #### Parameters metric The metric to query for averaged data. time\_start Earliest UTC time you are interested in. time\_end Latest UTC time you are interested in. aggregation The aggregation to perform scope [HealthServiceTimeScope](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthServiceTimeScope) value describing how the average should be computed. #### Returns A \HealthServiceAccessibilityMask value decribing whether averaged data is available. [HealthServiceAccessibilityMask](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthServiceAccessibilityMask) health\_service\_metric\_aggregate\_averaged\_accessible([HealthMetric](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthMetric) metric, [time\_t](https://developer.repebble.com/docs/c/Standard_C/Time.md#time_t) time\_start, [time\_t](https://developer.repebble.com/docs/c/Standard_C/Time.md#time_t) time\_end, [HealthAggregation](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthAggregation) aggregation, [HealthServiceTimeScope](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthServiceTimeScope) scope) Check if a certain combination of metric, time span, aggregation operation, and scope is accessible for calculating aggregated, averaged data by returning a value of [HealthServiceAccessibilityMask](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthServiceAccessibilityMask). Developers should check if the return value is HealthServiceAccessibilityMaskAvailable before calling [health\_service\_aggregate\_averaged](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#health_service_aggregate_averaged). #### Parameters metric The metric to query for averaged data. time\_start Earliest UTC time you are interested in. time\_end Latest UTC time you are interested in. aggregation The aggregation to perform scope [HealthServiceTimeScope](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthServiceTimeScope) value describing how the average should be computed. #### Returns A \HealthServiceAccessibilityMask value decribing whether averaged data is available. [HealthServiceAccessibilityMask](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthServiceAccessibilityMask) health\_service\_metric\_aggregate\_averaged\_accessible([HealthMetric](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthMetric) metric, [time\_t](https://developer.repebble.com/docs/c/Standard_C/Time.md#time_t) time\_start, [time\_t](https://developer.repebble.com/docs/c/Standard_C/Time.md#time_t) time\_end, [HealthAggregation](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthAggregation) aggregation, [HealthServiceTimeScope](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthServiceTimeScope) scope) Check if a certain combination of metric, time span, aggregation operation, and scope is accessible for calculating aggregated, averaged data by returning a value of [HealthServiceAccessibilityMask](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthServiceAccessibilityMask). Developers should check if the return value is HealthServiceAccessibilityMaskAvailable before calling [health\_service\_aggregate\_averaged](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#health_service_aggregate_averaged). #### Parameters metric The metric to query for averaged data. time\_start Earliest UTC time you are interested in. time\_end Latest UTC time you are interested in. aggregation The aggregation to perform scope [HealthServiceTimeScope](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthServiceTimeScope) value describing how the average should be computed. #### Returns A [HealthServiceAccessibilityMask](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthServiceAccessibilityMask) value decribing whether averaged data is available. [HealthServiceAccessibilityMask](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthServiceAccessibilityMask) health\_service\_any\_activity\_accessible([HealthActivityMask](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthActivityMask) activity\_mask, [time\_t](https://developer.repebble.com/docs/c/Standard_C/Time.md#time_t) time\_start, [time\_t](https://developer.repebble.com/docs/c/Standard_C/Time.md#time_t) time\_end) Check if a certain combination of metric, [HealthActivityMask](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthActivityMask) and time span is accessible. Developers should check if the return value is HealthServiceAccessibilityMaskAvailable before calling any other HealthService APIs that involve the given activities. #### Parameters activity\_mask A bitmask of activities you are interested in. time\_start Earliest UTC time you are interested in. time\_end Latest UTC time you are interested in. #### Returns A [HealthServiceAccessibilityMask](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthServiceAccessibilityMask) representing which of the passed [HealthActivityMask](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthActivityMask) values are available under the given constraints. bool health\_service\_events\_subscribe([HealthEventHandler](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthEventHandler) handler, void \* context) Subscribe to HealthService events. This allocates a cache on the application's heap of up to 2048 bytes that will be de-allocated if you call [health\_service\_events\_unsubscribe()](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#health_service_events_unsubscribe). If there's not enough heap available, this function will return `false` and will not subscribe to any events. #### Parameters handler Developer-supplied event handler function. context Developer-supplied context pointer. #### Returns `true` on success, `false` on failure. bool health\_service\_events\_unsubscribe(void) Unsubscribe from HealthService events. #### Returns `true` on success, `false` on failure. bool health\_service\_set\_heart\_rate\_sample\_period([uint16\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint16_t) interval\_sec) Set the desired sampling period for heart rate readings. Normally, the system will sample the heart rate using a sampling period that is automatically chosen to provide useful information without undue battery drain (it automatically samples more often during periods of intense activity, and less often when the user is idle). If desired though, an application can request a specific sampling period using this call. The system will use this as a suggestion, but does not guarantee that the requested period will be used. The actual sampling period may be greater or less due to system needs or heart rate sensor reading quality issues. Each time a new heart rate reading becomes available, a `HealthEventHeartRateUpdate` event will be sent to the application's `HealthEventHandler`. The sample period request will remain in effect the entire time the app is running unless it is explicitly cancelled (by calling this method again with 0 as the desired interval). If the app exits without first cancelling the request, it will remain in effect even for a limited time afterwards. To determine how long it will remain active after the app exits, use `health_service_get_heart_rate_sample_period_expiration_sec`. Unless the app explicitly needs to access to historical high-resolution heart rate data, it is best practice to always cancel the sample period request before exiting in order to maximize battery life. Historical heart rate data can be accessed using the `health_service_get_minute_history` call. #### Parameters interval\_sec desired interval between heart rate reading updates. Pass 0 to go back to automatically chosen intervals. #### Returns `true` on success, `false` on failure [uint16\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint16_t) health\_service\_get\_heart\_rate\_sample\_period\_expiration\_sec(void) Return how long a heart rate sample period request (sent via `health_service_set_heart_rate_sample_period`) will remain active after the app exits. If there is no current request by this app, this call will return 0. #### Returns The number of seconds the heart rate sample period request will remain active after the app exits, or 0 if there is no active request by this app. [HealthMetricAlert](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthMetricAlert) \* health\_service\_register\_metric\_alert([HealthMetric](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthMetric) metric, [HealthValue](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthValue) threshold) Register for an alert when a metric crosses the given threshold. When the metric crosses this threshold (either goes above or below it), a HealthEventMetricAlert event will be generated. To cancel this registration, pass the returned [HealthMetricAlert](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthMetricAlert) value to [health\_service\_cancel\_metric\_alert](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#health_service_cancel_metric_alert). The only metric currently supported by this call is HealthMetricHeartRateBPM, but future versions may support additional metrics. To see if a specific metric is supported by this call, use: ``` time\_t now = time(NULL);HealthServiceAccessibilityMask accessible =health\_service\_metric\_aggregate\_averaged\_accessible(metric, now, now, HealthAggregationAvg,HealthServiceTimeScopeOnce);bool alert\_supported = (accessible & HealthServiceAccessibilityMaskAvailable); ``` In the current implementation, only one alert per metric can be registered at a time. Future implementations may support two or more simulataneous alert registrations per metric. To change the alert threshold in the current implementation, cancel the original registration using `health_service_cancel_metric_alert` before registering the new threshold. #### Parameters metric Which [HealthMetric](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthMetric) to query. threshold The threshold value. #### Returns handle to the alert registration on success, NULL on failure bool health\_service\_cancel\_metric\_alert([HealthMetricAlert](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthMetricAlert) \* alert) Cancel an metric alert previously created with [health\_service\_register\_metric\_alert](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#health_service_register_metric_alert). #### Parameters alert the [HealthMetricAlert](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthMetricAlert) previously returned by [health\_service\_register\_metric\_alert](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#health_service_register_metric_alert) #### Returns `true` on success, `false` on failure [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) health\_service\_get\_minute\_history([HealthMinuteData](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthMinuteData) \* minute\_data, [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) max\_records, [time\_t](https://developer.repebble.com/docs/c/Standard_C/Time.md#time_t) \* time\_start, [time\_t](https://developer.repebble.com/docs/c/Standard_C/Time.md#time_t) \* time\_end) Return historical minute data records. This fills in the `minute_data` array parameter with minute by minute statistics of the user's steps, average watch orientation, etc. The data is returned in time order, with the oldest minute data returned at `minute_data[0]`. ##### Note If the return value is zero, `time_start` and `time_end` are meaningless. It's not guaranteed that all records contain valid data, even if the return value is greater than zero. Check `HealthMinuteData.is_invalid` to see if a given record contains valid data. #### Parameters minute\_data Pointer to an array of [HealthMinuteData](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthMinuteData) records that will be filled in with the historical minute data. max\_records The maximum number of records the `minute_data` array can hold. time\_start (inout) On entry, the UTC time of the first requested record. On exit, the UTC time of the first second of the first record actually returned. If `time_start` on entry is somewhere in the middle of a minute interval, this function behaves as if the caller passed in the start of that minute. time\_end (inout) On entry, the UTC time of the end of the requested range of records. On exit, the UTC time of the end of the last record actually returned (i.e. start time of last record + 60). If `time_end` on entry is somewhere in the middle of a minute interval, this function behaves as if the caller passed in the end of that minute. #### Returns Actual number of records returned. May be less then the maximum requested. [MeasurementSystem](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#MeasurementSystem) health\_service\_get\_measurement\_system\_for\_display([HealthMetric](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthMetric) metric) Get the preferred measurement system for a given [HealthMetric](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthMetric), if the user has chosen a preferred system and it is applicable to that metric. #### Parameters metric A metric value chosen from [HealthMetric](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthMetric). #### Returns A value from [MeasurementSystem](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#MeasurementSystem) if applicable, else MeasurementSystemUnknown. ## Data Structure Documentation struct HealthMinuteData Structure representing a single minute data record returned by [health\_service\_get\_minute\_history()](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#health_service_get_minute_history). The `orientation` field encodes the angle of the watch in the x-y plane (the "yaw") in the lower 4 bits (360 degrees linearly mapped to 1 of 16 different values) and the angle to the z axis (the "pitch") in the upper 4 bits. The `vmc` value is a measure of the total amount of movement seen by the watch. More vigorous movement yields higher VMC values. #### Data Fields uint8\_t steps Number of steps taken in this minute. uint8\_t orientation Quantized average orientation. [uint16\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint16_t) vmc Vector Magnitude Counts (vmc). bool is\_invalid `true` if the item doesn't represents actual data and should be ignored. [AmbientLightLevel](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#AmbientLightLevel) light Instantaneous light level during this minute. uint8\_t paddinguint8\_t heart\_rate\_bpm heart rate in beats per minute uint8\_t reserved Reserved for future use. ## Enum Documentation enum HealthMetric Health metric values used to retrieve health data. For example, using [health\_service\_sum()](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#health_service_sum). #### Enumerators HealthMetricStepCount The number of steps counted. HealthMetricActiveSeconds The number of seconds spent active (i.e. not resting). HealthMetricWalkedDistanceMeters The distance walked, in meters. HealthMetricSleepSeconds The number of seconds spent sleeping. HealthMetricSleepRestfulSeconds The number of sleep seconds in the 'restful' or deep sleep state. HealthMetricRestingKCalories The number of kcal (Calories) burned while resting due to resting metabolism. HealthMetricActiveKCalories The number of kcal (Calories) burned while active. HealthMetricHeartRateBPM The heart rate, in beats per minute. This is a filtered value that is at most 15 minutes old. HealthMetricHeartRateRawBPM The raw heart rate value of the most recent sample, in beats per minute. enum HealthServiceTimeScope Used by [health\_service\_sum\_averaged()](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#health_service_sum_averaged) to specify how the average is computed. #### Enumerators HealthServiceTimeScopeOnce No average computed. The result is the same as calling [health\_service\_sum()](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#health_service_sum). HealthServiceTimeScopeWeekly Compute average using the same day from each week. For example, every Monday if the passed in time range falls on a Monday. HealthServiceTimeScopeDailyWeekdayOrWeekend Compute average using either weekdays (Monday to Friday) or weekends (Saturday and Sunday), depending on which day the passed in time range falls. HealthServiceTimeScopeDaily Compute average across all days of the week. enum HealthAggregation Used by [health\_service\_aggregate\_averaged()](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#health_service_aggregate_averaged) to specify what type of aggregation to perform. This aggregation is applied to the metric before the average is computed. #### Enumerators HealthAggregationSum Sum the metric. The result is the same as calling [health\_service\_sum\_averaged()](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#health_service_sum_averaged). This operation is only applicable for metrics that accumulate, like HealthMetricStepCount, HealthMetricActiveSeconds, etc. HealthAggregationAvg Use the average of the metric. This is only applicable for metrics that measure instantaneous values, like HealthMetricHeartRateBPM. HealthAggregationMin Use the minimum value of the metric. This is only applicable for metrics that measure instantaneous values, like HealthMetricHeartRateBPM. HealthAggregationMax Use the maximum value of the metric. This is only applicable for metrics that measure instantaneous values, like HealthMetricHeartRateBPM. enum HealthActivity Health-related activities that can be accessed using. #### Enumerators HealthActivityNone No special activity. HealthActivitySleep The 'sleeping' activity. HealthActivityRestfulSleep The 'restful sleeping' activity. HealthActivityWalk The 'walk' activity. HealthActivityRun The 'run' activity. HealthActivityOpenWorkout The 'generic' activity. enum HealthIterationDirection Iteration direction, passed to [health\_service\_activities\_iterate()](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#health_service_activities_iterate). When iterating backwards (`HealthIterationDirectionPast`), activities that have a greater value for `time_end` come first. When iterating forward (`HealthIterationDirectionFuture`), activities that have a smaller value for `time_start` come first. #### Enumerators HealthIterationDirectionPast Iterate into the past. HealthIterationDirectionFuture Iterate into the future. enum HealthServiceAccessibilityMask Possible values returned by [health\_service\_metric\_accessible()](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#health_service_metric_accessible). The values are used in combination as a bitmask. For example, to check if any data is available for a given request use: bool any\_data\_available = value & HealthServiceAccessibilityMaskAvailable;. #### Enumerators HealthServiceAccessibilityMaskAvailable Return values are available and represent the collected health information. HealthServiceAccessibilityMaskNoPermission The user hasn't granted permission. HealthServiceAccessibilityMaskNotSupported The queried combination of time span and [HealthMetric](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthMetric) or [HealthActivityMask](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthActivityMask) is currently unsupported. HealthServiceAccessibilityMaskNotAvailable No samples were recorded for the given time span. enum HealthEventType Health event enum. Passed into the [HealthEventHandler](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthEventHandler). #### Enumerators HealthEventSignificantUpdate All data is considered as outdated and apps should re-read all health data. This happens after an app is subscribed via [health\_service\_events\_subscribe()](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#health_service_events_subscribe), on a change of the day, or in other cases that significantly change the underlying data. HealthEventMovementUpdate Recent values around HealthMetricStepCount, HealthMetricActiveSeconds, or HealthMetricWalkedDistanceMeters have changed. HealthEventSleepUpdate Recent values around HealthMetricSleepSeconds, HealthMetricSleepRestfulSeconds, HealthActivitySleep, and HealthActivityRestfulSleep changed. HealthEventMetricAlert A metric has crossed the threshold set by [health\_service\_register\_metric\_alert](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#health_service_register_metric_alert). HealthEventHeartRateUpdate Value of HealthMetricHeartRateBPM or HealthMetricHeartRateRawBPM has changed. HealthEventHRVUpdate A new HRV peak-to-peak interval reading is available. enum AmbientLightLevel Light level enum. #### Enumerators AmbientLightLevelUnknownAmbientLightLevelVeryDarkAmbientLightLevelDarkAmbientLightLevelLightAmbientLightLevelVeryLight enum MeasurementSystem Types of measurement system a [HealthMetric](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthMetric) may be measured in. #### Enumerators MeasurementSystemUnknown The measurement system is unknown, or does not apply to the chosen metric. MeasurementSystemMetric The metric measurement system. MeasurementSystemImperial The imperial measurement system. ## Typedef Documentation typedef int32\_t HealthValue Type used to represent [HealthMetric](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthMetric) values. typedef struct [HealthMetricAlert](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthMetricAlert) HealthMetricAlert Type used as a handle to a registered metric alert (returned by [health\_service\_register\_metric\_alert](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#health_service_register_metric_alert)) typedef [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) HealthActivityMask Expresses a set of [HealthActivity](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#HealthActivity) values as a bitmask. typedef bool(\* HealthActivityIteratorCB)(HealthActivity activity, time\_t time\_start, time\_t time\_end, void \*context) Callback used by [health\_service\_activities\_iterate()](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#health_service_activities_iterate). #### Parameters activity Which activity the caller is being informed about. time\_start Start UTC time of the activity. time\_end End UTC time of the activity. context The `context` parameter initially passed to [health\_service\_activities\_iterate()](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#health_service_activities_iterate). #### Returns `true` if you are interested in more activities, or `false` to stop iterating. typedef void(\* HealthEventHandler)(HealthEventType event, void \*context) Developer-supplied event handler, called when a health-related event occurs after subscribing via [health\_service\_events\_subscribe()](https://developer.repebble.com/docs/c/Foundation/Event_Service/HealthService.md#health_service_events_subscribe);. #### Parameters event The type of health-related event that occured. context The developer-supplied context pointer. ## Macro Definition Documentation #define HealthActivityMaskAll ((HealthActivityOpenWorkout \<\< 1) - 1) A mask value representing all available activities. - [SDK 3](javascript:void(0);) - [SDK 4](javascript:void(0);) - [SDK 4.9+](javascript:void(0);) #define PBL\_IF\_HEALTH\_ELSE ( if\_true, if\_false) Convenience macro to switch between two expressions depending on health support. On platforms with health support the first expression will be chosen, the second otherwise. #define PBL\_IF\_HEALTH\_ELSE ( if\_true, if\_false) Convenience macro to switch between two expressions depending on health support. On platforms with health support the first expression will be chosen, the second otherwise. #define PBL\_IF\_HEALTH\_ELSE ( if\_true, if\_false) Convenience macro to switch between two expressions depending on health support. On platforms with health support the first expression will be chosen, the second otherwise. --- # Internationalization Source: https://developer.repebble.com/docs/c/Foundation/Internationalization/ Internationalization & Localization APIs ## Function Documentation const char \* i18n\_get\_system\_locale(void) Get the ISO locale name for the language currently set on the watch. ##### Note It is possible for the locale to change while your app is running. And thus, two calls to i18n\_get\_system\_locale may return different values. #### Returns A string containing the ISO locale name (e.g. "fr", "en\_US", ...) --- # Launch Reason Source: https://developer.repebble.com/docs/c/Foundation/Launch_Reason/ API for checking what caused the application to launch. This includes the system, launch by user interaction (User selects the application from the launcher menu), launch by the mobile or a mobile companion application, or launch by a scheduled wakeup event for the specified application. ## Function Documentation [AppLaunchReason](https://developer.repebble.com/docs/c/Foundation/Launch_Reason.md#AppLaunchReason) launch\_reason(void) Provides the method used to launch the current application. #### Returns The method or reason the current application was launched [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) launch\_get\_args(void) Get the argument passed to the app when it was launched. ##### Note Currently the only way to pass arguments to apps is by using an openWatchApp action on a pin. #### Returns The argument passed to the app, or 0 if the app wasn't launched from a Launch App action [ButtonId](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#ButtonId) launch\_button(void) Get the button id used to launch the app. Only valid if the launch reason is APP\_LAUNCH\_USER or APP\_LAUNCH\_QUICK\_LAUNCH. [AppQuickLaunchAction](https://developer.repebble.com/docs/c/Foundation/Launch_Reason.md#AppQuickLaunchAction) launch\_get\_quick\_launch\_action(void) Get the action that was used to quick launch the app. #### Returns The [AppQuickLaunchAction](https://developer.repebble.com/docs/c/Foundation/Launch_Reason.md#AppQuickLaunchAction) used to launch the app, or APP\_QUICK\_LAUNCH\_ACTION\_NONE if the app was not launched via Quick Launch. ## Enum Documentation enum AppLaunchReason [AppLaunchReason](https://developer.repebble.com/docs/c/Foundation/Launch_Reason.md#AppLaunchReason) is used to inform the application about how it was launched. New launch reasons may be added in the future. As a best practice, it is recommended to only handle the cases that the app needs to know about, rather than trying to handle all possible launch reasons. #### Enumerators APP\_LAUNCH\_SYSTEM App launched by the system. APP\_LAUNCH\_USER App launched by user selection in launcher menu. APP\_LAUNCH\_PHONE App launched by mobile or companion app. APP\_LAUNCH\_WAKEUP App launched by wakeup event. APP\_LAUNCH\_WORKER App launched by worker calling [worker\_launch\_app()](https://developer.repebble.com/docs/c/Worker.md#worker_launch_app) APP\_LAUNCH\_QUICK\_LAUNCH App launched by user using quick launch. APP\_LAUNCH\_TIMELINE\_ACTION App launched by user opening it from a pin. APP\_LAUNCH\_SMARTSTRAP App launched by a smartstrap. enum AppQuickLaunchAction Details about how an app was quick launched. Returned by app\_launch\_get\_quick\_launch\_action. #### Enumerators APP\_QUICK\_LAUNCH\_ACTION\_NONE App was not launched via Quick Launch. APP\_QUICK\_LAUNCH\_ACTION\_HOLD User held a single button. APP\_QUICK\_LAUNCH\_ACTION\_TAP User tapped a button (single click) APP\_QUICK\_LAUNCH\_ACTION\_COMBO User held a button combination. --- # Layers Source: https://developer.repebble.com/docs/c/User_Interface/Layers/ User interface layers for displaying graphic components Layers are objects that can be displayed on a Pebble watchapp window, enabling users to see visual objects, like text or images. Each layer stores the information about its state necessary to draw or redraw the object that it represents and uses graphics routines along with this state to draw itself when asked. Layers can be used to display various graphics. Layers are the basic building blocks for your application UI. Layers can be nested inside each other. Every window has a root layer which is always the topmost layer. You provide a function that is called to draw the content of the layer when needed; or you can use standard layers that are provided by the system, such as text layer, image layer, menu layer, action bar layer, and so on. The Pebble layer hierarchy is the list of things that need to be drawn to the screen. Multiple layers can be arranged into a hierarchy. This enables ordering (front to back), layout and hierarchy. Through relative positioning, visual objects that are grouped together by adding them into the same layer can be moved all at once. This means that the child layers will move accordingly. If a parent layer has clipping enabled, all the children will be clipped to the frame of the parent. Pebble OS provides convenience layers with built-in logic for displaying different graphic components, like text and bitmap layers. Refer to the [User Interface Layers chapter in the Pebble Developer Guides](https://developer.repebble.com/guides/user-interfaces/layers.md) (chapter "Layers") for a conceptual overview of Layers and relevant code examples. The Modules listed here contain what can be thought of conceptually as subclasses of Layer. The listed types can be safely type-casted to `Layer` (or `Layer *` in case of a pointer). The `layer_...` functions can then be used with the data structures of these subclasses. For example, the following is legal: ``` TextLayer \*text\_layer;...layer\_set\_hidden((Layer \*)text\_layer, true); ``` ## Modules #### [ActionBarLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/ActionBarLayer.md) Vertical, bar-shaped control widget on the right edge of the window #### [BitmapLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/BitmapLayer.md) Layer that displays a bitmap image. #### [MenuLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md) Layer that displays a standard list menu. Data is provided using callbacks. #### [RotBitmapLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/RotBitmapLayer.md) Layer that displays a rotated bitmap image. #### [ScrollLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/ScrollLayer.md) Layer that scrolls its contents, animated. #### [SimpleMenuLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/SimpleMenuLayer.md) Wrapper around [MenuLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md), that uses static data to display a list menu. #### [StatusBarLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/StatusBarLayer.md) Layer that serves as a configurable status bar. #### [TextLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/TextLayer.md) Layer that displays and formats a text string. ## Function Documentation Layer \* layer\_create([GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) frame) Creates a layer on the heap and sets its frame and bounds. Default values: - `bounds` : origin (0, 0) and a size equal to the frame that is passed in. - `clips` : `true` - `hidden` : `false` - `update_proc` : `NULL` (draws nothing) #### Parameters frame The frame at which the layer should be initialized. #### Returns A pointer to the layer. `NULL` if the layer could not be created #### See Also [layer\_set\_frame()](https://developer.repebble.com/docs/c/User_Interface/Layers.md#layer_set_frame) [layer\_set\_bounds()](https://developer.repebble.com/docs/c/User_Interface/Layers.md#layer_set_bounds) Layer \* layer\_create\_with\_data([GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) frame, [size\_t](https://developer.repebble.com/docs/c/Standard_C/Memory.md#size_t) data\_size) Creates a layer on the heap with extra space for callback data, and set its frame andbounds. Default values: - `bounds` : origin (0, 0) and a size equal to the frame that is passed in. - `clips` : `true` - `hidden` : `false` - `update_proc` : `NULL` (draws nothing) #### Parameters frame The frame at which the layer should be initialized. data\_size The size (in bytes) of memory to allocate for callback data. #### Returns A pointer to the layer. `NULL` if the layer could not be created #### See Also [layer\_create()](https://developer.repebble.com/docs/c/User_Interface/Layers.md#layer_create) [layer\_set\_frame()](https://developer.repebble.com/docs/c/User_Interface/Layers.md#layer_set_frame) [layer\_set\_bounds()](https://developer.repebble.com/docs/c/User_Interface/Layers.md#layer_set_bounds) void layer\_destroy(Layer \* layer) Destroys a layer previously created by layer\_create. void layer\_mark\_dirty(Layer \* layer) Marks the complete layer as "dirty", awaiting to be asked by the system to redraw itself. Typically, this function is called whenever state has changed that affects what the layer is displaying. - The layer's `.update_proc` will not be called before this function returns, but will be called asynchronously, shortly. - Internally, a call to this function will schedule a re-render of the window that the layer belongs to. In effect, all layers in that window's layer hierarchy will be asked to redraw. - If an earlier re-render request is still pending, this function is a no-op. #### Parameters layer The layer to mark dirty void layer\_set\_update\_proc(Layer \* layer, [LayerUpdateProc](https://developer.repebble.com/docs/c/User_Interface/Layers.md#LayerUpdateProc) update\_proc) Sets the layer's render function. The system will call the `update_proc` automatically when the layer needs to redraw itself, see also [layer\_mark\_dirty()](https://developer.repebble.com/docs/c/User_Interface/Layers.md#layer_mark_dirty). #### Parameters layer Pointer to the layer structure. update\_proc Pointer to the function that will be called when the layer needs to be rendered. Typically, one performs a series of drawing commands in the implementation of the `update_proc`, see [Drawing Primitives](https://developer.repebble.com/docs/c/Graphics/Drawing_Primitives.md), [Drawing Paths](https://developer.repebble.com/docs/c/Graphics/Drawing_Paths.md) and [Drawing Text](https://developer.repebble.com/docs/c/Graphics/Drawing_Text.md). void layer\_set\_frame(Layer \* layer, [GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) frame) Sets the frame of the layer, which is it's bounding box relative to the coordinate system of its parent layer. The size of the layer's bounds will be extended automatically, so that the bounds cover the new frame. #### Parameters layer The layer for which to set the frame frame The new frame #### See Also [layer\_set\_bounds()](https://developer.repebble.com/docs/c/User_Interface/Layers.md#layer_set_bounds) [GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) layer\_get\_frame(const Layer \* layer) Gets the frame of the layer, which is it's bounding box relative to the coordinate system of its parent layer. If the frame has changed, [layer\_mark\_dirty()](https://developer.repebble.com/docs/c/User_Interface/Layers.md#layer_mark_dirty) will be called automatically. #### Parameters layer The layer for which to get the frame #### Returns The frame of the layer #### See Also [layer\_set\_frame](https://developer.repebble.com/docs/c/User_Interface/Layers.md#layer_set_frame) void layer\_set\_bounds(Layer \* layer, [GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) bounds) Sets the bounds of the layer, which is it's bounding box relative to its frame. If the bounds has changed, [layer\_mark\_dirty()](https://developer.repebble.com/docs/c/User_Interface/Layers.md#layer_mark_dirty) will be called automatically. #### Parameters layer The layer for which to set the bounds bounds The new bounds #### See Also [layer\_set\_frame()](https://developer.repebble.com/docs/c/User_Interface/Layers.md#layer_set_frame) [GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) layer\_get\_bounds(const Layer \* layer) Gets the bounds of the layer. #### Parameters layer The layer for which to get the bounds #### Returns The bounds of the layer #### See Also [layer\_set\_bounds](https://developer.repebble.com/docs/c/User_Interface/Layers.md#layer_set_bounds) [GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) layer\_get\_unobstructed\_bounds(const Layer \* layer) Get the largest unobstructed bounds rectangle of a layer. #### Parameters layer The layer for which to get the unobstructed bounds. #### Returns The unobstructed bounds of the layer. #### See Also [UnobstructedArea](https://developer.repebble.com/docs/c/User_Interface/UnobstructedArea.md) [GPoint](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPoint) layer\_convert\_point\_to\_screen(const Layer \* layer, [GPoint](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPoint) point) Converts a point from the layer's local coordinate system to screen coordinates. ##### Note If the layer isn't part of the view hierarchy the result is undefined. #### Parameters layer The view whose coordinate system will be used to convert the value to the screen. point A point specified in the local coordinate system (bounds) of the layer. #### Returns The point converted to the coordinate system of the screen. [GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) layer\_convert\_rect\_to\_screen(const Layer \* layer, [GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) rect) Converts a rectangle from the layer's local coordinate system to screen coordinates. ##### Note If the layer isn't part of the view hierarchy the result is undefined. #### Parameters layer The view whose coordinate system will be used to convert the value to the screen. rect A rectangle specified in the local coordinate system (bounds) of the layer. #### Returns The rectangle converted to the coordinate system of the screen. struct Window \* layer\_get\_window(const Layer \* layer) Gets the window that the layer is currently attached to. #### Parameters layer The layer for which to get the window #### Returns The window that this layer is currently attached to, or `NULL` if it has not been added to a window's layer hierarchy. #### See Also [window\_get\_root\_layer()](https://developer.repebble.com/docs/c/User_Interface/Window.md#window_get_root_layer) [layer\_add\_child()](https://developer.repebble.com/docs/c/User_Interface/Layers.md#layer_add_child) void layer\_remove\_from\_parent(Layer \* child) Removes the layer from its current parent layer If removed successfully, the child's parent layer will be marked dirty automatically. #### Parameters child The layer to remove void layer\_remove\_child\_layers(Layer \* parent) Removes child layers from given layer If removed successfully, the child's parent layer will be marked dirty automatically. #### Parameters parent The layer from which to remove all child layers void layer\_add\_child(Layer \* parent, Layer \* child) Adds the child layer to a given parent layer, making it appear in front of its parent and in front of any existing child layers of the parent. If the child layer was already part of a layer hierarchy, it will be removed from its old parent first. If added successfully, the parent (and children) will be marked dirty automatically. #### Parameters parent The layer to which to add the child layer child The layer to add to the parent layer void layer\_insert\_below\_sibling(Layer \* layer\_to\_insert, Layer \* below\_sibling\_layer) Inserts the layer as a sibling behind another layer. If the layer to insert was already part of a layer hierarchy, it will be removed from its old parent first. The below\_layer has to be a child of a parent layer, otherwise this function will be a noop. If inserted successfully, the parent (and children) will be marked dirty automatically. #### Parameters layer\_to\_insert The layer to insert into the hierarchy below\_sibling\_layer The layer that will be used as the sibling layer above which the insertion will take place void layer\_insert\_above\_sibling(Layer \* layer\_to\_insert, Layer \* above\_sibling\_layer) Inserts the layer as a sibling in front of another layer. The above\_layer has to be a child of a parent layer, otherwise this function will be a noop. If inserted successfully, the parent (and children) will be marked dirty automatically. #### Parameters layer\_to\_insert The layer to insert into the hierarchy above\_sibling\_layer The layer that will be used as the sibling layer below which the insertion will take place void layer\_set\_hidden(Layer \* layer, bool hidden) Sets the visibility of the layer. If the visibility has changed, [layer\_mark\_dirty()](https://developer.repebble.com/docs/c/User_Interface/Layers.md#layer_mark_dirty) will be called automatically on the parent layer. #### Parameters layer The layer for which to set the visibility hidden Supply `true` to make the layer hidden, or `false` to make it non-hidden. bool layer\_get\_hidden(const Layer \* layer) Gets the visibility of the layer. #### Parameters layer The layer for which to get the visibility #### Returns True if the layer is hidden, false if it is not hidden. void layer\_set\_clips(Layer \* layer, bool clips) Sets whether clipping is enabled for the layer. If enabled, whatever the layer _and its children_ will draw using their `.update_proc` callbacks, will be clipped by the this layer's frame. If the clipping has changed, [layer\_mark\_dirty()](https://developer.repebble.com/docs/c/User_Interface/Layers.md#layer_mark_dirty) will be called automatically. #### Parameters layer The layer for which to set the clipping property clips Supply `true` to make the layer clip to its frame, or `false` to make it non-clipping. bool layer\_get\_clips(const Layer \* layer) Gets whether clipping is enabled for the layer. If enabled, whatever the layer _and its children_ will draw using their `.update_proc` callbacks, will be clipped by the this layer's frame. #### Parameters layer The layer for which to get the clipping property #### Returns True if clipping is enabled for the layer, false if clipping is not enabled for the layer. void \* layer\_get\_data(const Layer \* layer) Gets the data from a layer that has been created with an extra data region. #### Parameters layer The layer to get the data region from. #### Returns A void pointer to the data region. ## Typedef Documentation typedef struct Layer Layer typedef void(\* LayerUpdateProc)(struct Layer \*layer, GContext \*ctx) Function signature for a Layer's render callback (the name of the type is derived from the words 'update procedure'). The system will call the `.update_proc` callback whenever the Layer needs to be rendered. #### Parameters layer The layer that needs to be rendered ctx The destination graphics context to draw into #### See Also [Graphics](https://developer.repebble.com/docs/c/Graphics.md) [layer\_set\_update\_proc()](https://developer.repebble.com/docs/c/User_Interface/Layers.md#layer_set_update_proc) --- # Light Source: https://developer.repebble.com/docs/c/User_Interface/Light/ Controlling Pebble's backlight The Light API provides you with functions to turn on Pebble’s backlight or put it back into automatic control. You can trigger the backlight and schedule a timer to automatically disable the backlight after a short delay, which is the preferred method of interacting with the backlight. ## Function Documentation void light\_enable\_interaction(void) Trigger the backlight and schedule a timer to automatically disable the backlight after a short delay. This is the preferred method of interacting with the backlight. void light\_enable(bool enable) Turn the watch's backlight on or put it back into automatic control. Developers should take care when calling this function, keeping Pebble's backlight on for long periods of time will rapidly deplete the battery. #### Parameters enable Turn the backlight on if `true`, otherwise `false` to put it back into automatic control. bool light\_is\_on(void) #### Returns true if the backlight is currently on in any form (on, timed, or fading out). Returns false only when the backlight is fully off. Useful for apps that want to behave differently depending on whether the screen is currently lit — e.g. skipping an animation or queuing a visual cue for when the screen wakes. void light\_set\_color(GColor color) Tint the backlight LED to the given color. The color persists while the app is foregrounded and is automatically reset to the user's default (white) when the app exits or is preempted by a system notification. On platforms without a color backlight this is a no-op. ##### Note GColor carries only 2 bits per channel (64 distinct tints). Use [light\_set\_color\_rgb888()](https://developer.repebble.com/docs/c/User_Interface/Light.md#light_set_color_rgb888) if you need the full 8-bit-per-channel range that the LED hardware supports. #### Parameters color The color to tint the backlight to. void light\_set\_color\_rgb888([uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) rgb) Tint the backlight LED to a packed 24-bit RGB value (0x00RRGGBB). Same persistence semantics as [light\_set\_color()](https://developer.repebble.com/docs/c/User_Interface/Light.md#light_set_color): the override lasts while the app is foregrounded and is reset on app exit or system preempt. No-op on platforms without a color backlight. #### Parameters rgb Packed 0x00RRGGBB value; 8 bits per channel. High byte ignored. void light\_set\_system\_color(void) Restore the backlight to the user's default color. Rarely needed — the system resets automatically on app exit. No-op on platforms without a color backlight. --- # Locale Source: https://developer.repebble.com/docs/c/Standard_C/Locale/ Standard locale functions. ## Function Documentation char \* setlocale(int category, char \* locale) Set the app's locale for a category of routines. `setlocale` can be used to: - set the app's locale to a specific locale: `setlocale(LC_ALL, "en_CA")` - set the app's locale to the system locale: `setlocale(LC_ALL, "")` - get the app's curent locale: `setlocale(LC_ALL, NULL)` ##### Note Currently, we only support two categories: LC\_ALL and LC\_TIME #### Parameters category The category of routines for which to set the locale locale The ISO formatted locale to use, or "" for the system locale #### Returns the locale after the change is applied, NULL on failure (e.g. unsuported category) --- # Logging Source: https://developer.repebble.com/docs/c/Foundation/Logging/ Functions related to logging from apps. This module contains the functions necessary to log messages through Bluetooth. ## Function Documentation void app\_log(uint8\_t log\_level, const char \* src\_filename, int src\_line\_number, const char \* fmt, ...) ## Enum Documentation enum AppLogLevel Suggested log level values. #### Enumerators APP\_LOG\_LEVEL\_ERROR Error level log message. APP\_LOG\_LEVEL\_WARNING Warning level log message. APP\_LOG\_LEVEL\_INFO Info level log message. APP\_LOG\_LEVEL\_DEBUG Debug level log message. APP\_LOG\_LEVEL\_DEBUG\_VERBOSE Verbose Debug level log message. ## Macro Definition Documentation #define APP\_LOG ( level, fmt, args...) A helper macro that simplifies the use of the app\_log function. #### Parameters level The log level to log output as fmt A C formatting string args The arguments for the formatting string --- # Math Source: https://developer.repebble.com/docs/c/Foundation/Math/ Math routines. Below is a code example that uses the trigonometry functions to calculate the coordinate at which the second hand of a watch ends, using seconds from the system time. ``` GPoint secondHand;GPoint center;struct tm \*tick\_time = ...;int32\_t secondHandLength = ...;...int32\_t second\_angle = TRIG\_MAX\_ANGLE \* tick\_time-\>tm\_sec / 60;secondHand.y = (-cos\_lookup(second\_angle) \* secondHandLength / TRIG\_MAX\_RATIO) + center.y;secondHand.x = (sin\_lookup(second\_angle) \* secondHandLength / TRIG\_MAX\_RATIO) + center.x; ``` ## Function Documentation int32\_t sin\_lookup(int32\_t angle) Look-up the sine of the given angle from a pre-computed table. #### Parameters angle The angle for which to compute the cosine. The angle value is scaled linearly, such that a value of 0x10000 corresponds to 360 degrees or 2 PI radians. int32\_t cos\_lookup(int32\_t angle) Look-up the cosine of the given angle from a pre-computed table. This is equivalent to calling `sin_lookup(angle + TRIG_MAX_ANGLE / 4)`. #### Parameters angle The angle for which to compute the cosine. The angle value is scaled linearly, such that a value of 0x10000 corresponds to 360 degrees or 2 PI radians. int32\_t atan2\_lookup(int16\_t y, int16\_t x) Look-up the arctangent of a given x, y pair The angle value is scaled linearly, such that a value of 0x10000 corresponds to 360 degrees or 2 PI radians. ## Macro Definition Documentation #define TRIG\_MAX\_RATIO 0xffff The largest value that can result from a call to [sin\_lookup](https://developer.repebble.com/docs/c/Foundation/Math.md#sin_lookup) or [cos\_lookup](https://developer.repebble.com/docs/c/Foundation/Math.md#cos_lookup). For a code example, see the detailed description at the top of this chapter: [Math](https://developer.repebble.com/docs/c/Foundation/Math.md). #define TRIG\_MAX\_ANGLE 0x10000 Angle value that corresponds to 360 degrees or 2 PI radians. #### See Also [sin\_lookup](https://developer.repebble.com/docs/c/Foundation/Math.md#sin_lookup) [cos\_lookup](https://developer.repebble.com/docs/c/Foundation/Math.md#cos_lookup) #define TRIGANGLE\_TO\_DEG ( trig\_angle) Converts from a fixed point value representation to the equivalent value in degrees. #### See Also [DEG\_TO\_TRIGANGLE](https://developer.repebble.com/docs/c/Foundation/Math.md#DEG_TO_TRIGANGLE) [TRIG\_MAX\_ANGLE](https://developer.repebble.com/docs/c/Foundation/Math.md#TRIG_MAX_ANGLE) #define DEG\_TO\_TRIGANGLE ( angle) Converts from an angle in degrees to the equivalent fixed point value representation. #### See Also [TRIGANGLE\_TO\_DEG](https://developer.repebble.com/docs/c/Foundation/Math.md#TRIGANGLE_TO_DEG) [TRIG\_MAX\_ANGLE](https://developer.repebble.com/docs/c/Foundation/Math.md#TRIG_MAX_ANGLE) --- # Math Source: https://developer.repebble.com/docs/c/Standard_C/Math/ Standard math functions. ## Function Documentation int rand() Generate a pseudo-random integer between 0 and [RAND\_MAX](https://developer.repebble.com/docs/c/Standard_C/Math.md#RAND_MAX) inclusive. This function can be seeded by [srand()](https://developer.repebble.com/docs/c/Standard_C/Math.md#srand). A simple way to change the range to be an integer between 0 and n-1 inclusive is using % e.g. `rand() % n`. #### Returns The pseudo-randomly generated number void srand(unsigned int seed) Seed the pseudo-random number generator. When your app starts, the pseudo-random number generator is automatically seeded with a random number that is generated by a high-entropy hardware random number generator. This function affects subsequent calls to [rand()](https://developer.repebble.com/docs/c/Standard_C/Math.md#rand) to produce a sequence of numbers for a given seed value. You can use this to either create a different sequence of numbers by always using a different seed or to obtain the same sequence of numbers by reusing the same seed. #### Parameters seed The source number used to generate a sequence of pseudo-random numbers ## Macro Definition Documentation #define RAND\_MAX The maximum integer value [rand()](https://developer.repebble.com/docs/c/Standard_C/Math.md#rand) may return. --- # Memory Source: https://developer.repebble.com/docs/c/Standard_C/Memory/ Standard memory functions. ## Function Documentation void \* malloc([size\_t](https://developer.repebble.com/docs/c/Standard_C/Memory.md#size_t) size) Allocates a requested amount of memory. #### Parameters size The number of bytes to allocate #### Returns A pointer to the allocated memory or NULL on error. void \* calloc([size\_t](https://developer.repebble.com/docs/c/Standard_C/Memory.md#size_t) count, [size\_t](https://developer.repebble.com/docs/c/Standard_C/Memory.md#size_t) size) Allocates space for count objects that are size bytes and fills the memory with bytes of value 0. #### Parameters count The number of objects to allocate space for size The size of the object type being allocated #### Returns A pointer to the allocated memory or NULL on error. void \* realloc(void \* ptr, [size\_t](https://developer.repebble.com/docs/c/Standard_C/Memory.md#size_t) size) Takes the memory allocated at ptr and changes the length of its allocation to the size specified. Copies the smaller of the length of the original allocation or the new size into the newly allocated buffer. #### Parameters ptr The memory allocation to be changed size The size to change the ptr allocation to #### Returns A pointer to the new allocated memory or NULL on error void free(void \* ptr) Frees previously allocated memory. #### Parameters ptr The memory buffer to free. int memcmp(const void \* ptr1, const void \* ptr2, [size\_t](https://developer.repebble.com/docs/c/Standard_C/Memory.md#size_t) n) Compares the first n bytes of memory regions ptr1 and ptr2. #### Parameters ptr1 The pointer to the first memory region to compare ptr2 The pointer to the second memory region to compare n The number of bytes to compare #### Returns 0 if the first n bytes of ptr1 and ptr 2 match. Otherwise, the sign is determined by the sign of the difference between the first pair of bytes that differ in ptr1 and ptr2. void \* memcpy(void \* dest, const void \* src, [size\_t](https://developer.repebble.com/docs/c/Standard_C/Memory.md#size_t) n) Copies n bytes from src to dest. #### Parameters dest The pointer to the destination memory region src The pointer to the source memory region n The number of bytes to copy void \* memmove(void \* dest, const void \* src, [size\_t](https://developer.repebble.com/docs/c/Standard_C/Memory.md#size_t) n) Copies n bytes from src to dest by first copying to a temporary area first, allowing dest and src to potentially overlap. This can be used to move data to a location that overlaps its previous location. #### Parameters dest The pointer to the destination memory region src The pointer to the source memory region n The number of bytes to copy void \* memset(void \* dest, int c, [size\_t](https://developer.repebble.com/docs/c/Standard_C/Memory.md#size_t) n) Sets n bytes to c starting at dest. This can be used to clear a memory region for example if c is 0. #### Parameters dest The pointer to the destination memory region c The integer used as an unsigned char to assign to each byte n The number of bytes to set ## Typedef Documentation typedef unsigned int size\_t size as an unsigned integer --- # Memory Management Source: https://developer.repebble.com/docs/c/Foundation/Memory_Management/ Utility functions for managing an application's memory. ## Function Documentation [size\_t](https://developer.repebble.com/docs/c/Standard_C/Memory.md#size_t) heap\_bytes\_free(void) Calculates the number of bytes of heap memory _not_ currently being used by the application. #### Returns The number of bytes on the heap not currently being used. [size\_t](https://developer.repebble.com/docs/c/Standard_C/Memory.md#size_t) heap\_bytes\_used(void) Calculates the number of bytes of heap memory currently being used by the application. #### Returns The number of bytes on the heap currently being used. void memory\_cache\_flush(void \* start, [size\_t](https://developer.repebble.com/docs/c/Standard_C/Memory.md#size_t) size) Flushes the data cache and invalidates the instruction cache for the given region of memory, if necessary. This is only required when your app is loading or modifying code in memory and intends to execute it. On some platforms, code executed may be cached internally to improve performance. After writing to memory, but before executing, this function must be called in order to avoid undefined behavior. On platforms without caching, this performs no operation. #### Parameters start The beginning of the buffer to flush size How many bytes to flush --- # MenuLayer Source: https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer/ Layer that displays a standard list menu. Data is provided using callbacks. ![](https://developer.repebble.com/assets/images/docs/c/aplite/menu_layer.png) ![](https://developer.repebble.com/assets/images/docs/c/aplite/menu_layer.png) ![](https://developer.repebble.com/assets/images/docs/c/aplite/menu_layer.png) ![](https://developer.repebble.com/assets/images/docs/c/aplite/menu_layer.png) ![](https://developer.repebble.com/assets/images/docs/c/aplite/menu_layer.png) ### Key Points - The familiar list-style menu widget, as used throughout the Pebble user interface. - Built on top of [ScrollLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/ScrollLayer.md), inheriting all its goodness like animated scrolling, automatic "more content" shadow indicators, etc. - All data needed to render the menu is requested on-demand via callbacks, to avoid the need to keep a lot of data in memory. - Support for "sections". A section is a group of items, visually separated by a header with the name at the top of the section. - Variable heights: each menu item cell and each section header can have its own height. The heights are provided by callbacks. - Deviation from the Layer system for cell drawing: Each menu item does _not_ have its own Layer (to minimize memory usage). Instead, a drawing callback is set onto the [MenuLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md) that is responsible for drawing each menu item. The [MenuLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md) will call this callback for each menu item that is visible and needs to be rendered. - Cell and header drawing can be customized by implementing a custom drawing callback. - A few "canned" menu cell drawing functions are provided for convenience, which support the default menu cell layout with a title, optional subtitle and icon. For short, static list menus, consider using [SimpleMenuLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/SimpleMenuLayer.md). ## Function Documentation void menu\_cell\_basic\_draw(GContext \* ctx, const Layer \* cell\_layer, const char \* title, const char \* subtitle, GBitmap \* icon) Section drawing function to draw a basic section cell with the title, subtitle, and icon of the section. Call this function inside the `.draw_row` callback implementation, see [MenuLayerCallbacks](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#MenuLayerCallbacks). Note that if the size of `cell_layer` is too small to fit all of the cell items specified, not all of them may be drawn. #### Parameters ctx The destination graphics context cell\_layer The layer of the cell to draw title If non-null, draws a title in larger text (24 points, bold Raster Gothic system font). subtitle If non-null, draws a subtitle in smaller text (18 points, Raster Gothic system font). If `NULL`, the title will be centered vertically inside the menu cell. icon If non-null, draws an icon to the left of the text. If `NULL`, the icon will be omitted and the leftover space is used for the title and subtitle. void menu\_cell\_title\_draw(GContext \* ctx, const Layer \* cell\_layer, const char \* title) Cell drawing function to draw a basic menu cell layout with title, subtitle Cell drawing function to draw a menu cell layout with only one big title. Call this function inside the `.draw_row` callback implementation, see [MenuLayerCallbacks](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#MenuLayerCallbacks). #### Parameters ctx The destination graphics context cell\_layer The layer of the cell to draw title If non-null, draws a title in larger text (28 points, bold Raster Gothic system font). void menu\_cell\_basic\_header\_draw(GContext \* ctx, const Layer \* cell\_layer, const char \* title) Section header drawing function to draw a basic section header cell layout with the title of the section. Call this function inside the `.draw_header` callback implementation, see [MenuLayerCallbacks](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#MenuLayerCallbacks). #### Parameters ctx The destination graphics context cell\_layer The layer of the cell to draw title If non-null, draws the title in small text (14 points, bold Raster Gothic system font). int16\_t menu\_index\_compare(const [MenuIndex](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#MenuIndex) \* a, const [MenuIndex](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#MenuIndex) \* b) Comparator function to determine the order of two [MenuIndex](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#MenuIndex) values. #### Parameters a Pointer to the menu index of the first item b Pointer to the menu index of the second item #### Returns 0 if A and B are equal, 1 if A has a higher section & row combination than B or else -1 MenuLayer \* menu\_layer\_create([GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) frame) Creates a new [MenuLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md) on the heap and initalizes it with the default values. - Clips: `true` - Hidden: `false` - Content size: `frame.size` - Content offset: [GPointZero](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPointZero) - Callbacks: None (`NULL` for each one) - Callback context: `NULL` - After the relevant callbacks are called to populate the menu, the item at [MenuIndex(0, 0)](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#MenuIndex) will be selected initially. #### Returns A pointer to the [MenuLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md). `NULL` if the [MenuLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md) could not be created void menu\_layer\_destroy(MenuLayer \* menu\_layer) Destroys a [MenuLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md) previously created by menu\_layer\_create. Layer \* menu\_layer\_get\_layer(const MenuLayer \* menu\_layer) Gets the "root" Layer of the [MenuLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md), which is the parent for the sub- layers used for its implementation. #### Parameters menu\_layer Pointer to the MenuLayer for which to get the "root" Layer #### Returns The "root" Layer of the [MenuLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md). ScrollLayer \* menu\_layer\_get\_scroll\_layer(const MenuLayer \* menu\_layer) Gets the ScrollLayer of the [MenuLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md), which is the layer responsible for the scrolling of the [MenuLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md). #### Parameters menu\_layer Pointer to the [MenuLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md) for which to get the ScrollLayer #### Returns The ScrollLayer of the [MenuLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md). void menu\_layer\_set\_callbacks(MenuLayer \* menu\_layer, void \* callback\_context, [MenuLayerCallbacks](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#MenuLayerCallbacks) callbacks) Sets the callbacks for the MenuLayer. #### Parameters menu\_layer Pointer to the [MenuLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md) for which to set the callbacks and callback context. callback\_context The new callback context. This is passed into each of the callbacks and can be set to point to application provided data. callbacks The new callbacks for the [MenuLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md). The storage for this data structure must be long lived. Therefore, it cannot be stack-allocated. #### See Also [MenuLayerCallbacks](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#MenuLayerCallbacks) void menu\_layer\_set\_click\_config\_onto\_window(MenuLayer \* menu\_layer, struct Window \* window) Convenience function to set the [ClickConfigProvider](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#ClickConfigProvider) callback on the given window to the [MenuLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md) internal click config provider. This internal click configuration provider, will set up the default UP & DOWN scrolling / menu item selection behavior. This function calls [scroll\_layer\_set\_click\_config\_onto\_window](https://developer.repebble.com/docs/c/User_Interface/Layers/ScrollLayer.md#scroll_layer_set_click_config_onto_window) to accomplish this. Click and long click events for the SELECT button can be handled by installing the appropriate callbacks using [menu\_layer\_set\_callbacks()](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#menu_layer_set_callbacks). This is a deviation from the usual click configuration provider pattern. #### Parameters menu\_layer The [MenuLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md) that needs to receive click events. window The window for which to set the click configuration. #### See Also [Clicks](https://developer.repebble.com/docs/c/User_Interface/Clicks.md) [window\_set\_click\_config\_provider\_with\_context()](https://developer.repebble.com/docs/c/User_Interface/Window.md#window_set_click_config_provider_with_context) [scroll\_layer\_set\_click\_config\_onto\_window()](https://developer.repebble.com/docs/c/User_Interface/Layers/ScrollLayer.md#scroll_layer_set_click_config_onto_window) void menu\_layer\_set\_selected\_next(MenuLayer \* menu\_layer, bool up, [MenuRowAlign](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#MenuRowAlign) scroll\_align, bool animated) Selects the next or previous item, relative to the current selection. ##### Note If there is no next/previous item, this function is a no-op. #### Parameters menu\_layer The [MenuLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md) for which to select the next item up Supply `false` to select the next item in the list (downwards), or `true` to select the previous item in the list (upwards). scroll\_align The alignment of the new selection animated Supply `true` to animate changing the selection, or `false` to change the selection instantly. void menu\_layer\_set\_selected\_index(MenuLayer \* menu\_layer, [MenuIndex](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#MenuIndex) index, [MenuRowAlign](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#MenuRowAlign) scroll\_align, bool animated) Selects the item with given [MenuIndex](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#MenuIndex). ##### Note If the section and/or row index exceeds the avaible number of sections or resp. rows, the exceeding index/indices will be capped, effectively selecting the last section and/or row, resp. #### Parameters menu\_layer The [MenuLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md) for which to change the selection index The index of the item to select scroll\_align The alignment of the new selection animated Supply `true` to animate changing the selection, or `false` to change the selection instantly. [MenuIndex](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#MenuIndex) menu\_layer\_get\_selected\_index(const MenuLayer \* menu\_layer) Gets the [MenuIndex](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#MenuIndex) of the currently selected menu item. ##### Note This function should not be used to determine whether a cell should be highlighted or not. See [menu\_cell\_layer\_is\_highlighted](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#menu_cell_layer_is_highlighted) for more information. #### Parameters menu\_layer The [MenuLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md) for which to get the current selected index. #### See Also [menu\_cell\_layer\_is\_highlighted](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#menu_cell_layer_is_highlighted) void menu\_layer\_reload\_data(MenuLayer \* menu\_layer) Reloads the data of the menu. This causes the menu to re-request the menu item data, by calling the relevant callbacks. The current selection and scroll position will not be changed. See the note with [menu\_layer\_set\_selected\_index()](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#menu_layer_set_selected_index) for the behavior if the old selection is no longer valid. #### Parameters menu\_layer The [MenuLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md) for which to reload the data. bool menu\_cell\_layer\_is\_highlighted(const Layer \* cell\_layer) Returns whether or not the given cell layer is highlighted. Using this for determining highlight behaviour is preferable to using [menu\_layer\_get\_selected\_index](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#menu_layer_get_selected_index). Row drawing callbacks may be invoked multiple times with a different highlight status on the same cell in order to handle partially highlighted cells during animation. #### Parameters cell\_layer The [Layers](https://developer.repebble.com/docs/c/User_Interface/Layers.md) for the cell to check highlight status. #### Returns true if the given cell layer is highlighted in the menu. void menu\_layer\_set\_normal\_colors(MenuLayer \* menu\_layer, GColor background, GColor foreground) Set the default colors to be used for cells when it is in a normal state (not highlighted). The GContext's text and fill colors will be set appropriately prior to calling the `.draw_row` callback. If this function is not explicitly called on a [MenuLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md), it will default to white background with black foreground. #### Parameters menu\_layer The [MenuLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md) for which to set the colors. background The color to be used for the background of the cell. foreground The color to be used for the foreground and text of the cell. #### See Also [menu\_layer\_set\_highlight\_colors](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#menu_layer_set_highlight_colors) void menu\_layer\_set\_highlight\_colors(MenuLayer \* menu\_layer, GColor background, GColor foreground) Set the default colors to be used for cells when it is in a highlighted state. The GContext's text and fill colors will be set appropriately prior to calling the `.draw_row` callback. If this function is not explicitly called on a [MenuLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md), it will default to black background with white foreground. #### Parameters menu\_layer The [MenuLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md) for which to set the colors. background The color to be used for the background of the cell. foreground The color to be used for the foreground and text of the cell. #### See Also [menu\_layer\_set\_normal\_colors](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#menu_layer_set_normal_colors) void menu\_layer\_pad\_bottom\_enable(MenuLayer \* menu\_layer, bool enable) This enables or disables padding at the bottom of the [MenuLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md). Padding at the bottom of the layer keeps the bottom item from being at the very bottom of the screen. Padding is turned on by default for all MenuLayers. The color of the padded area will be the background color set using [menu\_layer\_set\_normal\_colors()](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#menu_layer_set_normal_colors). To color the padding a different color, use [MenuLayerDrawBackgroundCallback](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#MenuLayerDrawBackgroundCallback). #### Parameters menu\_layer The menu layer for which to enable or disable the padding. enable True = enable padding, False = disable padding. bool menu\_layer\_get\_center\_focused(MenuLayer \* menu\_layer) True, if the [MenuLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md) generally scrolls such that the selected row is in the center. #### See Also [menu\_layer\_set\_center\_focused](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#menu_layer_set_center_focused) void menu\_layer\_set\_center\_focused(MenuLayer \* menu\_layer, bool center\_focused) Controls if the [MenuLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md) generally scrolls such that the selected row is in the center. For platforms with a round display (PBL\_ROUND) the default is true, otherwise false is the default. #### Parameters menu\_layer The menu layer for which to enable or disable the behavior. center\_focused true = enable the mode, false = disable it. #### See Also [menu\_layer\_get\_center\_focused](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#menu_layer_get_center_focused) bool menu\_layer\_is\_index\_selected(const MenuLayer \* menu\_layer, [MenuIndex](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#MenuIndex) \* index) Returns whether or not the specified cell index is currently selected. ##### Note This function should not be used to determine whether a cell is highlighted or not. See [menu\_cell\_layer\_is\_highlighted](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#menu_cell_layer_is_highlighted) for more information. #### Parameters menu\_layer The [MenuLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md) to use when determining if the index is selected. index The [MenuIndex](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#MenuIndex) of the cell to check for selection. ## Data Structure Documentation struct MenuCellSpan #### Data Fields int16\_t yint16\_t hint16\_t sep[MenuIndex](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#MenuIndex) index struct MenuIndex Data structure to represent an menu item's position in a menu, by specifying the section index and the row index within that section. #### Data Fields [uint16\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint16_t) section The index of the section. [uint16\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint16_t) row The index of the row within the section with index `.section` struct MenuLayerCallbacks Data structure containing all the callbacks of a [MenuLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md). #### Data Fields [MenuLayerGetNumberOfSectionsCallback](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#MenuLayerGetNumberOfSectionsCallback) get\_num\_sections Callback that gets called to get the number of sections in the menu. This can get called at various moments throughout the life of a menu. ##### Note When `NULL`, the number of sections defaults to 1. [MenuLayerGetNumberOfRowsInSectionsCallback](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#MenuLayerGetNumberOfRowsInSectionsCallback) get\_num\_rows Callback that gets called to get the number of rows in a section. This can get called at various moments throughout the life of a menu. ##### Note Must be set to a valid callback; `NULL` causes undefined behavior. [MenuLayerGetCellHeightCallback](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#MenuLayerGetCellHeightCallback) get\_cell\_height Callback that gets called to get the height of a cell. This can get called at various moments throughout the life of a menu. ##### Note When `NULL`, the default height of `MENU_CELL_BASIC_CELL_HEIGHT` pixels is used. Developers may wish to use [MENU\_CELL\_ROUND\_FOCUSED\_SHORT\_CELL\_HEIGHT](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#MENU_CELL_ROUND_FOCUSED_SHORT_CELL_HEIGHT) and [MENU\_CELL\_ROUND\_UNFOCUSED\_SHORT\_CELL\_HEIGHT](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#MENU_CELL_ROUND_UNFOCUSED_SHORT_CELL_HEIGHT) on a round display to respect the system aesthetic. [MenuLayerGetHeaderHeightCallback](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#MenuLayerGetHeaderHeightCallback) get\_header\_height Callback that gets called to get the height of a section header. This can get called at various moments throughout the life of a menu. ##### Note When `NULL`, the default height of 0 pixels is used. This disables section headers. [MenuLayerDrawRowCallback](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#MenuLayerDrawRowCallback) draw\_row Callback that gets called to render a menu item. This gets called for each menu item, every time it needs to be re-rendered. ##### Note Must be set to a valid callback; `NULL` causes undefined behavior. [MenuLayerDrawHeaderCallback](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#MenuLayerDrawHeaderCallback) draw\_header Callback that gets called to render a section header. This gets called for each section header, every time it needs to be re-rendered. ##### Note Must be set to a valid callback, unless `.get_header_height` is `NULL`. Causes undefined behavior otherwise. [MenuLayerSelectCallback](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#MenuLayerSelectCallback) select\_click Callback that gets called when the user triggers a click with the SELECT button. ##### Note When `NULL`, click events for the SELECT button are ignored. [MenuLayerSelectCallback](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#MenuLayerSelectCallback) select\_long\_click Callback that gets called when the user triggers a long click with the SELECT button. ##### Note When `NULL`, long click events for the SELECT button are ignored. [MenuLayerSelectionChangedCallback](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#MenuLayerSelectionChangedCallback) selection\_changed Callback that gets called whenever the selection changes. ##### Note When `NULL`, selection change events are ignored. [MenuLayerGetSeparatorHeightCallback](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#MenuLayerGetSeparatorHeightCallback) get\_separator\_height Callback that gets called to get the height of a separator This can get called at various moments throughout the life of a menu. ##### Note When `NULL`, the default height of 0 is used. [MenuLayerDrawSeparatorCallback](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#MenuLayerDrawSeparatorCallback) draw\_separator Callback that gets called to render a separator. This gets called for each separator, every time it needs to be re-rendered. ##### Note Must be set to a valid callback, unless `.get_separator_height` is `NULL`. Causes undefined behavior otherwise. [MenuLayerSelectionWillChangeCallback](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#MenuLayerSelectionWillChangeCallback) selection\_will\_change Callback that gets called before the selected cell changes. This gets called before the selected item in the MenuLayer is changed, and will allow for the selected cell to be overridden. This allows for skipping cells in the menu, locking selection onto a given item,. [MenuLayerDrawBackgroundCallback](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#MenuLayerDrawBackgroundCallback) draw\_background Callback that gets called before any cells are drawn. This supports two states, either highlighted or not highlighted. If highlighted is specified, it is expected to be colored in the same style as the menu's cells are. If this callback is not specified, it will default to the colors set with [menu\_layer\_set\_normal\_colors](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#menu_layer_set_normal_colors) and [menu\_layer\_set\_highlight\_colors](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#menu_layer_set_highlight_colors). ## Enum Documentation enum MenuRowAlign Values to specify how a (selected) row should be aligned relative to the visible area of the [MenuLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md). #### Enumerators MenuRowAlignNone Don't align or update the scroll offset of the [MenuLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md). MenuRowAlignCenter Scroll the contents of the [MenuLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md) in such way that the selected row is centered relative to the visible area. MenuRowAlignTop Scroll the contents of the [MenuLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md) in such way that the selected row is at the top of the visible area. MenuRowAlignBottom Scroll the contents of the [MenuLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md) in such way that the selected row is at the bottom of the visible area. ## Typedef Documentation typedef struct MenuLayer MenuLayer typedef [uint16\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint16_t)(\* MenuLayerGetNumberOfSectionsCallback)(struct MenuLayer \*menu\_layer, void \*callback\_context) Function signature for the callback to get the number of sections in a menu. #### Parameters menu\_layer The [MenuLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md) for which the data is requested callback\_context The callback context #### Returns The number of sections in the menu #### See Also [menu\_layer\_set\_callbacks()](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#menu_layer_set_callbacks) [MenuLayerCallbacks](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#MenuLayerCallbacks) typedef [uint16\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint16_t)(\* MenuLayerGetNumberOfRowsInSectionsCallback)(struct MenuLayer \*menu\_layer, uint16\_t section\_index, void \*callback\_context) Function signature for the callback to get the number of rows in a given section in a menu. #### Parameters menu\_layer The [MenuLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md) for which the data is requested section\_index The index of the section of the menu for which the number of items it contains is requested callback\_context The callback context #### Returns The number of rows in the given section in the menu #### See Also [menu\_layer\_set\_callbacks()](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#menu_layer_set_callbacks) [MenuLayerCallbacks](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#MenuLayerCallbacks) typedef int16\_t(\* MenuLayerGetCellHeightCallback)(struct MenuLayer \*menu\_layer, MenuIndex \*cell\_index, void \*callback\_context) Function signature for the callback to get the height of the menu cell at a given index. #### Parameters menu\_layer The [MenuLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md) for which the data is requested cell\_index The [MenuIndex](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#MenuIndex) for which the cell height is requested callback\_context The callback context #### Returns The height of the cell at the given [MenuIndex](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#MenuIndex) #### See Also [menu\_layer\_set\_callbacks()](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#menu_layer_set_callbacks) [MenuLayerCallbacks](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#MenuLayerCallbacks) typedef int16\_t(\* MenuLayerGetHeaderHeightCallback)(struct MenuLayer \*menu\_layer, uint16\_t section\_index, void \*callback\_context) Function signature for the callback to get the height of the section header at a given section index. #### Parameters menu\_layer The [MenuLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md) for which the data is requested section\_index The index of the section for which the header height is requested callback\_context The callback context #### Returns The height of the section header at the given section index #### See Also [menu\_layer\_set\_callbacks()](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#menu_layer_set_callbacks) [MenuLayerCallbacks](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#MenuLayerCallbacks) typedef int16\_t(\* MenuLayerGetSeparatorHeightCallback)(struct MenuLayer \*menu\_layer, MenuIndex \*cell\_index, void \*callback\_context) Function signature for the callback to get the height of the separator at a given index. #### Parameters menu\_layer The [MenuLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md) for which the data is requested cell\_index The [MenuIndex](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#MenuIndex) for which the cell height is requested callback\_context The callback context #### Returns The height of the separator at the given [MenuIndex](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#MenuIndex) #### See Also [menu\_layer\_set\_callbacks()](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#menu_layer_set_callbacks) [MenuLayerCallbacks](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#MenuLayerCallbacks) typedef void(\* MenuLayerDrawRowCallback)(GContext \*ctx, const Layer \*cell\_layer, MenuIndex \*cell\_index, void \*callback\_context) Function signature for the callback to render the menu cell at a given [MenuIndex](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#MenuIndex). ##### Note The `cell_layer` argument is provided to make it easy to re-use an `.update_proc` implementation in this callback. Only the bounds and frame of the `cell_layer` are actually valid and other properties should be ignored. #### Parameters ctx The destination graphics context to draw into cell\_layer The cell's layer, containing the geometry of the cell cell\_index The [MenuIndex](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#MenuIndex) of the cell that needs to be drawn callback\_context The callback context #### See Also [menu\_layer\_set\_callbacks()](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#menu_layer_set_callbacks) [MenuLayerCallbacks](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#MenuLayerCallbacks) typedef void(\* MenuLayerDrawHeaderCallback)(GContext \*ctx, const Layer \*cell\_layer, uint16\_t section\_index, void \*callback\_context) Function signature for the callback to render the section header at a given section index. ##### Note The `cell_layer` argument is provided to make it easy to re-use an `.update_proc` implementation in this callback. Only the bounds and frame of the `cell_layer` are actually valid and other properties should be ignored. #### Parameters ctx The destination graphics context to draw into cell\_layer The header cell's layer, containing the geometry of the header cell section\_index The section index of the section header that needs to be drawn callback\_context The callback context #### See Also [menu\_layer\_set\_callbacks()](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#menu_layer_set_callbacks) [MenuLayerCallbacks](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#MenuLayerCallbacks) typedef void(\* MenuLayerDrawSeparatorCallback)(GContext \*ctx, const Layer \*cell\_layer, MenuIndex \*cell\_index, void \*callback\_context) Function signature for the callback to render the separator at a given [MenuIndex](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#MenuIndex). ##### Note The `cell_layer` argument is provided to make it easy to re-use an `.update_proc` implementation in this callback. Only the bounds and frame of the `cell_layer` are actually valid and other properties should be ignored. #### Parameters ctx The destination graphics context to draw into cell\_layer The cell's layer, containing the geometry of the cell cell\_index The [MenuIndex](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#MenuIndex) of the separator that needs to be drawn callback\_context The callback context #### See Also [menu\_layer\_set\_callbacks()](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#menu_layer_set_callbacks) [MenuLayerCallbacks](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#MenuLayerCallbacks) typedef void(\* MenuLayerSelectCallback)(struct MenuLayer \*menu\_layer, MenuIndex \*cell\_index, void \*callback\_context) Function signature for the callback to handle the event that a user hits the SELECT button. #### Parameters menu\_layer The [MenuLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md) for which the selection event occured cell\_index The [MenuIndex](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#MenuIndex) of the cell that is selected callback\_context The callback context #### See Also [menu\_layer\_set\_callbacks()](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#menu_layer_set_callbacks) [MenuLayerCallbacks](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#MenuLayerCallbacks) typedef void(\* MenuLayerSelectionChangedCallback)(struct MenuLayer \*menu\_layer, MenuIndex new\_index, MenuIndex old\_index, void \*callback\_context) Function signature for the callback to handle a change in the current selected item in the menu. #### Parameters menu\_layer The [MenuLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md) for which the selection event occured new\_index The [MenuIndex](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#MenuIndex) of the new item that is selected now old\_index The [MenuIndex](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#MenuIndex) of the old item that was selected before callback\_context The callback context #### See Also [menu\_layer\_set\_callbacks()](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#menu_layer_set_callbacks) [MenuLayerCallbacks](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#MenuLayerCallbacks) typedef void(\* MenuLayerSelectionWillChangeCallback)(struct MenuLayer \*menu\_layer, MenuIndex \*new\_index, MenuIndex old\_index, void \*callback\_context) Function signature for the callback which allows or changes selection behavior of the menu. In order to change the cell that should be selected, modify the passed in new\_index. Preventing the selection from changing, new\_index can be assigned the value of old\_index. ##### Note [menu\_layer\_set\_selected\_index](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#menu_layer_set_selected_index) will not trigger this callback when the selection changes, but [menu\_layer\_set\_selected\_next](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#menu_layer_set_selected_next) will. #### Parameters menu\_layer The [MenuLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md) for which the selection event that occured new\_index Pointer to the index that the MenuLayer is going to change selection to. old\_index The index that is being unselected. callback\_context The callback context typedef void(\* MenuLayerDrawBackgroundCallback)(GContext \*ctx, const Layer \*bg\_layer, bool highlight, void \*callback\_context) Function signature for the callback which draws the menu's background. The background is underneath the cells of the menu, and is visible in the padding below the bottom cell, or if a cell's background color is set to GColorClear. #### Parameters ctx The destination graphics context to draw into. bg\_layer The background's layer, containing the geometry of the background. highlight Whether this should be rendered as highlighted or not. Highlight style should match the highlight style of cells, since this color can be used for animating selection. ## Macro Definition Documentation #define MENU\_CELL\_BASIC\_HEADER\_HEIGHT ((const int16\_t) 16) Default section header height in pixels. #define MENU\_INDEX\_NOT\_FOUND ((const [uint16\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint16_t)) ~0) #define MenuIndex ( section, row) Macro to create a [MenuIndex](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md#MenuIndex). #define MENU\_CELL\_ROUND\_FOCUSED\_SHORT\_CELL\_HEIGHT ((const int16\_t) 68) Constant value representing [MenuLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md) short cell height when this item is the selected item on a round display. #define MENU\_CELL\_ROUND\_UNFOCUSED\_SHORT\_CELL\_HEIGHT ((const int16\_t) 24) Constant value representing [MenuLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md) short cell height when this item is not the selected item on a round display. #define MENU\_CELL\_ROUND\_FOCUSED\_TALL\_CELL\_HEIGHT ((const int16\_t) 84) Constant value representing [MenuLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md) tall cell height when this item is the selected item on a round display. #define MENU\_CELL\_ROUND\_UNFOCUSED\_TALL\_CELL\_HEIGHT ((const int16\_t) 32) Constant value representing [MenuLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md) tall cell height when this item is not the selected item on a round display. --- # NumberWindow Source: https://developer.repebble.com/docs/c/User_Interface/Window/NumberWindow/ A ready-made Window prompting the user to pick a number ![](https://developer.repebble.com/assets/images/docs/c/aplite/number_window.png) ![](https://developer.repebble.com/assets/images/docs/c/aplite/number_window.png) ![](https://developer.repebble.com/assets/images/docs/c/aplite/number_window.png) ![](https://developer.repebble.com/assets/images/docs/c/aplite/number_window.png) ![](https://developer.repebble.com/assets/images/docs/c/aplite/number_window.png) ## Function Documentation NumberWindow \* number\_window\_create(const char \* label, [NumberWindowCallbacks](https://developer.repebble.com/docs/c/User_Interface/Window/NumberWindow.md#NumberWindowCallbacks) callbacks, void \* callback\_context) Creates a new NumberWindow on the heap and initalizes it with the default values. ##### Note The number window is not pushed to the window stack. Use [window\_stack\_push()](https://developer.repebble.com/docs/c/User_Interface/Window_Stack.md#window_stack_push) to do this. #### Parameters label The title or prompt to display in the NumberWindow. Must be long-lived and cannot be stack-allocated. callbacks The callbacks callback\_context Pointer to application specific data that is passed #### Returns A pointer to the NumberWindow. `NULL` if the NumberWindow could not be created void number\_window\_destroy(NumberWindow \* number\_window) Destroys a NumberWindow previously created by number\_window\_create. void number\_window\_set\_label(NumberWindow \* numberwindow, const char \* label) Sets the text of the title or prompt label. #### Parameters numberwindow Pointer to the NumberWindow for which to set the label text label The new label text. Must be long-lived and cannot be stack-allocated. void number\_window\_set\_max(NumberWindow \* numberwindow, int32\_t max) Sets the maximum value this field can hold. #### Parameters numberwindow Pointer to the NumberWindow for which to set the maximum value max The maximum value void number\_window\_set\_min(NumberWindow \* numberwindow, int32\_t min) Sets the minimum value this field can hold. #### Parameters numberwindow Pointer to the NumberWindow for which to set the minimum value min The minimum value void number\_window\_set\_value(NumberWindow \* numberwindow, int32\_t value) Sets the current value of the field. #### Parameters numberwindow Pointer to the NumberWindow for which to set the current value value The new current value void number\_window\_set\_step\_size(NumberWindow \* numberwindow, int32\_t step) Sets the amount by which to increment/decrement by on a button click. #### Parameters numberwindow Pointer to the NumberWindow for which to set the step increment step The new step increment int32\_t number\_window\_get\_value(const NumberWindow \* numberwindow) Gets the current value. #### Parameters numberwindow Pointer to the NumberWindow for which to get the current value #### Returns The current value Window \* number\_window\_get\_window(NumberWindow \* numberwindow) Gets the "root" Window of the number window. #### Parameters numberwindow Pointer to the NumberWindow for which to get the "root" Window #### Returns The "root" Window of the number window. ## Data Structure Documentation struct NumberWindowCallbacks Data structure containing all the callbacks for a NumberWindow. #### Data Fields [NumberWindowCallback](https://developer.repebble.com/docs/c/User_Interface/Window/NumberWindow.md#NumberWindowCallback) incremented Callback that gets called as the value is incremented. Optional, leave `NULL` if unused. [NumberWindowCallback](https://developer.repebble.com/docs/c/User_Interface/Window/NumberWindow.md#NumberWindowCallback) decremented Callback that gets called as the value is decremented. Optional, leave `NULL` if unused. [NumberWindowCallback](https://developer.repebble.com/docs/c/User_Interface/Window/NumberWindow.md#NumberWindowCallback) selected Callback that gets called as the value is confirmed, in other words the SELECT button is clicked. Optional, leave `NULL` if unused. ## Typedef Documentation typedef struct NumberWindow NumberWindow typedef void(\* NumberWindowCallback)(struct NumberWindow \*number\_window, void \*context) Function signature for NumberWindow callbacks. --- # PBI File Format Source: https://developer.repebble.com/docs/c/Foundation/Resources/File_Formats/PBI_File_Format/ PBIs are uncompressed bitmap images with support for color-mapping palettes. PBIs store images either as raw image pixels (1-bit black and white, or 8-bit ARGB) or as palette-based images with 1, 2, or 4 bits per pixel. For palette-based images the pixel data represents the index into the palette, such that each pixel only needs to be large enough to represent the palette size, so - `1-bit` supports up to 2 colors, - `2-bit` supports up to 4 colors, - `4-bit` supports up to 16 colors. The metadata describes how long each row of pixels is in the buffer (the stride). The following restrictions on stride are in place for different formats: - GBitmapFormat1Bit: Each row must be a multiple of 32 pixels (4 bytes). Using the `bounds` field, the area that is actually relevant can be specified. For example, when the image is 29 by 5 pixels (width by height) and the first bit of image data is the pixel at (0, 0), then the bounds.size would be `GSize(29, 5)` and bounds.origin would be `GPoint(0, 0)`. ![](https://developer.repebble.com/assets/images/docs/c/aplite/gbitmap.png) ![](https://developer.repebble.com/assets/images/docs/c/aplite/gbitmap.png) ![](https://developer.repebble.com/assets/images/docs/c/aplite/gbitmap.png) ![](https://developer.repebble.com/assets/images/docs/c/aplite/gbitmap.png) ![](https://developer.repebble.com/assets/images/docs/c/aplite/gbitmap.png) - GBitmapFormat8Bit: Each pixel in the bitmap is represented by 1 byte. The color value of that byte correspends to a GColor.argb value. There is no restriction on row\_size\_bytes / stride. - GBitmapFormat1BitPalette, GBitmapFormat2BitPalette, GBitmapFormat4BitPalette: Each pixel in the bitmap is represented by the number of bits the format specifies. Pixels must be packed. For example, in GBitmapFormat2BitPalette, each pixel uses 2 bits. This means 4 pixels / byte. Rows need to be byte-aligned, meaning that there can be up to 3 unused pixels at the end of each line. If the image is 5 pixels wide and 4 pixels tall, row\_size\_bytes = 2, and each row in the bitmap must take 2 bytes, so the bitmap data is 8 bytes in total. Palettized bitmaps also need to have a palette. The palette must be of the correct size, which is specified by the format. For example, GBitmapFormat4BitPalette uses 4 bits per pixel, meaning that there must be 2^4 = 16 colors in the palette. The Basalt Platform provides for 2-bits per color channel, so images are optimized by the SDK tooling when loaded as a resource-type "pbi" to the Pebble's 64-colors with 4 levels of transparency. This optimization also handles mapping unsupported colors to the nearest supported color, and reducing the pixel depth to the number of bits required to support the optimized number of colors. --- # Platform Source: https://developer.repebble.com/docs/c/Foundation/Platform/ ## Enum Documentation enum PlatformType #### Enumerators PlatformTypeAplitePlatformTypeBasaltPlatformTypeChalkPlatformTypeDioritePlatformTypeEmeryPlatformTypeFlintPlatformTypeGabbro ## Macro Definition Documentation #define PBL\_PLATFORM\_TYPE\_CURRENT PlatformTypeEmery #define PBL\_PLATFORM\_SWITCH\_DEFAULT ( PLAT, DEFAULT, APLITE, BASALT, CHALK, DIORITE, EMERY, FLINT, GABBRO) #define PBL\_PLATFORM\_SWITCH ( PLAT, APLITE, BASALT, CHALK, DIORITE, EMERY, FLINT, GABBRO) --- # PNG8 File Format Source: https://developer.repebble.com/docs/c/Foundation/Resources/File_Formats/PNG8_File_Format/ Pebble supports both a PBIs (uncompressed bitmap images) as well as PNG8 images. PNG images are compressed allowing for storage savings up to 90%. PNG8 is a PNG that uses palette-based or grayscale images with 1, 2, 4 or 8 bits per pixel. For palette-based images the pixel data represents the index into the palette, such that each pixel only needs to be large enough to represent the palette size, so - `1-bit` supports up to 2 colors, - `2-bit` supports up to 4 colors, - `4-bit` supports up to 16 colors, - `8-bit` supports up to 256 colors. There are 2 parts to the palette: the RGB24 color-mapping palette ("PLTE"), and the optional 8-bit transparency palette ("tRNs"). A pixel's color index maps to both tables, combining to allow the pixel to have both color as well as transparency. For grayscale images, the pixel data represents the luminosity (or shade of gray). - `1-bit` supports black and white - `2-bit` supports black, dark\_gray, light\_gray and white - `4-bit` supports black, white and 14 shades of gray - `8-bit` supports black, white and 254 shades of gray Optionally, grayscale images allow for 1 fully transparent color, which is removed from the fully-opaque colors above (e.g. a 2 bit grayscale image can have black, white, dark\_gray and a transparent color). The Basalt Platform provides for 2-bits per color channel, so images are optimized by the SDK tooling when loaded as a resource-type "png" to the Pebble's 64-colors with 4 levels of transparency. This optimization also handles mapping unsupported colors to the nearest supported color, and reducing the pixel depth to the number of bits required to support the optimized number of colors. PNG8 images from other sources are supported, with the colors truncated to match supported colors at runtime. --- # Preferences Source: https://developer.repebble.com/docs/c/User_Interface/Preferences/ Values recommended by the system ## Function Documentation [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) preferred\_result\_display\_duration(void) Get the recommended amount of milliseconds a result window should be visible before it should automatically close. ##### Note It is the application developer's responsibility to automatically close a result window. #### Returns The recommended result window timeout duration in milliseconds [PreferredContentSize](https://developer.repebble.com/docs/c/User_Interface/Preferences.md#PreferredContentSize) preferred\_content\_size(void) Returns the user's preferred content size representing the scale of all the app's UI components should use for display. #### Returns The user's [PreferredContentSize](https://developer.repebble.com/docs/c/User_Interface/Preferences.md#PreferredContentSize) setting. bool quiet\_time\_is\_active(void) Users can toggle Quiet Time manually or on schedule. Watchfaces and apps should respect this choice and avoid disturbing actions such as vibration if quiet time is active. #### Returns True, if Quiet Time is currently active. ## Enum Documentation enum PreferredContentSize [PreferredContentSize](https://developer.repebble.com/docs/c/User_Interface/Preferences.md#PreferredContentSize) represents the display scale of all the app's UI components. The enum contains all sizes that all platforms as a whole are capable of displaying, but each individual platform may not be able to display all sizes. As of version 4.1, platforms other than Emery cannot display extra large and Emery itself cannot display small. #### Enumerators PreferredContentSizeSmallPreferredContentSizeMediumPreferredContentSizeLargePreferredContentSizeExtraLargeNumPreferredContentSizes --- # PropertyAnimation Source: https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation/ A ProperyAnimation animates the value of a "property" of a "subject" over time. ### Animating a Layer's frame property Currently there is only one specific type of property animation offered off-the-shelf, namely one to change the frame (property) of a layer (subject), see [property\_animation\_create\_layer\_frame()](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md#property_animation_create_layer_frame). ### Implementing a custom PropertyAnimation It is fairly simple to create your own variant of a PropertyAnimation. Please refer to [User Interface Layers chapter in the Pebble Developer Guides](https://developer.repebble.com/guides/user-interfaces/layers.md) (chapter "Property Animations") for a conceptual overview of the animation framework and make sure you understand the underlying [Animation](https://developer.repebble.com/docs/c/User_Interface/Animation.md), in case you are not familiar with it, before trying to implement a variation on PropertyAnimation. To implement a custom property animation, use [property\_animation\_create()](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md#property_animation_create) and provide a function pointers to the accessors (getter and setter) and setup, update and teardown callbacks in the implementation argument. Note that the type of property to animate with [PropertyAnimation](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md) is limited to int16\_t, [GPoint](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPoint) or [GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect). For each of these types, there are implementations provided for the necessary `.update` handler of the animation: see [property\_animation\_update\_int16()](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md#property_animation_update_int16), [property\_animation\_update\_gpoint()](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md#property_animation_update_gpoint) and [property\_animation\_update\_grect()](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md#property_animation_update_grect). These update functions expect the `.accessors` to conform to the following interface: Any getter needs to have the following function signature: ` __type__ getter(void *subject);` Any setter needs to have to following function signature: `void setter(void *subject, __type__ value);` See [Int16Getter](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md#Int16Getter), [Int16Setter](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md#Int16Setter), [GPointGetter](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md#GPointGetter), [GPointSetter](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md#GPointSetter), [GRectGetter](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md#GRectGetter), [GRectSetter](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md#GRectSetter) for the typedefs that accompany the update fuctions. ``` static const PropertyAnimationImplementation my\_implementation = {.base = {// using the "stock" update callback:.update = (AnimationUpdateImplementation) property\_animation\_update\_gpoint,},.accessors = {// my accessors that get/set a GPoint from/onto my subject:.setter = { .gpoint = my\_layer\_set\_corner\_point, },.getter = { .gpoint = (const GPointGetter) my\_layer\_get\_corner\_point, },},};static PropertyAnimation\* s\_my\_animation\_ptr = NULL;static GPoint s\_to\_point = GPointZero;...// Use NULL as 'from' value, this will make the animation framework call the getter// to get the current value of the property and use that as the 'from' value:s\_my\_animation\_ptr = property\_animation\_create(&my\_implementation, my\_layer, NULL, &s\_to\_point);animation\_schedule(property\_animation\_get\_animation(s\_my\_animation\_ptr)); ``` ## Function Documentation PropertyAnimation \* property\_animation\_create\_layer\_frame(struct Layer \* layer, [GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) \* from\_frame, [GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) \* to\_frame) Convenience function to create and initialize a property animation that animates the frame of a Layer. It sets up the PropertyAnimation to use [layer\_set\_frame()](https://developer.repebble.com/docs/c/User_Interface/Layers.md#layer_set_frame) and [layer\_get\_frame()](https://developer.repebble.com/docs/c/User_Interface/Layers.md#layer_get_frame) as accessors and uses the `layer` parameter as the subject for the animation. The same defaults are used as with [animation\_create()](https://developer.repebble.com/docs/c/User_Interface/Animation.md#animation_create). ##### Note Pass in `NULL` as one of the frame arguments to have it set automatically to the layer's current frame. This will result in a call to [layer\_get\_frame()](https://developer.repebble.com/docs/c/User_Interface/Layers.md#layer_get_frame) to get the current frame of the layer. #### Parameters layer the layer that will be animated from\_frame the frame that the layer should animate from to\_frame the frame that the layer should animate to #### Returns A handle to the property animation. `NULL` if animation could not be created - [SDK 3](javascript:void(0);) - [SDK 4](javascript:void(0);) - [SDK 4.9+](javascript:void(0);) PropertyAnimation \* property\_animation\_create\_bounds\_origin(struct Layer \* layer, [GPoint](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPoint) \* from, [GPoint](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPoint) \* to) Convenience function to create and initialize a property animation that animates the bound's origin of a Layer. It sets up the PropertyAnimation to use [layer\_set\_bounds()](https://developer.repebble.com/docs/c/User_Interface/Layers.md#layer_set_bounds) and [layer\_get\_bounds()](https://developer.repebble.com/docs/c/User_Interface/Layers.md#layer_get_bounds) as accessors and uses the `layer` parameter as the subject for the animation. The same defaults are used as with [animation\_create()](https://developer.repebble.com/docs/c/User_Interface/Animation.md#animation_create). #### Parameters layer the layer that will be animated from\_origin the origin that the bounds should animate from to\_origin the origin that the layer should animate to #### Returns A handle to the property animation. `NULL` if animation could not be created PropertyAnimation \* property\_animation\_create\_bounds\_origin(struct Layer \* layer, [GPoint](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPoint) \* from, [GPoint](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPoint) \* to) Convenience function to create and initialize a property animation that animates the bound's origin of a Layer. It sets up the PropertyAnimation to use [layer\_set\_bounds()](https://developer.repebble.com/docs/c/User_Interface/Layers.md#layer_set_bounds) and [layer\_get\_bounds()](https://developer.repebble.com/docs/c/User_Interface/Layers.md#layer_get_bounds) as accessors and uses the `layer` parameter as the subject for the animation. The same defaults are used as with [animation\_create()](https://developer.repebble.com/docs/c/User_Interface/Animation.md#animation_create). #### Parameters layer the layer that will be animated from\_origin the origin that the bounds should animate from to\_origin the origin that the layer should animate to #### Returns A handle to the property animation. `NULL` if animation could not be created PropertyAnimation \* property\_animation\_create\_bounds\_origin(struct Layer \* layer, [GPoint](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPoint) \* from, [GPoint](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPoint) \* to) Convenience function to create and initialize a property animation that animates the bound's origin of a Layer. It sets up the PropertyAnimation to use [layer\_set\_bounds()](https://developer.repebble.com/docs/c/User_Interface/Layers.md#layer_set_bounds) and [layer\_get\_bounds()](https://developer.repebble.com/docs/c/User_Interface/Layers.md#layer_get_bounds) as accessors and uses the `layer` parameter as the subject for the animation. The same defaults are used as with [animation\_create()](https://developer.repebble.com/docs/c/User_Interface/Animation.md#animation_create). #### Parameters layer the layer that will be animated from the origin that the bounds should animate from to the origin that the layer should animate to #### Returns A handle to the property animation. `NULL` if animation could not be created PropertyAnimation \* property\_animation\_create(const [PropertyAnimationImplementation](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md#PropertyAnimationImplementation) \* implementation, void \* subject, void \* from\_value, void \* to\_value) Creates a new PropertyAnimation on the heap and and initializes it with the specified values. The same defaults are used as with [animation\_create()](https://developer.repebble.com/docs/c/User_Interface/Animation.md#animation_create). If the `from_value` or the `to_value` is `NULL`, the getter accessor will be called to get the current value of the property and be used instead. ##### Note Pass in `NULL` as one of the value arguments to have it set automatically to the subject's current property value, as returned by the getter function. Also note that passing in `NULL` for both `from_value` and `to_value`, will result in the animation having the same from- and to- values, effectively not doing anything. #### Parameters implementation Pointer to the implementation of the animation. In most cases, it makes sense to pass in a `static const` struct pointer. subject Pointer to the "subject" being animated. This will be passed in when the getter/ setter accessors are called, see [PropertyAnimationAccessors](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md#PropertyAnimationAccessors), [GPointSetter](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md#GPointSetter), and friends. The value of this pointer will be copied into the `.subject` field of the PropertyAnimation struct. from\_value Pointer to the value that the subject should animate from to\_value Pointer to the value that the subject should animate to #### Returns A handle to the property animation. `NULL` if animation could not be created void property\_animation\_destroy(PropertyAnimation \* property\_animation) Destroy a property animation allocated by [property\_animation\_create()](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md#property_animation_create) or relatives. #### Parameters property\_animation the return value from property\_animation\_create void property\_animation\_update\_int16(PropertyAnimation \* property\_animation, const [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) distance\_normalized) Default update callback for a property animations to update a property of type int16\_t. Assign this function to the `.base.update` callback field of your [PropertyAnimationImplementation](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md#PropertyAnimationImplementation), in combination with a `.getter` and `.setter` accessors of types [Int16Getter](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md#Int16Getter) and [Int16Setter](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md#Int16Setter). The implementation of this function will calculate the next value of the animation and call the setter to set the new value upon the subject. ##### Note This function is not supposed to be called "manually", but will be called automatically when the animation is being run. #### Parameters property\_animation The property animation for which the update is requested. distance\_normalized The current normalized distance. See [AnimationUpdateImplementation](https://developer.repebble.com/docs/c/User_Interface/Animation.md#AnimationUpdateImplementation) void property\_animation\_update\_uint32(PropertyAnimation \* property\_animation, const [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) distance\_normalized) Default update callback for a property animations to update a property of type [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t). Assign this function to the `.base.update` callback field of your [PropertyAnimationImplementation](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md#PropertyAnimationImplementation), in combination with a `.getter` and `.setter` accessors of types [UInt32Getter](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md#UInt32Getter) and [UInt32Setter](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md#UInt32Setter). The implementation of this function will calculate the next value of the animation and call the setter to set the new value upon the subject. ##### Note This function is not supposed to be called "manually", but will be called automatically when the animation is being run. #### Parameters property\_animation The property animation for which the update is requested. distance\_normalized The current normalized distance. See [AnimationUpdateImplementation](https://developer.repebble.com/docs/c/User_Interface/Animation.md#AnimationUpdateImplementation) void property\_animation\_update\_gpoint(PropertyAnimation \* property\_animation, const [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) distance\_normalized) Default update callback for a property animations to update a property of type [GPoint](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPoint). Assign this function to the `.base.update` callback field of your [PropertyAnimationImplementation](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md#PropertyAnimationImplementation), in combination with a `.getter` and `.setter` accessors of types [GPointGetter](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md#GPointGetter) and [GPointSetter](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md#GPointSetter). The implementation of this function will calculate the next point of the animation and call the setter to set the new point upon the subject. ##### Note This function is not supposed to be called "manually", but will be called automatically when the animation is being run. #### Parameters property\_animation The property animation for which the update is requested. distance\_normalized The current normalized distance. See [AnimationUpdateImplementation](https://developer.repebble.com/docs/c/User_Interface/Animation.md#AnimationUpdateImplementation) void property\_animation\_update\_grect(PropertyAnimation \* property\_animation, const [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) distance\_normalized) Default update callback for a property animations to update a property of type [GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect). Assign this function to the `.base.update` callback field of your [PropertyAnimationImplementation](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md#PropertyAnimationImplementation), in combination with a `.getter` and `.setter` accessors of types [GRectGetter](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md#GRectGetter) and [GRectSetter](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md#GRectSetter). The implementation of this function will calculate the next rectangle of the animation and call the setter to set the new rectangle upon the subject. ##### Note This function is not supposed to be called "manually", but will be called automatically when the animation is being run. #### Parameters property\_animation The property animation for which the update is requested. distance\_normalized The current normalized distance. See [AnimationUpdateImplementation](https://developer.repebble.com/docs/c/User_Interface/Animation.md#AnimationUpdateImplementation) void property\_animation\_update\_gcolor8(PropertyAnimation \* property\_animation, const [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) distance\_normalized) Default update callback for a property animations to update a property of type GColor8. Assign this function to the `.base.update` callback field of your [PropertyAnimationImplementation](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md#PropertyAnimationImplementation), in combination with a `.getter` and `.setter` accessors of types [GColor8Getter](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md#GColor8Getter) and [GColor8Setter](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md#GColor8Setter). The implementation of this function will calculate the next rectangle of the animation and call the setter to set the new value upon the subject. ##### Note This function is not supposed to be called "manually", but will be called automatically when the animation is being run. #### Parameters property\_animation The property animation for which the update is requested. distance\_normalized The current normalized distance. See [AnimationUpdateImplementation](https://developer.repebble.com/docs/c/User_Interface/Animation.md#AnimationUpdateImplementation) Animation \* property\_animation\_get\_animation(PropertyAnimation \* property\_animation) Convenience function to retrieve an animation instance from a property animation instance. #### Parameters property\_animation The property animation #### Returns The [Animation](https://developer.repebble.com/docs/c/User_Interface/Animation.md) within this PropertyAnimation bool property\_animation\_subject(PropertyAnimation \* property\_animation, void \*\* subject, bool set) Helper function used by the property\_animation\_get|set\_subject macros. #### Parameters property\_animation Handle to the property animation subject The subject to get or set. set true to set new subject, false to retrieve existing value #### Returns true if successful, false on failure (usually a bad animation\_h) bool property\_animation\_from(PropertyAnimation \* property\_animation, void \* from, [size\_t](https://developer.repebble.com/docs/c/Standard_C/Memory.md#size_t) size, bool set) Helper function used by the property\_animation\_get|set\_from\_.\* macros. #### Parameters property\_animation Handle to the property animation from Pointer to the value size Size of the from value set true to set new value, false to retrieve existing one #### Returns true if successful, false on failure (usually a bad animation\_h) bool property\_animation\_to(PropertyAnimation \* property\_animation, void \* to, [size\_t](https://developer.repebble.com/docs/c/Standard_C/Memory.md#size_t) size, bool set) Helper function used by the property\_animation\_get|set\_to\_.\* macros. #### Parameters property\_animation handle to the property animation to Pointer to the value size Size of the to value set true to set new value, false to retrieve existing one #### Returns true if successful, false on failure (usually a bad animation\_h) ## Data Structure Documentation struct PropertyAnimationAccessors Data structure containing the setter and getter function pointers that the property animation should use. The specified setter function will be used by the animation's update callback. Based on the type of the property (int16\_t, [GPoint](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPoint) or [GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect)), the accompanying update callback should be used, see [property\_animation\_update\_int16()](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md#property_animation_update_int16), [property\_animation\_update\_gpoint()](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md#property_animation_update_gpoint) and [property\_animation\_update\_grect()](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md#property_animation_update_grect). The getter function is used when the animation is initialized, to assign the current value of the subject's property as "from" or "to" value, see [property\_animation\_create()](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md#property_animation_create). #### Data Fields union [PropertyAnimationAccessors](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md#PropertyAnimationAccessors) setter Function pointer to the implementation of the function that **sets** the updated property value. This function will be called repeatedly for each animation frame. union [PropertyAnimationAccessors](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md#PropertyAnimationAccessors) getter Function pointer to the implementation of the function that **gets** the current property value. This function will be called during [property\_animation\_create()](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md#property_animation_create), to get the current property value, in case the `from_value` or `to_value` argument is `NULL`. struct PropertyAnimationImplementation Data structure containing a collection of function pointers that form the implementation of the property animation. See the code example at the top ([PropertyAnimation](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md)). #### Data Fields [AnimationImplementation](https://developer.repebble.com/docs/c/User_Interface/Animation.md#AnimationImplementation) base The "inherited" fields from the Animation "base class". [PropertyAnimationAccessors](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md#PropertyAnimationAccessors) accessors The accessors to set/get the property to be animated. ## Typedef Documentation typedef struct PropertyAnimation PropertyAnimation typedef [GPoint](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPoint) GPointReturn Work-around for function pointer return type [GPoint](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPoint) to avoid tripping the pre-processor to use the equally named [GPoint](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPoint) define. typedef [GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) GRectReturn Work-around for function pointer return type [GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) to avoid tripping the pre-processor to use the equally named [GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) define. typedef void(\* Int16Setter)(void \*subject, int16\_t int16) Function signature of a setter function to set a property of type int16\_t onto the subject. #### See Also [property\_animation\_update\_int16()](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md#property_animation_update_int16) [PropertyAnimationAccessors](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md#PropertyAnimationAccessors) typedef int16\_t(\* Int16Getter)(void \*subject) Function signature of a getter function to get the current property of type int16\_t of the subject. #### See Also [property\_animation\_create()](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md#property_animation_create) [PropertyAnimationAccessors](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md#PropertyAnimationAccessors) typedef void(\* UInt32Setter)(void \*subject, uint32\_t uint32) Function signature of a setter function to set a property of type [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) onto the subject. #### See Also [property\_animation\_update\_int16()](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md#property_animation_update_int16) [PropertyAnimationAccessors](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md#PropertyAnimationAccessors) typedef [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t)(\* UInt32Getter)(void \*subject) Function signature of a getter function to get the current property of type [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) of the subject. #### See Also [property\_animation\_create()](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md#property_animation_create) [PropertyAnimationAccessors](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md#PropertyAnimationAccessors) typedef void(\* GPointSetter)(void \*subject, GPoint gpoint) Function signature of a setter function to set a property of type [GPoint](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPoint) onto the subject. #### See Also [property\_animation\_update\_gpoint()](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md#property_animation_update_gpoint) [PropertyAnimationAccessors](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md#PropertyAnimationAccessors) typedef [GPointReturn](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md#GPointReturn)(\* GPointGetter)(void \*subject) Function signature of a getter function to get the current property of type [GPoint](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPoint) of the subject. #### See Also [property\_animation\_create()](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md#property_animation_create) [PropertyAnimationAccessors](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md#PropertyAnimationAccessors) typedef void(\* GRectSetter)(void \*subject, GRect grect) Function signature of a setter function to set a property of type [GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) onto the subject. #### See Also [property\_animation\_update\_grect()](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md#property_animation_update_grect) [PropertyAnimationAccessors](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md#PropertyAnimationAccessors) typedef [GRectReturn](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md#GRectReturn)(\* GRectGetter)(void \*subject) Function signature of a getter function to get the current property of type [GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) of the subject. #### See Also [property\_animation\_create()](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md#property_animation_create) [PropertyAnimationAccessors](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md#PropertyAnimationAccessors) typedef void(\* GColor8Setter)(void \*subject, GColor8 gcolor) Function signature of a setter function to set a property of type GColor8 onto the subject. #### See Also [property\_animation\_update\_gcolor8()](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md#property_animation_update_gcolor8) [PropertyAnimationAccessors](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md#PropertyAnimationAccessors) typedef GColor8(\* GColor8Getter)(void \*subject) Function signature of a getter function to get the current property of type GColor8 of the subject. #### See Also [property\_animation\_create()](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md#property_animation_create) [PropertyAnimationAccessors](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md#PropertyAnimationAccessors) ## Macro Definition Documentation #define property\_animation\_clone ( property\_animation) Convenience function to clone a property animation instance. #### Parameters property\_animation The property animation #### Returns A clone of the original Animation #define property\_animation\_get\_from\_grect ( property\_animation, value\_ptr) Convenience function to retrieve the 'from' [GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) value from property animation handle. #### Parameters property\_animation The PropertyAnimation to be accessed value\_ptr The value will be retrieved into this pointer #### Returns true on success, false on failure #define property\_animation\_set\_from\_grect ( property\_animation, value\_ptr) Convenience function to set the 'from' [GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) value of property animation handle. #### Parameters property\_animation The PropertyAnimation to be accessed value\_ptr Pointer to the new value #### Returns true on success, false on failure #define property\_animation\_get\_from\_gpoint ( property\_animation, value\_ptr) Convenience function to retrieve the 'from' [GPoint](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPoint) value from property animation handle. #### Parameters property\_animation The PropertyAnimation to be accessed value\_ptr The value will be retrieved into this pointer #### Returns true on success, false on failure #define property\_animation\_set\_from\_gpoint ( property\_animation, value\_ptr) Convenience function to set the 'from' [GPoint](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPoint) value of property animation handle. #### Parameters property\_animation The PropertyAnimation to be accessed value\_ptr Pointer to the new value #### Returns true on success, false on failure #define property\_animation\_get\_from\_int16 ( property\_animation, value\_ptr) Convenience function to retrieve the 'from' int16\_t value from property animation handle. #### Parameters property\_animation The PropertyAnimation to be accessed value\_ptr The value will be retrieved into this pointer #### Returns true on success, false on failure #define property\_animation\_set\_from\_int16 ( property\_animation, value\_ptr) Convenience function to set the 'from' int16\_t value of property animation handle. #### Parameters property\_animation The PropertyAnimation to be accessed value\_ptr Pointer to the new value #### Returns true on success, false on failure #define property\_animation\_get\_to\_grect ( property\_animation, value\_ptr) Convenience function to retrieve the 'to' [GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) value from property animation handle. #### Parameters property\_animation The PropertyAnimation to be accessed value\_ptr The value will be retrieved into this pointer #### Returns true on success, false on failure #define property\_animation\_set\_to\_grect ( property\_animation, value\_ptr) Convenience function to set the 'to' [GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) value of property animation handle. #### Parameters property\_animation The PropertyAnimation to be accessed value\_ptr Pointer to the new value #### Returns true on success, false on failure #define property\_animation\_get\_to\_gpoint ( property\_animation, value\_ptr) Convenience function to retrieve the 'to' [GPoint](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPoint) value from property animation handle. #### Parameters property\_animation The PropertyAnimation to be accessed value\_ptr The value will be retrieved into this pointer #### Returns true on success, false on failure #define property\_animation\_set\_to\_gpoint ( property\_animation, value\_ptr) Convenience function to set the 'to' [GPoint](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPoint) value of property animation handle. #### Parameters property\_animation The PropertyAnimation to be accessed value\_ptr Pointer to the new value #### Returns true on success, false on failure #define property\_animation\_get\_to\_int16 ( property\_animation, value\_ptr) Convenience function to retrieve the 'to' int16\_t value from property animation handle. #### Parameters property\_animation The PropertyAnimation to be accessed value\_ptr The value will be retrieved into this pointer #### Returns true on success, false on failure #define property\_animation\_set\_to\_int16 ( property\_animation, value\_ptr) Convenience function to set the 'to' int16\_t value of property animation handle. #### Parameters property\_animation The PropertyAnimation to be accessed value\_ptr Pointer to the new value #### Returns true on success, false on failure #define property\_animation\_get\_subject ( property\_animation, value\_ptr) Retrieve the subject of a property animation. #### Parameters property\_animation The PropertyAnimation to be accessed value\_ptr Pointer used to store the subject of this property animation #### Returns The subject of this PropertyAnimation #define property\_animation\_set\_subject ( property\_animation, value\_ptr) Set the subject of a property animation. #### Parameters property\_animation The PropertyAnimation to be accessed value\_ptr Pointer to the new subject value --- # Resources Source: https://developer.repebble.com/docs/c/Foundation/Resources/ Managing application resources Resources are data files that are bundled with your application binary and can be loaded at runtime. You use resources to embed images or custom fonts in your app, but also to embed any data file. Resources are always read-only. Resources are stored on Pebble’s flash memory and only loaded in RAM when you load them. This means that you can have a large number of resources embedded inside your app, even though Pebble’s RAM memory is very limited. See [App Resources in the Pebble Developer Guides](https://developer.repebble.com/guides/pebble-apps/resources/) for information on how to embed resources into your app's bundle. ## Modules #### [File Formats](https://developer.repebble.com/docs/c/Foundation/Resources/File_Formats.md)   ## Function Documentation [ResHandle](https://developer.repebble.com/docs/c/Foundation/Resources.md#ResHandle) resource\_get\_handle([uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) resource\_id) Gets the resource handle for a file identifier. The resource IDs are auto-generated by the Pebble build process, based on the `appinfo.json`. The "name" field of each resource is prefixed by `RESOURCE_ID_` and made visible to the application (through the `build/src/resource_ids.auto.h` header which is automatically included). For example, given the following fragment of `appinfo.json`: ``` ..."resources" : {"media": [{"name": "MY\_ICON","file": "img/icon.png","type": "png",}, ... ``` The generated file identifier for this resource is `RESOURCE_ID_MY_ICON`. To get a resource handle for that resource write: ``` ResHandle rh = resource\_get\_handle(RESOURCE\_ID\_MY\_ICON); ``` #### Parameters resource\_id The resource ID [size\_t](https://developer.repebble.com/docs/c/Standard_C/Memory.md#size_t) resource\_size([ResHandle](https://developer.repebble.com/docs/c/Foundation/Resources.md#ResHandle) h) Gets the size of the resource given a resource handle. #### Parameters h The handle to the resource #### Returns The size of the resource in bytes [size\_t](https://developer.repebble.com/docs/c/Standard_C/Memory.md#size_t) resource\_load([ResHandle](https://developer.repebble.com/docs/c/Foundation/Resources.md#ResHandle) h, uint8\_t \* buffer, [size\_t](https://developer.repebble.com/docs/c/Standard_C/Memory.md#size_t) max\_length) Copies the bytes for the resource with a given handle from flash storage into a given buffer. #### Parameters h The handle to the resource buffer The buffer to load the resource data into max\_length The maximum number of bytes to copy #### Returns The number of bytes actually copied [size\_t](https://developer.repebble.com/docs/c/Standard_C/Memory.md#size_t) resource\_load\_byte\_range([ResHandle](https://developer.repebble.com/docs/c/Foundation/Resources.md#ResHandle) h, [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) start\_offset, uint8\_t \* buffer, [size\_t](https://developer.repebble.com/docs/c/Standard_C/Memory.md#size_t) num\_bytes) Copies a range of bytes from a resource with a given handle into a given buffer. #### Parameters h The handle to the resource start\_offset The offset in bytes at which to start reading from the resource buffer The buffer to load the resource data into num\_bytes The maximum number of bytes to copy #### Returns The number of bytes actually copied ## Typedef Documentation - [SDK 3](javascript:void(0);) - [SDK 4](javascript:void(0);) - [SDK 4.9+](javascript:void(0);) typedef void \* ResHandle Opaque reference to a resource. #### See Also [resource\_get\_handle()](https://developer.repebble.com/docs/c/Foundation/Resources.md#resource_get_handle) typedef void \* ResHandle Opaque reference to a resource. #### See Also [resource\_get\_handle()](https://developer.repebble.com/docs/c/Foundation/Resources.md#resource_get_handle) typedef void \* ResHandle Opaque reference to a resource. #### See Also `resource_get_handle()` ## Macro Definition Documentation #define RESOURCE\_ID\_FONT\_FALLBACK RESOURCE\_ID\_GOTHIC\_14 --- # RotBitmapLayer Source: https://developer.repebble.com/docs/c/User_Interface/Layers/RotBitmapLayer/ Layer that displays a rotated bitmap image. A RotBitmapLayer is like a [BitmapLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/BitmapLayer.md) but has the ability to be rotated (by default, around its center). The amount of rotation is specified using [rot\_bitmap\_layer\_set\_angle()](https://developer.repebble.com/docs/c/User_Interface/Layers/RotBitmapLayer.md#rot_bitmap_layer_set_angle) or [rot\_bitmap\_layer\_increment\_angle()](https://developer.repebble.com/docs/c/User_Interface/Layers/RotBitmapLayer.md#rot_bitmap_layer_increment_angle). The rotation argument to those functions is specified as an amount of clockwise rotation, where the value 0x10000 represents a full 360 degree rotation and 0 represent no rotation, and it scales linearly between those values, just like [sin\_lookup](https://developer.repebble.com/docs/c/Foundation/Math.md#sin_lookup). The center of rotation in the source bitmap is always placed at the center of the RotBitmapLayer and the size of the RotBitmapLayer is automatically calculated so that the entire Bitmap can fit in at all rotation angles. For example, if the image is 10px wide and high, the RotBitmapLayer will be 14px wide ( sqrt(10^2+10^2) ). By default, the center of rotation in the source bitmap is the center of the bitmap but you can call [rot\_bitmap\_set\_src\_ic()](https://developer.repebble.com/docs/c/User_Interface/Layers/RotBitmapLayer.md#rot_bitmap_set_src_ic) to change the center of rotation. ## Function Documentation RotBitmapLayer \* rot\_bitmap\_layer\_create(GBitmap \* bitmap) Creates a new RotBitmapLayer on the heap and initializes it with the default values: - Angle: 0 - Compositing mode: GCompOpAssign - Corner clip color: GColorClear #### Parameters bitmap The bitmap to display in this RotBitmapLayer #### Returns A pointer to the RotBitmapLayer. `NULL` if the RotBitmapLayer could not be created void rot\_bitmap\_layer\_destroy(RotBitmapLayer \* bitmap) Destroys a RotBitmapLayer and frees all associated memory. ##### Note It is the developer responsibility to free the GBitmap. #### Parameters bitmap The RotBitmapLayer to destroy. void rot\_bitmap\_layer\_set\_corner\_clip\_color(RotBitmapLayer \* bitmap, GColor color) Defines what color to use in areas that are not covered by the source bitmap. By default this is GColorClear. #### Parameters bitmap The RotBitmapLayer on which to change the corner clip color color The corner clip color void rot\_bitmap\_layer\_set\_angle(RotBitmapLayer \* bitmap, int32\_t angle) Sets the rotation angle of this RotBitmapLayer. #### Parameters bitmap The RotBitmapLayer on which to change the rotation angle Rotation is an integer between 0 (no rotation) and 0x10000 (360 degree rotation). #### See Also [sin\_lookup()](https://developer.repebble.com/docs/c/Foundation/Math.md#sin_lookup) void rot\_bitmap\_layer\_increment\_angle(RotBitmapLayer \* bitmap, int32\_t angle\_change) Change the rotation angle of this RotBitmapLayer. #### Parameters bitmap The RotBitmapLayer on which to change the rotation angle\_change The rotation angle change void rot\_bitmap\_set\_src\_ic(RotBitmapLayer \* bitmap, [GPoint](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPoint) ic) Defines the only point that will not be affected by the rotation in the source bitmap. For example, if you pass [GPoint(0, 0)](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPoint), the image will rotate around the top-left corner. This point is always projected at the center of the RotBitmapLayer. Calling this function automatically adjusts the width and height of the RotBitmapLayer so that the entire bitmap can fit inside the layer at all rotation angles. #### Parameters bitmap The RotBitmapLayer on which to change the rotation ic The only point in the original image that will not be affected by the rotation. - [SDK 3](javascript:void(0);) - [SDK 4](javascript:void(0);) - [SDK 4.9+](javascript:void(0);) void rot\_bitmap\_set\_compositing\_mode(RotBitmapLayer \* bitmap, [GCompOp](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GCompOp) mode) Sets the compositing mode of how the bitmap image is composited onto what has been drawn beneath the RotBitmapLayer. By default this is GCompOpAssign. The RotBitmapLayer is automatically marked dirty after this operation. #### Parameters bitmap The RotBitmapLayer on which to change the rotation mode The compositing mode to set #### See Also [GCompOp](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GCompOp) void rot\_bitmap\_set\_compositing\_mode(RotBitmapLayer \* bitmap, [GCompOp](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GCompOp) mode) Sets the compositing mode of how the bitmap image is composited onto what has been drawn beneath the RotBitmapLayer. By default this is GCompOpAssign. The RotBitmapLayer is automatically marked dirty after this operation. #### Parameters bitmap The RotBitmapLayer on which to change the rotation mode The compositing mode to set #### See Also [GCompOp](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GCompOp) void rot\_bitmap\_set\_compositing\_mode(RotBitmapLayer \* bitmap, [GCompOp](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GCompOp) mode) Sets the compositing mode of how the bitmap image is composited onto what has been drawn beneath the RotBitmapLayer. By default this is GCompOpAssign, i.e. transparency disabled. The RotBitmapLayer is automatically marked dirty after this operation. #### Parameters bitmap The RotBitmapLayer on which to change the rotation mode The compositing mode to set #### See Also [GCompOp](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GCompOp) Layer \* rot\_bitmap\_layer\_get\_layer(const RotBitmapLayer \* rot\_bitmap\_layer) Gets the "root" Layer of the RotBitmapLayer, which is the parent for the sub- layers used for its implementation. #### Parameters rot\_bitmap\_layer Pointer to the RotBitmapLayer for which to get the "root" Layer #### Returns The "root" Layer of the RotBitmapLayer. ## Typedef Documentation typedef struct RotBitmapLayer RotBitmapLayer --- # ScrollLayer Source: https://developer.repebble.com/docs/c/User_Interface/Layers/ScrollLayer/ Layer that scrolls its contents, animated. ![](https://developer.repebble.com/assets/images/docs/c/aplite/scroll_layer.png) ![](https://developer.repebble.com/assets/images/docs/c/aplite/scroll_layer.png) ![](https://developer.repebble.com/assets/images/docs/c/aplite/scroll_layer.png) ![](https://developer.repebble.com/assets/images/docs/c/aplite/scroll_layer.png) ![](https://developer.repebble.com/assets/images/docs/c/aplite/scroll_layer.png) ### Key Points - Facilitates vertical scrolling of a layer sub-hierarchy zero or more arbitrary layers. The example image shows a scroll layer containing one large TextLayer. - Shadows to indicate that there is more content are automatically drawn on top of the content. When the end of the scroll layer is reached, the shadow will automatically be retracted. - Scrolling from one offset to another is animated implicitly by default. - The scroll layer contains a "content" sub-layer, which is the layer that is actually moved up an down. Any layer that is a child of this "content" sub-layer, will be moved as well. Effectively, an entire layout of layers can be scrolled this way. Use the convenience function [scroll\_layer\_add\_child()](https://developer.repebble.com/docs/c/User_Interface/Layers/ScrollLayer.md#scroll_layer_add_child) to add child layers to the "content" sub-layer. - The scroll layer needs to be informed of the total size of the contents, in order to calculate from and to what point it should be able to scroll. Use [scroll\_layer\_set\_content\_size()](https://developer.repebble.com/docs/c/User_Interface/Layers/ScrollLayer.md#scroll_layer_set_content_size) to set the size of the contents. - The button behavior is set up, using the convenience function [scroll\_layer\_set\_click\_config\_onto\_window()](https://developer.repebble.com/docs/c/User_Interface/Layers/ScrollLayer.md#scroll_layer_set_click_config_onto_window). This will associate the UP and DOWN buttons with scrolling up and down. - The SELECT button can be configured by installing a click configuration provider using [scroll\_layer\_set\_callbacks()](https://developer.repebble.com/docs/c/User_Interface/Layers/ScrollLayer.md#scroll_layer_set_callbacks). - To scroll programatically to a certain offset, use [scroll\_layer\_set\_content\_offset()](https://developer.repebble.com/docs/c/User_Interface/Layers/ScrollLayer.md#scroll_layer_set_content_offset). - It is possible to get called back for each scrolling increment, by installing the `.content_offset_changed_handler` callback using [scroll\_layer\_set\_callbacks()](https://developer.repebble.com/docs/c/User_Interface/Layers/ScrollLayer.md#scroll_layer_set_callbacks). - Only vertical scrolling is supported at the moment. ## Function Documentation ScrollLayer \* scroll\_layer\_create([GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) frame) Creates a new ScrollLayer on the heap and initalizes it with the default values: - Clips: `true` - Hidden: `false` - Content size: `frame.size` - Content offset: [GPointZero](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPointZero) - Callbacks: None (`NULL` for each one) - Callback context: `NULL` #### Returns A pointer to the ScrollLayer. `NULL` if the ScrollLayer could not be created void scroll\_layer\_destroy(ScrollLayer \* scroll\_layer) Destroys a ScrollLayer previously created by scroll\_layer\_create. Layer \* scroll\_layer\_get\_layer(const ScrollLayer \* scroll\_layer) Gets the "root" Layer of the scroll layer, which is the parent for the sub- layers used for its implementation. #### Parameters scroll\_layer Pointer to the ScrollLayer for which to get the "root" Layer #### Returns The "root" Layer of the scroll layer. void scroll\_layer\_add\_child(ScrollLayer \* scroll\_layer, Layer \* child) Adds the child layer to the content sub-layer of the ScrollLayer. This will make the child layer part of the scrollable contents. The content sub-layer of the ScrollLayer will become the parent of the child layer. ##### Note You may need to update the size of the scrollable contents using [scroll\_layer\_set\_content\_size()](https://developer.repebble.com/docs/c/User_Interface/Layers/ScrollLayer.md#scroll_layer_set_content_size). #### Parameters scroll\_layer The ScrollLayer to which to add the child layer. child The Layer to add to the content sub-layer of the ScrollLayer. void scroll\_layer\_set\_click\_config\_onto\_window(ScrollLayer \* scroll\_layer, struct Window \* window) Convenience function to set the [ClickConfigProvider](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#ClickConfigProvider) callback on the given window to scroll layer's internal click config provider. This internal click configuration provider, will set up the default UP & DOWN scrolling behavior. This function calls [window\_set\_click\_config\_provider\_with\_context](https://developer.repebble.com/docs/c/User_Interface/Window.md#window_set_click_config_provider_with_context) to accomplish this. If you application has set a `.click_config_provider` callback using [scroll\_layer\_set\_callbacks()](https://developer.repebble.com/docs/c/User_Interface/Layers/ScrollLayer.md#scroll_layer_set_callbacks), this will be called by the internal click config provider, after configuring the UP & DOWN buttons. This allows your application to configure the SELECT button behavior and optionally override the UP & DOWN button behavior. The callback context for the SELECT click recognizer is automatically set to the scroll layer's context (see [scroll\_layer\_set\_context()](https://developer.repebble.com/docs/c/User_Interface/Layers/ScrollLayer.md#scroll_layer_set_context) ). This context is passed into [ClickHandler](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#ClickHandler) callbacks. For the UP and DOWN buttons, the scroll layer itself is passed in by default as the callback context in order to deal with those buttons presses to scroll up and down automatically. #### Parameters scroll\_layer The ScrollLayer that needs to receive click events. window The window for which to set the click configuration. #### See Also [Clicks](https://developer.repebble.com/docs/c/User_Interface/Clicks.md) [window\_set\_click\_config\_provider\_with\_context](https://developer.repebble.com/docs/c/User_Interface/Window.md#window_set_click_config_provider_with_context) void scroll\_layer\_set\_callbacks(ScrollLayer \* scroll\_layer, [ScrollLayerCallbacks](https://developer.repebble.com/docs/c/User_Interface/Layers/ScrollLayer.md#ScrollLayerCallbacks) callbacks) Sets the callbacks that the scroll layer exposes. The `context` as set by [scroll\_layer\_set\_context()](https://developer.repebble.com/docs/c/User_Interface/Layers/ScrollLayer.md#scroll_layer_set_context) is passed into each of the callbacks. See [ScrollLayerCallbacks](https://developer.repebble.com/docs/c/User_Interface/Layers/ScrollLayer.md#ScrollLayerCallbacks) for the different callbacks. ##### Note If the `context` is NULL, a pointer to scroll\_layer is used as context parameter instead when calling callbacks. #### Parameters scroll\_layer The ScrollLayer for which to assign new callbacks. callbacks The new callbacks. void scroll\_layer\_set\_context(ScrollLayer \* scroll\_layer, void \* context) Sets a new callback context. This context is passed into the scroll layer's callbacks and also the [ClickHandler](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#ClickHandler) for the SELECT button. If `NULL` or not set, the context defaults to a pointer to the ScrollLayer itself. #### Parameters scroll\_layer The ScrollLayer for which to assign the new callback context. context The new callback context. #### See Also [scroll\_layer\_set\_click\_config\_onto\_window](https://developer.repebble.com/docs/c/User_Interface/Layers/ScrollLayer.md#scroll_layer_set_click_config_onto_window) [scroll\_layer\_set\_callbacks](https://developer.repebble.com/docs/c/User_Interface/Layers/ScrollLayer.md#scroll_layer_set_callbacks) void scroll\_layer\_set\_content\_offset(ScrollLayer \* scroll\_layer, [GPoint](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPoint) offset, bool animated) Scrolls to the given offset, optionally animated. ##### Notes When scrolling down, the offset's `.y` decrements. When scrolling up, the offset's `.y` increments. If scrolled completely to the top, the offset is [GPointZero](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPointZero). The `.x` field must be `0`. Horizontal scrolling is not supported. #### Parameters scroll\_layer The ScrollLayer for which to set the content offset offset The final content offset animated Pass in `true` to animate to the new content offset, or `false` to set the new content offset without animating. #### See Also [scroll\_layer\_get\_content\_offset](https://developer.repebble.com/docs/c/User_Interface/Layers/ScrollLayer.md#scroll_layer_get_content_offset) [GPoint](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GPoint) scroll\_layer\_get\_content\_offset(ScrollLayer \* scroll\_layer) Gets the point by which the contents are offset. #### Parameters scroll\_layer The ScrollLayer for which to get the content offset #### See Also [scroll\_layer\_set\_content\_offset](https://developer.repebble.com/docs/c/User_Interface/Layers/ScrollLayer.md#scroll_layer_set_content_offset) void scroll\_layer\_set\_content\_size(ScrollLayer \* scroll\_layer, [GSize](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GSize) size) Sets the size of the contents layer. This determines the area that is scrollable. At the moment, this needs to be set "manually" and is not derived from the geometry of the contents layers. #### Parameters scroll\_layer The ScrollLayer for which to set the content size. size The new content size. #### See Also [scroll\_layer\_get\_content\_size](https://developer.repebble.com/docs/c/User_Interface/Layers/ScrollLayer.md#scroll_layer_get_content_size) [GSize](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GSize) scroll\_layer\_get\_content\_size(const ScrollLayer \* scroll\_layer) Gets the size of the contents layer. #### Parameters scroll\_layer The ScrollLayer for which to get the content size #### See Also [scroll\_layer\_set\_content\_size](https://developer.repebble.com/docs/c/User_Interface/Layers/ScrollLayer.md#scroll_layer_set_content_size) void scroll\_layer\_set\_frame(ScrollLayer \* scroll\_layer, [GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) frame) Set the frame of the scroll layer and adjusts the internal layers' geometry accordingly. The scroll layer is marked dirty automatically. #### Parameters scroll\_layer The ScrollLayer for which to set the frame frame The new frame void scroll\_layer\_scroll\_up\_click\_handler([ClickRecognizerRef](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#ClickRecognizerRef) recognizer, void \* context) The click handlers for the UP button that the scroll layer will install as part of [scroll\_layer\_set\_click\_config\_onto\_window()](https://developer.repebble.com/docs/c/User_Interface/Layers/ScrollLayer.md#scroll_layer_set_click_config_onto_window). ##### Note This handler is exposed, in case one wants to implement an alternative handler for the UP button, as a way to invoke the default behavior. #### Parameters recognizer The click recognizer for which the handler is called context A void pointer to the ScrollLayer that is the context of the click event void scroll\_layer\_scroll\_down\_click\_handler([ClickRecognizerRef](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#ClickRecognizerRef) recognizer, void \* context) The click handlers for the DOWN button that the scroll layer will install as part of [scroll\_layer\_set\_click\_config\_onto\_window()](https://developer.repebble.com/docs/c/User_Interface/Layers/ScrollLayer.md#scroll_layer_set_click_config_onto_window). ##### Note This handler is exposed, in case one wants to implement an alternative handler for the DOWN button, as a way to invoke the default behavior. #### Parameters recognizer The click recognizer for which the handler is called context A void pointer to the ScrollLayer that is the context of the click event void scroll\_layer\_set\_shadow\_hidden(ScrollLayer \* scroll\_layer, bool hidden) Sets the visibility of the scroll layer shadow. If the visibility has changed, [layer\_mark\_dirty()](https://developer.repebble.com/docs/c/User_Interface/Layers.md#layer_mark_dirty) will be called automatically on the scroll layer. #### Parameters scroll\_layer The scroll layer for which to set the shadow visibility hidden Supply `true` to make the shadow hidden, or `false` to make it non-hidden. bool scroll\_layer\_get\_shadow\_hidden(const ScrollLayer \* scroll\_layer) Gets the visibility of the scroll layer shadow. #### Parameters scroll\_layer The scroll layer for which to get the visibility #### Returns True if the shadow is hidden, false if it is not hidden. void scroll\_layer\_set\_paging(ScrollLayer \* scroll\_layer, bool paging\_enabled) Enables or disables paging of the ScrollLayer (default: disabled). When enabled, every button press will change the scroll offset by the frame's height. #### Parameters scroll\_layer The scroll layer for which to enable or disable paging paging\_enabled True, if paging should be enabled. False to enable. bool scroll\_layer\_get\_paging(ScrollLayer \* scroll\_layer) Check whether or not the ScrollLayer uses paging when pressing buttons. #### Parameters scroll\_layer The scroll layer for which to get the paging behavior. #### Returns True, if paging is enabled; false otherwise. ContentIndicator \* scroll\_layer\_get\_content\_indicator(ScrollLayer \* scroll\_layer) Gets the ContentIndicator for a ScrollLayer. #### Parameters scroll\_layer The ScrollLayer for which to get the ContentIndicator #### Returns A pointer to the ContentIndicator, or `NULL` upon failure. ContentIndicator \* content\_indicator\_create(void) Creates a ContentIndicator on the heap. #### Returns A pointer to the ContentIndicator. `NULL` if the ContentIndicator could not be created. void content\_indicator\_destroy(ContentIndicator \* content\_indicator) Destroys a ContentIndicator previously created using [content\_indicator\_create()](https://developer.repebble.com/docs/c/User_Interface/Layers/ScrollLayer.md#content_indicator_create). #### Parameters content\_indicator The ContentIndicator to destroy. bool content\_indicator\_configure\_direction(ContentIndicator \* content\_indicator, [ContentIndicatorDirection](https://developer.repebble.com/docs/c/User_Interface/Layers/ScrollLayer.md#ContentIndicatorDirection) direction, const [ContentIndicatorConfig](https://developer.repebble.com/docs/c/User_Interface/Layers/ScrollLayer.md#ContentIndicatorConfig) \* config) Configures a ContentIndicator for the given direction. #### Parameters content\_indicator The ContentIndicator to configure. direction The direction for which to configure the ContentIndicator. config The configuration to use to configure the ContentIndicator. If NULL, the data for the specified direction will be reset. #### Returns True if the ContentIndicator was successfully configured for the given direction, false otherwise. bool content\_indicator\_get\_content\_available(ContentIndicator \* content\_indicator, [ContentIndicatorDirection](https://developer.repebble.com/docs/c/User_Interface/Layers/ScrollLayer.md#ContentIndicatorDirection) direction) Retrieves the availability status of content in the given direction. #### Parameters content\_indicator The ContentIndicator for which to get the content availability. direction The direction for which to get the content availability. #### Returns True if content is available in the given direction, false otherwise. void content\_indicator\_set\_content\_available(ContentIndicator \* content\_indicator, [ContentIndicatorDirection](https://developer.repebble.com/docs/c/User_Interface/Layers/ScrollLayer.md#ContentIndicatorDirection) direction, bool available) Sets the availability status of content in the given direction. ##### Note If times\_out is enabled, calling this function resets any previously scheduled timeout timer for the ContentIndicator. #### Parameters content\_indicator The ContentIndicator for which to set the content availability. direction The direction for which to set the content availability. available Whether or not content is available. ## Data Structure Documentation struct ContentIndicatorConfig Struct used to configure directions for ContentIndicator. #### Data Fields Layer \* layer The layer where the arrow indicator will be rendered when content is available. bool times\_out Whether the display of the arrow indicator should timeout. [GAlign](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GAlign) alignment The alignment of the arrow within the provided layer. struct [ContentIndicatorConfig](https://developer.repebble.com/docs/c/User_Interface/Layers/ScrollLayer.md#ContentIndicatorConfig) colors #### See Also [content\_indicator\_configure\_direction](https://developer.repebble.com/docs/c/User_Interface/Layers/ScrollLayer.md#content_indicator_configure_direction) struct ScrollLayerCallbacks All the callbacks that the ScrollLayer exposes for use by applications. ##### Note The context parameter can be set using [scroll\_layer\_set\_context()](https://developer.repebble.com/docs/c/User_Interface/Layers/ScrollLayer.md#scroll_layer_set_context) and gets passed in as context with all of these callbacks. #### Data Fields [ClickConfigProvider](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#ClickConfigProvider) click\_config\_provider Provider function to set up the SELECT button handlers. This will be called after the scroll layer has configured the click configurations for the up/down buttons, so it can also be used to modify the default up/down scrolling behavior. [ScrollLayerCallback](https://developer.repebble.com/docs/c/User_Interface/Layers/ScrollLayer.md#ScrollLayerCallback) content\_offset\_changed\_handler Called every time the the content offset changes. During a scrolling animation, it will be called for each intermediary offset as well. ## Enum Documentation enum ContentIndicatorDirection Value to describe directions for ContentIndicator. content\_indicator\_configure\_direction content\_indicator\_set\_content\_available #### Enumerators ContentIndicatorDirectionUp The up direction. ContentIndicatorDirectionDown The down direction. NumContentIndicatorDirections The number of supported directions. ## Typedef Documentation typedef struct ScrollLayer ScrollLayer typedef void(\* ScrollLayerCallback)(struct ScrollLayer \*scroll\_layer, void \*context) Function signature for the `.content_offset_changed_handler` callback. typedef struct ContentIndicator ContentIndicator --- # SimpleMenuLayer Source: https://developer.repebble.com/docs/c/User_Interface/Layers/SimpleMenuLayer/ Wrapper around [MenuLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md), that uses static data to display a list menu. ![](https://developer.repebble.com/assets/images/docs/c/aplite/simple_menu_layer.png) ![](https://developer.repebble.com/assets/images/docs/c/aplite/simple_menu_layer.png) ![](https://developer.repebble.com/assets/images/docs/c/aplite/simple_menu_layer.png) ![](https://developer.repebble.com/assets/images/docs/c/aplite/simple_menu_layer.png) ![](https://developer.repebble.com/assets/images/docs/c/aplite/simple_menu_layer.png) ## Function Documentation SimpleMenuLayer \* simple\_menu\_layer\_create([GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) frame, Window \* window, const [SimpleMenuSection](https://developer.repebble.com/docs/c/User_Interface/Layers/SimpleMenuLayer.md#SimpleMenuSection) \* sections, int32\_t num\_sections, void \* callback\_context) Creates a new SimpleMenuLayer on the heap and initializes it. It also sets the internal click configuration provider onto given window. ##### Notes The `sections` array is not deep-copied and can therefore not be stack allocated, but needs to be backed by long-lived storage. This function does not add the menu's layer to the window. #### Parameters frame The frame at which to initialize the menu window The window onto which to set the click configuration provider sections Array with sections that need to be displayed in the menu num\_sections The number of sections in the `sections` array. callback\_context Pointer to application specific data, that is passed into the callbacks. #### Returns A pointer to the SimpleMenuLayer. `NULL` if the SimpleMenuLayer could not be created void simple\_menu\_layer\_destroy(SimpleMenuLayer \* menu\_layer) Destroys a SimpleMenuLayer previously created by simple\_menu\_layer\_create. Layer \* simple\_menu\_layer\_get\_layer(const SimpleMenuLayer \* simple\_menu) Gets the "root" Layer of the simple menu layer, which is the parent for the sub-layers used for its implementation. #### Parameters simple\_menu Pointer to the SimpleMenuLayer for which to get the "root" Layer #### Returns The "root" Layer of the menu layer. int simple\_menu\_layer\_get\_selected\_index(const SimpleMenuLayer \* simple\_menu) Gets the row index of the currently selection menu item. #### Parameters simple\_menu The SimpleMenuLayer for which to get the current selected row index. void simple\_menu\_layer\_set\_selected\_index(SimpleMenuLayer \* simple\_menu, int32\_t index, bool animated) Selects the item in the first section at given row index. #### Parameters simple\_menu The SimpleMenuLayer for which to change the selection index The row index of the item to select animated Supply `true` to animate changing the selection, or `false` to change the selection instantly. MenuLayer \* simple\_menu\_layer\_get\_menu\_layer(SimpleMenuLayer \* simple\_menu) #### Parameters simple\_menu The [SimpleMenuLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/SimpleMenuLayer.md) to get the [MenuLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md) from. #### Returns The [MenuLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/MenuLayer.md). ## Data Structure Documentation struct SimpleMenuItem Data structure containing the information of a menu item. #### Data Fields const char \* title The title of the menu item. Required. const char \* subtitle The subtitle of the menu item. Optional, leave `NULL` if unused. GBitmap \* icon The icon of the menu item. Optional, leave `NULL` if unused. [SimpleMenuLayerSelectCallback](https://developer.repebble.com/docs/c/User_Interface/Layers/SimpleMenuLayer.md#SimpleMenuLayerSelectCallback) callback The callback that needs to be called upon a click on the SELECT button. Optional, leave `NULL` if unused. struct SimpleMenuSection Data structure containing the information of a menu section. #### Data Fields const char \* title Title of the section. Optional, leave `NULL` if unused. const [SimpleMenuItem](https://developer.repebble.com/docs/c/User_Interface/Layers/SimpleMenuLayer.md#SimpleMenuItem) \* items Array of items in the section. [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) num\_items Number of items in the `.items` array. ## Typedef Documentation typedef struct SimpleMenuLayer SimpleMenuLayer typedef void(\* SimpleMenuLayerSelectCallback)(int index, void \*context) Function signature for the callback to handle the event that a user hits the SELECT button. #### Parameters index The row index of the item context The callback context --- # Speaker Source: https://developer.repebble.com/docs/c/User_Interface/Speaker/ The APIs on this page will only work with SDK 4.9+. Controlling the speaker The Speaker API provides calls that let you play sounds through the watch's speaker. You can play simple note sequences (melodies), single tones, or stream raw PCM audio. Note sequences are compact representations of melodies using MIDI-like note definitions, supporting 4 basic waveforms: sine, square, triangle, and sawtooth. Raw PCM streaming allows apps to generate arbitrary audio in configurable formats. ## Function Documentation bool speaker\_play\_notes(const [SpeakerNote](https://developer.repebble.com/docs/c/User_Interface/Speaker.md#SpeakerNote) \* notes, [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) num\_notes, uint8\_t volume) Play a sequence of notes on the speaker. #### Parameters notes Array of [SpeakerNote](https://developer.repebble.com/docs/c/User_Interface/Speaker.md#SpeakerNote) structs defining the melody num\_notes Number of notes in the array (max SPEAKER\_MAX\_NOTES) volume Playback volume (0-100) #### Returns true if playback started successfully bool speaker\_play\_tracks(const [SpeakerTrack](https://developer.repebble.com/docs/c/User_Interface/Speaker.md#SpeakerTrack) \* tracks, [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) num\_tracks, uint8\_t volume) Play N monophonic tracks in parallel, mixed (polyphony). #### Parameters tracks Array of track descriptors (notes + optional sample). num\_tracks Number of tracks. Must be \>= 1 and \<= SPEAKER\_MAX\_TRACKS. volume Playback volume (0-100). #### Returns true if playback started successfully. bool speaker\_play\_tone([uint16\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint16_t) frequency\_hz, [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) duration\_ms, uint8\_t volume, SpeakerWaveform waveform) Play a single tone on the speaker (convenience wrapper). #### Parameters frequency\_hz Tone frequency in Hz duration\_ms Tone duration in milliseconds (max 10000) volume Playback volume (0-100) waveform Waveform to use #### Returns true if playback started successfully bool speaker\_stream\_open([SpeakerPcmFormat](https://developer.repebble.com/docs/c/User_Interface/Speaker.md#SpeakerPcmFormat) format, uint8\_t volume) Open a raw PCM stream for app-generated audio. #### Parameters format PCM format specifying sample rate and bit depth volume Playback volume (0-100) #### Returns true if stream opened successfully [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) speaker\_stream\_write(const void \* data, [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) num\_bytes) Write PCM data to the open stream. #### Parameters data Buffer of PCM data in the format specified at open num\_bytes Number of bytes to write #### Returns Number of bytes actually written (may be less if buffer is full) void speaker\_stream\_close(void) Close the PCM stream. Buffered data will be played before stopping. void speaker\_stop(void) Stop any active speaker playback immediately. void speaker\_set\_volume(uint8\_t volume) Set the speaker volume. #### Parameters volume Volume level (0-100) [SpeakerStatus](https://developer.repebble.com/docs/c/User_Interface/Speaker.md#SpeakerStatus) speaker\_get\_status(void) Get the current speaker status. #### Returns Current [SpeakerStatus](https://developer.repebble.com/docs/c/User_Interface/Speaker.md#SpeakerStatus) void speaker\_set\_finish\_callback([SpeakerFinishedCallback](https://developer.repebble.com/docs/c/User_Interface/Speaker.md#SpeakerFinishedCallback) cb, void \* ctx) Register a callback invoked when speaker playback ends. The callback runs on the app task. #### Parameters cb Callback to invoke, or NULL to unregister. ctx User context passed back to cb. bool speaker\_is\_muted(void) Check whether the speaker is currently muted system-wide. The watch can mute the speaker either always-on (Settings → Sounds & Haptics) or for the duration of Quiet Time (Settings → Quiet Time). Apps cannot override the mute, but they can use this to adapt UI or skip long sounds the user won't hear. #### Returns true if the speaker is currently muted ## Data Structure Documentation struct SpeakerNote A single note in a sequence. midi\_note: MIDI note number (0-127, 60=C4). 0 = rest (silence). waveform: SpeakerWaveform value. duration\_ms: Note duration in ms (max 10000). velocity: Volume 0-127 (0 = use global volume). #### Data Fields uint8\_t midi\_noteuint8\_t waveform[uint16\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint16_t) duration\_msuint8\_t velocityuint8\_t reserved struct SpeakerSample A raw PCM sample that can be pitch-shifted when played by a track. data: mono signed PCM in the given format. num\_bytes: size of data in bytes. format: sample rate + bit depth (see [SpeakerPcmFormat](https://developer.repebble.com/docs/c/User_Interface/Speaker.md#SpeakerPcmFormat)). base\_midi\_note: the MIDI note at which the sample plays unshifted (e.g. 60 = C4). Notes above/below this value are produced by resampling. loop: if true, the sample restarts from the beginning each time it runs out, and keeps playing until the owning note's duration elapses. #### Data Fields const void \* data[uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) num\_bytes[SpeakerPcmFormat](https://developer.repebble.com/docs/c/User_Interface/Speaker.md#SpeakerPcmFormat) formatuint8\_t base\_midi\_notebool loop struct SpeakerTrack A single monophonic voice. Multiple tracks are mixed together by [speaker\_play\_tracks()](https://developer.repebble.com/docs/c/User_Interface/Speaker.md#speaker_play_tracks) to produce polyphony. notes: array of notes to play sequentially. num\_notes: length of the notes array. sample: if non-NULL, notes are played by pitch-shifting this sample; note.waveform is ignored. If NULL, notes use their waveform field. #### Data Fields const [SpeakerNote](https://developer.repebble.com/docs/c/User_Interface/Speaker.md#SpeakerNote) \* notes[uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) num\_notesconst [SpeakerSample](https://developer.repebble.com/docs/c/User_Interface/Speaker.md#SpeakerSample) \* sample ## Enum Documentation enum SpeakerWaveform #### Enumerators SpeakerWaveformSineSpeakerWaveformSquareSpeakerWaveformTriangleSpeakerWaveformSawtoothSpeakerWaveformCount enum SpeakerPcmFormat PCM audio format for speaker streaming. Bit layout: bit0 = sample rate (0=8kHz, 1=16kHz), bit1 = bit depth (0=8-bit, 1=16-bit). All formats are mono signed PCM (8-bit samples are signed [-128,127], not unsigned). #### Enumerators SpeakerPcmFormat\_8kHz\_8bit 8kHz 8-bit signed (1 byte/sample) SpeakerPcmFormat\_16kHz\_8bit 16kHz 8-bit signed (1 byte/sample) SpeakerPcmFormat\_8kHz\_16bit 8kHz 16-bit signed little-endian (2 bytes/sample) SpeakerPcmFormat\_16kHz\_16bit 16kHz 16-bit signed little-endian (2 bytes/sample) SpeakerPcmFormatCount enum SpeakerStatus Speaker status. #### Enumerators SpeakerStatusIdleSpeakerStatusPlayingSpeakerStatusDraining enum SpeakerFinishReason Reason reported when speaker playback ends. #### Enumerators SpeakerFinishReasonDone Playback completed naturally. SpeakerFinishReasonStopped Playback was stopped by the app. SpeakerFinishReasonPreempted Preempted by higher priority source. SpeakerFinishReasonError An error occurred. ## Typedef Documentation typedef void(\* SpeakerFinishedCallback)(SpeakerFinishReason reason, void \*ctx) Callback invoked when playback finishes. #### Parameters reason Why playback ended ctx User context ## Macro Definition Documentation #define SPEAKER\_MAX\_NOTES 256 Maximum number of notes in a single [speaker\_play\_notes()](https://developer.repebble.com/docs/c/User_Interface/Speaker.md#speaker_play_notes) call. #define SPEAKER\_MAX\_TRACKS 4 Maximum number of parallel tracks in a single [speaker\_play\_tracks()](https://developer.repebble.com/docs/c/User_Interface/Speaker.md#speaker_play_tracks) call. #define SPEAKER\_MAX\_SAMPLE\_BYTES\_TOTAL (16 \* 1024) Maximum total sample-data bytes across all tracks in one [speaker\_play\_tracks()](https://developer.repebble.com/docs/c/User_Interface/Speaker.md#speaker_play_tracks) call. --- # Standard C Source: https://developer.repebble.com/docs/c/Standard_C/ Standard C types, functions, constants, etc. The standard C functions available here, such as [snprintf()](https://developer.repebble.com/docs/c/Standard_C/Format.md#snprintf) and [time()](https://developer.repebble.com/docs/c/Standard_C/Time.md#time), are provided by the firmware. Using these functions will not significantly increase the size of your app beyond what is needed to call the function. You may use other standard C functions not listed here, but be aware that not all will successfully be added to your app, and if they are added, your app's binary size will increase accordingly. ## Modules #### [Format](https://developer.repebble.com/docs/c/Standard_C/Format.md) Standard formatting. #### [Locale](https://developer.repebble.com/docs/c/Standard_C/Locale.md) Standard locale functions. #### [Math](https://developer.repebble.com/docs/c/Standard_C/Math.md) Standard math functions. #### [Memory](https://developer.repebble.com/docs/c/Standard_C/Memory.md) Standard memory functions. #### [String](https://developer.repebble.com/docs/c/Standard_C/String.md) Standard C-string manipulation. #### [Time](https://developer.repebble.com/docs/c/Standard_C/Time.md)   ## Typedef Documentation typedef int uint16\_t 16-bit unsigned integer number typedef int uint32\_t 32-bit unsigned integer number --- # StatusBarLayer Source: https://developer.repebble.com/docs/c/User_Interface/Layers/StatusBarLayer/ Layer that serves as a configurable status bar. ## Function Documentation StatusBarLayer \* status\_bar\_layer\_create(void) Creates a new StatusBarLayer on the heap and initializes it with the default values. - Text color: [GColorBlack](https://developer.repebble.com/docs/c/Graphics/Graphics_Types/Color_Definitions.md#GColorBlack) - Background color: [GColorWhite](https://developer.repebble.com/docs/c/Graphics/Graphics_Types/Color_Definitions.md#GColorWhite) - Frame: `GRect(0, 0, screen_width, STATUS_BAR_LAYER_HEIGHT)` The status bar is automatically marked dirty after this operation. You can call [layer\_set\_frame()](https://developer.repebble.com/docs/c/User_Interface/Layers.md#layer_set_frame) to create a StatusBarLayer of a different width. ``` // Change the status bar width to make space for the action barint16\_t width = layer\_get\_bounds(root\_layer).size.w - ACTION\_BAR\_WIDTH;GRect frame = GRect(0, 0, width, STATUS\_BAR\_LAYER\_HEIGHT);layer\_set\_frame(status\_bar\_layer\_get\_layer(status\_bar), frame);layer\_add\_child(root\_layer, status\_bar\_layer\_get\_layer(status\_bar)); ``` #### Returns A pointer to the StatusBarLayer, which will be allocated to the heap, `NULL` if the StatusBarLayer could not be created void status\_bar\_layer\_destroy(StatusBarLayer \* status\_bar\_layer) Destroys a StatusBarLayer previously created by status\_bar\_layer\_create. #### Parameters status\_bar\_layer The StatusBarLayer to destroy Layer \* status\_bar\_layer\_get\_layer(StatusBarLayer \* status\_bar\_layer) Gets the "root" Layer of the status bar, which is the parent for the sub- layers used for its implementation. ##### Note The result is always equal to `(Layer *) status_bar_layer`. #### Parameters status\_bar\_layer Pointer to the StatusBarLayer for which to get the "root" Layer #### Returns The "root" Layer of the status bar. GColor status\_bar\_layer\_get\_background\_color(const StatusBarLayer \* status\_bar\_layer) Gets background color of StatusBarLayer. #### Parameters status\_bar\_layer The StatusBarLayer of which to get the color #### Returns GColor of background color property GColor status\_bar\_layer\_get\_foreground\_color(const StatusBarLayer \* status\_bar\_layer) Gets foreground color of StatusBarLayer. #### Parameters status\_bar\_layer The StatusBarLayer of which to get the color #### Returns GColor of foreground color property void status\_bar\_layer\_set\_colors(StatusBarLayer \* status\_bar\_layer, GColor background, GColor foreground) Sets the background and foreground colors of StatusBarLayer. #### Parameters status\_bar\_layer The StatusBarLayer of which to set the colors background The new GColor to set for background foreground The new GColor to set for text and other foreground elements void status\_bar\_layer\_set\_separator\_mode(StatusBarLayer \* status\_bar\_layer, [StatusBarLayerSeparatorMode](https://developer.repebble.com/docs/c/User_Interface/Layers/StatusBarLayer.md#StatusBarLayerSeparatorMode) mode) Sets the mode of the StatusBarLayer separator, to help divide it from content. #### Parameters status\_bar\_layer The StatusBarLayer of which to set the separator mode mode Determines the separator mode ## Enum Documentation enum StatusBarLayerSeparatorMode Values that are used to indicate the different status bar separator modes. #### Enumerators StatusBarLayerSeparatorModeNone The default mode. No separator will be shown. StatusBarLayerSeparatorModeDotted A dotted separator at the bottom of the status bar. ## Typedef Documentation typedef struct StatusBarLayer StatusBarLayer ## Macro Definition Documentation #define STATUS\_BAR\_LAYER\_HEIGHT [\_STATUS\_BAR\_LAYER\_HEIGHT](https://developer.repebble.com/docs/c/User_Interface/Layers/StatusBarLayer.md#_STATUS_BAR_LAYER_HEIGHT)(PBL\_PLATFORM\_TYPE\_CURRENT) The fixed height of the status bar, including separator height. - [SDK 3](javascript:void(0);) - [SDK 4](javascript:void(0);) - [SDK 4.9+](javascript:void(0);) #define \_STATUS\_BAR\_LAYER\_HEIGHT ( plat) The fixed height of the status bar, including separator height, for all platforms. #define \_STATUS\_BAR\_LAYER\_HEIGHT ( plat) The fixed height of the status bar, including separator height, for all platforms. #define \_STATUS\_BAR\_LAYER\_HEIGHT ( plat) The fixed height of the status bar, including separator height, for all platforms. --- # Storage Source: https://developer.repebble.com/docs/c/Foundation/Storage/ A mechanism to store persistent application data and state The Persistent Storage API provides you with a mechanism for performing a variety of tasks, like saving user settings, caching data from the phone app, or counting high scores for Pebble watchapp games. In Pebble OS, storage is defined by a collection of fields that you can create, modify or delete. In the API, a field is specified as a key with a corresponding value. Using the Storage API, every app is able to get its own persistent storage space. Each value in that space is associated with a [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) key. Storage supports saving integers, strings and byte arrays. The maximum size of byte arrays and strings is defined by PERSIST\_DATA\_MAX\_LENGTH (currently set to 256 bytes). You call the function persist\_exists(key), which returns a boolean indicating if the key exists or not. The Storage API enables your app to save its state, and when compared to using [AppMessage](https://developer.repebble.com/docs/c/Foundation/AppMessage.md) to retrieve values from the phone, it provides you with a much faster way to restore state. In addition, it draws less power from the battery. The total size of an app's persisted values is capped; call [persist\_get\_max\_size](https://developer.repebble.com/docs/c/Foundation/Storage.md#persist_get_max_size) to query the limit at runtime. ## Function Documentation bool persist\_exists(const [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) key) Checks whether a value has been set for a given key in persistent storage. #### Parameters key The key of the field to check. #### Returns true if a value exists, otherwise false. int persist\_get\_size(const [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) key) Gets the size of a value for a given key in persistent storage. #### Parameters key The key of the field to lookup the data size. #### Returns The size of the value in bytes or E\_DOES\_NOT\_EXIST if there is no field matching the given key. bool persist\_read\_bool(const [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) key) Reads a bool value for a given key from persistent storage. If the value has not yet been set, this will return false. #### Parameters key The key of the field to read from. #### Returns The bool value of the key to read from. int32\_t persist\_read\_int(const [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) key) Reads an int value for a given key from persistent storage. ##### Note The int is a signed 32-bit integer. If the value has not yet been set, this will return 0. #### Parameters key The key of the field to read from. #### Returns The int value of the key to read from. int persist\_read\_data(const [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) key, void \* buffer, const [size\_t](https://developer.repebble.com/docs/c/Standard_C/Memory.md#size_t) buffer\_size) Reads a blob of data for a given key from persistent storage into a given buffer. If the value has not yet been set, the given buffer is left unchanged. #### Parameters key The key of the field to read from. buffer The pointer to a buffer to be written to. buffer\_size The maximum size of the given buffer. #### Returns The number of bytes written into the buffer or E\_DOES\_NOT\_EXIST if there is no field matching the given key. int persist\_read\_string(const [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) key, char \* buffer, const [size\_t](https://developer.repebble.com/docs/c/Standard_C/Memory.md#size_t) buffer\_size) Reads a string for a given key from persistent storage into a given buffer. The string will be null terminated. If the value has not yet been set, the given buffer is left unchanged. #### Parameters key The key of the field to read from. buffer The pointer to a buffer to be written to. buffer\_size The maximum size of the given buffer. This includes the null character. #### Returns The number of bytes written into the buffer or E\_DOES\_NOT\_EXIST if there is no field matching the given key. [status\_t](https://developer.repebble.com/docs/c/Foundation/Storage.md#status_t) persist\_write\_bool(const [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) key, const bool value) Writes a bool value flag for a given key into persistent storage. #### Parameters key The key of the field to write to. value The boolean value to write. #### Returns The number of bytes written if successful, a value from [StatusCode](https://developer.repebble.com/docs/c/Foundation/Storage.md#StatusCode) otherwise. [status\_t](https://developer.repebble.com/docs/c/Foundation/Storage.md#status_t) persist\_write\_int(const [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) key, const int32\_t value) Writes an int value for a given key into persistent storage. ##### Note The int is a signed 32-bit integer. #### Parameters key The key of the field to write to. value The int value to write. #### Returns The number of bytes written if successful, a value from [StatusCode](https://developer.repebble.com/docs/c/Foundation/Storage.md#StatusCode) otherwise. int persist\_write\_data(const [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) key, const void \* data, const [size\_t](https://developer.repebble.com/docs/c/Standard_C/Memory.md#size_t) size) Writes a blob of data of a specified size in bytes for a given key into persistent storage. The maximum size is [PERSIST\_DATA\_MAX\_LENGTH](https://developer.repebble.com/docs/c/Foundation/Storage.md#PERSIST_DATA_MAX_LENGTH). #### Parameters key The key of the field to write to. data The pointer to the blob of data. size The size in bytes. #### Returns The number of bytes written if successful, a value from [StatusCode](https://developer.repebble.com/docs/c/Foundation/Storage.md#StatusCode) otherwise. int persist\_write\_string(const [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) key, const char \* cstring) Writes a string a given key into persistent storage. The maximum size is [PERSIST\_STRING\_MAX\_LENGTH](https://developer.repebble.com/docs/c/Foundation/Storage.md#PERSIST_STRING_MAX_LENGTH) including the null terminator. #### Parameters key The key of the field to write to. cstring The pointer to null terminated string. #### Returns The number of bytes written if successful, a value from [StatusCode](https://developer.repebble.com/docs/c/Foundation/Storage.md#StatusCode) otherwise. - [SDK 3](javascript:void(0);) - [SDK 4](javascript:void(0);) - [SDK 4.9+](javascript:void(0);) [status\_t](https://developer.repebble.com/docs/c/Foundation/Storage.md#status_t) persist\_delete(const [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) key) Deletes the value of a key from persistent storage. #### Parameters key The key of the field to delete from. [status\_t](https://developer.repebble.com/docs/c/Foundation/Storage.md#status_t) persist\_delete(const [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) key) Deletes the value of a key from persistent storage. #### Parameters key The key of the field to delete from. [status\_t](https://developer.repebble.com/docs/c/Foundation/Storage.md#status_t) persist\_delete(const [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) key) Deletes the value of a key from persistent storage. #### Parameters key The key of the field to delete from. #### Returns S\_TRUE if successful, E\_DOES\_NOT\_EXIST if a value was not set, or another error value from [StatusCode](https://developer.repebble.com/docs/c/Foundation/Storage.md#StatusCode). [size\_t](https://developer.repebble.com/docs/c/Standard_C/Memory.md#size_t) persist\_get\_max\_size(void) Gets the maximum total size in bytes of all persisted values for the current app on this firmware. Apps targeting older SDKs that don't have this function should assume a 4 KB limit. #### Returns The per-app persistent storage capacity in bytes. ## Enum Documentation enum StatusCode Status codes. See [status\_t](https://developer.repebble.com/docs/c/Foundation/Storage.md#status_t). #### Enumerators S\_SUCCESS Operation completed successfully. E\_ERROR An error occurred (no description). E\_UNKNOWN No idea what went wrong. E\_INTERNAL There was a generic internal logic error. E\_INVALID\_ARGUMENT The function was not called correctly. E\_OUT\_OF\_MEMORY Insufficient allocatable memory available. E\_OUT\_OF\_STORAGE Insufficient long-term storage available. E\_OUT\_OF\_RESOURCES Insufficient resources available. E\_RANGE Argument out of range (may be dynamic). E\_DOES\_NOT\_EXIST Target of operation does not exist. E\_INVALID\_OPERATION Operation not allowed (may depend on state). E\_BUSY Another operation prevented this one. E\_AGAIN Operation not completed; try again. S\_TRUE Equivalent of boolean true. S\_FALSE Equivalent of boolean false. S\_NO\_MORE\_ITEMS For list-style requests. At end of list. S\_NO\_ACTION\_REQUIRED No action was taken as none was required. ## Typedef Documentation typedef int32\_t status\_t Return value for system operations. See [StatusCode](https://developer.repebble.com/docs/c/Foundation/Storage.md#StatusCode) for possible values. ## Macro Definition Documentation #define PERSIST\_DATA\_MAX\_LENGTH 256 The maximum size of a persist value in bytes. #define PERSIST\_STRING\_MAX\_LENGTH [PERSIST\_DATA\_MAX\_LENGTH](https://developer.repebble.com/docs/c/Foundation/Storage.md#PERSIST_DATA_MAX_LENGTH) The maximum size of a persist string in bytes including the NULL terminator. --- # String Source: https://developer.repebble.com/docs/c/Standard_C/String/ Standard C-string manipulation. ## Function Documentation int strcmp(const char \* str1, const char \* str2) Compares the null terminated strings str1 and str2 to each other. #### Parameters str1 The first C string to compare str2 The second C string to compare #### Returns The difference of the first differing pair of bytes or 0 if the strings are identical int strncmp(const char \* str1, const char \* str2, [size\_t](https://developer.repebble.com/docs/c/Standard_C/Memory.md#size_t) n) Compares the null terminated strings str1 and str2 to each other for up to n bytes. Comparison ends when a null is read or when n bytes are read, whichever happens first. #### Parameters str1 The first C string to compare str2 The second C string to compare n The maximum number of bytes to compare #### Returns The difference of the first differing pair of bytes or the final pair of bytes read or 0 if the portions of the strings read are identical char \* strcpy(char \* dest, const char \* src) Copies the string in src into dest and null terminates dest. There should be no overlap of dest and src in memory. #### Parameters dest The destination buffer with enough space for src src The source C string #### Returns The destination buffer dest char \* strncpy(char \* dest, const char \* src, [size\_t](https://developer.repebble.com/docs/c/Standard_C/Memory.md#size_t) n) Copies up to n bytes from the string in src into dest and null terminates dest. If dest is null terminated before n bytes have been written, null bytes will continue to be written until n bytes total were written. There should be no overlap of dest and src in memory. #### Parameters dest The destination buffer with enough space for n bytes src The source string n The number of bytes to copy #### Returns The destination buffer dest char \* strcat(char \* dest, const char \* src) Concatenates the string in src to the end of the string pointed by dest and null terminates dest. There should be no overlap of dest and src. #### Parameters dest The destination buffer with enough space for src beyond the null character src The source C string #### Returns The destination buffer dest char \* strncat(char \* dest, const char \* src, [size\_t](https://developer.repebble.com/docs/c/Standard_C/Memory.md#size_t) n) Concatenates up to n bytes from the string in src to the end of the string pointed by dest and null terminates dest. There should be no overlap of dest and src in memeory. #### Parameters dest The destination buffer with enough space for src beyond the null character src The source string n The maximum number of bytes to copy #### Returns The destination buffer dest [size\_t](https://developer.repebble.com/docs/c/Standard_C/Memory.md#size_t) strlen(const char \* str) Calculates the length of a null terminated string. #### Parameters str The C string. #### Returns The length of the C string str. --- # TextLayer Source: https://developer.repebble.com/docs/c/User_Interface/Layers/TextLayer/ Layer that displays and formats a text string. ![](https://developer.repebble.com/assets/images/docs/c/aplite/text_layer.png) ![](https://developer.repebble.com/assets/images/docs/c/aplite/text_layer.png) ![](https://developer.repebble.com/assets/images/docs/c/aplite/text_layer.png) ![](https://developer.repebble.com/assets/images/docs/c/aplite/text_layer.png) ![](https://developer.repebble.com/assets/images/docs/c/aplite/text_layer.png) The geometric information (bounds, frame) of the Layer is used as the "box" in which the text is drawn. The [TextLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/TextLayer.md) also has a number of other properties that influence how the text is drawn. Most important of these properties are: a pointer to the string to draw itself, the font, the text color, the background color of the layer, the overflow mode and alignment of the text inside the layer. ## Function Documentation TextLayer \* text\_layer\_create([GRect](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GRect) frame) Creates a new TextLayer on the heap and initializes it with the default values. - Font: Raster Gothic 14-point Boldface (system font) - Text Alignment: GTextAlignmentLeft - Text color: [GColorBlack](https://developer.repebble.com/docs/c/Graphics/Graphics_Types/Color_Definitions.md#GColorBlack) - Background color: [GColorWhite](https://developer.repebble.com/docs/c/Graphics/Graphics_Types/Color_Definitions.md#GColorWhite) - Clips: `true` - Hidden: `false` - Caching: `false` The text layer is automatically marked dirty after this operation. #### Parameters frame The frame with which to initialze the TextLayer #### Returns A pointer to the TextLayer. `NULL` if the TextLayer could not be created void text\_layer\_destroy(TextLayer \* text\_layer) Destroys a TextLayer previously created by text\_layer\_create. Layer \* text\_layer\_get\_layer(TextLayer \* text\_layer) Gets the "root" Layer of the text layer, which is the parent for the sub- layers used for its implementation. #### Parameters text\_layer Pointer to the TextLayer for which to get the "root" Layer #### Returns The "root" Layer of the text layer. void text\_layer\_set\_text(TextLayer \* text\_layer, const char \* text) Sets the pointer to the string where the TextLayer is supposed to find the text at a later point in time, when it needs to draw itself. ##### Note The string is not copied, so its buffer most likely cannot be stack allocated, but is recommended to be a buffer that is long-lived, at least as long as the TextLayer is part of a visible Layer hierarchy. #### Parameters text\_layer The TextLayer of which to set the text text The new text to set onto the TextLayer. This must be a null-terminated and valid UTF-8 string! #### See Also [text\_layer\_get\_text](https://developer.repebble.com/docs/c/User_Interface/Layers/TextLayer.md#text_layer_get_text) const char \* text\_layer\_get\_text(TextLayer \* text\_layer) Gets the pointer to the string that the TextLayer is using. #### Parameters text\_layer The TextLayer for which to get the text #### See Also [text\_layer\_set\_text](https://developer.repebble.com/docs/c/User_Interface/Layers/TextLayer.md#text_layer_set_text) void text\_layer\_set\_background\_color(TextLayer \* text\_layer, GColor color) Sets the background color of the bounding box that will be drawn behind the text. #### Parameters text\_layer The TextLayer of which to set the background color color The new GColor to set the background to #### See Also [text\_layer\_set\_text\_color](https://developer.repebble.com/docs/c/User_Interface/Layers/TextLayer.md#text_layer_set_text_color) void text\_layer\_set\_text\_color(TextLayer \* text\_layer, GColor color) Sets the color of text that will be drawn. #### Parameters text\_layer The TextLayer of which to set the text color color The new GColor to set the text color to #### See Also [text\_layer\_set\_background\_color](https://developer.repebble.com/docs/c/User_Interface/Layers/TextLayer.md#text_layer_set_background_color) void text\_layer\_set\_overflow\_mode(TextLayer \* text\_layer, [GTextOverflowMode](https://developer.repebble.com/docs/c/Graphics/Drawing_Text.md#GTextOverflowMode) line\_mode) Sets the line break mode of the TextLayer. #### Parameters text\_layer The TextLayer of which to set the overflow mode line\_mode The new [GTextOverflowMode](https://developer.repebble.com/docs/c/Graphics/Drawing_Text.md#GTextOverflowMode) to set void text\_layer\_set\_font(TextLayer \* text\_layer, [GFont](https://developer.repebble.com/docs/c/Graphics/Fonts.md#GFont) font) Sets the font of the TextLayer. #### Parameters text\_layer The TextLayer of which to set the font font The new [GFont](https://developer.repebble.com/docs/c/Graphics/Fonts.md#GFont) for the TextLayer #### See Also [fonts\_get\_system\_font](https://developer.repebble.com/docs/c/Graphics/Fonts.md#fonts_get_system_font) [fonts\_load\_custom\_font](https://developer.repebble.com/docs/c/Graphics/Fonts.md#fonts_load_custom_font) void text\_layer\_set\_text\_alignment(TextLayer \* text\_layer, [GTextAlignment](https://developer.repebble.com/docs/c/Graphics/Drawing_Text.md#GTextAlignment) text\_alignment) Sets the alignment of the TextLayer. #### Parameters text\_layer The TextLayer of which to set the alignment text\_alignment The new text alignment for the TextLayer #### See Also [GTextAlignment](https://developer.repebble.com/docs/c/Graphics/Drawing_Text.md#GTextAlignment) void text\_layer\_enable\_screen\_text\_flow\_and\_paging(TextLayer \* text\_layer, uint8\_t inset) Enables text flow following the boundaries of the screen and pagination that introduces extra line spacing at page breaks to avoid partially clipped lines for the TextLayer. If the TextLayer is part of a [ScrollLayer](https://developer.repebble.com/docs/c/User_Interface/Layers/ScrollLayer.md) the ScrollLayer's frame will be used to configure paging. ##### Note Make sure the TextLayer is part of the view hierarchy before calling this function. Otherwise it has no effect. #### Parameters text\_layer The TextLayer for which to enable text flow and paging inset Additional amount of pixels to inset to the inside of the screen for text flow #### See Also [text\_layer\_restore\_default\_text\_flow\_and\_paging](https://developer.repebble.com/docs/c/User_Interface/Layers/TextLayer.md#text_layer_restore_default_text_flow_and_paging) [graphics\_text\_attributes\_enable\_screen\_text\_flow](https://developer.repebble.com/docs/c/Graphics/Drawing_Text.md#graphics_text_attributes_enable_screen_text_flow) [graphics\_text\_attributes\_enable\_paging](https://developer.repebble.com/docs/c/Graphics/Drawing_Text.md#graphics_text_attributes_enable_paging) void text\_layer\_restore\_default\_text\_flow\_and\_paging(TextLayer \* text\_layer) Restores text flow and paging for the TextLayer to the rectangular defaults. #### Parameters text\_layer The TextLayer for which to restore text flow and paging #### See Also [text\_layer\_enable\_screen\_text\_flow\_and\_paging](https://developer.repebble.com/docs/c/User_Interface/Layers/TextLayer.md#text_layer_enable_screen_text_flow_and_paging) [graphics\_text\_attributes\_restore\_default\_text\_flow](https://developer.repebble.com/docs/c/Graphics/Drawing_Text.md#graphics_text_attributes_restore_default_text_flow) [graphics\_text\_attributes\_restore\_default\_paging](https://developer.repebble.com/docs/c/Graphics/Drawing_Text.md#graphics_text_attributes_restore_default_paging) [GSize](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GSize) text\_layer\_get\_content\_size(TextLayer \* text\_layer) Calculates the size occupied by the current text of the TextLayer. #### Parameters text\_layer the TextLayer for which to calculate the text's size #### Returns The size occupied by the current text of the TextLayer void text\_layer\_set\_size(TextLayer \* text\_layer, const [GSize](https://developer.repebble.com/docs/c/Graphics/Graphics_Types.md#GSize) max\_size) Update the size of the text layer This is a convenience function to update the frame of the TextLayer. #### Parameters text\_layer The TextLayer of which to set the size max\_size The new size for the TextLayer ## Typedef Documentation typedef struct TextLayer TextLayer --- # TickTimerService Source: https://developer.repebble.com/docs/c/Foundation/Event_Service/TickTimerService/ Handling time components The TickTimerService allows your app to be called every time one Time component has changed. This is extremely important for watchfaces. Your app can choose on which time component change a tick should occur. Time components are defined by a [TimeUnits](https://developer.repebble.com/docs/c/Foundation/Event_Service/TickTimerService.md#TimeUnits) enum bitmask. ## Function Documentation void tick\_timer\_service\_subscribe([TimeUnits](https://developer.repebble.com/docs/c/Foundation/Event_Service/TickTimerService.md#TimeUnits) tick\_units, [TickHandler](https://developer.repebble.com/docs/c/Foundation/Event_Service/TickTimerService.md#TickHandler) handler) Subscribe to the tick timer event service. Once subscribed, the handler gets called on every requested unit change. Calling this function multiple times will override the units and handler (i.e., only  the last tick\_units and handler passed will be used). #### Parameters handler The callback to be executed on tick events tick\_units a bitmask of all the units that have changed void tick\_timer\_service\_unsubscribe(void) Unsubscribe from the tick timer event service. Once unsubscribed, the previously registered handler will no longer be called. ## Enum Documentation enum TimeUnits Time unit flags that can be used to create a bitmask for use in [tick\_timer\_service\_subscribe()](https://developer.repebble.com/docs/c/Foundation/Event_Service/TickTimerService.md#tick_timer_service_subscribe). This will also be passed to [TickHandler](https://developer.repebble.com/docs/c/Foundation/Event_Service/TickTimerService.md#TickHandler). #### Enumerators SECOND\_UNIT Flag to represent the "seconds" time unit. MINUTE\_UNIT Flag to represent the "minutes" time unit. HOUR\_UNIT Flag to represent the "hours" time unit. DAY\_UNIT Flag to represent the "days" time unit. MONTH\_UNIT Flag to represent the "months" time unit. YEAR\_UNIT Flag to represent the "years" time unit. ## Typedef Documentation typedef void(\* TickHandler)(struct tm \*tick\_time, TimeUnits units\_changed) Callback type for tick timer events. #### Parameters tick\_time the time at which the tick event was triggered units\_changed which unit change triggered this tick event --- # Time Source: https://developer.repebble.com/docs/c/Standard_C/Time/ Standard system time functions This module contains standard time functions and formatters for printing. Note that Pebble now supports both local time and UTC time (including timezones and daylight savings time). Most of these functions are part of the C standard library which is documented at [https://sourceware.org/newlib/libc.html#Timefns](https://sourceware.org/newlib/libc.html#Timefns) ## Function Documentation - [SDK 3](javascript:void(0);) - [SDK 4](javascript:void(0);) - [SDK 4.9+](javascript:void(0);) int strftime(char \* s, [size\_t](https://developer.repebble.com/docs/c/Standard_C/Memory.md#size_t) maxsize, const char \* format, const struct tm \* tm\_p) Format the time value at tm according to fmt and place the result in a buffer s of size max. #### Parameters s A preallocation char array of size max maxsize the size of the array s format a formatting string tm\_p A pointer to a struct tm containing a broken out time value #### Returns The number of bytes placed in the array s, not including the null byte, 0 if the value does not fit. int strftime(char \* s, [size\_t](https://developer.repebble.com/docs/c/Standard_C/Memory.md#size_t) maxsize, const char \* format, const struct tm \* tm\_p) Format the time value at tm according to fmt and place the result in a buffer s of size max. #### Parameters s A preallocation char array of size max maxsize the size of the array s format a formatting string tm\_p A pointer to a struct tm containing a broken out time value #### Returns The number of bytes placed in the array s, not including the null byte, 0 if the value does not fit. [size\_t](https://developer.repebble.com/docs/c/Standard_C/Memory.md#size_t) strftime(char \* s, [size\_t](https://developer.repebble.com/docs/c/Standard_C/Memory.md#size_t) maxsize, const char \* format, const struct tm \* tm\_p) Format the time value at tm according to fmt and place the result in a buffer s of size max. #### Parameters s A preallocation char array of size max maxsize the size of the array s format a formatting string tm\_p A pointer to a struct tm containing a broken out time value #### Returns The number of bytes placed in the array s, not including the null byte, 0 if the value does not fit. struct tm \* localtime(const [time\_t](https://developer.repebble.com/docs/c/Standard_C/Time.md#time_t) \* timep) convert the time value pointed at by clock to a struct tm which contains the time adjusted for the local timezone #### Parameters timep A pointer to an object of type [time\_t](https://developer.repebble.com/docs/c/Standard_C/Time.md#time_t) that contains a time value #### Returns A pointer to a struct tm containing the broken out time value adjusted for the local timezone struct tm \* gmtime(const [time\_t](https://developer.repebble.com/docs/c/Standard_C/Time.md#time_t) \* timep) convert the time value pointed at by clock to a struct tm which contains the time expressed in Coordinated Universal Time (UTC) #### Parameters timep A pointer to an object of type [time\_t](https://developer.repebble.com/docs/c/Standard_C/Time.md#time_t) that contains a time value #### Returns A pointer to a struct tm containing Coordinated Universal Time (UTC) [time\_t](https://developer.repebble.com/docs/c/Standard_C/Time.md#time_t) mktime(struct tm \* tb) convert the broken-down time structure to a timestamp expressed in Coordinated Universal Time (UTC) #### Parameters tb A pointer to an object of type tm that contains broken-down time #### Returns The number of seconds since epoch, January 1st 1970 [time\_t](https://developer.repebble.com/docs/c/Standard_C/Time.md#time_t) time([time\_t](https://developer.repebble.com/docs/c/Standard_C/Time.md#time_t) \* tloc) Obtain the number of seconds since epoch. Note that the epoch is not adjusted for Timezones and Daylight Savings. #### Parameters tloc Optionally points to an address of a [time\_t](https://developer.repebble.com/docs/c/Standard_C/Time.md#time_t) variable to store the time in. If you only want to use the return value, you may pass NULL into tloc instead #### Returns The number of seconds since epoch, January 1st 1970 double difftime([time\_t](https://developer.repebble.com/docs/c/Standard_C/Time.md#time_t) end, [time\_t](https://developer.repebble.com/docs/c/Standard_C/Time.md#time_t) beginning) Obtain the number of seconds elapsed between beginning and end represented as a double. ##### Note Pebble uses software floating point emulation. Including this function which returns a double will significantly increase the size of your binary. We recommend directly subtracting both timestamps to calculate a time difference. ``` int difference = ts1 - ts2; ``` #### Parameters end A [time\_t](https://developer.repebble.com/docs/c/Standard_C/Time.md#time_t) variable representing some number of seconds since epoch, January 1st 1970 beginning A [time\_t](https://developer.repebble.com/docs/c/Standard_C/Time.md#time_t) variable representing some number of seconds since epoch, January 1st 1970. Note that end should be greater than beginning, but this is not enforced. #### Returns The number of seconds elapsed between beginning and end. - [SDK 3](javascript:void(0);) - [SDK 4](javascript:void(0);) - [SDK 4.9+](javascript:void(0);) [uint16\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint16_t) time\_ms([time\_t](https://developer.repebble.com/docs/c/Standard_C/Time.md#time_t) \* t\_utc, [uint16\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint16_t) \* out\_ms) Obtain the number of seconds and milliseconds part since the epoch. This is a non-standard C function provided for convenience. #### Parameters tloc Optionally points to an address of a [time\_t](https://developer.repebble.com/docs/c/Standard_C/Time.md#time_t) variable to store the time in. You may pass NULL into tloc if you don't need a [time\_t](https://developer.repebble.com/docs/c/Standard_C/Time.md#time_t) variable to be set with the seconds since the epoch out\_ms Optionally points to an address of a [uint16\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint16_t) variable to store the number of milliseconds since the last second in. If you only want to use the return value, you may pass NULL into out\_ms instead #### Returns The number of milliseconds since the last second [uint16\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint16_t) time\_ms([time\_t](https://developer.repebble.com/docs/c/Standard_C/Time.md#time_t) \* t\_utc, [uint16\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint16_t) \* out\_ms) Obtain the number of seconds and milliseconds part since the epoch. This is a non-standard C function provided for convenience. #### Parameters tloc Optionally points to an address of a [time\_t](https://developer.repebble.com/docs/c/Standard_C/Time.md#time_t) variable to store the time in. You may pass NULL into tloc if you don't need a [time\_t](https://developer.repebble.com/docs/c/Standard_C/Time.md#time_t) variable to be set with the seconds since the epoch out\_ms Optionally points to an address of a [uint16\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint16_t) variable to store the number of milliseconds since the last second in. If you only want to use the return value, you may pass NULL into out\_ms instead #### Returns The number of milliseconds since the last second [uint16\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint16_t) time\_ms([time\_t](https://developer.repebble.com/docs/c/Standard_C/Time.md#time_t) \* tloc, [uint16\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint16_t) \* out\_ms) Obtain the number of seconds and milliseconds part since the epoch. This is a non-standard C function provided for convenience. #### Parameters tloc if provided receives the current UTC Unix Time seconds portion out\_ms if provided receives the current Unix Time milliseconds portion #### Returns Current Unix Time milliseconds portion [time\_t](https://developer.repebble.com/docs/c/Standard_C/Time.md#time_t) time\_start\_of\_today(void) Return the UTC time that corresponds to the start of today (midnight). #### Returns the UTC time corresponding to the start of today (midnight) ## Typedef Documentation typedef unsigned int time\_t time in seconds since the epoch, January 1st 1970 ## Macro Definition Documentation #define TZ\_LEN 6 #define SECONDS\_PER\_MINUTE (60) #define MINUTES\_PER\_HOUR (60) #define SECONDS\_PER\_HOUR (SECONDS\_PER\_MINUTE \* MINUTES\_PER\_HOUR) #define HOURS\_PER\_DAY (24) #define MINUTES\_PER\_DAY (HOURS\_PER\_DAY \* MINUTES\_PER\_HOUR) #define SECONDS\_PER\_DAY (MINUTES\_PER\_DAY \* SECONDS\_PER\_MINUTE) --- # Timer Source: https://developer.repebble.com/docs/c/Foundation/Timer/ Can be used to execute some code at some point in the future. ## Function Documentation void psleep(int millis) Waits for a certain amount of milliseconds. #### Parameters millis The number of milliseconds to wait for AppTimer \* app\_timer\_register([uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) timeout\_ms, [AppTimerCallback](https://developer.repebble.com/docs/c/Foundation/Timer.md#AppTimerCallback) callback, void \* callback\_data) Registers a timer that ends up in callback being called some specified time in the future. #### Parameters timeout\_ms The expiry time in milliseconds from the current time callback The callback that gets called at expiry time callback\_data The data that will be passed to callback #### Returns A pointer to an `AppTimer` that can be used to later reschedule or cancel this timer - [SDK 3](javascript:void(0);) - [SDK 4](javascript:void(0);) - [SDK 4.9+](javascript:void(0);) bool app\_timer\_reschedule(AppTimer \* timer\_handle, [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) new\_timeout\_ms) Reschedules an already running timer for some point in the future. #### Parameters timer\_handle The timer to reschedule new\_timeout\_ms The new expiry time in milliseconds from the current time #### Returns true if the timer was rescheduled, false if the timer has already elapsed bool app\_timer\_reschedule(AppTimer \* timer\_handle, [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) new\_timeout\_ms) Reschedules an already running timer for some point in the future. #### Parameters timer\_handle The timer to reschedule new\_timeout\_ms The new expiry time in milliseconds from the current time #### Returns true if the timer was rescheduled, false if the timer has already elapsed bool app\_timer\_reschedule(AppTimer \* timer\_handle, [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) new\_timeout\_ms) Reschedules an already running timer for some point in the future. Elapsed timers cannot be rescheduled. #### Parameters timer\_handle The timer to reschedule new\_timeout\_ms The new expiry time in milliseconds from the current time #### Returns true if the timer was rescheduled, false if the timer has already elapsed - [SDK 3](javascript:void(0);) - [SDK 4](javascript:void(0);) - [SDK 4.9+](javascript:void(0);) void app\_timer\_cancel(AppTimer \* timer\_handle) Cancels an already registered timer. Once cancelled the handle may no longer be used for any purpose. void app\_timer\_cancel(AppTimer \* timer\_handle) Cancels an already registered timer. Once cancelled the handle may no longer be used for any purpose. void app\_timer\_cancel(AppTimer \* timer\_handle) Cancels an already registered timer. Once cancelled the handle may no longer be used for any purpose. Elapsed timers do not need to be cancelled. ## Typedef Documentation typedef struct AppTimer AppTimer typedef void(\* AppTimerCallback)(void \*data) The type of function which can be called when a timer fires. The argument will be the `callback_data` passed to [app\_timer\_register()](https://developer.repebble.com/docs/c/Foundation/Timer.md#app_timer_register). --- # TouchService Source: https://developer.repebble.com/docs/c/Foundation/Event_Service/TouchService/ The APIs on this page will only work with SDK 4.9+. ## Function Documentation void touch\_service\_subscribe([TouchServiceHandler](https://developer.repebble.com/docs/c/Foundation/Event_Service/TouchService.md#TouchServiceHandler) handler, void \* context) Subscribe to touch events. The touch sensor is enabled while subscribed. #### Parameters handler Callback invoked for each touch event context User context passed to the callback void touch\_service\_unsubscribe(void) Unsubscribe from touch events. The touch sensor is disabled if no other subscribers remain. bool touch\_service\_is\_enabled(void) #### Returns true if touch input is currently being delivered to apps. Returns false on platforms without a touchscreen, or when touch has been disabled system-wide (future feature). Apps can poll this (for example on window appear) to avoid looking broken when touch is unavailable. void app\_touch\_navigation\_enable(bool enable) Opt this app into (or out of) touch navigation: the system gesture bridge that maps swipes/taps on a MenuLayer/ScrollLayer to button presses. Third-party apps are opt-out by default and receive no touch navigation even when the user has enabled it system-wide; call this with _enable_ true to participate. Takes effect immediately when touch navigation is enabled system-wide, otherwise once the user enables it. #### Parameters enable true to participate in touch navigation, false to stop participating. ## Data Structure Documentation struct TouchEvent Touch event data, carried directly in PebbleTouchEvent. #### Data Fields [TouchEventType](https://developer.repebble.com/docs/c/Foundation/Event_Service/TouchService.md#TouchEventType) typebool non\_navigational true when the touch must not drive navigation: the interaction session was inactive at Touchdown (unarmed contact on the idle watchface). Latched on Touchdown and carried across the whole gesture. int16\_t xint16\_t y ## Enum Documentation enum TouchEventType Touch event type. #### Enumerators TouchEvent\_TouchdownTouchEvent\_LiftoffTouchEvent\_PositionUpdate ## Typedef Documentation typedef void(\* TouchServiceHandler)(const TouchEvent \*event, void \*context) Callback for touch events. #### Parameters event The touch event data context User-provided context --- # UnobstructedArea Source: https://developer.repebble.com/docs/c/User_Interface/UnobstructedArea/ Events about when the app's unobstructed area changes for visually adapting Unobstructed Area enables a watchface to adapt to overlays partially obstructing it. Timeline Peek is the only overlay, and it partially obstructs the bottom of watchfaces, displaying the immediately upcoming or newly began event. Unobstructed Area is for use only with watchfaces. There will be no Unobstructed Area events emitted for apps that are not watchfaces. Timeline Peek is also limited to rectangular platforms, thus using Unobstructed Area on Chalk will also result in no events. Watchfaces are encouraged to respect Unobstructed Area in order to dynamically resize within the remaining screen area that isn't obstructed by an overlay. Unobstructed Area provides handlers for when the screen area will begin and end changing as well as progress for every frame of the animation, allowing one to animate the watchface to resize while the overlay animates into or out of the screen. Additionally, at any point, a watchface can query the Unobstructed Area using [layer\_get\_unobstructed\_bounds](https://developer.repebble.com/docs/c/User_Interface/Layers.md#layer_get_unobstructed_bounds) even if there was not event or if it didn't subscribe to them. The simplest usage of Unobstructed Area is to change rendering of your watchface to render within the unobstructed bounds obtained by [layer\_get\_unobstructed\_bounds](https://developer.repebble.com/docs/c/User_Interface/Layers.md#layer_get_unobstructed_bounds). This is accomplished by modifying your layer update procedure that you setup a layer with using [layer\_set\_update\_proc](https://developer.repebble.com/docs/c/User_Interface/Layers.md#layer_set_update_proc) to use [layer\_get\_unobstructed\_bounds](https://developer.repebble.com/docs/c/User_Interface/Layers.md#layer_get_unobstructed_bounds) instead of [layer\_get\_bounds](https://developer.repebble.com/docs/c/User_Interface/Layers.md#layer_get_bounds) or [layer\_get\_frame](https://developer.repebble.com/docs/c/User_Interface/Layers.md#layer_get_frame) and adjusting all the rendering logic within it to handle resizing bounds. The app will redraw automatically whenever the Unobstructed Area changes, even if you did not subscribe to the events. Subscribing to `will_change`, `change`, and `did_change` events with app\_unobstructed\_area\_service\_subscribe will allow you to obtain the final unobstructed area as soon as the animation begins and the current animation progress for each frame as they occur should you need that information to resize your watchface. When designing your watchface resizing logic or animation, take into consideration the way Timeline Peek animates. Timeline Peek appears from the bottom with an animation that moves slightly at first and snaps across with a bounce back. Because there is a bounce back in the animation, there will be momentary frames where the unobstructed area is slightly smaller than when Timeline Peek is visible but not animating. If you intend to hide or show layers on the screen depending on the unobstructed area, there are two ways to do this. For anything inside a layer update procedure the simple solution would be sufficient. That is, in your update procedure, you can to determine whether something is to be rendered or not based on the remaining height available to you determined from [layer\_get\_unobstructed\_bounds](https://developer.repebble.com/docs/c/User_Interface/Layers.md#layer_get_unobstructed_bounds). The other method for deciding whether to show or hide layers is to subscribe to events using app\_unobstructed\_area\_service\_subscribe. Note that hiding or showing elements in your `will_change` can be too early due to the nature of the Timeline Peek animation where it moves slowly in the first few frames. After judging the animation visually, you may instead show or hide your layers based on both the final unobstructed area obtained from `will_change` in combination with the progress obtained from `change`, or check the current height available to you by calling [layer\_get\_unobstructed\_bounds](https://developer.repebble.com/docs/c/User_Interface/Layers.md#layer_get_unobstructed_bounds) in your `change` handler to update your state. For more advance usages such as functionally defined animations whose animation frames are a function of animation progress, you will want to subscribe to `will_change`, `change`, and optionally `did_change` events if you need to clean up resources or layers created in your `will_change` handler. For example, in your `will_change` handler, you may use [layer\_get\_unobstructed\_bounds](https://developer.repebble.com/docs/c/User_Interface/Layers.md#layer_get_unobstructed_bounds) to get the current unobstructed area, and combine it with the final unobstructed area passed into `will_change` to set up a [PropertyAnimation](https://developer.repebble.com/docs/c/User_Interface/Animation/PropertyAnimation.md). A separate example would be to save the animation progress passed to your `change` handler for use in your own custom easing curve in your layer update procedure. ## Function Documentation void unobstructed\_area\_service\_subscribe(UnobstructedAreaHandlers handlers, void \* context) Subscribe to be notified when the app's unobstructed area changes. When an unobstructed area begins changing, the `will_change` handler will be called, and every `will_change` call is always paired with a `did_change` call that occurs when it is done changing given that the `will_change` and `did_change` handlers are set. When subscribing while the unobstructed area is changing, the `will_change` handler will be called after subscription in the next event loop. #### Parameters handlers The handlers that should be called when the unobstructed area changes. context A user-provided context that will be passed to the callback handlers. #### See Also [layer\_get\_unobstructed\_bounds](https://developer.repebble.com/docs/c/User_Interface/Layers.md#layer_get_unobstructed_bounds) void unobstructed\_area\_service\_unsubscribe(void) Unsubscribe from notifications about changes to the app's unobstructed area. ## Data Structure Documentation struct UnobstructedAreaHandlers #### Data Fields [UnobstructedAreaWillChangeHandler](https://developer.repebble.com/docs/c/User_Interface/UnobstructedArea.md#UnobstructedAreaWillChangeHandler) will\_change Handler that will be called just before the unobstructed area will begin changing. [UnobstructedAreaChangeHandler](https://developer.repebble.com/docs/c/User_Interface/UnobstructedArea.md#UnobstructedAreaChangeHandler) change Handler that will be called every time the unobstructed area changes. [UnobstructedAreaDidChangeHandler](https://developer.repebble.com/docs/c/User_Interface/UnobstructedArea.md#UnobstructedAreaDidChangeHandler) did\_change Handler that will be called after the unobstructed area has finished changing. ## Typedef Documentation typedef void(\* UnobstructedAreaWillChangeHandler)(GRect final\_unobstructed\_screen\_area, void \*context) Handler that will be called just before the unobstructed area will begin changing. #### Parameters final\_unobstructed\_screen\_area The final unobstructed screen area after the unobstructed area has finished changing. context A user-provided context. typedef void(\* UnobstructedAreaChangeHandler)(AnimationProgress progress, void \*context) Handler that will be called every time the unobstructed area changes. #### Parameters progress The progress of the animation changing the unobstructed area. context A user-provided context. typedef void(\* UnobstructedAreaDidChangeHandler)(void \*context) Handler that will be called after the unobstructed area has finished changing. #### Parameters context A user-provided context. --- # User Interface Source: https://developer.repebble.com/docs/c/User_Interface/ Everything related to user interface. The User Interface framework enables your Pebble watchface or watchapp to handle basic UI components, like clicks, layers, vibes, windows and window stacks. ## Modules #### [Animation](https://developer.repebble.com/docs/c/User_Interface/Animation.md) Abstract framework to create arbitrary animations #### [Clicks](https://developer.repebble.com/docs/c/User_Interface/Clicks.md) Handling button click interactions #### [Gesture Recognizers](https://developer.repebble.com/docs/c/User_Interface/Gesture_Recognizers.md) Low-level touch-gesture recognizers for building fully custom touch interactions on touch-capable hardware. #### [Layers](https://developer.repebble.com/docs/c/User_Interface/Layers.md) User interface layers for displaying graphic components #### [Light](https://developer.repebble.com/docs/c/User_Interface/Light.md) Controlling Pebble's backlight #### [Preferences](https://developer.repebble.com/docs/c/User_Interface/Preferences.md)   #### [Speaker](https://developer.repebble.com/docs/c/User_Interface/Speaker.md) Controlling the speaker #### [UnobstructedArea](https://developer.repebble.com/docs/c/User_Interface/UnobstructedArea.md)   #### [Vibes](https://developer.repebble.com/docs/c/User_Interface/Vibes.md) Controlling the vibration motor #### [Window](https://developer.repebble.com/docs/c/User_Interface/Window.md) The basic building block of the user interface #### [Window Stack](https://developer.repebble.com/docs/c/User_Interface/Window_Stack.md) The multiple window manager --- # UUID Source: https://developer.repebble.com/docs/c/Foundation/DataStructures/UUID/ ## Function Documentation bool uuid\_equal(const Uuid \* uu1, const Uuid \* uu2) Compares two UUIDs. #### Returns True if the two UUIDs are equal, false if they are not. void uuid\_to\_string(const Uuid \* uuid, char \* buffer) Writes UUID in a string form into buffer that looks like the following... {12345678-1234-5678-1234-567812345678} or {NULL UUID} if NULL was passed. #### Parameters uuid The Uuid to write into the buffer as human-readable string buffer Memory to write the string to. Must be at least [UUID\_STRING\_BUFFER\_LENGTH](https://developer.repebble.com/docs/c/Foundation/DataStructures/UUID.md#UUID_STRING_BUFFER_LENGTH) bytes long. ## Data Structure Documentation struct Uuid #### Data Fields uint8\_t byte0uint8\_t byte1uint8\_t byte2uint8\_t byte3uint8\_t byte4uint8\_t byte5uint8\_t byte6uint8\_t byte7uint8\_t byte8uint8\_t byte9uint8\_t byte10uint8\_t byte11uint8\_t byte12uint8\_t byte13uint8\_t byte14uint8\_t byte15 ## Macro Definition Documentation #define UUID\_SIZE 16 #define UuidMake ( p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15) Make a Uuid object from sixteen bytes. #### Returns A Uuid structure representing the bytes p0 to p15. #define UuidMakeFromBEBytes ( b) Creates a Uuid from an array of bytes with 16 bytes in Big Endian order. #### Returns The created Uuid #define UuidMakeFromLEBytes ( b) Creates a Uuid from an array of bytes with 16 bytes in Little Endian order. #### Returns The created Uuid #define UUID\_STRING\_BUFFER\_LENGTH (32 + 4 + 2 + 1) The minimum required length of a string used to hold a uuid (including null). --- # Vibes Source: https://developer.repebble.com/docs/c/User_Interface/Vibes/ Controlling the vibration motor The Vibes API provides calls that let you control Pebble’s vibration motor. The vibration motor can be used as a visceral mechanism for giving immediate feedback to the user. You can use it to highlight important moments in games, or to draw the attention of the user. However, you should use the vibration feature sparingly, because sustained use will rapidly deplete Pebble’s battery, and vibrating Pebble too much and too often can become annoying for users. ## Function Documentation void vibes\_cancel(void) Cancel any in-flight vibe patterns; this is a no-op if there is no on-going vibe. void vibes\_short\_pulse(void) Makes the watch emit one short vibration. void vibes\_long\_pulse(void) Makes the watch emit one long vibration. void vibes\_double\_pulse(void) Makes the watch emit two brief vibrations. - [SDK 3](javascript:void(0);) - [SDK 4](javascript:void(0);) - [SDK 4.9+](javascript:void(0);) void vibes\_enqueue\_custom\_pattern([VibePattern](https://developer.repebble.com/docs/c/User_Interface/Vibes.md#VibePattern) pattern) Makes the watch emit a ‘custom’ vibration pattern. #### Parameters pattern An arbitrary vibration pattern #### See Also [VibePattern](https://developer.repebble.com/docs/c/User_Interface/Vibes.md#VibePattern) void vibes\_enqueue\_custom\_pattern([VibePattern](https://developer.repebble.com/docs/c/User_Interface/Vibes.md#VibePattern) pattern) Makes the watch emit a ‘custom’ vibration pattern. #### Parameters pattern An arbitrary vibration pattern #### See Also [VibePattern](https://developer.repebble.com/docs/c/User_Interface/Vibes.md#VibePattern) void vibes\_enqueue\_custom\_pattern([VibePattern](https://developer.repebble.com/docs/c/User_Interface/Vibes.md#VibePattern) pattern) Makes the watch emit a 'custom' vibration pattern. #### Parameters pattern An arbitrary vibration pattern #### See Also [VibePattern](https://developer.repebble.com/docs/c/User_Interface/Vibes.md#VibePattern) ## Data Structure Documentation - [SDK 3](javascript:void(0);) - [SDK 4](javascript:void(0);) - [SDK 4.9+](javascript:void(0);) struct VibePattern Data structure describing a vibration pattern. A pattern consists of at least 1 vibe-on duration, optionally followed by alternating vibe-off + vibe-on durations. Each segment may have a different duration. Example code: ``` // Vibe pattern: ON for 200ms, OFF for 100ms, ON for 400ms:static const uint32\_t const segments[] = { 200, 100, 400 };VibePattern pat = {.durations = segments,.num\_segments = ARRAY\_LENGTH(segments),};vibes\_enqueue\_custom\_pattern(pat); ``` #### Data Fields const [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) \* durations Pointer to an array of segment durations, measured in milli-seconds. The maximum allowed duration is 10000ms. [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) num\_segments The length of the array of durations. #### See Also [vibes\_enqueue\_custom\_pattern](https://developer.repebble.com/docs/c/User_Interface/Vibes.md#vibes_enqueue_custom_pattern) struct VibePattern Data structure describing a vibration pattern. A pattern consists of at least 1 vibe-on duration, optionally followed by alternating vibe-off + vibe-on durations. Each segment may have a different duration. Example code: ``` // Vibe pattern: ON for 200ms, OFF for 100ms, ON for 400ms:static const uint32\_t const segments[] = { 200, 100, 400 };VibePattern pat = {.durations = segments,.num\_segments = ARRAY\_LENGTH(segments),};vibes\_enqueue\_custom\_pattern(pat); ``` #### Data Fields const [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) \* durations Pointer to an array of segment durations, measured in milli-seconds. The maximum allowed duration is 10000ms. [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) num\_segments The length of the array of durations. #### See Also [vibes\_enqueue\_custom\_pattern](https://developer.repebble.com/docs/c/User_Interface/Vibes.md#vibes_enqueue_custom_pattern) struct VibePattern Data structure describing a vibration pattern. A pattern consists of at least 1 vibe-on duration, optionally followed by alternating vibe-off + vibe-on durations. Each segment may have a different duration. Example code: ``` // Vibe pattern: ON for 200ms, OFF for 100ms, ON for 400ms:static const uint32\_t segments[] = { 200, 100, 400 };VibePattern pat = {.durations = segments,.num\_segments = ARRAY\_LENGTH(segments),};vibes\_enqueue\_custom\_pattern(pat); ``` #### Data Fields const [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) \* durations Pointer to an array of segment durations, measured in milli-seconds. The maximum allowed duration is 10000ms. [uint32\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint32_t) num\_segments The length of the array of durations. #### See Also [vibes\_enqueue\_custom\_pattern](https://developer.repebble.com/docs/c/User_Interface/Vibes.md#vibes_enqueue_custom_pattern) --- # Wakeup Source: https://developer.repebble.com/docs/c/Foundation/Wakeup/ Allows applications to schedule to be launched even if they are not running. ## Function Documentation - [SDK 3](javascript:void(0);) - [SDK 4](javascript:void(0);) - [SDK 4.9+](javascript:void(0);) void wakeup\_service\_subscribe([WakeupHandler](https://developer.repebble.com/docs/c/Foundation/Wakeup.md#WakeupHandler) handler) Registers a [WakeupHandler](https://developer.repebble.com/docs/c/Foundation/Wakeup.md#WakeupHandler) to be called when wakeup events occur. #### Parameters handler The callback that gets called when the wakeup event occurs void wakeup\_service\_subscribe([WakeupHandler](https://developer.repebble.com/docs/c/Foundation/Wakeup.md#WakeupHandler) handler) Registers a [WakeupHandler](https://developer.repebble.com/docs/c/Foundation/Wakeup.md#WakeupHandler) to be called when wakeup events occur. #### Parameters handler The callback that gets called when the wakeup event occurs void wakeup\_service\_subscribe([WakeupHandler](https://developer.repebble.com/docs/c/Foundation/Wakeup.md#WakeupHandler) handler) Registers a [WakeupHandler](https://developer.repebble.com/docs/c/Foundation/Wakeup.md#WakeupHandler) to be called when wakeup events occur. ##### Note The handler is only called for wakeup events which occur while the app is already running; use `launch_reason()` === APP\_LAUNCH\_WAKEUP to detect when the app was launched by a wakeup event. #### Parameters handler The callback that gets called when the wakeup event occurs [WakeupId](https://developer.repebble.com/docs/c/Foundation/Wakeup.md#WakeupId) wakeup\_schedule([time\_t](https://developer.repebble.com/docs/c/Standard_C/Time.md#time_t) timestamp, int32\_t cookie, bool notify\_if\_missed) Registers a wakeup event that triggers a callback at the specified time. Applications may only schedule up to 8 wakeup events. Wakeup events are given a 1 minute duration window, in that no application may schedule a wakeup event with 1 minute of a currently scheduled wakeup event. #### Parameters timestamp The requested time (UTC) for the wakeup event to occur cookie The application specific reason for the wakeup event notify\_if\_missed On powering on Pebble, will alert user when notifications were missed due to Pebble being off. #### Returns negative values indicate errors ([StatusCode](https://developer.repebble.com/docs/c/Foundation/Storage.md#StatusCode)) E\_RANGE if the event cannot be scheduled due to another event in that period. E\_INVALID\_ARGUMENT if the time requested is in the past. E\_OUT\_OF\_RESOURCES if the application has already scheduled all 8 wakeup events. E\_INTERNAL if a system error occurred during scheduling. void wakeup\_cancel([WakeupId](https://developer.repebble.com/docs/c/Foundation/Wakeup.md#WakeupId) wakeup\_id) Cancels a wakeup event. #### Parameters wakeup\_id Wakeup event to cancel void wakeup\_cancel\_all(void) Cancels all wakeup event for the app. bool wakeup\_get\_launch\_event([WakeupId](https://developer.repebble.com/docs/c/Foundation/Wakeup.md#WakeupId) \* wakeup\_id, int32\_t \* cookie) Retrieves the wakeup event info for an app that was launched by a wakeup\_event (ie. `launch_reason()` === APP\_LAUNCH\_WAKEUP) so that an app may display information regarding the wakeup event. #### Parameters wakeup\_id [WakeupId](https://developer.repebble.com/docs/c/Foundation/Wakeup.md#WakeupId) for the wakeup event that caused the app to wakeup cookie App provided reason for the wakeup event #### Returns True if app was launched due to a wakeup event, false otherwise bool wakeup\_query([WakeupId](https://developer.repebble.com/docs/c/Foundation/Wakeup.md#WakeupId) wakeup\_id, [time\_t](https://developer.repebble.com/docs/c/Standard_C/Time.md#time_t) \* timestamp) Checks if the current [WakeupId](https://developer.repebble.com/docs/c/Foundation/Wakeup.md#WakeupId) is still scheduled and therefore valid. #### Parameters wakeup\_id Wakeup event to query for validity and scheduled time timestamp Optionally points to an address of a [time\_t](https://developer.repebble.com/docs/c/Standard_C/Time.md#time_t) variable to store the time that the wakeup event is scheduled to occur. (The time is in UTC, but local time when [clock\_is\_timezone\_set](https://developer.repebble.com/docs/c/Foundation/Wall_Time.md#clock_is_timezone_set) returns false). You may pass NULL instead if you do not need it. #### Returns True if [WakeupId](https://developer.repebble.com/docs/c/Foundation/Wakeup.md#WakeupId) is still scheduled, false if it doesn't exist or has already occurred ## Typedef Documentation typedef int32\_t WakeupId [WakeupId](https://developer.repebble.com/docs/c/Foundation/Wakeup.md#WakeupId) is an identifier for a wakeup event. typedef void(\* WakeupHandler)(WakeupId wakeup\_id, int32\_t cookie) The type of function which can be called when a wakeup event occurs. The arguments will be the id of the wakeup event that occurred, as well as the scheduled cookie provided to `wakeup_schedule`. --- # Wall Time Source: https://developer.repebble.com/docs/c/Foundation/Wall_Time/ Functions, data structures and other things related to wall clock time. This module contains utilities to get the current time and create strings with formatted dates and times. ## Function Documentation void clock\_copy\_time\_string(char \* buffer, uint8\_t size) Copies a time string into the buffer, formatted according to the user's time display preferences (such as 12h/24h time). Example results: "7:30" or "15:00". ##### Note AM/PM are also outputted with the time if the user's preference is 12h time. #### Parameters buffer (out) A pointer to the buffer to copy the time string into size The maximum size of buffer bool clock\_is\_24h\_style(void) Gets the user's 12/24h clock style preference. #### Returns `true` if the user prefers 24h-style time display or `false` if the user prefers 12h-style time display. - [SDK 3](javascript:void(0);) - [SDK 4](javascript:void(0);) - [SDK 4.9+](javascript:void(0);) [time\_t](https://developer.repebble.com/docs/c/Standard_C/Time.md#time_t) clock\_to\_timestamp([WeekDay](https://developer.repebble.com/docs/c/Foundation/Wall_Time.md#WeekDay) day, int hour, int minute) Converts a (day, hour, minute) specification to a UTC timestamp occurring in the future Always returns a timestamp for the next occurring instance, example: specifying TODAY@14:30 when it is 14:40 will return a timestamp for 7 days from now at 14:30. ##### Note This function does not support Daylight Saving Time (DST) changes, events scheduled during a DST change will be off by an hour. #### Parameters day [WeekDay](https://developer.repebble.com/docs/c/Foundation/Wall_Time.md#WeekDay) day of week including support for specifying TODAY hour hour specified in 24-hour format [0-23] minute minute [0-59] [time\_t](https://developer.repebble.com/docs/c/Standard_C/Time.md#time_t) clock\_to\_timestamp([WeekDay](https://developer.repebble.com/docs/c/Foundation/Wall_Time.md#WeekDay) day, int hour, int minute) Converts a (day, hour, minute) specification to a UTC timestamp occurring in the future Always returns a timestamp for the next occurring instance, example: specifying TODAY@14:30 when it is 14:40 will return a timestamp for 7 days from now at 14:30. ##### Note This function does not support Daylight Saving Time (DST) changes, events scheduled during a DST change will be off by an hour. #### Parameters day [WeekDay](https://developer.repebble.com/docs/c/Foundation/Wall_Time.md#WeekDay) day of week including support for specifying TODAY hour hour specified in 24-hour format [0-23] minute minute [0-59] [time\_t](https://developer.repebble.com/docs/c/Standard_C/Time.md#time_t) clock\_to\_timestamp([WeekDay](https://developer.repebble.com/docs/c/Foundation/Wall_Time.md#WeekDay) day, int hour, int minute) Converts a (day, hour, minute) specification to a UTC timestamp occurring in the future Always returns a timestamp for the next occurring instance, example: specifying TODAY@14:30 when it is 14:40 will return a timestamp for 7 days from now at 14:30. #### Parameters day [WeekDay](https://developer.repebble.com/docs/c/Foundation/Wall_Time.md#WeekDay) day of week including support for specifying TODAY hour hour specified in 24-hour format [0-23] minute minute [0-59] bool clock\_is\_timezone\_set(void) Checks if timezone is currently set, otherwise gmtime == localtime. #### Returns `true` if timezone has been set, false otherwise void clock\_get\_timezone(char \* timezone, const [size\_t](https://developer.repebble.com/docs/c/Standard_C/Memory.md#size_t) buffer\_size) If timezone is set, copies the current timezone long name (e.g. America/Chicago) to user-provided buffer. ##### Note timezone buffer should be at least TIMEZONE\_NAME\_LENGTH bytes #### Parameters timezone A pointer to the buffer to copy the timezone long name into buffer\_size Size of the allocated buffer to copy the timezone long name into ## Enum Documentation enum WeekDay Weekday values. #### Enumerators TODAY Today. SUNDAY Sunday. MONDAY Monday. TUESDAY Tuesday. WEDNESDAY Wednesday. THURSDAY Thursday. FRIDAY Friday. SATURDAY Saturday. ## Macro Definition Documentation #define TIMEZONE\_NAME\_LENGTH 32 The maximum length for a timezone full name (e.g. America/Chicago) --- # WatchInfo Source: https://developer.repebble.com/docs/c/Foundation/WatchInfo/ Provides information about the watch itself. This API provides access to information such as the watch model, watch color and watch firmware version. ## Function Documentation [WatchInfoModel](https://developer.repebble.com/docs/c/Foundation/WatchInfo.md#WatchInfoModel) watch\_info\_get\_model(void) Provides the model of the watch. #### Returns `WatchInfoModel` representing the model of the watch. [WatchInfoVersion](https://developer.repebble.com/docs/c/Foundation/WatchInfo.md#WatchInfoVersion) watch\_info\_get\_firmware\_version(void) Provides the version of the firmware running on the watch. #### Returns `WatchInfoVersion` representing the version of the firmware running on the watch. [WatchInfoColor](https://developer.repebble.com/docs/c/Foundation/WatchInfo.md#WatchInfoColor) watch\_info\_get\_color(void) ## Data Structure Documentation struct WatchInfoVersion Data structure containing the version of the firmware running on the watch. The version of the firmware has the form X.[X.[X]]. If a version number is not present it will be 0. For example: the version numbers of 2.4.1 are 2, 4, and 1. The version numbers of 2.4 are 2, 4, and 0. #### Data Fields uint8\_t major Major version number. uint8\_t minor Minor version number. uint8\_t patch Patch version number. ## Enum Documentation enum WatchInfoModel The different watch models. #### Enumerators WATCH\_INFO\_MODEL\_UNKNOWN Unknown model. WATCH\_INFO\_MODEL\_PEBBLE\_ORIGINAL Original Pebble. WATCH\_INFO\_MODEL\_PEBBLE\_STEEL Pebble Steel. WATCH\_INFO\_MODEL\_PEBBLE\_TIME Pebble Time. WATCH\_INFO\_MODEL\_PEBBLE\_TIME\_STEEL Pebble Time Steel. WATCH\_INFO\_MODEL\_PEBBLE\_TIME\_ROUND\_14 Pebble Time Round, 14mm lug size. WATCH\_INFO\_MODEL\_PEBBLE\_TIME\_ROUND\_20 Pebble Time Round, 20mm lug size. WATCH\_INFO\_MODEL\_PEBBLE\_2\_HR Pebble 2 HR. WATCH\_INFO\_MODEL\_PEBBLE\_2\_SE Pebble 2 SE. WATCH\_INFO\_MODEL\_PEBBLE\_TIME\_2 Pebble Time 2. WATCH\_INFO\_MODEL\_COREDEVICES\_P2D CoreDevices P2D (Pebble 2 Duo) WATCH\_INFO\_MODEL\_COREDEVICES\_PT2 CoreDevices PT2 (Pebble Time 2) WATCH\_INFO\_MODEL\_COREDEVICES\_PR2 CoreDevices PR2 (Pebble Round 2) WATCH\_INFO\_MODEL\_\_MAX enum WatchInfoColor The different watch colors. #### Enumerators WATCH\_INFO\_COLOR\_UNKNOWN Unknown color. WATCH\_INFO\_COLOR\_BLACK Black. WATCH\_INFO\_COLOR\_WHITE White. WATCH\_INFO\_COLOR\_RED Red. WATCH\_INFO\_COLOR\_ORANGE Orange. WATCH\_INFO\_COLOR\_GRAY Gray. WATCH\_INFO\_COLOR\_STAINLESS\_STEEL Stainless Steel. WATCH\_INFO\_COLOR\_MATTE\_BLACK Matte Black. WATCH\_INFO\_COLOR\_BLUE Blue. WATCH\_INFO\_COLOR\_GREEN Green. WATCH\_INFO\_COLOR\_PINK Pink. WATCH\_INFO\_COLOR\_TIME\_WHITE Time White. WATCH\_INFO\_COLOR\_TIME\_BLACK Time Black. WATCH\_INFO\_COLOR\_TIME\_RED Time Red. WATCH\_INFO\_COLOR\_TIME\_STEEL\_SILVER Time Steel Silver. WATCH\_INFO\_COLOR\_TIME\_STEEL\_BLACK Time Steel Black. WATCH\_INFO\_COLOR\_TIME\_STEEL\_GOLD Time Steel Gold. WATCH\_INFO\_COLOR\_TIME\_ROUND\_SILVER\_14 Time Round 14mm lug size, Silver. WATCH\_INFO\_COLOR\_TIME\_ROUND\_BLACK\_14 Time Round 14mm lug size, Black. WATCH\_INFO\_COLOR\_TIME\_ROUND\_SILVER\_20 Time Round 20mm lug size, Silver. WATCH\_INFO\_COLOR\_TIME\_ROUND\_BLACK\_20 Time Round 20mm lug size, Black. WATCH\_INFO\_COLOR\_TIME\_ROUND\_ROSE\_GOLD\_14 Time Round 14mm lug size, Rose Gold. WATCH\_INFO\_COLOR\_PEBBLE\_2\_HR\_BLACK Pebble 2 HR, Black / Charcoal. WATCH\_INFO\_COLOR\_PEBBLE\_2\_HR\_LIME Pebble 2 HR, Charcoal / Sorbet Green. WATCH\_INFO\_COLOR\_PEBBLE\_2\_HR\_FLAME Pebble 2 HR, Charcoal / Red. WATCH\_INFO\_COLOR\_PEBBLE\_2\_HR\_WHITE Pebble 2 HR, White / Gray. WATCH\_INFO\_COLOR\_PEBBLE\_2\_HR\_AQUA Pebble 2 HR, White / Turquoise. WATCH\_INFO\_COLOR\_PEBBLE\_2\_SE\_BLACK Pebble 2 SE, Black / Charcoal. WATCH\_INFO\_COLOR\_PEBBLE\_2\_SE\_WHITE Pebble 2 SE, White / Gray. WATCH\_INFO\_COLOR\_PEBBLE\_TIME\_2\_BLACK Pebble Time 2, Black. WATCH\_INFO\_COLOR\_PEBBLE\_TIME\_2\_SILVER Pebble Time 2, Silver. WATCH\_INFO\_COLOR\_PEBBLE\_TIME\_2\_GOLD Pebble Time 2, Gold. WATCH\_INFO\_COLOR\_COREDEVICES\_P2D\_BLACK CoreDevices P2D, Black. WATCH\_INFO\_COLOR\_COREDEVICES\_P2D\_WHITE CoreDevices P2D, White. WATCH\_INFO\_COLOR\_COREDEVICES\_PT2\_BLACK\_GREY CoreDevices PT2, Black/Grey. WATCH\_INFO\_COLOR\_COREDEVICES\_PT2\_BLACK\_RED CoreDevices PT2, Black/Red. WATCH\_INFO\_COLOR\_COREDEVICES\_PT2\_SILVER\_BLUE CoreDevices PT2, Silver/Blue. WATCH\_INFO\_COLOR\_COREDEVICES\_PT2\_SILVER\_GREY CoreDevices PT2, Silver/Grey. WATCH\_INFO\_COLOR\_COREDEVICES\_PR2\_BLACK\_20 CoreDevices PR2, Black (20mm) WATCH\_INFO\_COLOR\_COREDEVICES\_PR2\_SILVER\_20 CoreDevices PR2, Silver (20mm) WATCH\_INFO\_COLOR\_COREDEVICES\_PR2\_GOLD\_14 CoreDevices PR2, Gold (14mm) WATCH\_INFO\_COLOR\_COREDEVICES\_PR2\_SILVER\_14 CoreDevices PR2, Silver (14mm) WATCH\_INFO\_COLOR\_\_MAX --- # Window Source: https://developer.repebble.com/docs/c/User_Interface/Window/ The basic building block of the user interface Windows are the top-level elements in the UI hierarchy and the basic building blocks for a Pebble UI. A single window is always displayed at a time on Pebble, with the exception of when animating from one window to the other, which, in that case, is managed by the window stack. You can stack windows on top of each other, but only the topmost window will be visible. Users wearing a Pebble typically interact with the content and media displayed in a window, clicking and pressing buttons on the watch, depending on what they see and wish to respond to in a window. Windows serve to display a hierarchy of layers on the screen and handle user input. When a window is visible, its root Layer (and all its child layers) are drawn onto the screen automatically. You need a window, which always fills the entire screen, to display images, text, and graphics in your Pebble app. A layer by itself doesn’t display on Pebble; it must be in the current window’s layer hierarchy to be visible. The Window Stack serves as the global manager of what window is presented and makes sure that input events are forwarded to the topmost window. Refer to the [User Interface Layers chapter in the Pebble Developer Guides](https://developer.repebble.com/guides/user-interfaces/layers.md) (chapter "Window") for a conceptual overview of Window, the Window Stack and relevant code examples. ## Modules #### [ActionMenu](https://developer.repebble.com/docs/c/User_Interface/Window/ActionMenu.md)   #### [NumberWindow](https://developer.repebble.com/docs/c/User_Interface/Window/NumberWindow.md) A ready-made Window prompting the user to pick a number ## Function Documentation Window \* window\_create(void) Creates a new Window on the heap and initalizes it with the default values. - Background color : `GColorWhite` - Root layer's `update_proc` : function that fills the window's background using `background_color`. - `click_config_provider` : `NULL` - `window_handlers` : all `NULL` #### Returns A pointer to the window. `NULL` if the window could not be created void window\_destroy(Window \* window) Destroys a Window previously created by window\_create. void window\_set\_click\_config\_provider(Window \* window, [ClickConfigProvider](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#ClickConfigProvider) click\_config\_provider) Sets the click configuration provider callback function on the window. This will automatically setup the input handlers of the window as well to use the click recognizer subsystem. #### Parameters window The window for which to set the click config provider click\_config\_provider The callback that will be called to configure the click recognizers with the window #### See Also [Clicks](https://developer.repebble.com/docs/c/User_Interface/Clicks.md) [ClickConfigProvider](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#ClickConfigProvider) void window\_set\_click\_config\_provider\_with\_context(Window \* window, [ClickConfigProvider](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#ClickConfigProvider) click\_config\_provider, void \* context) Same as [window\_set\_click\_config\_provider()](https://developer.repebble.com/docs/c/User_Interface/Window.md#window_set_click_config_provider), but will assign a custom context pointer (instead of the window pointer) that will be passed into the [ClickHandler](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#ClickHandler) click event handlers. #### Parameters window The window for which to set the click config provider click\_config\_provider The callback that will be called to configure the click recognizers with the window context Pointer to application specific data that will be passed to the click configuration provider callback (defaults to the window). #### See Also [Clicks](https://developer.repebble.com/docs/c/User_Interface/Clicks.md) [window\_set\_click\_config\_provider](https://developer.repebble.com/docs/c/User_Interface/Window.md#window_set_click_config_provider) [ClickConfigProvider](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#ClickConfigProvider) window\_get\_click\_config\_provider(const Window \* window) Gets the current click configuration provider of the window. #### Parameters window The window for which to get the click config provider void \* window\_get\_click\_config\_context(Window \* window) Gets the current click configuration provider context of the window. #### Parameters window The window for which to get the click config provider context void window\_set\_window\_handlers(Window \* window, [WindowHandlers](https://developer.repebble.com/docs/c/User_Interface/Window.md#WindowHandlers) handlers) Sets the window handlers of the window. These handlers get called e.g. when the user enters or leaves the window. #### Parameters window The window for which to set the window handlers handlers The handlers for the specified window #### See Also [WindowHandlers](https://developer.repebble.com/docs/c/User_Interface/Window.md#WindowHandlers) struct Layer \* window\_get\_root\_layer(const Window \* window) Gets the root Layer of the window. The root layer is the layer at the bottom of the layer hierarchy for this window. It is the window's "canvas" if you will. By default, the root layer only draws a solid fill with the window's background color. #### Parameters window The window for which to get the root layer #### Returns The window's root layer void window\_set\_background\_color(Window \* window, GColor background\_color) Sets the background color of the window, which is drawn automatically by the root layer of the window. #### Parameters window The window for which to set the background color background\_color The new background color #### See Also [window\_get\_root\_layer()](https://developer.repebble.com/docs/c/User_Interface/Window.md#window_get_root_layer) bool window\_is\_loaded(Window \* window) Gets whether the window has been loaded. If a window is loaded, its `.load` handler has been called (and the `.unload` handler has not been called since). #### Parameters window The window to query its loaded status #### Returns true if the window is currently loaded or false if not. #### See Also [WindowHandlers](https://developer.repebble.com/docs/c/User_Interface/Window.md#WindowHandlers) void window\_set\_user\_data(Window \* window, void \* data) Sets a pointer to developer-supplied data that the window uses, to provide a means to access the data at later times in one of the window event handlers. #### Parameters window The window for which to set the user data data A pointer to user data. #### See Also [window\_get\_user\_data](https://developer.repebble.com/docs/c/User_Interface/Window.md#window_get_user_data) void \* window\_get\_user\_data(const Window \* window) Gets the pointer to developer-supplied data that was previously set using [window\_set\_user\_data()](https://developer.repebble.com/docs/c/User_Interface/Window.md#window_set_user_data). #### Parameters window The window for which to get the user data #### See Also [window\_set\_user\_data](https://developer.repebble.com/docs/c/User_Interface/Window.md#window_set_user_data) void window\_single\_click\_subscribe([ButtonId](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#ButtonId) button\_id, [ClickHandler](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#ClickHandler) handler) Subscribe to single click events. ##### Notes Must be called from the [ClickConfigProvider](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#ClickConfigProvider). [window\_single\_click\_subscribe()](https://developer.repebble.com/docs/c/User_Interface/Window.md#window_single_click_subscribe) and [window\_single\_repeating\_click\_subscribe()](https://developer.repebble.com/docs/c/User_Interface/Window.md#window_single_repeating_click_subscribe) conflict, and cannot both be used on the same button. When there is a multi\_click and/or long\_click setup, there will be a delay before the single click #### Parameters button\_id The button events to subscribe to. handler The [ClickHandler](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#ClickHandler) to fire on this event. handler will get fired. On the other hand, when there is no multi\_click nor long\_click setup, the single click handler will fire directly on button down. #### See Also [ButtonId](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#ButtonId) [Clicks](https://developer.repebble.com/docs/c/User_Interface/Clicks.md) [window\_single\_repeating\_click\_subscribe](https://developer.repebble.com/docs/c/User_Interface/Window.md#window_single_repeating_click_subscribe) void window\_single\_repeating\_click\_subscribe([ButtonId](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#ButtonId) button\_id, [uint16\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint16_t) repeat\_interval\_ms, [ClickHandler](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#ClickHandler) handler) Subscribe to single click event, with a repeat interval. A single click is detected every time "repeat\_interval\_ms" has been reached. ##### Notes Must be called from the [ClickConfigProvider](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#ClickConfigProvider). [window\_single\_click\_subscribe()](https://developer.repebble.com/docs/c/User_Interface/Window.md#window_single_click_subscribe) and [window\_single\_repeating\_click\_subscribe()](https://developer.repebble.com/docs/c/User_Interface/Window.md#window_single_repeating_click_subscribe) conflict, and cannot both be used on the same button. The back button cannot be overridden with a repeating click. #### Parameters button\_id The button events to subscribe to. repeat\_interval\_ms When holding down, how many milliseconds before the handler is fired again. A value of 0ms means "no repeat timer". The minimum is 30ms, and values below will be disregarded. If there is a long-click handler subscribed on this button, `repeat_interval_ms` will not be used. handler The [ClickHandler](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#ClickHandler) to fire on this event. #### See Also [window\_single\_click\_subscribe](https://developer.repebble.com/docs/c/User_Interface/Window.md#window_single_click_subscribe) void window\_multi\_click\_subscribe([ButtonId](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#ButtonId) button\_id, uint8\_t min\_clicks, uint8\_t max\_clicks, [uint16\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint16_t) timeout, bool last\_click\_only, [ClickHandler](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#ClickHandler) handler) Subscribe to multi click events. ##### Note Must be called from the [ClickConfigProvider](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#ClickConfigProvider). #### Parameters button\_id The button events to subscribe to. min\_clicks Minimum number of clicks before handler is fired. Defaults to 2. max\_clicks Maximum number of clicks after which the click counter is reset. A value of 0 means use "min" also as "max". timeout The delay after which a sequence of clicks is considered finished, and the click counter is reset. A value of 0 means to use the system default 300ms. last\_click\_only Defaults to false. When true, only the handler for the last multi-click is called. handler The [ClickHandler](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#ClickHandler) to fire on this event. Fired for multi-clicks, as "filtered" by the `last_click_only`, `min`, and `max` parameters. void window\_long\_click\_subscribe([ButtonId](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#ButtonId) button\_id, [uint16\_t](https://developer.repebble.com/docs/c/Standard_C.md#uint16_t) delay\_ms, [ClickHandler](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#ClickHandler) down\_handler, [ClickHandler](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#ClickHandler) up\_handler) Subscribe to long click events. ##### Notes Must be called from the [ClickConfigProvider](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#ClickConfigProvider). The back button cannot be overridden with a long click. #### Parameters button\_id The button events to subscribe to. delay\_ms Milliseconds after which "handler" is fired. A value of 0 means to use the system default 500ms. down\_handler The [ClickHandler](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#ClickHandler) to fire as soon as the button has been held for `delay_ms`. This may be NULL to have no down handler. up\_handler The [ClickHandler](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#ClickHandler) to fire on the release of a long click. This may be NULL to have no up handler. void window\_raw\_click\_subscribe([ButtonId](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#ButtonId) button\_id, [ClickHandler](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#ClickHandler) down\_handler, [ClickHandler](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#ClickHandler) up\_handler, void \* context) Subscribe to raw click events. ##### Notes Must be called from within the [ClickConfigProvider](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#ClickConfigProvider). The back button cannot be overridden with a raw click. #### Parameters button\_id The button events to subscribe to. down\_handler The [ClickHandler](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#ClickHandler) to fire as soon as the button has been pressed. This may be NULL to have no down handler. up\_handler The [ClickHandler](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#ClickHandler) to fire on the release of the button. This may be NULL to have no up handler. context If this context is not NULL, it will override the general context. void window\_set\_click\_context([ButtonId](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#ButtonId) button\_id, void \* context) Set the context that will be passed to handlers for the given button's events. By default the context passed to handlers is equal to the [ClickConfigProvider](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#ClickConfigProvider) context (defaults to the window). ##### Note Must be called from within the [ClickConfigProvider](https://developer.repebble.com/docs/c/User_Interface/Clicks.md#ClickConfigProvider). #### Parameters button\_id The button to set the context for. context Set the context that will be passed to handlers for the given button's events. void window\_attach\_recognizer(Window \* window, Recognizer \* recognizer) Attach a recognizer to the window. #### Parameters window [Window](https://developer.repebble.com/docs/c/User_Interface/Window.md) to which to attach the [Gesture Recognizers](https://developer.repebble.com/docs/c/User_Interface/Gesture_Recognizers.md) recognizer [Gesture Recognizers](https://developer.repebble.com/docs/c/User_Interface/Gesture_Recognizers.md) to attach void window\_detach\_recognizer(Window \* window, Recognizer \* recognizer) Detach a recognizer from the window. #### Parameters window [Window](https://developer.repebble.com/docs/c/User_Interface/Window.md) from which to detach the [Gesture Recognizers](https://developer.repebble.com/docs/c/User_Interface/Gesture_Recognizers.md) recognizer [Gesture Recognizers](https://developer.repebble.com/docs/c/User_Interface/Gesture_Recognizers.md) to detach void window\_set\_touch\_bridge\_disabled(Window \* window, bool disabled) Disable the system touch-navigation bridge for a window. With the bridge disabled the system recognizer set fails on Touchdown for this window, handing every touch to the recognizers the app attached, so an app can take over touch input instead of the built-in button emulation. #### Parameters window [Window](https://developer.repebble.com/docs/c/User_Interface/Window.md) to configure disabled true to disable the bridge for this window ## Data Structure Documentation struct WindowHandlers [WindowHandlers](https://developer.repebble.com/docs/c/User_Interface/Window.md#WindowHandlers) These handlers are called by the [Window Stack](https://developer.repebble.com/docs/c/User_Interface/Window_Stack.md) as windows get pushed on / popped. All these handlers use [WindowHandler](https://developer.repebble.com/docs/c/User_Interface/Window.md#WindowHandler) as their function signature. #### Data Fields [WindowHandler](https://developer.repebble.com/docs/c/User_Interface/Window.md#WindowHandler) load Called when the window is pushed to the screen when it's not loaded. This is a good moment to do the layout of the window. [WindowHandler](https://developer.repebble.com/docs/c/User_Interface/Window.md#WindowHandler) appear Called when the window comes on the screen (again). E.g. when second-top-most window gets revealed (again) after popping the top-most window, but also when the window is pushed for the first time. This is a good moment to start timers related to the window, or reset the UI, etc. [WindowHandler](https://developer.repebble.com/docs/c/User_Interface/Window.md#WindowHandler) disappear Called when the window leaves the screen, e.g. when another window is pushed, or this window is popped. Good moment to stop timers related to the window. [WindowHandler](https://developer.repebble.com/docs/c/User_Interface/Window.md#WindowHandler) unload Called when the window is deinited, but could be used in the future to free resources bound to windows that are not on screen. #### See Also [window\_set\_window\_handlers()](https://developer.repebble.com/docs/c/User_Interface/Window.md#window_set_window_handlers) [Window Stack](https://developer.repebble.com/docs/c/User_Interface/Window_Stack.md) ## Typedef Documentation typedef struct Window Window typedef void(\* WindowHandler)(struct Window \*window) Function signature for a handler that deals with transition events of a window. #### See Also [WindowHandlers](https://developer.repebble.com/docs/c/User_Interface/Window.md#WindowHandlers) [window\_set\_window\_handlers()](https://developer.repebble.com/docs/c/User_Interface/Window.md#window_set_window_handlers) --- # Window Stack Source: https://developer.repebble.com/docs/c/User_Interface/Window_Stack/ The multiple window manager In Pebble OS, the window stack serves as the global manager of what window is presented, ensuring that input events are forwarded to the topmost window. The navigation model of Pebble centers on the concept of a vertical “stack” of windows, similar to mobile app interactions. In working with the Window Stack API, the basic operations include push and pop. When an app wants to display a new window, it pushes a new window onto the stack. This appears like a window sliding in from the right. As an app is closed, the window is popped off the stack and disappears. For more complicated operations, involving multiple windows, you can determine which windows reside on the stack, using [window\_stack\_contains\_window()](https://developer.repebble.com/docs/c/User_Interface/Window_Stack.md#window_stack_contains_window) and remove any specific window, using [window\_stack\_remove()](https://developer.repebble.com/docs/c/User_Interface/Window_Stack.md#window_stack_remove). Refer to the [User Interface Layers chapter in the Pebble Developer Guides](https://developer.repebble.com/guides/user-interfaces/layers.md) (chapter "Window Stack") for a conceptual overview of the window stack and relevant code examples. Also see the [WindowHandlers](https://developer.repebble.com/docs/c/User_Interface/Window.md#WindowHandlers) of a [Window](https://developer.repebble.com/docs/c/User_Interface/Window.md) for the callbacks that can be added to a window in order to act upon window stack transitions. ## Function Documentation void window\_stack\_push(Window \* window, bool animated) Pushes the given window on the window navigation stack, on top of the current topmost window of the app. #### Parameters window The window to push on top animated Pass in `true` to animate the push using a sliding animation, or `false` to skip the animation. Window \* window\_stack\_pop(bool animated) Pops the topmost window on the navigation stack. #### Parameters animated See [window\_stack\_remove()](https://developer.repebble.com/docs/c/User_Interface/Window_Stack.md#window_stack_remove) #### Returns The window that is popped, or NULL if there are no windows to pop. void window\_stack\_pop\_all(const bool animated) Pops all windows. See [window\_stack\_remove()](https://developer.repebble.com/docs/c/User_Interface/Window_Stack.md#window_stack_remove) for a description of the `animated` parameter and notes. bool window\_stack\_remove(Window \* window, bool animated) Removes a given window from the window stack that belongs to the app task. ##### Note If there are no windows for the app left on the stack, the app will be killed by the system, shortly. To avoid this, make sure to push another window shortly after or before removing the last window. #### Parameters window The window to remove. If the window is NULL or if it is not on the stack, this function is a no-op. animated Pass in `true` to animate the removal of the window using a side-to-side sliding animation to reveal the next window. This is only used in case the window happens to be on top of the window stack (thus visible). #### Returns True if window was successfully removed, false otherwise. Window \* window\_stack\_get\_top\_window(void) Gets the topmost window on the stack that belongs to the app. #### Returns The topmost window on the stack that belongs to the app or NULL if no app window could be found. bool window\_stack\_contains\_window(Window \* window) Checks if the window is on the window stack. #### Parameters window The window to look for on the window stack #### Returns true if the window is currently on the window stack. --- # Worker Source: https://developer.repebble.com/docs/c/Worker/ ## Function Documentation void worker\_event\_loop(void) The event loop for workers, to be used in worker's main(). Will block until the worker is ready to exit. #### See Also [App](https://developer.repebble.com/docs/c/Foundation/App.md) void worker\_launch\_app(void) Launch the foreground app for this worker.