Import of the watch repository from Pebble

This commit is contained in:
Matthieu Jeanson
2024-12-12 16:43:03 -08:00
committed by Katharine Berry
commit 3b92768480
10334 changed files with 2564465 additions and 0 deletions

226
src/fw/apps/sdk/sdk_app.c Normal file
View File

@@ -0,0 +1,226 @@
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "sdk_app.h"
#include "applib/app.h"
#include "applib/graphics/perimeter.h"
#include "applib/ui/app_window_stack.h"
#include "applib/ui/text_layer.h"
#include "applib/ui/window_private.h"
#include "apps/system_app_ids.h"
#include "apps/system_apps/launcher/launcher_app.h"
#include "apps/system_apps/timeline/timeline.h"
#include "kernel/pbl_malloc.h"
#include "process_management/app_install_manager.h"
#include "process_management/app_manager.h"
#include "process_state/app_state/app_state.h"
#include "services/common/clock.h"
#include "shell/sdk/shell_sdk.h"
#include "shell/sdk/watchface.h"
#include "system/logging.h"
typedef struct SdkAppData {
Window window;
TextLayer info_text_layer;
#if CAPABILITY_HAS_SDK_SHELL4
TextLayer time_text_layer;
char time_buffer[TIME_STRING_TIME_LENGTH];
#endif
} SdkAppData;
static void prv_sdk_home_update_proc(Layer *layer, GContext *ctx) {
window_do_layer_update_proc(layer, ctx);
#if CAPABILITY_HAS_SDK_SHELL4
SdkAppData *data = app_state_get_user_data();
const int time_max_y = grect_get_max_y(&data->time_text_layer.layer.frame);
const int line_top_margin = 14;
const int line_stroke_width = 2;
graphics_context_set_fill_color(ctx, GColorBlack);
graphics_fill_rect(ctx, &GRect(0, time_max_y + line_top_margin, DISP_COLS, line_stroke_width));
#endif
}
static void prv_update_time(SdkAppData *data) {
#if CAPABILITY_HAS_SDK_SHELL4
clock_copy_time_string(data->time_buffer, sizeof(data->time_buffer));
text_layer_set_text(&data->time_text_layer, data->time_buffer);
#endif
}
static void prv_update_info(SdkAppData *data) {
const AppInstallId app_id = shell_sdk_get_last_installed_app();
const char *text;
#if CAPABILITY_HAS_SDK_SHELL4
const unsigned int tip_delay_s = 5;
if ((app_id == INSTALL_ID_INVALID) || shell_sdk_last_installed_app_is_watchface()) {
text = "Install an app to continue";
} else if ((rtc_get_time() / tip_delay_s) & 1) {
// Show the launcher help on every odd set of five seconds since the epoch
text = "Press Select to access Launcher";
} else {
text = "Press Down to access Timeline";
}
#else
GColor color;
if (app_id == INSTALL_ID_INVALID) {
text = "Install an app to continue or press up / down to browse the timeline";
color = GColorChromeYellow;
} else {
text = "Press select to launch your app or press up / down to browse the timeline";
color = GColorPictonBlue;
}
window_set_background_color(&data->window, PBL_IF_COLOR_ELSE(color, GColorWhite));
#endif
text_layer_set_text(&data->info_text_layer, text);
}
static void prv_update_ui(SdkAppData *data) {
prv_update_time(data);
prv_update_info(data);
}
static void prv_handle_tick_timer(struct tm *tick_time, TimeUnits units_changed) {
prv_update_ui(app_state_get_user_data());
}
#if !CAPABILITY_HAS_SDK_SHELL4
static void prv_launch_last_installed_app(ClickRecognizerRef recognizer, void *data) {
const AppInstallId app_id = shell_sdk_get_last_installed_app();
PBL_LOG(LOG_LEVEL_DEBUG, "Last installed app is %"PRId32, app_id);
if (app_id != INSTALL_ID_INVALID) {
app_manager_put_launch_app_event(&(AppLaunchEventConfig) { .id = app_id });
}
}
static void prv_launch_timeline(ClickRecognizerRef recognizer, void *data) {
static TimelineArgs s_timeline_args = {
.launch_into_pin = false,
.pin_id = UUID_INVALID_INIT,
};
const bool is_up = (click_recognizer_get_button_id(recognizer) == BUTTON_ID_UP);
if (is_up) {
PBL_LOG(LOG_LEVEL_DEBUG, "Launching timeline in past mode.");
s_timeline_args.direction = TimelineIterDirectionPast;
} else {
PBL_LOG(LOG_LEVEL_DEBUG, "Launching timeline in future mode.");
s_timeline_args.direction = TimelineIterDirectionFuture;
}
app_manager_put_launch_app_event(&(AppLaunchEventConfig) {
.id = APP_ID_TIMELINE,
.common.args = &s_timeline_args,
});
}
#endif
static void prv_config_provider(void *data) {
#if !CAPABILITY_HAS_SDK_SHELL4
window_single_click_subscribe(BUTTON_ID_UP, prv_launch_timeline);
window_single_click_subscribe(BUTTON_ID_SELECT, prv_launch_last_installed_app);
window_single_click_subscribe(BUTTON_ID_DOWN, prv_launch_timeline);
#endif
}
static void prv_init(void) {
SdkAppData *data = app_malloc_check(sizeof(SdkAppData));
Window *window = &data->window;
window_init(window, WINDOW_NAME("SDK Home"));
window_set_click_config_provider(window, prv_config_provider);
window_set_overrides_back_button(window, true);
window_set_fullscreen(window, true);
layer_set_update_proc(&window->layer, prv_sdk_home_update_proc);
GRect frame = data->window.layer.frame;
#if CAPABILITY_HAS_SDK_SHELL4
const int top_margin = PBL_IF_RECT_ELSE(19, 25);
const int time_height = 46;
frame.origin.y = top_margin;
frame.size.h = time_height;
TextLayer *time_text_layer = &data->time_text_layer;
text_layer_init(time_text_layer, &frame);
text_layer_set_font(time_text_layer, fonts_get_system_font(FONT_KEY_LECO_42_NUMBERS));
text_layer_set_text_alignment(time_text_layer, GTextAlignmentCenter);
text_layer_set_overflow_mode(time_text_layer, GTextOverflowModeWordWrap);
text_layer_set_background_color(&data->time_text_layer, GColorClear);
layer_add_child(&window->layer, &time_text_layer->layer);
const int time_padding = 22;
frame.origin.y += time_height + time_padding;
frame.size.h = DISP_ROWS - frame.origin.y;
#elif PBL_RECT
const int top_margin = 23;
frame.origin.y = top_margin;
frame.size.h -= top_margin;
#endif
TextLayer *info_text_layer = &data->info_text_layer;
text_layer_init(info_text_layer, &frame);
text_layer_set_font(info_text_layer, fonts_get_system_font(FONT_KEY_GOTHIC_24_BOLD));
text_layer_set_text_alignment(info_text_layer, GTextAlignmentCenter);
text_layer_set_background_color(&data->info_text_layer, GColorClear);
layer_add_child(&window->layer, &info_text_layer->layer);
#if PBL_ROUND
#if CAPABILITY_HAS_SDK_SHELL4
const uint8_t inset = 8;
#else
const uint8_t inset = 18;
#endif
text_layer_enable_screen_text_flow_and_paging(info_text_layer, inset);
#endif
app_state_set_user_data(data);
#if CAPABILITY_HAS_SDK_SHELL4
window_set_background_color(window, PBL_IF_COLOR_ELSE(GColorLightGray, GColorWhite));
tick_timer_service_subscribe(SECOND_UNIT, prv_handle_tick_timer);
#endif
prv_update_ui(data);
app_window_stack_push(window, true /* is_animated */);
}
static void s_main(void) {
prv_init();
app_event_loop();
}
const PebbleProcessMd* sdk_app_get_info(void) {
static const PebbleProcessMdSystem s_app_md = {
.common = {
.main_func = s_main,
// UUID: 1197fc39-47e7-439b-82be-f56d9ba1dbd8
.uuid = { 0x11, 0x97, 0xfc, 0x39, 0x47, 0xe7, 0x43, 0x9b,
0x82, 0xbe, 0xf5, 0x6d, 0x9b, 0xa1, 0xdb, 0xd8 },
#if CAPABILITY_HAS_SDK_SHELL4
.process_type = ProcessTypeWatchface
#endif
},
.icon_resource_id = RESOURCE_ID_MENU_ICON_TICTOC_WATCH,
.name = "TicToc"
};
return (const PebbleProcessMd*) &s_app_md;
}

21
src/fw/apps/sdk/sdk_app.h Normal file
View File

@@ -0,0 +1,21 @@
/*
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include "process_management/pebble_process_md.h"
const PebbleProcessMd* sdk_app_get_info(void);