536 lines
19 KiB
C
536 lines
19 KiB
C
#include "src/resource_ids.auto.h"
|
|
#include <pebble.h>
|
|
|
|
// types
|
|
typedef struct TheTime {
|
|
uint8_t HourWIP;
|
|
uint8_t MinuteWIP;
|
|
uint8_t HourSet;
|
|
uint8_t MinuteSet;
|
|
} __attribute__((__packed__)) TheTime;
|
|
|
|
// layer-age
|
|
static Window *s_window;
|
|
static Layer *s_top_bar_layer;
|
|
static Layer *s_bottom_bar_layer;
|
|
//// setter
|
|
static BitmapLayer *s_clock_bmp_layer;
|
|
static BitmapLayer *s_check_bmp_layer;
|
|
static TextLayer *s_countdown_txt_layer;
|
|
static TextLayer *s_setter_txt_layer;
|
|
static Layer *s_setter_highlight_layer;
|
|
//// alarm
|
|
static TextLayer *s_type_txt_layer;
|
|
static TextLayer *s_theta_txt_layer;
|
|
static TextLayer *s_parenthesis_txt_layer;
|
|
static Layer *s_drop_type_layer;
|
|
static Layer *s_drop_function_layer;
|
|
static Layer *s_drop_over_layer;
|
|
static Layer *s_drop_under_layer;
|
|
static Layer *s_division_layer;
|
|
static Layer *s_alarm_highlight_layer;
|
|
|
|
// fonts
|
|
//// setter
|
|
GFont s_font_lecoish_big;
|
|
GFont s_font_lecoish_small;
|
|
//// alarm
|
|
GFont s_font_mansalva_big;
|
|
GFont s_font_mansalva_small;
|
|
|
|
// bitmaps
|
|
//// setter
|
|
static GBitmap *s_clock_bmp;
|
|
static GBitmap *s_check_bmp;
|
|
|
|
// global vars
|
|
static GColor s_setter_highlight_color;
|
|
static uint8_t s_highlight_pos = 0;
|
|
static struct TheTime s_the_time;
|
|
|
|
// constants
|
|
static const uint8_t s_edge_bar_height = ((PBL_DISPLAY_HEIGHT / 7) * 2);
|
|
static const GRect s_top_bar_grect = GRect(0, 0, PBL_DISPLAY_WIDTH, s_edge_bar_height);
|
|
static const GRect s_bottom_bar_grect = GRect(0, PBL_DISPLAY_HEIGHT - s_edge_bar_height, PBL_DISPLAY_WIDTH, s_edge_bar_height);
|
|
static const GColor s_primary_color = GColorJaegerGreen;
|
|
#define STORAGE_KEY_ALARM_HOUR 0
|
|
#define STORAGE_KEY_ALARM_MINUTE 1
|
|
//// alarm
|
|
static const uint8_t s_drop_height = 22;
|
|
static const GRect s_drop_type_grect = GRect(PBL_IF_ROUND_ELSE(48, 62), (s_top_bar_grect.size.h / 2) - PBL_IF_ROUND_ELSE(-4, s_drop_height / 2), PBL_DISPLAY_WIDTH - PBL_IF_ROUND_ELSE(96, 70), s_drop_height);
|
|
static const GRect s_drop_function_grect = GRect(PBL_IF_ROUND_ELSE(55, 45), s_bottom_bar_grect.origin.y + ((s_bottom_bar_grect.size.h / 2) - PBL_IF_ROUND_ELSE(s_drop_height - 1, s_drop_height / 2)), 50, s_drop_height);
|
|
static const GRect s_drop_over_grect = GRect(s_drop_function_grect.origin.x + 78, s_drop_function_grect.origin.y - 13, s_drop_function_grect.size.w + 1, s_drop_function_grect.size.h);
|
|
static const GRect s_drop_under_grect = GRect(s_drop_over_grect.origin.x, s_drop_over_grect.origin.y + s_drop_over_grect.size.h + 5, s_drop_function_grect.size.w, s_drop_over_grect.size.h);
|
|
|
|
/////////////////////////////////
|
|
|
|
static void glance_reload_callback(AppGlanceReloadSession *session, size_t limit, void *target) {
|
|
static char s_glance_buffer[11];
|
|
snprintf(s_glance_buffer, sizeof(s_glance_buffer), "Up @ %02d:%02d", s_the_time.HourSet, s_the_time.MinuteSet);
|
|
AppGlanceSlice slice = {
|
|
.expiration_time = (time_t)(uintptr_t)target,
|
|
.layout.icon = APP_GLANCE_SLICE_DEFAULT_ICON,
|
|
.layout.subtitle_template_string = s_glance_buffer,
|
|
};
|
|
app_glance_add_slice(session, slice);
|
|
}
|
|
|
|
// returns (passes through) the negative value from wakeup_schedule
|
|
// when an error is encountered
|
|
static int8_t schedule_main_alarm() {
|
|
time_t now = time(NULL);
|
|
struct tm now_tm = *localtime(&now);
|
|
struct tm target_tm = now_tm;
|
|
target_tm.tm_hour = s_the_time.HourWIP;
|
|
target_tm.tm_min = s_the_time.MinuteWIP;
|
|
target_tm.tm_sec = 0;
|
|
time_t target = mktime(&target_tm);
|
|
if (target <= now) {
|
|
target += SECONDS_PER_DAY;
|
|
}
|
|
wakeup_cancel_all();
|
|
WakeupId status = wakeup_schedule(target, 0, true);
|
|
if (status < 0) {
|
|
APP_LOG(APP_LOG_LEVEL_DEBUG, "SCHEDULING ERROR: %d", status);
|
|
return status;
|
|
}
|
|
s_the_time.HourSet = s_the_time.HourWIP;
|
|
s_the_time.MinuteSet = s_the_time.MinuteWIP;
|
|
app_glance_reload(glance_reload_callback, (void *)(uintptr_t)target);
|
|
return 0;
|
|
}
|
|
|
|
static void setter_seconds_handler(struct tm *tick_time, TimeUnits units_changed) {
|
|
struct tm now_tm = *tick_time;
|
|
|
|
// build the target time today
|
|
struct tm target_tm = now_tm;
|
|
target_tm.tm_hour = s_the_time.HourSet;
|
|
target_tm.tm_min = s_the_time.MinuteSet;
|
|
target_tm.tm_sec = 0;
|
|
|
|
time_t now = mktime(&now_tm);
|
|
time_t target = mktime(&target_tm);
|
|
|
|
if (target <= now) {
|
|
target += SECONDS_PER_DAY;
|
|
}
|
|
|
|
int32_t diff = (int32_t)(target - now);
|
|
|
|
uint8_t hours = diff / 3600;
|
|
uint8_t minutes = (diff % 3600) / 60;
|
|
uint8_t seconds = diff % 60;
|
|
|
|
static char s_countdown_buffer[9];
|
|
snprintf(s_countdown_buffer, sizeof(s_countdown_buffer),
|
|
"%02d:%02d:%02d", hours, minutes, seconds);
|
|
text_layer_set_text(s_countdown_txt_layer, s_countdown_buffer);
|
|
}
|
|
|
|
static void update_countdown_display() {
|
|
time_t now = time(NULL);
|
|
setter_seconds_handler(localtime(&now), SECOND_UNIT);
|
|
}
|
|
|
|
static void update_setter_display() {
|
|
static char s_setter_buffer[PBL_IF_ROUND_ELSE(8, 12)];
|
|
snprintf(s_setter_buffer, sizeof(s_setter_buffer), PBL_IF_ROUND_ELSE("%02d : %02d", "%02d : %02d"), s_the_time.HourWIP, s_the_time.MinuteWIP);
|
|
text_layer_set_text(s_setter_txt_layer, s_setter_buffer);
|
|
}
|
|
|
|
static void setter_up_click_handler(void *recognizer, void *ctx) {
|
|
switch (s_highlight_pos) {
|
|
case 0:
|
|
if (s_the_time.HourWIP == 23) {
|
|
s_the_time.HourWIP = 0;
|
|
} else {
|
|
s_the_time.HourWIP++;
|
|
}
|
|
break;
|
|
case 1:
|
|
if (s_the_time.MinuteWIP == 59) {
|
|
s_the_time.MinuteWIP = 0;
|
|
} else {
|
|
s_the_time.MinuteWIP++;
|
|
}
|
|
break;
|
|
default:
|
|
return;
|
|
}
|
|
update_setter_display();
|
|
}
|
|
|
|
static void setter_down_click_handler(void *recognizer, void *ctx) {
|
|
switch (s_highlight_pos) {
|
|
case 0:
|
|
if (s_the_time.HourWIP == 0) {
|
|
s_the_time.HourWIP = 23;
|
|
} else {
|
|
s_the_time.HourWIP--;
|
|
}
|
|
break;
|
|
case 1:
|
|
if (s_the_time.MinuteWIP == 0) {
|
|
s_the_time.MinuteWIP = 59;
|
|
} else {
|
|
s_the_time.MinuteWIP--;
|
|
}
|
|
break;
|
|
default:
|
|
return;
|
|
}
|
|
update_setter_display();
|
|
}
|
|
|
|
static void setter_select_click_handler(void *recognizer, void *ctx) {
|
|
if (s_highlight_pos == 2) {
|
|
int8_t status = schedule_main_alarm();
|
|
if (status < 0) {
|
|
return; // early return to avoid indicating alarm was set when it was not
|
|
}
|
|
|
|
// persist
|
|
persist_write_int(STORAGE_KEY_ALARM_HOUR, s_the_time.HourSet);
|
|
persist_write_int(STORAGE_KEY_ALARM_MINUTE, s_the_time.MinuteSet);
|
|
|
|
// update countdown immediately
|
|
update_countdown_display();
|
|
|
|
// move selection back to start
|
|
s_highlight_pos = 0;
|
|
} else {
|
|
s_highlight_pos++;
|
|
}
|
|
layer_mark_dirty(s_setter_highlight_layer);
|
|
layer_mark_dirty(s_bottom_bar_layer);
|
|
}
|
|
|
|
static void setter_back_click_handler(void *recognizer, void *ctx) {
|
|
if (s_highlight_pos == 0) {
|
|
window_stack_pop_all(true);
|
|
} else {
|
|
s_highlight_pos--;
|
|
}
|
|
layer_mark_dirty(s_setter_highlight_layer);
|
|
layer_mark_dirty(s_bottom_bar_layer);
|
|
}
|
|
|
|
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) {
|
|
graphics_context_set_fill_color(ctx, s_primary_color);
|
|
graphics_fill_rect(ctx, layer_get_bounds(layer), 0, GCornerNone);
|
|
}
|
|
|
|
static void bottom_bar_layer_update_proc(Layer *layer, GContext *ctx) {
|
|
graphics_context_set_fill_color(ctx, (s_highlight_pos == 2 ? s_setter_highlight_color : s_primary_color));
|
|
graphics_fill_rect(ctx, layer_get_bounds(layer), 0, GCornerNone);
|
|
}
|
|
|
|
static void add_bar_layers_to_window(Layer *window_layer) {
|
|
s_top_bar_layer = layer_create(s_top_bar_grect);
|
|
layer_set_update_proc(s_top_bar_layer, top_bar_layer_update_proc);
|
|
layer_add_child(window_layer, s_top_bar_layer);
|
|
s_bottom_bar_layer = layer_create(s_bottom_bar_grect);
|
|
layer_set_update_proc(s_bottom_bar_layer, bottom_bar_layer_update_proc);
|
|
layer_add_child(window_layer, s_bottom_bar_layer);
|
|
}
|
|
|
|
static void highlight_layer_update_proc(Layer *layer, GContext *ctx) {
|
|
GRect fill_area = layer_get_bounds(layer);
|
|
fill_area.size.w = PBL_DISPLAY_WIDTH / 2;
|
|
switch (s_highlight_pos) {
|
|
case 2:
|
|
return; // do not draw highlight
|
|
case 1:
|
|
// draw highlight on minutes site
|
|
fill_area.origin.x = fill_area.size.w;
|
|
break;
|
|
}
|
|
graphics_context_set_fill_color(ctx, s_setter_highlight_color);
|
|
graphics_fill_rect(ctx, fill_area, 0, GCornerNone);
|
|
}
|
|
|
|
static void setter_window_load() {
|
|
s_setter_highlight_color = GColorMediumAquamarine;
|
|
Layer *window_layer = window_get_root_layer(s_window);
|
|
|
|
// top&bottom bars
|
|
add_bar_layers_to_window(window_layer);
|
|
|
|
// clock icon
|
|
s_clock_bmp = gbitmap_create_with_resource(RESOURCE_ID_CLOCK35);
|
|
s_clock_bmp_layer = bitmap_layer_create(GRect(PBL_IF_ROUND_ELSE(0, 8), PBL_IF_ROUND_ELSE(6, 0), s_top_bar_grect.size.w, s_top_bar_grect.size.h));
|
|
bitmap_layer_set_bitmap(s_clock_bmp_layer, s_clock_bmp);
|
|
bitmap_layer_set_alignment(s_clock_bmp_layer, PBL_IF_ROUND_ELSE(GAlignTop, GAlignLeft));
|
|
bitmap_layer_set_compositing_mode(s_clock_bmp_layer, GCompOpSet);
|
|
layer_add_child(window_layer, bitmap_layer_get_layer(s_clock_bmp_layer));
|
|
|
|
// check icon
|
|
s_check_bmp = gbitmap_create_with_resource(RESOURCE_ID_CHECK);
|
|
s_check_bmp_layer = bitmap_layer_create(s_bottom_bar_grect);
|
|
bitmap_layer_set_bitmap(s_check_bmp_layer, s_check_bmp);
|
|
bitmap_layer_set_compositing_mode(s_check_bmp_layer, GCompOpSet);
|
|
layer_add_child(window_layer, bitmap_layer_get_layer(s_check_bmp_layer));
|
|
|
|
// countdown
|
|
s_font_lecoish_small = fonts_load_custom_font(resource_get_handle(RESOURCE_ID_FONT_LECOISH_MONO_BOLD_20));
|
|
s_countdown_txt_layer = text_layer_create(GRect(PBL_IF_ROUND_ELSE(0, 39), (s_top_bar_grect.size.h / 2) + PBL_IF_ROUND_ELSE(10, -10), PBL_IF_ROUND_ELSE(s_top_bar_grect.size.w, s_top_bar_grect.size.w - 39), 32));
|
|
text_layer_set_text_alignment(s_countdown_txt_layer, GTextAlignmentCenter);
|
|
text_layer_set_text_color(s_countdown_txt_layer, GColorWhite);
|
|
text_layer_set_background_color(s_countdown_txt_layer, GColorClear);
|
|
text_layer_set_font(s_countdown_txt_layer, s_font_lecoish_small);
|
|
layer_add_child(window_layer, text_layer_get_layer(s_countdown_txt_layer));
|
|
update_countdown_display();
|
|
|
|
// highlighter
|
|
s_setter_highlight_layer = layer_create(GRect(0, s_top_bar_grect.size.h, PBL_DISPLAY_WIDTH, PBL_DISPLAY_HEIGHT - (2 * s_top_bar_grect.size.h)));
|
|
layer_set_update_proc(s_setter_highlight_layer, highlight_layer_update_proc);
|
|
layer_add_child(window_layer, s_setter_highlight_layer);
|
|
|
|
// setter
|
|
s_font_lecoish_big = fonts_load_custom_font(resource_get_handle(PBL_IF_ROUND_ELSE(RESOURCE_ID_FONT_LECOISH_MONO_BOLD_60, RESOURCE_ID_FONT_LECOISH_MONO_BOLD_40)));
|
|
s_setter_txt_layer = text_layer_create(GRect(0, (PBL_DISPLAY_HEIGHT / 2) - PBL_IF_ROUND_ELSE(30, 20), PBL_DISPLAY_WIDTH, PBL_IF_ROUND_ELSE(60, 40)));
|
|
text_layer_set_text_alignment(s_setter_txt_layer, GTextAlignmentCenter);
|
|
text_layer_set_background_color(s_setter_txt_layer, GColorClear);
|
|
text_layer_set_font(s_setter_txt_layer, s_font_lecoish_big);
|
|
layer_add_child(window_layer, text_layer_get_layer(s_setter_txt_layer));
|
|
update_setter_display();
|
|
|
|
tick_timer_service_subscribe(SECOND_UNIT, setter_seconds_handler);
|
|
}
|
|
|
|
static void setter_window_unload() {
|
|
text_layer_destroy(s_setter_txt_layer);
|
|
layer_destroy(s_setter_highlight_layer);
|
|
text_layer_destroy(s_countdown_txt_layer);
|
|
bitmap_layer_destroy(s_check_bmp_layer);
|
|
bitmap_layer_destroy(s_clock_bmp_layer);
|
|
gbitmap_destroy(s_check_bmp);
|
|
gbitmap_destroy(s_clock_bmp);
|
|
layer_destroy(s_bottom_bar_layer);
|
|
layer_destroy(s_top_bar_layer);
|
|
fonts_unload_custom_font(s_font_lecoish_big);
|
|
fonts_unload_custom_font(s_font_lecoish_small);
|
|
}
|
|
|
|
static void schedule_fallback_alarm() {
|
|
wakeup_cancel_all();
|
|
time_t target_time = time(NULL);
|
|
WakeupId status;
|
|
while (true) {
|
|
target_time += 15;
|
|
status = wakeup_schedule(target_time, 0, true);
|
|
if (status >= 0) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void alarm_seconds_handler(struct tm *tick_time, TimeUnits units_changed) {
|
|
if (tick_time->tm_sec % 15 == 0) {
|
|
schedule_fallback_alarm();
|
|
}
|
|
vibes_short_pulse();
|
|
}
|
|
|
|
static void drop_layer_update_proc(Layer *layer, GContext *ctx) {
|
|
graphics_context_set_fill_color(ctx, GColorWhite);
|
|
graphics_fill_rect(ctx, layer_get_bounds(layer), 5, GCornersAll);
|
|
}
|
|
|
|
static void division_layer_update_proc(Layer *layer, GContext *ctx) {
|
|
GRect bounds = layer_get_bounds(layer);
|
|
graphics_context_set_stroke_color(ctx, GColorWhite);
|
|
graphics_draw_line(ctx, GPoint(bounds.origin.x, bounds.origin.y), GPoint(bounds.origin.x + bounds.size.w, bounds.origin.y));
|
|
}
|
|
|
|
static void alarm_highlight_layer_update_proc(Layer *layer, GContext *ctx) {
|
|
graphics_context_set_stroke_color(ctx, GColorRed);
|
|
graphics_context_set_stroke_width(ctx, 3);
|
|
graphics_draw_rect(ctx, layer_get_bounds(layer));
|
|
}
|
|
|
|
static void alarm_window_load() {
|
|
s_setter_highlight_color = s_primary_color;
|
|
Layer *window_layer = window_get_root_layer(s_window);
|
|
|
|
// top&bottom bars
|
|
add_bar_layers_to_window(window_layer);
|
|
|
|
// type text
|
|
s_font_mansalva_small = fonts_load_custom_font(resource_get_handle(RESOURCE_ID_FONT_MANSALVA_REGULAR_22));
|
|
s_type_txt_layer = text_layer_create(GRect(PBL_IF_ROUND_ELSE(0, 7), PBL_IF_ROUND_ELSE(4, 16), PBL_DISPLAY_WIDTH, 26));
|
|
text_layer_set_text_alignment(s_type_txt_layer, PBL_IF_ROUND_ELSE(GTextAlignmentCenter, GTextAlignmentLeft));
|
|
text_layer_set_background_color(s_type_txt_layer, GColorClear);
|
|
text_layer_set_text_color(s_type_txt_layer, GColorWhite);
|
|
text_layer_set_font(s_type_txt_layer, s_font_mansalva_small);
|
|
text_layer_set_text(s_type_txt_layer, "type:");
|
|
layer_add_child(window_layer, text_layer_get_layer(s_type_txt_layer));
|
|
|
|
// theta text
|
|
s_theta_txt_layer = text_layer_create(GRect(PBL_IF_ROUND_ELSE(0, 8), s_bottom_bar_grect.origin.y + PBL_IF_ROUND_ELSE(50, 16), PBL_DISPLAY_WIDTH, 26));
|
|
text_layer_set_text_alignment(s_theta_txt_layer, PBL_IF_ROUND_ELSE(GTextAlignmentCenter, GTextAlignmentLeft));
|
|
text_layer_set_background_color(s_theta_txt_layer, GColorClear);
|
|
text_layer_set_text_color(s_theta_txt_layer, GColorWhite);
|
|
text_layer_set_font(s_theta_txt_layer, s_font_mansalva_small);
|
|
text_layer_set_text(s_theta_txt_layer, PBL_IF_ROUND_ELSE("= θ", "θ ="));
|
|
layer_add_child(window_layer, text_layer_get_layer(s_theta_txt_layer));
|
|
|
|
// drop backgrounds
|
|
//// type
|
|
s_drop_type_layer = layer_create(s_drop_type_grect);
|
|
layer_set_update_proc(s_drop_type_layer, drop_layer_update_proc);
|
|
layer_add_child(window_layer, s_drop_type_layer);
|
|
//// function
|
|
s_drop_function_layer = layer_create(s_drop_function_grect);
|
|
layer_set_update_proc(s_drop_function_layer, drop_layer_update_proc);
|
|
layer_add_child(window_layer, s_drop_function_layer);
|
|
//// over
|
|
s_drop_over_layer = layer_create(s_drop_over_grect);
|
|
layer_set_update_proc(s_drop_over_layer, drop_layer_update_proc);
|
|
layer_add_child(window_layer, s_drop_over_layer);
|
|
//// under
|
|
s_drop_under_layer = layer_create(s_drop_under_grect);
|
|
layer_set_update_proc(s_drop_under_layer, drop_layer_update_proc);
|
|
layer_add_child(window_layer, s_drop_under_layer);
|
|
|
|
// parenthesis text
|
|
s_font_mansalva_big = fonts_load_custom_font(resource_get_handle(RESOURCE_ID_FONT_MANSALVA_REGULAR_50));
|
|
s_parenthesis_txt_layer = text_layer_create(GRect(s_drop_function_grect.origin.x + s_drop_function_grect.size.w + 2, s_bottom_bar_grect.origin.y - PBL_IF_ROUND_ELSE(12, 5), 200, 60));
|
|
text_layer_set_background_color(s_parenthesis_txt_layer, GColorClear);
|
|
text_layer_set_text_color(s_parenthesis_txt_layer, GColorWhite);
|
|
text_layer_set_font(s_parenthesis_txt_layer, s_font_mansalva_big);
|
|
text_layer_set_text(s_parenthesis_txt_layer, "( )");
|
|
layer_add_child(window_layer, text_layer_get_layer(s_parenthesis_txt_layer));
|
|
|
|
// division layer
|
|
s_division_layer = layer_create(GRect(s_drop_function_grect.origin.x + s_drop_function_grect.size.w + 25, s_drop_function_grect.origin.y + s_drop_function_grect.size.h / 2, 57, 1));
|
|
layer_set_update_proc(s_division_layer, division_layer_update_proc);
|
|
layer_add_child(window_layer, s_division_layer);
|
|
|
|
// highlighter
|
|
s_alarm_highlight_layer = layer_create(s_drop_type_grect);
|
|
layer_set_update_proc(s_alarm_highlight_layer, alarm_highlight_layer_update_proc);
|
|
layer_add_child(window_layer, s_alarm_highlight_layer);
|
|
|
|
schedule_fallback_alarm();
|
|
tick_timer_service_subscribe(SECOND_UNIT, alarm_seconds_handler);
|
|
}
|
|
|
|
static void alarm_window_unload() {
|
|
layer_destroy(s_alarm_highlight_layer);
|
|
layer_destroy(s_division_layer);
|
|
text_layer_destroy(s_parenthesis_txt_layer);
|
|
layer_destroy(s_drop_under_layer);
|
|
layer_destroy(s_drop_over_layer);
|
|
layer_destroy(s_drop_function_layer);
|
|
layer_destroy(s_drop_type_layer);
|
|
text_layer_destroy(s_theta_txt_layer);
|
|
text_layer_destroy(s_type_txt_layer);
|
|
layer_destroy(s_bottom_bar_layer);
|
|
layer_destroy(s_top_bar_layer);
|
|
fonts_unload_custom_font(s_font_mansalva_big);
|
|
fonts_unload_custom_font(s_font_mansalva_small);
|
|
}
|
|
|
|
static void set_alarm_highlighter_frame() {
|
|
switch (s_highlight_pos) {
|
|
case 0:
|
|
layer_set_frame(s_alarm_highlight_layer, s_drop_type_grect);
|
|
break;
|
|
case 1:
|
|
layer_set_frame(s_alarm_highlight_layer, s_drop_function_grect);
|
|
break;
|
|
case 2:
|
|
layer_set_frame(s_alarm_highlight_layer, s_drop_over_grect);
|
|
break;
|
|
case 3:
|
|
layer_set_frame(s_alarm_highlight_layer, s_drop_under_grect);
|
|
}
|
|
}
|
|
|
|
static void alarm_up_click_handler(void *recognizer, void *ctx) {
|
|
if (s_highlight_pos == 0) {
|
|
s_highlight_pos = 3;
|
|
} else {
|
|
s_highlight_pos--;
|
|
}
|
|
set_alarm_highlighter_frame();
|
|
}
|
|
|
|
static void alarm_down_click_handler(void *recognizer, void *ctx) {
|
|
if (s_highlight_pos == 3) {
|
|
s_highlight_pos = 0;
|
|
} else {
|
|
s_highlight_pos++;
|
|
}
|
|
set_alarm_highlighter_frame();
|
|
}
|
|
|
|
// DEBUG: logic will eventually be mapped to when triangle is solved
|
|
static void alarm_select_click_handler(void *recognizer, void *ctx) {
|
|
wakeup_cancel_all();
|
|
int8_t status = schedule_main_alarm();
|
|
while (status < 0) {
|
|
s_the_time.MinuteWIP++;
|
|
if (s_the_time.MinuteWIP >= 60) {
|
|
s_the_time.MinuteWIP = 0;
|
|
s_the_time.HourWIP++;
|
|
if (s_the_time.HourWIP >= 24) {
|
|
s_the_time.HourWIP = 0;
|
|
}
|
|
}
|
|
status = schedule_main_alarm();
|
|
}
|
|
window_stack_pop_all(true);
|
|
}
|
|
|
|
static void alarm_click_config_provider(void *ctx) {
|
|
window_single_click_subscribe(BUTTON_ID_BACK, NULL);
|
|
window_single_click_subscribe(BUTTON_ID_UP, alarm_up_click_handler);
|
|
window_single_click_subscribe(BUTTON_ID_DOWN, alarm_down_click_handler);
|
|
window_long_click_subscribe(BUTTON_ID_SELECT, 5000, alarm_select_click_handler, NULL);
|
|
}
|
|
|
|
static void init() {
|
|
s_window = window_create();
|
|
s_the_time.HourWIP = persist_read_int(STORAGE_KEY_ALARM_HOUR);
|
|
s_the_time.MinuteWIP = persist_read_int(STORAGE_KEY_ALARM_MINUTE);
|
|
s_the_time.HourSet = s_the_time.HourWIP;
|
|
s_the_time.MinuteSet = s_the_time.MinuteWIP;
|
|
|
|
switch (launch_reason()) {
|
|
case APP_LAUNCH_PHONE: // DEBUG, REMOVE PRIOR TO RELEASE!
|
|
case APP_LAUNCH_WAKEUP:
|
|
window_set_window_handlers(
|
|
s_window,
|
|
(WindowHandlers){.load = alarm_window_load, .unload = alarm_window_unload});
|
|
window_set_click_config_provider(s_window, alarm_click_config_provider);
|
|
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, setter_click_config_provider);
|
|
window_stack_push(s_window, false);
|
|
};
|
|
}
|
|
|
|
static void deinit() {
|
|
window_destroy(s_window);
|
|
}
|
|
|
|
int main(void) {
|
|
init();
|
|
app_event_loop();
|
|
deinit();
|
|
}
|