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_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 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
|
||||
static uint8_t s_animation_duration = 255;
|
||||
static Animation *s_head_raise_template;
|
||||
static Animation *s_head_out_template;
|
||||
static Animation *s_butt_raise_template;
|
||||
static Animation *s_butt_out_template;
|
||||
|
||||
// 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 uint32_t s_random_heads[] = {
|
||||
RESOURCE_ID_H001, RESOURCE_ID_H002, RESOURCE_ID_H003, RESOURCE_ID_H004,
|
||||
@@ -75,6 +88,12 @@ static const GColor8 s_dark_bg_colors[] = {
|
||||
// Brown
|
||||
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() {
|
||||
// get a tm structure
|
||||
time_t temp = time(NULL);
|
||||
@@ -88,19 +107,53 @@ static void update_minute_1() {
|
||||
static char s_date_buffer[16];
|
||||
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_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
|
||||
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());
|
||||
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) {
|
||||
Animation *raise = animation_clone(raise_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_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
|
||||
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);
|
||||
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
|
||||
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));
|
||||
@@ -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);
|
||||
s_butt_raise_template = property_animation_get_animation(butt_raise_prop);
|
||||
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
|
||||
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);
|
||||
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
|
||||
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);
|
||||
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
|
||||
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);
|
||||
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
|
||||
@@ -262,14 +290,8 @@ static void main_window_unload(Window *window) {
|
||||
// destroy layers
|
||||
bitmap_layer_destroy(s_guy_head_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);
|
||||
|
||||
// DEBUG memory usage layer
|
||||
text_layer_destroy(s_memory_layer);
|
||||
|
||||
// Destroy animation templates
|
||||
animation_destroy(s_butt_raise_template);
|
||||
animation_destroy(s_butt_out_template);
|
||||
@@ -327,11 +349,37 @@ static void init() {
|
||||
// load bluetooth indicator
|
||||
s_bt_icon = gbitmap_create_with_resource(RESOURCE_ID_BT);
|
||||
|
||||
// show the Window on the watch, with animated=true
|
||||
window_stack_push(s_main_window, true);
|
||||
// pre-create layers used in update_minute_1
|
||||
//// 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
|
||||
// and that the date/bt indicators are centered
|
||||
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
|
||||
tick_timer_service_subscribe(MINUTE_UNIT, minute_handler);
|
||||
@@ -342,6 +390,14 @@ static void init() {
|
||||
|
||||
// free memory on app exit
|
||||
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
|
||||
fonts_unload_custom_font(s_custom_font);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user