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

View file

@ -0,0 +1,221 @@
/*
* 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 "action_menu_demo.h"
#include "applib/app.h"
#include "applib/graphics/graphics.h"
#include "applib/ui/action_menu_hierarchy.h"
#include "applib/ui/action_menu_window.h"
#include "applib/ui/action_menu_window_private.h"
#include "applib/ui/app_window_stack.h"
#include "applib/ui/text_layer.h"
#include "applib/ui/window.h"
#include "kernel/pbl_malloc.h"
#include "process_state/app_state/app_state.h"
#include "resource/resource_ids.auto.h"
#include "system/passert.h"
#include "util/size.h"
#include <string.h>
static struct {
// main window
Window *main_window;
TextLayer *info_layer;
// action menu
ActionMenu *action_menu;
// result_window
Window *result_window;
TextLayer *result_layer;
} *s_app_data;
///////////////////////
// Result Window
static void prv_result_window_load(Window *window) {
Layer *root_layer = window_get_root_layer(window);
s_app_data->result_layer = text_layer_create(GRect(0, 60, root_layer->bounds.size.w, 50));
text_layer_set_text_alignment(s_app_data->result_layer, GTextAlignmentCenter);
text_layer_set_text(s_app_data->result_layer, "Result!");
layer_add_child(root_layer, (Layer *)s_app_data->result_layer);
}
static void prv_result_window_unload(Window *window) {
window_destroy(window);
}
///////////////////////
// Action Menu Window
static void prv_action_menu_did_close_cb(ActionMenu *action_menu,
const ActionMenuItem *item,
void *context) {
ActionMenuLevel *root_level = action_menu_get_root_level(action_menu);
action_menu_hierarchy_destroy(root_level, NULL, NULL);
}
static void prv_action_callback(ActionMenu *action_menu,
const ActionMenuItem *action,
void *context) {
s_app_data->result_window = window_create();
window_set_window_handlers(s_app_data->result_window, &(WindowHandlers) {
.load = prv_result_window_load,
.unload = prv_result_window_unload,
});
action_menu_set_result_window(action_menu, s_app_data->result_window);
}
static void prv_select_click_handler(ClickRecognizerRef recognizer, void *context) {
// First Level
ActionMenuLevel *first_level = action_menu_level_create(10);
action_menu_level_add_action(first_level,
"First!",
prv_action_callback,
NULL);
action_menu_level_add_action(first_level,
"Second!",
prv_action_callback,
NULL);
// More Levels
ActionMenuLevel *more_level = action_menu_level_create(1);
action_menu_level_add_action(more_level,
"That's it, folks!",
prv_action_callback,
NULL);
action_menu_level_add_child(first_level,
more_level,
"More...");
// Levels with multiple lines of text
ActionMenuLevel *multiline_level = action_menu_level_create(5);
action_menu_level_add_action(multiline_level,
"Sorry, I can't talk right now.",
prv_action_callback,
NULL);
action_menu_level_add_action(multiline_level,
"I can't talk just now, please text me if this is an emergency.",
prv_action_callback,
NULL);
action_menu_level_add_action(multiline_level,
"In a meeting, I will call you back when the meeting is over.",
prv_action_callback,
NULL);
action_menu_level_add_action(multiline_level,
"On my way, I will text you when I'm nearby.",
prv_action_callback,
NULL);
action_menu_level_add_action(multiline_level,
"I am busy.",
prv_action_callback,
NULL);
action_menu_level_add_child(first_level,
multiline_level,
"Canned Responses");
// Level with multi-column values of various row lengths
ActionMenuLevel *multicolumn_select = action_menu_level_create(3);
static const char* thin_values[] = { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L",
"M", "🍺" };
ActionMenuLevel *multicolumn_one = action_menu_level_create(2);
action_menu_level_set_display_mode(multicolumn_one, ActionMenuLevelDisplayModeThin);
for (size_t i = 0; i < 2; i++) {
action_menu_level_add_action(multicolumn_one, thin_values[i], prv_action_callback, NULL);
}
// ah ah ah
ActionMenuLevel *multicolumn_two = action_menu_level_create(5);
action_menu_level_set_display_mode(multicolumn_two, ActionMenuLevelDisplayModeThin);
for (size_t i = 0; i < 5; i++) {
action_menu_level_add_action(multicolumn_two, thin_values[i], prv_action_callback, NULL);
}
// ah ah ah
ActionMenuLevel *multicolumn_many = action_menu_level_create(ARRAY_LENGTH(thin_values));
action_menu_level_set_display_mode(multicolumn_many, ActionMenuLevelDisplayModeThin);
for (size_t i = 0; i < ARRAY_LENGTH(thin_values); i++) {
action_menu_level_add_action(multicolumn_many, thin_values[i], prv_action_callback, NULL);
}
// ah ah ah
action_menu_level_add_child(multicolumn_select, multicolumn_one, "One row");
action_menu_level_add_child(multicolumn_select, multicolumn_two, "Two rows");
action_menu_level_add_child(multicolumn_select, multicolumn_many, "Many rows");
action_menu_level_add_child(first_level, multicolumn_select, "Columns");
first_level->separator_index = first_level->num_items - 1;
ActionMenuConfig config = {
.root_level = first_level,
.context = NULL,
.colors.background = GColorOxfordBlue,
.colors.foreground = GColorOrange,
.did_close = prv_action_menu_did_close_cb,
};
s_app_data->action_menu = app_action_menu_open(&config);
}
///////////////////////
// Main Window
static void prv_main_window_click_config_provider(void *context) {
window_single_click_subscribe(BUTTON_ID_SELECT, prv_select_click_handler);
}
static void prv_main_window_load(Window *window) {
Layer *root_layer = window_get_root_layer(window);
s_app_data->info_layer = text_layer_create(GRect(0, 60, root_layer->bounds.size.w, 50));
text_layer_set_text_alignment(s_app_data->info_layer, GTextAlignmentCenter);
text_layer_set_text(s_app_data->info_layer, "Press the select button");
layer_add_child(root_layer, (Layer *)s_app_data->info_layer);
}
////////////////////
// App boilerplate
static void prv_init(void) {
s_app_data = app_zalloc_check(sizeof(*s_app_data));
s_app_data->main_window = window_create();
window_set_window_handlers(s_app_data->main_window, &(WindowHandlers) {
.load = prv_main_window_load,
});
window_set_click_config_provider(s_app_data->main_window, prv_main_window_click_config_provider);
app_window_stack_push(s_app_data->main_window, true /* animated */);
}
static void s_main(void) {
prv_init();
app_event_loop();
}
const PebbleProcessMd* action_menu_demo_get_app_info() {
static const PebbleProcessMdSystem s_app_data = {
.common = {
.main_func = s_main,
// UUID: 101a32d95-ef69-46d4-a0b9-854cc62f97f9
.uuid = {0x99, 0xa3, 0x2d, 0x95, 0xef, 0x69, 0x46, 0xd4,
0xa0, 0xb9, 0x85, 0x4c, 0xc6, 0x2f, 0x97, 0xf9},
},
.name = "Action Menu Demo",
};
return (const PebbleProcessMd*) &s_app_data;
}