Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 51 additions & 8 deletions src/fw/applib/app_glance.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,47 @@
//! @addtogroup Foundation
//! @{
//! @addtogroup AppGlance App Glance
//! \brief API for the application to modify its glance.
//! \brief 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 \ref 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
//! \ref AppGlanceReloadCallback and give it to \ref app_glance_reload.
//! The implementation of your \ref AppGlanceReloadCallback should call
//! \ref app_glance_add_slice to add slices to the glance.
//!
//! The main window's unload handler is usually a good place to call \ref app_glance_reload.
//!
//! @warning \ref PBL_PLATFORM_APLITE does not support App Glance.
//!
//! Example code:
//! \code{.c}
//! #if !PBL_PLATFORM_APLITE
//! static 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_APLITE
//!
//! static void main_window_unload(Window *window) {
//! #if !PBL_PLATFORM_APLITE
//! app_glance_reload(glance_reload_callback, NULL);
//! #endif // !PBL_PLATFORM_APLITE
//! }
//! \endcode
//!
//! @{

Expand All @@ -25,19 +65,22 @@ typedef uint32_t PublishedId;
//! icon.
#define APP_GLANCE_SLICE_DEFAULT_ICON ((PublishedId)0)

//! 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.
typedef struct AppGlanceSlice {
//! Describes how the slice should be visualized in the app's glance in the launcher.
struct {
//! Describes how the slice should be visualized in the app's glance in the launcher.
typedef struct AppGlanceSliceLayout {
//! The published resource ID of the bitmap icon to display in the app's glance. Use \ref
//! APP_GLANCE_SLICE_DEFAULT_ICON to use the app's default bitmap icon.
PublishedId icon;
//! 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.
const char *subtitle_template_string;
} layout;
} AppGlanceSliceLayout;

//! 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.
typedef struct AppGlanceSlice {
//! Describes how the slice should be visualized in the app's glance in the launcher.
AppGlanceSliceLayout layout;
//! The UTC time after which this slice should no longer be shown in the app's glance. Use \ref
//! APP_GLANCE_SLICE_NO_EXPIRATION if the slice should never expire.
time_t expiration_time;
Expand Down
2 changes: 2 additions & 0 deletions src/fw/applib/app_timer.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,15 @@ AppTimer* app_timer_register_repeatable(uint32_t timeout_ms,
void *app_timer_get_data(AppTimer *timer);

//! Reschedules an already running timer for some point in the future.
//! Elapsed timers cannot be rescheduled.
//! @param timer_handle The timer to reschedule
//! @param new_timeout_ms The new expiry time in milliseconds from the current time
//! @return true if the timer was rescheduled, false if the timer has already elapsed
bool app_timer_reschedule(AppTimer *timer_handle, uint32_t new_timeout_ms);

//! 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.
void app_timer_cancel(AppTimer *timer_handle);

//! @} // group Timer
Expand Down
2 changes: 2 additions & 0 deletions src/fw/applib/app_wakeup.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
typedef void (*WakeupHandler)(WakeupId wakeup_id, int32_t cookie);

//! Registers a 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 \ref launch_reason() === \ref APP_LAUNCH_WAKEUP to detect when the app was launched by a wakeup event.
//! @param handler The callback that gets called when the wakeup event occurs
void app_wakeup_service_subscribe(WakeupHandler handler);

Expand Down
1 change: 1 addition & 0 deletions src/fw/applib/graphics/gcontext.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ void graphics_context_set_text_color_2bit(GContext* ctx, GColor2 color);
void graphics_context_set_tint_color(GContext *ctx, GColor color);

//! Sets the current bitmap compositing mode of the graphics context.
//! The default mode is GCompOpAssign i.e. bitmap transparency disabled.
//! @param ctx The graphics context onto which to set the compositing mode
//! @param mode The new compositing mode
//! @see \ref GCompOp
Expand Down
1 change: 1 addition & 0 deletions src/fw/applib/persist.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ int persist_write_string(const uint32_t key, const char *cstring);

//! Deletes the value of a key from persistent storage.
//! @param key The key of the field to delete from.
//! @return S_TRUE if successful, E_DOES_NOT_EXIST if a value was not set, or another error value from \ref StatusCode.
status_t persist_delete(const uint32_t key);

//! @} // end addtogroup Storage
Expand Down
9 changes: 5 additions & 4 deletions src/fw/applib/ui/bitmap_layer.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ void bitmap_layer_set_alignment(BitmapLayer *bitmap_layer, GAlign alignment);
//! The bitmap layer is automatically marked dirty after this operation.
//! @param bitmap_layer The BitmapLayer for which to set the background color
//! @param color The new \ref GColor to set the background to
//! @see \ref bitmap_layer_set_compositing_mode for enabling transparency
void bitmap_layer_set_background_color(BitmapLayer *bitmap_layer, GColor color);
void bitmap_layer_set_background_color_2bit(BitmapLayer *bitmap_layer, GColor2 color);

Expand All @@ -133,11 +134,11 @@ void bitmap_layer_set_background_color_2bit(BitmapLayer *bitmap_layer, GColor2 c
//! 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 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 Basalt, when drawing \ref GBitmap images, \ref GCompOpSet will be required to apply any
//! transparency.
//! For color platforms, when drawing \ref GBitmap images, \ref GCompOpSet is
//! required to apply any transparency.
//!
//! The bitmap layer is automatically marked dirty after this operation.
//! @param bitmap_layer The BitmapLayer for which to set the compositing mode
Expand Down
4 changes: 4 additions & 0 deletions src/fw/applib/ui/rotate_bitmap_layer.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ void rot_bitmap_layer_destroy(RotBitmapLayer *rot_bitmap_layer) {
applib_free(rot_bitmap_layer);
}

Layer* rot_bitmap_layer_get_layer(const RotBitmapLayer *rot_bitmap_layer) {
return &((RotBitmapLayer *)rot_bitmap_layer)->layer;
}

void rot_bitmap_layer_set_corner_clip_color(RotBitmapLayer *image, GColor color) {
if (gcolor_equal(color, image->corner_clip_color)) {
return;
Expand Down
10 changes: 9 additions & 1 deletion src/fw/applib/ui/rotate_bitmap_layer.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,14 @@ void rot_bitmap_layer_deinit(RotBitmapLayer *bitmap);
//! @param bitmap The RotBitmapLayer to destroy.
void rot_bitmap_layer_destroy(RotBitmapLayer *bitmap);

//! Gets the "root" Layer of the RotBitmapLayer, which is the parent for the sub-
//! layers used for its implementation.
//! @param rot_bitmap_layer Pointer to the RotBitmapLayer for which to get the "root" Layer
//! @return The "root" Layer of the RotBitmapLayer.
//! @internal
//! @note The result is always equal to `(Layer *) rot_bitmap_layer`.
Layer* rot_bitmap_layer_get_layer(const RotBitmapLayer *rot_bitmap_layer);

//! Defines what color to use in areas that are not covered by the source bitmap.
//! By default this is \ref GColorClear.
//! @param bitmap The RotBitmapLayer on which to change the corner clip color
Expand Down Expand Up @@ -113,7 +121,7 @@ void rot_bitmap_set_src_ic(RotBitmapLayer *bitmap, GPoint ic);

//! Sets the compositing mode of how the bitmap image is composited onto what has been drawn beneath the
//! RotBitmapLayer.
//! By default this is \ref GCompOpAssign.
//! By default this is \ref GCompOpAssign, i.e. transparency disabled.
//! The RotBitmapLayer is automatically marked dirty after this operation.
//! @param bitmap The RotBitmapLayer on which to change the rotation
//! @param mode The compositing mode to set
Expand Down
6 changes: 3 additions & 3 deletions src/fw/applib/ui/vibes.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
Example code:
\code{.c}
// Vibe pattern: ON for 200ms, OFF for 100ms, ON for 400ms:
static const uint32_t const segments[] = { 200, 100, 400 };
static const uint32_t segments[] = { 200, 100, 400 };
VibePattern pat = {
.durations = segments,
.num_segments = ARRAY_LENGTH(segments),
Expand Down Expand Up @@ -56,8 +56,8 @@ typedef struct {
Example code:
\code{.c}
// Ramp-down pattern: 100% for 200ms, 50% for 200ms, 25% for 200ms:
static const uint32_t const segments[] = { 200, 200, 200 };
static const uint32_t const amplitudes[] = { 100, 50, 25 };
static const uint32_t segments[] = { 200, 200, 200 };
static const uint32_t amplitudes[] = { 100, 50, 25 };
VibePatternWithAmplitudes pat = {
.durations = segments,
.amplitudes = amplitudes,
Expand Down
4 changes: 3 additions & 1 deletion src/fw/applib/ui/window.c
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,7 @@ void window_single_click_subscribe(ButtonId button_id, ClickHandler handler) {
void window_single_repeating_click_subscribe(ButtonId button_id, uint16_t repeat_interval_ms, ClickHandler handler) {
prv_check_is_in_click_config_provider(window_manager_get_top_window(), "subscribe");
if (button_id == BUTTON_ID_BACK) {
PBL_LOG_ERR("Cannot register BUTTON_ID_BACK repeating click handler");
return;
}
ClickManager *mgr = prv_get_current_click_manager();
Expand Down Expand Up @@ -322,6 +323,7 @@ void window_long_click_subscribe(ButtonId button_id, uint16_t delay_ms, ClickHan
// long-pressing the back button a normal interaction method, and users may
// unintentionally hold the button too long and force-quit the app.
if (app_install_id_from_app_db(sys_process_manager_get_current_process_id())) {
PBL_LOG_ERR("Cannot register BUTTON_ID_BACK long click handler");
return;
} else {
Window *window = window_manager_get_top_window();
Expand All @@ -339,7 +341,7 @@ void window_long_click_subscribe(ButtonId button_id, uint16_t delay_ms, ClickHan
void window_raw_click_subscribe(ButtonId button_id, ClickHandler down_handler, ClickHandler up_handler, void *context) {
prv_check_is_in_click_config_provider(window_manager_get_top_window(), "subscribe");
if (button_id == BUTTON_ID_BACK) {
PBL_LOG_DBG("Cannot register BUTTON_ID_BACK raw handler");
PBL_LOG_ERR("Cannot register BUTTON_ID_BACK raw handler");
return;
}
ClickManager *mgr = prv_get_current_click_manager();
Expand Down
2 changes: 1 addition & 1 deletion src/fw/applib/voice/dictation_session.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ typedef void (*DictationSessionStatusCallback)(DictationSession *session,

//! 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 \ref buffer_size. When a transcription and accepted by the user
//! with a maximum size specified by \ref 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.
//! @param buffer_size size of buffer to allocate for the transcription text; text will be
Expand Down
3 changes: 2 additions & 1 deletion src/fw/process_management/pebble_process_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,9 +155,10 @@ typedef enum {
// sdk.major:0x5 .minor:0x57 -- Add moddable_createMachine (rev 90)
// sdk.major:0x5 .minor:0x58 -- Add size 60 LECO font (rev 91)
// sdk.major:0x5 .minor:0x59 -- Add flags to ModdableCreationRecord (rev 92)
// sdk.major:0x5 .minor:0x5a -- Add rot_bitmap_layer_get_layer() and AppGlanceSliceLayout (rev 93)

#define PROCESS_INFO_CURRENT_SDK_VERSION_MAJOR 0x5
#define PROCESS_INFO_CURRENT_SDK_VERSION_MINOR 0x59
#define PROCESS_INFO_CURRENT_SDK_VERSION_MINOR 0x5a

// The first SDK to ship with 2.x APIs
#define PROCESS_INFO_FIRST_2X_SDK_VERSION_MAJOR 0x4
Expand Down
10 changes: 9 additions & 1 deletion tools/generate_native_sdk/exported_symbols.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"You should also make sure you are obeying our API design guidelines:",
"https://pebbletechnology.atlassian.net/wiki/display/DEV/SDK+API+Design+Guidelines"
],
"revision" : "92",
"revision" : "93",
"version" : "2.0",
"files": [
"fw/drivers/ambient_light.h",
Expand Down Expand Up @@ -1817,6 +1817,10 @@
"type": "define",
"name": "APP_GLANCE_SLICE_DEFAULT_ICON",
"addedRevision": "83"
}, {
"type": "type",
"name": "AppGlanceSliceLayout",
"addedRevision": "93"
}, {
"type": "type",
"name": "AppGlanceSlice",
Expand Down Expand Up @@ -4250,6 +4254,10 @@
"type": "function",
"name": "rot_bitmap_layer_destroy",
"addedRevision": "0"
}, {
"type": "function",
"name": "rot_bitmap_layer_get_layer",
"addedRevision": "93"
}, {
"type": "function",
"name": "rot_bitmap_layer_set_corner_clip_color_2bit",
Expand Down
Loading