Add basic alarm functionality
This commit is contained in:
+72
-16
@@ -11,6 +11,7 @@ typedef struct SetterTime {
|
||||
|
||||
// layer-age
|
||||
static Window *s_window;
|
||||
//// setter
|
||||
static Layer *s_top_bar_layer;
|
||||
static Layer *s_bottom_bar_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_setter_txt_layer;
|
||||
static Layer *s_highlight_layer;
|
||||
//// alarm
|
||||
static TextLayer *s_alarm_txt_layer;
|
||||
|
||||
// bitmaps
|
||||
//// setter
|
||||
static GBitmap *s_clock_bmp;
|
||||
static GBitmap *s_check_bmp;
|
||||
|
||||
// global vars
|
||||
//// setter
|
||||
static uint8_t s_highlight_pos = 0;
|
||||
static struct SetterTime s_setter_time;
|
||||
|
||||
// constants
|
||||
//// setter
|
||||
static const uint8_t s_edge_bar_height = ((PBL_DISPLAY_HEIGHT / 7) * 2);
|
||||
static const GColor s_primary_color = GColorJaegerGreen;
|
||||
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;
|
||||
|
||||
// Build the target time today
|
||||
// build the target time today
|
||||
struct tm target_tm = now_tm;
|
||||
target_tm.tm_hour = s_setter_time.HourSet;
|
||||
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() {
|
||||
time_t now = time(NULL);
|
||||
seconds_handler(localtime(&now), SECOND_UNIT);
|
||||
setter_seconds_handler(localtime(&now), SECOND_UNIT);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
static void up_click_handler(void *recognizer, void *ctx) {
|
||||
static void setter_up_click_handler(void *recognizer, void *ctx) {
|
||||
switch (s_highlight_pos) {
|
||||
case 0:
|
||||
if (s_setter_time.HourWIP == 23) {
|
||||
@@ -97,7 +103,7 @@ static void up_click_handler(void *recognizer, void *ctx) {
|
||||
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) {
|
||||
case 0:
|
||||
if (s_setter_time.HourWIP == 0) {
|
||||
@@ -119,13 +125,38 @@ static void down_click_handler(void *recognizer, void *ctx) {
|
||||
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) {
|
||||
// copy WIP time to set time
|
||||
s_setter_time.HourSet = s_setter_time.HourWIP;
|
||||
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_MINUTE, s_setter_time.MinuteSet);
|
||||
|
||||
// update countdown immediately
|
||||
update_countdown_display();
|
||||
|
||||
// move selection back to start
|
||||
s_highlight_pos = 0;
|
||||
} else {
|
||||
s_highlight_pos++;
|
||||
@@ -134,7 +165,7 @@ static void select_click_handler(void *recognizer, void *ctx) {
|
||||
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) {
|
||||
window_stack_pop_all(true); // exit app
|
||||
} else {
|
||||
@@ -144,11 +175,11 @@ static void back_click_handler(void *recognizer, void *ctx) {
|
||||
layer_mark_dirty(s_bottom_bar_layer);
|
||||
}
|
||||
|
||||
static void click_config_provider(void *ctx) {
|
||||
window_single_repeating_click_subscribe(BUTTON_ID_UP, 60, up_click_handler);
|
||||
window_single_repeating_click_subscribe(BUTTON_ID_DOWN, 60, down_click_handler);
|
||||
window_single_click_subscribe(BUTTON_ID_SELECT, select_click_handler);
|
||||
window_single_click_subscribe(BUTTON_ID_BACK, back_click_handler);
|
||||
static void setter_click_config_provider(void *ctx) {
|
||||
window_single_repeating_click_subscribe(BUTTON_ID_UP, 60, setter_up_click_handler);
|
||||
window_single_repeating_click_subscribe(BUTTON_ID_DOWN, 60, setter_down_click_handler);
|
||||
window_single_click_subscribe(BUTTON_ID_SELECT, setter_select_click_handler);
|
||||
window_single_click_subscribe(BUTTON_ID_BACK, setter_back_click_handler);
|
||||
}
|
||||
|
||||
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));
|
||||
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() {
|
||||
layer_destroy(s_highlight_layer);
|
||||
text_layer_destroy(s_setter_txt_layer);
|
||||
layer_destroy(s_highlight_layer);
|
||||
text_layer_destroy(s_countdown_txt_layer);
|
||||
bitmap_layer_destroy(s_check_bmp_layer);
|
||||
bitmap_layer_destroy(s_clock_bmp_layer);
|
||||
@@ -246,17 +277,42 @@ static void setter_window_unload() {
|
||||
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() {
|
||||
s_window = window_create();
|
||||
|
||||
switch (launch_reason()) {
|
||||
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:
|
||||
window_set_window_handlers(
|
||||
s_window,
|
||||
(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);
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user