Add basic alarm functionality
This commit is contained in:
+72
-16
@@ -11,6 +11,7 @@ typedef struct SetterTime {
|
|||||||
|
|
||||||
// layer-age
|
// layer-age
|
||||||
static Window *s_window;
|
static Window *s_window;
|
||||||
|
//// setter
|
||||||
static Layer *s_top_bar_layer;
|
static Layer *s_top_bar_layer;
|
||||||
static Layer *s_bottom_bar_layer;
|
static Layer *s_bottom_bar_layer;
|
||||||
static BitmapLayer *s_clock_bmp_layer;
|
static BitmapLayer *s_clock_bmp_layer;
|
||||||
@@ -18,16 +19,21 @@ static BitmapLayer *s_check_bmp_layer;
|
|||||||
static TextLayer *s_countdown_txt_layer;
|
static TextLayer *s_countdown_txt_layer;
|
||||||
static TextLayer *s_setter_txt_layer;
|
static TextLayer *s_setter_txt_layer;
|
||||||
static Layer *s_highlight_layer;
|
static Layer *s_highlight_layer;
|
||||||
|
//// alarm
|
||||||
|
static TextLayer *s_alarm_txt_layer;
|
||||||
|
|
||||||
// bitmaps
|
// bitmaps
|
||||||
|
//// setter
|
||||||
static GBitmap *s_clock_bmp;
|
static GBitmap *s_clock_bmp;
|
||||||
static GBitmap *s_check_bmp;
|
static GBitmap *s_check_bmp;
|
||||||
|
|
||||||
// global vars
|
// global vars
|
||||||
|
//// setter
|
||||||
static uint8_t s_highlight_pos = 0;
|
static uint8_t s_highlight_pos = 0;
|
||||||
static struct SetterTime s_setter_time;
|
static struct SetterTime s_setter_time;
|
||||||
|
|
||||||
// constants
|
// constants
|
||||||
|
//// setter
|
||||||
static const uint8_t s_edge_bar_height = ((PBL_DISPLAY_HEIGHT / 7) * 2);
|
static const uint8_t s_edge_bar_height = ((PBL_DISPLAY_HEIGHT / 7) * 2);
|
||||||
static const GColor s_primary_color = GColorJaegerGreen;
|
static const GColor s_primary_color = GColorJaegerGreen;
|
||||||
static const GColor s_highlight_color = GColorMediumAquamarine;
|
static const GColor s_highlight_color = GColorMediumAquamarine;
|
||||||
@@ -36,10 +42,10 @@ static const GColor s_highlight_color = GColorMediumAquamarine;
|
|||||||
|
|
||||||
/////////////////////////////////
|
/////////////////////////////////
|
||||||
|
|
||||||
static void seconds_handler(struct tm *tick_time, TimeUnits units_changed) {
|
static void setter_seconds_handler(struct tm *tick_time, TimeUnits units_changed) {
|
||||||
struct tm now_tm = *tick_time;
|
struct tm now_tm = *tick_time;
|
||||||
|
|
||||||
// Build the target time today
|
// build the target time today
|
||||||
struct tm target_tm = now_tm;
|
struct tm target_tm = now_tm;
|
||||||
target_tm.tm_hour = s_setter_time.HourSet;
|
target_tm.tm_hour = s_setter_time.HourSet;
|
||||||
target_tm.tm_min = s_setter_time.MinuteSet;
|
target_tm.tm_min = s_setter_time.MinuteSet;
|
||||||
@@ -66,7 +72,7 @@ static void seconds_handler(struct tm *tick_time, TimeUnits units_changed) {
|
|||||||
|
|
||||||
static void update_countdown_display() {
|
static void update_countdown_display() {
|
||||||
time_t now = time(NULL);
|
time_t now = time(NULL);
|
||||||
seconds_handler(localtime(&now), SECOND_UNIT);
|
setter_seconds_handler(localtime(&now), SECOND_UNIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void update_setter_display() {
|
static void update_setter_display() {
|
||||||
@@ -75,7 +81,7 @@ static void update_setter_display() {
|
|||||||
text_layer_set_text(s_setter_txt_layer, s_setter_buffer);
|
text_layer_set_text(s_setter_txt_layer, s_setter_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void up_click_handler(void *recognizer, void *ctx) {
|
static void setter_up_click_handler(void *recognizer, void *ctx) {
|
||||||
switch (s_highlight_pos) {
|
switch (s_highlight_pos) {
|
||||||
case 0:
|
case 0:
|
||||||
if (s_setter_time.HourWIP == 23) {
|
if (s_setter_time.HourWIP == 23) {
|
||||||
@@ -97,7 +103,7 @@ static void up_click_handler(void *recognizer, void *ctx) {
|
|||||||
update_setter_display();
|
update_setter_display();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void down_click_handler(void *recognizer, void *ctx) {
|
static void setter_down_click_handler(void *recognizer, void *ctx) {
|
||||||
switch (s_highlight_pos) {
|
switch (s_highlight_pos) {
|
||||||
case 0:
|
case 0:
|
||||||
if (s_setter_time.HourWIP == 0) {
|
if (s_setter_time.HourWIP == 0) {
|
||||||
@@ -119,13 +125,38 @@ static void down_click_handler(void *recognizer, void *ctx) {
|
|||||||
update_setter_display();
|
update_setter_display();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void select_click_handler(void *recognizer, void *ctx) {
|
static void setter_select_click_handler(void *recognizer, void *ctx) {
|
||||||
if (s_highlight_pos == 2) {
|
if (s_highlight_pos == 2) {
|
||||||
|
// copy WIP time to set time
|
||||||
s_setter_time.HourSet = s_setter_time.HourWIP;
|
s_setter_time.HourSet = s_setter_time.HourWIP;
|
||||||
s_setter_time.MinuteSet = s_setter_time.MinuteWIP;
|
s_setter_time.MinuteSet = s_setter_time.MinuteWIP;
|
||||||
|
|
||||||
|
// schedule wakeup
|
||||||
|
time_t now = time(NULL);
|
||||||
|
struct tm now_tm = *localtime(&now);
|
||||||
|
struct tm target_tm = now_tm;
|
||||||
|
target_tm.tm_hour = s_setter_time.HourSet;
|
||||||
|
target_tm.tm_min = s_setter_time.MinuteSet;
|
||||||
|
target_tm.tm_sec = 0;
|
||||||
|
time_t target = mktime(&target_tm);
|
||||||
|
if (target <= now) {
|
||||||
|
target += SECONDS_PER_DAY;
|
||||||
|
}
|
||||||
|
wakeup_cancel_all();
|
||||||
|
wakeup_schedule(target, 0, true);
|
||||||
|
for (int i = 0; i < 7; ++i) {
|
||||||
|
target += SECONDS_PER_DAY;
|
||||||
|
wakeup_schedule(target, 0, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// persist
|
||||||
persist_write_int(STORAGE_KEY_ALARM_HOUR, s_setter_time.HourSet);
|
persist_write_int(STORAGE_KEY_ALARM_HOUR, s_setter_time.HourSet);
|
||||||
persist_write_int(STORAGE_KEY_ALARM_MINUTE, s_setter_time.MinuteSet);
|
persist_write_int(STORAGE_KEY_ALARM_MINUTE, s_setter_time.MinuteSet);
|
||||||
|
|
||||||
|
// update countdown immediately
|
||||||
update_countdown_display();
|
update_countdown_display();
|
||||||
|
|
||||||
|
// move selection back to start
|
||||||
s_highlight_pos = 0;
|
s_highlight_pos = 0;
|
||||||
} else {
|
} else {
|
||||||
s_highlight_pos++;
|
s_highlight_pos++;
|
||||||
@@ -134,7 +165,7 @@ static void select_click_handler(void *recognizer, void *ctx) {
|
|||||||
layer_mark_dirty(s_bottom_bar_layer);
|
layer_mark_dirty(s_bottom_bar_layer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void back_click_handler(void *recognizer, void *ctx) {
|
static void setter_back_click_handler(void *recognizer, void *ctx) {
|
||||||
if (s_highlight_pos == 0) {
|
if (s_highlight_pos == 0) {
|
||||||
window_stack_pop_all(true); // exit app
|
window_stack_pop_all(true); // exit app
|
||||||
} else {
|
} else {
|
||||||
@@ -144,11 +175,11 @@ static void back_click_handler(void *recognizer, void *ctx) {
|
|||||||
layer_mark_dirty(s_bottom_bar_layer);
|
layer_mark_dirty(s_bottom_bar_layer);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void click_config_provider(void *ctx) {
|
static void setter_click_config_provider(void *ctx) {
|
||||||
window_single_repeating_click_subscribe(BUTTON_ID_UP, 60, up_click_handler);
|
window_single_repeating_click_subscribe(BUTTON_ID_UP, 60, setter_up_click_handler);
|
||||||
window_single_repeating_click_subscribe(BUTTON_ID_DOWN, 60, down_click_handler);
|
window_single_repeating_click_subscribe(BUTTON_ID_DOWN, 60, setter_down_click_handler);
|
||||||
window_single_click_subscribe(BUTTON_ID_SELECT, select_click_handler);
|
window_single_click_subscribe(BUTTON_ID_SELECT, setter_select_click_handler);
|
||||||
window_single_click_subscribe(BUTTON_ID_BACK, back_click_handler);
|
window_single_click_subscribe(BUTTON_ID_BACK, setter_back_click_handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void top_bar_layer_update_proc(Layer *layer, GContext *ctx) {
|
static void top_bar_layer_update_proc(Layer *layer, GContext *ctx) {
|
||||||
@@ -231,12 +262,12 @@ static void setter_window_load() {
|
|||||||
layer_add_child(window_layer, text_layer_get_layer(s_setter_txt_layer));
|
layer_add_child(window_layer, text_layer_get_layer(s_setter_txt_layer));
|
||||||
update_setter_display();
|
update_setter_display();
|
||||||
|
|
||||||
tick_timer_service_subscribe(SECOND_UNIT, seconds_handler);
|
tick_timer_service_subscribe(SECOND_UNIT, setter_seconds_handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setter_window_unload() {
|
static void setter_window_unload() {
|
||||||
layer_destroy(s_highlight_layer);
|
|
||||||
text_layer_destroy(s_setter_txt_layer);
|
text_layer_destroy(s_setter_txt_layer);
|
||||||
|
layer_destroy(s_highlight_layer);
|
||||||
text_layer_destroy(s_countdown_txt_layer);
|
text_layer_destroy(s_countdown_txt_layer);
|
||||||
bitmap_layer_destroy(s_check_bmp_layer);
|
bitmap_layer_destroy(s_check_bmp_layer);
|
||||||
bitmap_layer_destroy(s_clock_bmp_layer);
|
bitmap_layer_destroy(s_clock_bmp_layer);
|
||||||
@@ -246,17 +277,42 @@ static void setter_window_unload() {
|
|||||||
layer_destroy(s_top_bar_layer);
|
layer_destroy(s_top_bar_layer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void alarm_seconds_handler(struct tm *tick_time, TimeUnits units_changed) {
|
||||||
|
vibes_short_pulse();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void alarm_window_load() {
|
||||||
|
Layer *window_layer = window_get_root_layer(s_window);
|
||||||
|
|
||||||
|
s_alarm_txt_layer = text_layer_create(GRect(0, (PBL_DISPLAY_HEIGHT / 2) - 27, PBL_DISPLAY_WIDTH, 34));
|
||||||
|
text_layer_set_text_alignment(s_alarm_txt_layer, GTextAlignmentCenter);
|
||||||
|
text_layer_set_background_color(s_alarm_txt_layer, GColorClear);
|
||||||
|
text_layer_set_font(s_alarm_txt_layer, fonts_get_system_font(FONT_KEY_GOTHIC_24));
|
||||||
|
text_layer_set_text(s_alarm_txt_layer, "IMAGINE THIS IS A TRIANGLE");
|
||||||
|
layer_add_child(window_layer, text_layer_get_layer(s_alarm_txt_layer));
|
||||||
|
|
||||||
|
tick_timer_service_subscribe(SECOND_UNIT, alarm_seconds_handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void alarm_window_unload() {
|
||||||
|
text_layer_destroy(s_alarm_txt_layer);
|
||||||
|
}
|
||||||
|
|
||||||
static void init() {
|
static void init() {
|
||||||
s_window = window_create();
|
s_window = window_create();
|
||||||
|
|
||||||
switch (launch_reason()) {
|
switch (launch_reason()) {
|
||||||
case APP_LAUNCH_WAKEUP:
|
case APP_LAUNCH_WAKEUP:
|
||||||
break; // TODO math time!
|
window_set_window_handlers(
|
||||||
|
s_window,
|
||||||
|
(WindowHandlers){.load = alarm_window_load, .unload = alarm_window_unload});
|
||||||
|
window_stack_push(s_window, false);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
window_set_window_handlers(
|
window_set_window_handlers(
|
||||||
s_window,
|
s_window,
|
||||||
(WindowHandlers){.load = setter_window_load, .unload = setter_window_unload});
|
(WindowHandlers){.load = setter_window_load, .unload = setter_window_unload});
|
||||||
window_set_click_config_provider(s_window, click_config_provider);
|
window_set_click_config_provider(s_window, setter_click_config_provider);
|
||||||
window_stack_push(s_window, false);
|
window_stack_push(s_window, false);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user