Keep date and BT indicators centered at all times
This commit is contained in:
138
src/c/main.c
138
src/c/main.c
@@ -30,14 +30,27 @@ static GRect s_guy_head_grect_on_screen_resting = GRect(PBL_IF_ROUND_ELSE(0, -30
|
|||||||
static GRect s_guy_butt_grect_on_screen_raised = GRect(PBL_IF_ROUND_ELSE(0, -30), PBL_IF_ROUND_ELSE(160, 144), 260, 115);
|
static GRect s_guy_butt_grect_on_screen_raised = GRect(PBL_IF_ROUND_ELSE(0, -30), PBL_IF_ROUND_ELSE(160, 144), 260, 115);
|
||||||
static GRect s_guy_butt_grect_off_screen_raised = GRect(PBL_IF_ROUND_ELSE(260, 170), PBL_IF_ROUND_ELSE(160, 144), 260, 115);
|
static GRect s_guy_butt_grect_off_screen_raised = GRect(PBL_IF_ROUND_ELSE(260, 170), PBL_IF_ROUND_ELSE(160, 144), 260, 115);
|
||||||
static GRect s_guy_butt_grect_on_screen_resting = GRect(PBL_IF_ROUND_ELSE(0, -30), PBL_IF_ROUND_ELSE(145, 129), 260, 115);
|
static GRect s_guy_butt_grect_on_screen_resting = GRect(PBL_IF_ROUND_ELSE(0, -30), PBL_IF_ROUND_ELSE(145, 129), 260, 115);
|
||||||
|
static const uint8_t s_date_pos_x = 0;
|
||||||
|
static const uint8_t s_date_pos_y = PBL_IF_ROUND_ELSE(121, 105);
|
||||||
|
static const uint8_t s_date_bt_width = PBL_IF_ROUND_ELSE(69, 39);
|
||||||
|
static const uint8_t s_date_height = 14;
|
||||||
|
static GRect s_date_grect_a = GRect(s_date_pos_x, s_date_pos_y, s_date_bt_width, s_date_height);
|
||||||
|
static const uint8_t s_bt_pos_x = PBL_IF_ROUND_ELSE(191, 161);
|
||||||
|
static const uint8_t s_bt_pos_y = PBL_IF_ROUND_ELSE(118, 102);
|
||||||
|
static const uint8_t s_bt_height = 24;
|
||||||
|
static GRect s_bt_grect_a = GRect(s_bt_pos_x, s_bt_pos_y, s_date_bt_width, s_bt_height);
|
||||||
|
static GRect s_date_grect_b;
|
||||||
|
static GRect s_bt_grect_b;
|
||||||
|
|
||||||
// declare animation templates
|
// declare animation templates
|
||||||
|
static uint8_t s_animation_duration = 255;
|
||||||
static Animation *s_head_raise_template;
|
static Animation *s_head_raise_template;
|
||||||
static Animation *s_head_out_template;
|
static Animation *s_head_out_template;
|
||||||
static Animation *s_butt_raise_template;
|
static Animation *s_butt_raise_template;
|
||||||
static Animation *s_butt_out_template;
|
static Animation *s_butt_out_template;
|
||||||
|
|
||||||
// declare lookup tables
|
// declare lookup tables
|
||||||
|
static const uint8_t s_ones_offset[] = {0, 4, 7, 11, 15};
|
||||||
static const uint8_t s_head_count = 25;
|
static const uint8_t s_head_count = 25;
|
||||||
static const uint32_t s_random_heads[] = {
|
static const uint32_t s_random_heads[] = {
|
||||||
RESOURCE_ID_H001, RESOURCE_ID_H002, RESOURCE_ID_H003, RESOURCE_ID_H004,
|
RESOURCE_ID_H001, RESOURCE_ID_H002, RESOURCE_ID_H003, RESOURCE_ID_H004,
|
||||||
@@ -75,6 +88,12 @@ static const GColor8 s_dark_bg_colors[] = {
|
|||||||
// Brown
|
// Brown
|
||||||
GColorRoseVale};
|
GColorRoseVale};
|
||||||
|
|
||||||
|
static void destroy_animation_handler(Animation *animation, bool finished, void *context) {
|
||||||
|
animation_destroy(animation);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool first_minute_update = true;
|
||||||
|
|
||||||
static void update_minute_1() {
|
static void update_minute_1() {
|
||||||
// get a tm structure
|
// get a tm structure
|
||||||
time_t temp = time(NULL);
|
time_t temp = time(NULL);
|
||||||
@@ -88,19 +107,53 @@ static void update_minute_1() {
|
|||||||
static char s_date_buffer[16];
|
static char s_date_buffer[16];
|
||||||
strftime(s_date_buffer, sizeof(s_date_buffer), "%m.%d", tick_time);
|
strftime(s_date_buffer, sizeof(s_date_buffer), "%m.%d", tick_time);
|
||||||
|
|
||||||
|
// update layers
|
||||||
text_layer_set_text(s_time_layer, s_time_buffer);
|
text_layer_set_text(s_time_layer, s_time_buffer);
|
||||||
text_layer_set_text(s_date_layer, s_date_buffer);
|
text_layer_set_text(s_date_layer, s_date_buffer);
|
||||||
|
|
||||||
|
// create date/bt centering animations
|
||||||
|
//// count "1"s in s_time_buffer
|
||||||
|
static uint8_t ones;
|
||||||
|
uint8_t i, new_ones;
|
||||||
|
for (i = 0, new_ones = 0; s_time_buffer[i]; i++) {
|
||||||
|
new_ones += (s_time_buffer[i] == '1');
|
||||||
|
}
|
||||||
|
if (new_ones != ones) { // only animate if necessary
|
||||||
|
ones = new_ones;
|
||||||
|
//// calculate new positions
|
||||||
|
s_date_grect_b = GRect(s_ones_offset[ones], s_date_pos_y, s_date_bt_width, s_date_height);
|
||||||
|
s_bt_grect_b = GRect(s_bt_pos_x - s_ones_offset[ones], s_bt_pos_y, s_date_bt_width, s_bt_height);
|
||||||
|
if (!first_minute_update) {
|
||||||
|
//// configure animations
|
||||||
|
////// date
|
||||||
|
PropertyAnimation *date_center_prop = property_animation_create_layer_frame(text_layer_get_layer(s_date_layer), &s_date_grect_a, &s_date_grect_b);
|
||||||
|
Animation *date_center_anim = property_animation_get_animation(date_center_prop);
|
||||||
|
animation_set_curve(date_center_anim, AnimationCurveEaseOut);
|
||||||
|
animation_set_duration(date_center_anim, s_animation_duration);
|
||||||
|
////// bt
|
||||||
|
PropertyAnimation *s_bt_center_prop = property_animation_create_layer_frame(bitmap_layer_get_layer(s_bt_layer), &s_bt_grect_a, &s_bt_grect_b);
|
||||||
|
Animation *bt_center_anim = property_animation_get_animation(s_bt_center_prop);
|
||||||
|
animation_set_curve(bt_center_anim, AnimationCurveEaseOut);
|
||||||
|
animation_set_duration(bt_center_anim, s_animation_duration);
|
||||||
|
////// create spawn animation (animate centering of both elements at the same time)
|
||||||
|
Animation *centering_spawn_anim = animation_spawn_create(date_center_anim, bt_center_anim, NULL);
|
||||||
|
////// set the handler to destroy the spawn animation (and its children) when finished
|
||||||
|
animation_set_handlers(centering_spawn_anim, (AnimationHandlers){.stopped = destroy_animation_handler}, NULL);
|
||||||
|
////// run centering spawn animation
|
||||||
|
animation_schedule(centering_spawn_anim);
|
||||||
|
}
|
||||||
|
////// update current date/bt positions
|
||||||
|
s_date_grect_a = s_date_grect_b;
|
||||||
|
s_bt_grect_a = s_bt_grect_b;
|
||||||
|
}
|
||||||
|
first_minute_update = false;
|
||||||
|
|
||||||
// DEBUG memory usage layer
|
// DEBUG memory usage layer
|
||||||
static char s_memory_buffer[32];
|
static char s_memory_buffer[32];
|
||||||
snprintf(s_memory_buffer, sizeof(s_memory_buffer), "%d/%d", (int)heap_bytes_used(), (int)heap_bytes_free() + (int)heap_bytes_used());
|
snprintf(s_memory_buffer, sizeof(s_memory_buffer), "%d/%d", (int)heap_bytes_used(), (int)heap_bytes_free() + (int)heap_bytes_used());
|
||||||
text_layer_set_text(s_memory_layer, s_memory_buffer);
|
text_layer_set_text(s_memory_layer, s_memory_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void destroy_animation_handler(Animation *animation, bool finished, void *context) {
|
|
||||||
animation_destroy(animation);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void schedule_guy_animation(Animation *raise_tmpl, Animation *out_tmpl, AnimationStoppedHandler out_handler) {
|
static void schedule_guy_animation(Animation *raise_tmpl, Animation *out_tmpl, AnimationStoppedHandler out_handler) {
|
||||||
Animation *raise = animation_clone(raise_tmpl);
|
Animation *raise = animation_clone(raise_tmpl);
|
||||||
Animation *out = animation_clone(out_tmpl);
|
Animation *out = animation_clone(out_tmpl);
|
||||||
@@ -193,36 +246,11 @@ static void main_window_load(Window *window) {
|
|||||||
bitmap_layer_set_alignment(s_guy_butt_layer, GAlignTopLeft);
|
bitmap_layer_set_alignment(s_guy_butt_layer, GAlignTopLeft);
|
||||||
bitmap_layer_set_bitmap(s_guy_butt_layer, s_butt_current);
|
bitmap_layer_set_bitmap(s_guy_butt_layer, s_butt_current);
|
||||||
|
|
||||||
// format time layer
|
|
||||||
s_time_layer = text_layer_create(GRect(0, PBL_IF_ROUND_ELSE(109, 93), PBL_IF_ROUND_ELSE(260, 200), 34));
|
|
||||||
text_layer_set_background_color(s_time_layer, GColorClear);
|
|
||||||
text_layer_set_font(s_time_layer, s_custom_font);
|
|
||||||
text_layer_set_text_alignment(s_time_layer, GTextAlignmentCenter);
|
|
||||||
|
|
||||||
// format date layer
|
|
||||||
s_date_layer = text_layer_create(GRect(0, PBL_IF_ROUND_ELSE(121, 105), PBL_IF_ROUND_ELSE(69, 39), 14));
|
|
||||||
text_layer_set_background_color(s_date_layer, GColorClear);
|
|
||||||
text_layer_set_font(s_date_layer, fonts_get_system_font(FONT_KEY_GOTHIC_14_BOLD));
|
|
||||||
text_layer_set_text_alignment(s_date_layer, GTextAlignmentCenter);
|
|
||||||
|
|
||||||
// format BT indicator layer
|
|
||||||
s_bt_layer = bitmap_layer_create(GRect(PBL_IF_ROUND_ELSE(191, 161), PBL_IF_ROUND_ELSE(118, 102), PBL_IF_ROUND_ELSE(69, 39), 24));
|
|
||||||
bitmap_layer_set_compositing_mode(s_bt_layer, GCompOpSet);
|
|
||||||
bitmap_layer_set_alignment(s_bt_layer, GAlignCenter);
|
|
||||||
bitmap_layer_set_bitmap(s_bt_layer, s_bt_icon);
|
|
||||||
|
|
||||||
// create time bar layer
|
// create time bar layer
|
||||||
s_time_bar_layer = layer_create(GRect(0, PBL_IF_ROUND_ELSE(115, 99), PBL_IF_ROUND_ELSE(260, 200), 30));
|
s_time_bar_layer = layer_create(GRect(0, PBL_IF_ROUND_ELSE(115, 99), PBL_IF_ROUND_ELSE(260, 200), 30));
|
||||||
layer_set_update_proc(s_time_bar_layer, time_bar_update_proc);
|
layer_set_update_proc(s_time_bar_layer, time_bar_update_proc);
|
||||||
text_layer_set_text_alignment(s_date_layer, GTextAlignmentCenter);
|
text_layer_set_text_alignment(s_date_layer, GTextAlignmentCenter);
|
||||||
|
|
||||||
// DEBUG memory usage layer
|
|
||||||
s_memory_layer = text_layer_create(GRect(0, PBL_IF_ROUND_ELSE(220, 190), PBL_IF_ROUND_ELSE(260, 200), 14));
|
|
||||||
text_layer_set_background_color(s_memory_layer, GColorClear);
|
|
||||||
text_layer_set_font(s_memory_layer, fonts_get_system_font(FONT_KEY_GOTHIC_14));
|
|
||||||
text_layer_set_text_color(s_memory_layer, GColorWhite);
|
|
||||||
PBL_IF_ROUND_ELSE(text_layer_set_text_alignment(s_memory_layer, GTextAlignmentCenter), text_layer_set_text_alignment(s_memory_layer, GTextAlignmentLeft));
|
|
||||||
|
|
||||||
// add layers as children to window
|
// add layers as children to window
|
||||||
layer_add_child(window_layer, bitmap_layer_get_layer(s_guy_head_layer));
|
layer_add_child(window_layer, bitmap_layer_get_layer(s_guy_head_layer));
|
||||||
layer_add_child(window_layer, bitmap_layer_get_layer(s_guy_butt_layer));
|
layer_add_child(window_layer, bitmap_layer_get_layer(s_guy_butt_layer));
|
||||||
@@ -239,22 +267,22 @@ static void main_window_load(Window *window) {
|
|||||||
PropertyAnimation *butt_raise_prop = property_animation_create_layer_frame(bitmap_layer_get_layer(s_guy_butt_layer), &s_guy_butt_grect_on_screen_resting, &s_guy_butt_grect_on_screen_raised);
|
PropertyAnimation *butt_raise_prop = property_animation_create_layer_frame(bitmap_layer_get_layer(s_guy_butt_layer), &s_guy_butt_grect_on_screen_resting, &s_guy_butt_grect_on_screen_raised);
|
||||||
s_butt_raise_template = property_animation_get_animation(butt_raise_prop);
|
s_butt_raise_template = property_animation_get_animation(butt_raise_prop);
|
||||||
animation_set_curve(s_butt_raise_template, AnimationCurveEaseOut);
|
animation_set_curve(s_butt_raise_template, AnimationCurveEaseOut);
|
||||||
animation_set_duration(s_butt_raise_template, 350);
|
animation_set_duration(s_butt_raise_template, s_animation_duration);
|
||||||
// butt Out
|
// butt Out
|
||||||
PropertyAnimation *butt_out_prop = property_animation_create_layer_frame(bitmap_layer_get_layer(s_guy_butt_layer), &s_guy_butt_grect_on_screen_raised, &s_guy_butt_grect_off_screen_raised);
|
PropertyAnimation *butt_out_prop = property_animation_create_layer_frame(bitmap_layer_get_layer(s_guy_butt_layer), &s_guy_butt_grect_on_screen_raised, &s_guy_butt_grect_off_screen_raised);
|
||||||
s_butt_out_template = property_animation_get_animation(butt_out_prop);
|
s_butt_out_template = property_animation_get_animation(butt_out_prop);
|
||||||
animation_set_curve(s_butt_out_template, AnimationCurveEaseOut);
|
animation_set_curve(s_butt_out_template, AnimationCurveEaseOut);
|
||||||
animation_set_duration(s_butt_out_template, 350);
|
animation_set_duration(s_butt_out_template, s_animation_duration);
|
||||||
// head Raise
|
// head Raise
|
||||||
PropertyAnimation *head_raise_prop = property_animation_create_layer_frame(bitmap_layer_get_layer(s_guy_head_layer), &s_guy_head_grect_on_screen_resting, &s_guy_head_grect_on_screen_raised);
|
PropertyAnimation *head_raise_prop = property_animation_create_layer_frame(bitmap_layer_get_layer(s_guy_head_layer), &s_guy_head_grect_on_screen_resting, &s_guy_head_grect_on_screen_raised);
|
||||||
s_head_raise_template = property_animation_get_animation(head_raise_prop);
|
s_head_raise_template = property_animation_get_animation(head_raise_prop);
|
||||||
animation_set_curve(s_head_raise_template, AnimationCurveEaseOut);
|
animation_set_curve(s_head_raise_template, AnimationCurveEaseOut);
|
||||||
animation_set_duration(s_head_raise_template, 350);
|
animation_set_duration(s_head_raise_template, s_animation_duration);
|
||||||
// head Out
|
// head Out
|
||||||
PropertyAnimation *head_out_prop = property_animation_create_layer_frame(bitmap_layer_get_layer(s_guy_head_layer), &s_guy_head_grect_on_screen_raised, &s_guy_head_grect_off_screen_raised);
|
PropertyAnimation *head_out_prop = property_animation_create_layer_frame(bitmap_layer_get_layer(s_guy_head_layer), &s_guy_head_grect_on_screen_raised, &s_guy_head_grect_off_screen_raised);
|
||||||
s_head_out_template = property_animation_get_animation(head_out_prop);
|
s_head_out_template = property_animation_get_animation(head_out_prop);
|
||||||
animation_set_curve(s_head_out_template, AnimationCurveEaseOut);
|
animation_set_curve(s_head_out_template, AnimationCurveEaseOut);
|
||||||
animation_set_duration(s_head_out_template, 350);
|
animation_set_duration(s_head_out_template, s_animation_duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
// free memory on Window close
|
// free memory on Window close
|
||||||
@@ -262,14 +290,8 @@ static void main_window_unload(Window *window) {
|
|||||||
// destroy layers
|
// destroy layers
|
||||||
bitmap_layer_destroy(s_guy_head_layer);
|
bitmap_layer_destroy(s_guy_head_layer);
|
||||||
bitmap_layer_destroy(s_guy_butt_layer);
|
bitmap_layer_destroy(s_guy_butt_layer);
|
||||||
text_layer_destroy(s_time_layer);
|
|
||||||
text_layer_destroy(s_date_layer);
|
|
||||||
bitmap_layer_destroy(s_bt_layer);
|
|
||||||
layer_destroy(s_time_bar_layer);
|
layer_destroy(s_time_bar_layer);
|
||||||
|
|
||||||
// DEBUG memory usage layer
|
|
||||||
text_layer_destroy(s_memory_layer);
|
|
||||||
|
|
||||||
// Destroy animation templates
|
// Destroy animation templates
|
||||||
animation_destroy(s_butt_raise_template);
|
animation_destroy(s_butt_raise_template);
|
||||||
animation_destroy(s_butt_out_template);
|
animation_destroy(s_butt_out_template);
|
||||||
@@ -327,11 +349,37 @@ static void init() {
|
|||||||
// load bluetooth indicator
|
// load bluetooth indicator
|
||||||
s_bt_icon = gbitmap_create_with_resource(RESOURCE_ID_BT);
|
s_bt_icon = gbitmap_create_with_resource(RESOURCE_ID_BT);
|
||||||
|
|
||||||
// show the Window on the watch, with animated=true
|
// pre-create layers used in update_minute_1
|
||||||
window_stack_push(s_main_window, true);
|
//// time
|
||||||
|
s_time_layer = text_layer_create(GRect(0, PBL_IF_ROUND_ELSE(109, 93), PBL_IF_ROUND_ELSE(260, 200), 34));
|
||||||
|
text_layer_set_background_color(s_time_layer, GColorClear);
|
||||||
|
text_layer_set_font(s_time_layer, s_custom_font);
|
||||||
|
text_layer_set_text_alignment(s_time_layer, GTextAlignmentCenter);
|
||||||
|
//// date
|
||||||
|
s_date_layer = text_layer_create(s_date_grect_a);
|
||||||
|
text_layer_set_background_color(s_date_layer, GColorClear);
|
||||||
|
text_layer_set_font(s_date_layer, fonts_get_system_font(FONT_KEY_GOTHIC_14_BOLD));
|
||||||
|
text_layer_set_text_alignment(s_date_layer, GTextAlignmentCenter);
|
||||||
|
//// bt
|
||||||
|
s_bt_layer = bitmap_layer_create(s_bt_grect_a);
|
||||||
|
bitmap_layer_set_compositing_mode(s_bt_layer, GCompOpSet);
|
||||||
|
bitmap_layer_set_alignment(s_bt_layer, GAlignCenter);
|
||||||
|
bitmap_layer_set_bitmap(s_bt_layer, s_bt_icon);
|
||||||
|
//// DEBUG memory usage layer
|
||||||
|
s_memory_layer = text_layer_create(GRect(0, PBL_IF_ROUND_ELSE(220, 190), PBL_IF_ROUND_ELSE(260, 200), 14));
|
||||||
|
text_layer_set_background_color(s_memory_layer, GColorClear);
|
||||||
|
text_layer_set_font(s_memory_layer, fonts_get_system_font(FONT_KEY_GOTHIC_14));
|
||||||
|
text_layer_set_text_color(s_memory_layer, GColorWhite);
|
||||||
|
PBL_IF_ROUND_ELSE(text_layer_set_text_alignment(s_memory_layer, GTextAlignmentCenter), text_layer_set_text_alignment(s_memory_layer, GTextAlignmentLeft));
|
||||||
|
|
||||||
// make sure the time is displayed from the start
|
// make sure the time is displayed from the start
|
||||||
|
// and that the date/bt indicators are centered
|
||||||
update_minute_1();
|
update_minute_1();
|
||||||
|
layer_set_frame(text_layer_get_layer(s_date_layer), s_date_grect_a);
|
||||||
|
layer_set_frame(bitmap_layer_get_layer(s_bt_layer), s_bt_grect_a);
|
||||||
|
|
||||||
|
// show the Window on the watch, with animated=true
|
||||||
|
window_stack_push(s_main_window, true);
|
||||||
|
|
||||||
// register with TickTimerService
|
// register with TickTimerService
|
||||||
tick_timer_service_subscribe(MINUTE_UNIT, minute_handler);
|
tick_timer_service_subscribe(MINUTE_UNIT, minute_handler);
|
||||||
@@ -342,6 +390,14 @@ static void init() {
|
|||||||
|
|
||||||
// free memory on app exit
|
// free memory on app exit
|
||||||
static void deinit() {
|
static void deinit() {
|
||||||
|
// destroy layers
|
||||||
|
text_layer_destroy(s_time_layer);
|
||||||
|
text_layer_destroy(s_date_layer);
|
||||||
|
bitmap_layer_destroy(s_bt_layer);
|
||||||
|
|
||||||
|
// DEBUG memory usage layer
|
||||||
|
text_layer_destroy(s_memory_layer);
|
||||||
|
|
||||||
// unload font
|
// unload font
|
||||||
fonts_unload_custom_font(s_custom_font);
|
fonts_unload_custom_font(s_custom_font);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user