mirror of
https://github.com/google/pebble.git
synced 2025-05-23 03:34:55 +00:00
Import of the watch repository from Pebble
This commit is contained in:
commit
3b92768480
10334 changed files with 2564465 additions and 0 deletions
26
src/apps/complex_animations/appinfo.json
Normal file
26
src/apps/complex_animations/appinfo.json
Normal file
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"uuid": "f267008f-0206-4a52-a6cc-d8e2cf0c88d3",
|
||||
"shortName": "ComplexAnimations",
|
||||
"longName": "ComplexAnimations",
|
||||
"companyName": "MakeAwesomeHappen",
|
||||
"versionCode": 1,
|
||||
"versionLabel": "1.0",
|
||||
"targetPlatform": [
|
||||
"aplite",
|
||||
"basalt"
|
||||
],
|
||||
"watchapp": {
|
||||
"watchface": false
|
||||
},
|
||||
"appKeys": {
|
||||
"dummy": 0
|
||||
},
|
||||
"resources": {
|
||||
"media": []
|
||||
},
|
||||
"targetPlatforms": [
|
||||
"aplite",
|
||||
"basalt"
|
||||
],
|
||||
"sdkVersion": "3"
|
||||
}
|
231
src/apps/complex_animations/src/complex_animations.c
Normal file
231
src/apps/complex_animations/src/complex_animations.c
Normal file
|
@ -0,0 +1,231 @@
|
|||
/*
|
||||
* 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 "pebble.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
static Window *window;
|
||||
|
||||
static TextLayer *s_text_layer_a;
|
||||
static TextLayer *s_text_layer_b;
|
||||
|
||||
static Animation *s_animation;
|
||||
static int toggle;
|
||||
|
||||
#define DURATION 1000
|
||||
|
||||
static void animation_started(Animation *animation, void *data) {
|
||||
text_layer_set_text(s_text_layer_a, "Started.");
|
||||
}
|
||||
|
||||
static void animation_stopped(Animation *animation, bool finished, void *data) {
|
||||
text_layer_set_text(s_text_layer_a, finished ? "Hi, I'm a TextLayer!" : "Just Stopped.");
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// setup handler
|
||||
static void prv_setup_handler(Animation *animation) {
|
||||
APP_LOG(APP_LOG_LEVEL_DEBUG, "Executing setup handler for %d", (int)animation);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// teardown handler
|
||||
static void prv_teardown_handler(Animation *animation) {
|
||||
APP_LOG(APP_LOG_LEVEL_DEBUG, "Executing teardown handler for %d", (int)animation);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// update handler
|
||||
static void prv_update_handler(Animation *animation, const uint32_t distance) {
|
||||
APP_LOG(APP_LOG_LEVEL_DEBUG, "Executing update handler for %d, distance: %d", (int)animation,
|
||||
(int)distance);
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
static const AnimationImplementation s_custom_implementation = {
|
||||
.setup = prv_setup_handler,
|
||||
.update = prv_update_handler,
|
||||
.teardown = prv_teardown_handler
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
static Animation *prv_create_custom_animation(void) {
|
||||
// Create a custom animation with a custom update procedure
|
||||
Animation *d = animation_create();
|
||||
animation_set_implementation(d, &s_custom_implementation);
|
||||
animation_set_duration(d, DURATION);
|
||||
return d;
|
||||
}
|
||||
|
||||
|
||||
static void click_handler(ClickRecognizerRef recognizer, Window *window) {
|
||||
// If the animation is still running, fast-foward to 300ms from the end
|
||||
if (animation_is_scheduled(s_animation)) {
|
||||
uint32_t duration = animation_get_duration(s_animation, true, true);
|
||||
animation_set_elapsed(s_animation, duration - 300);
|
||||
APP_LOG(APP_LOG_LEVEL_INFO, "Advancing to 300ms from the end of %d ms", (int)duration);
|
||||
return;
|
||||
}
|
||||
|
||||
Layer *layer = text_layer_get_layer(s_text_layer_a);
|
||||
|
||||
GRect from_rect_a = GRect(0, 0, 60, 60);
|
||||
GRect to_rect_a = GRect(84, 92, 60, 60);
|
||||
|
||||
GRect from_rect_b = GRect(84, 0, 60, 60);
|
||||
GRect to_rect_b = GRect(0, 92, 60, 60);
|
||||
GRect tmp;
|
||||
if (toggle) {
|
||||
tmp = to_rect_b;
|
||||
to_rect_b = from_rect_b;
|
||||
from_rect_b = tmp;
|
||||
}
|
||||
toggle = !toggle;
|
||||
|
||||
|
||||
animation_destroy(s_animation);
|
||||
s_animation = NULL;
|
||||
|
||||
PropertyAnimation *a = property_animation_create_layer_frame(layer, &from_rect_a, &to_rect_a);
|
||||
animation_set_duration((Animation*)a, DURATION);
|
||||
animation_set_handlers((Animation*) a, (AnimationHandlers) {
|
||||
.started = (AnimationStartedHandler) animation_started,
|
||||
.stopped = (AnimationStoppedHandler) animation_stopped,
|
||||
}, NULL /* callback data */);
|
||||
|
||||
PropertyAnimation *a_rev = property_animation_clone(a);
|
||||
animation_set_handlers((Animation*) a_rev, (AnimationHandlers) {
|
||||
.started = (AnimationStartedHandler) animation_started,
|
||||
.stopped = (AnimationStoppedHandler) animation_stopped,
|
||||
}, NULL /* callback data */);
|
||||
animation_set_delay((Animation*)a_rev, 400);
|
||||
animation_set_duration((Animation*)a_rev, DURATION);
|
||||
animation_set_reverse((Animation *)a_rev, true);
|
||||
|
||||
GRect test_rect;
|
||||
property_animation_get_to_grect(a, &test_rect);
|
||||
APP_LOG(APP_LOG_LEVEL_DEBUG, "rect is %d, %d, %d, %d", test_rect.origin.x, test_rect.origin.y,
|
||||
test_rect.size.w, test_rect.size.h);
|
||||
|
||||
|
||||
switch (click_recognizer_get_button_id(recognizer)) {
|
||||
case BUTTON_ID_UP:
|
||||
animation_set_curve((Animation*) a, AnimationCurveEaseOut);
|
||||
animation_set_curve((Animation*) a_rev, AnimationCurveEaseOut);
|
||||
break;
|
||||
|
||||
case BUTTON_ID_DOWN:
|
||||
animation_set_curve((Animation*) a, AnimationCurveEaseIn);
|
||||
animation_set_curve((Animation*) a_rev, AnimationCurveEaseIn);
|
||||
break;
|
||||
|
||||
default:
|
||||
case BUTTON_ID_SELECT:
|
||||
animation_set_curve((Animation*) a, AnimationCurveEaseInOut);
|
||||
animation_set_curve((Animation*) a_rev, AnimationCurveEaseInOut);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
// Exmple animation parameters:
|
||||
|
||||
// Duration defaults to 250 ms
|
||||
animation_set_duration(&prop_animation->animation, 1000);
|
||||
|
||||
// Curve defaults to ease-in-out
|
||||
animation_set_curve(&prop_animation->animation, AnimationCurveEaseOut);
|
||||
|
||||
// Delay defaults to 0 ms
|
||||
animation_set_delay(&prop_animation->animation, 1000);
|
||||
*/
|
||||
|
||||
|
||||
Animation *seq = animation_sequence_create((Animation *)a, (Animation *)a_rev, NULL);
|
||||
|
||||
PropertyAnimation *c = property_animation_create_layer_frame(
|
||||
text_layer_get_layer(s_text_layer_b), &from_rect_b, &to_rect_b);
|
||||
animation_set_duration((Animation*)c, DURATION);
|
||||
|
||||
s_animation = animation_spawn_create(seq, (Animation *)c, prv_create_custom_animation());
|
||||
|
||||
animation_schedule(s_animation);
|
||||
}
|
||||
|
||||
static void config_provider(Window *window) {
|
||||
window_single_click_subscribe(BUTTON_ID_UP, (ClickHandler) click_handler);
|
||||
window_single_click_subscribe(BUTTON_ID_SELECT, (ClickHandler) click_handler);
|
||||
window_single_click_subscribe(BUTTON_ID_DOWN, (ClickHandler) click_handler);
|
||||
}
|
||||
|
||||
|
||||
static void init(void) {
|
||||
window = window_create();
|
||||
window_set_click_config_provider(window, (ClickConfigProvider) config_provider);
|
||||
window_stack_push(window, false);
|
||||
|
||||
GRect from_rect_a = GRect(0, 0, 60, 60);
|
||||
GRect to_rect_a = GRect(84, 92, 60, 60);
|
||||
|
||||
GRect from_rect_b = GRect(84, 0, 60, 60);
|
||||
GRect to_rect_b = GRect(0, 92, 60, 60);
|
||||
|
||||
s_text_layer_a = text_layer_create(from_rect_a);
|
||||
text_layer_set_text(s_text_layer_a, "Started!");
|
||||
layer_add_child(window_get_root_layer(window), text_layer_get_layer(s_text_layer_a));
|
||||
|
||||
s_text_layer_b = text_layer_create(from_rect_b);
|
||||
text_layer_set_text(s_text_layer_b, "Spawned");
|
||||
layer_add_child(window_get_root_layer(window), text_layer_get_layer(s_text_layer_b));
|
||||
|
||||
|
||||
// Animate text layer a from top-left to bottom right and back
|
||||
PropertyAnimation *a = property_animation_create_layer_frame(
|
||||
text_layer_get_layer(s_text_layer_a), &from_rect_a, &to_rect_a);
|
||||
animation_set_duration((Animation*)a, DURATION);
|
||||
|
||||
PropertyAnimation *a_rev = property_animation_clone(a);
|
||||
animation_set_delay((Animation*) a_rev, 400);
|
||||
animation_set_duration((Animation*)a_rev, DURATION);
|
||||
animation_set_reverse((Animation*) a_rev, true);
|
||||
Animation *seq = animation_sequence_create((Animation *)a, (Animation *)a_rev, NULL);
|
||||
|
||||
|
||||
// Animate text layer b from top-right to bottom-left
|
||||
PropertyAnimation *c = property_animation_create_layer_frame(
|
||||
text_layer_get_layer(s_text_layer_b), &from_rect_b, &to_rect_b);
|
||||
animation_set_duration((Animation*)c, DURATION);
|
||||
toggle = !toggle;
|
||||
|
||||
|
||||
s_animation = animation_spawn_create(seq, (Animation *)c, prv_create_custom_animation(), NULL);
|
||||
animation_schedule(s_animation);
|
||||
}
|
||||
|
||||
static void deinit(void) {
|
||||
animation_destroy(s_animation);
|
||||
|
||||
window_stack_remove(window, false);
|
||||
window_destroy(window);
|
||||
text_layer_destroy(s_text_layer_a);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
init();
|
||||
app_event_loop();
|
||||
deinit();
|
||||
}
|
41
src/apps/complex_animations/wscript
Normal file
41
src/apps/complex_animations/wscript
Normal file
|
@ -0,0 +1,41 @@
|
|||
|
||||
#
|
||||
# This file is the default set of rules to compile a Pebble project.
|
||||
#
|
||||
# Feel free to customize this to your needs.
|
||||
#
|
||||
|
||||
import os.path
|
||||
|
||||
top = '.'
|
||||
out = 'build'
|
||||
|
||||
def options(ctx):
|
||||
ctx.load('pebble_sdk')
|
||||
|
||||
def configure(ctx):
|
||||
ctx.load('pebble_sdk')
|
||||
|
||||
def build(ctx):
|
||||
ctx.load('pebble_sdk')
|
||||
|
||||
build_worker = os.path.exists('worker_src')
|
||||
binaries = []
|
||||
|
||||
for p in ctx.env.TARGET_PLATFORMS:
|
||||
ctx.set_env(ctx.all_envs[p])
|
||||
ctx.set_group(ctx.env.PLATFORM_NAME)
|
||||
app_elf='{}/pebble-app.elf'.format(ctx.env.BUILD_DIR)
|
||||
ctx.pbl_program(source=ctx.path.ant_glob('src/**/*.c'),
|
||||
target=app_elf)
|
||||
|
||||
if build_worker:
|
||||
worker_elf='{}/pebble-worker.elf'.format(ctx.env.BUILD_DIR)
|
||||
binaries.append({'platform': p, 'app_elf': app_elf, 'worker_elf': worker_elf})
|
||||
ctx.pbl_worker(source=ctx.path.ant_glob('worker_src/**/*.c'),
|
||||
target=worker_elf)
|
||||
else:
|
||||
binaries.append({'platform': p, 'app_elf': app_elf})
|
||||
|
||||
ctx.set_group('bundle')
|
||||
ctx.pbl_bundle(binaries=binaries, js=ctx.path.ant_glob('src/js/**/*.js'))
|
Loading…
Add table
Add a link
Reference in a new issue