686 lines
24 KiB
C
686 lines
24 KiB
C
#include "palette_manip.h"
|
|
#include "settings.h"
|
|
#include <pebble.h>
|
|
|
|
// window statics
|
|
static Window *s_main_window;
|
|
static Layer *s_window_layer;
|
|
static BitmapLayer *s_time_mg_layers[4];
|
|
static BitmapLayer *s_time_fg_layers[4];
|
|
static BitmapLayer *s_c_layer;
|
|
static BitmapLayer *s_h_layer;
|
|
static BitmapLayer *s_e_layer;
|
|
static BitmapLayer *s_f_layer;
|
|
static Layer *s_temp_mg_layer;
|
|
static Layer *s_temp_layer;
|
|
static Layer *s_fuel_mg_layer;
|
|
static Layer *s_fuel_layer;
|
|
static const uint8_t s_x_r = (PBL_DISPLAY_WIDTH / 2) + 2;
|
|
static const uint8_t s_x_l = (s_x_r - 2 * (69 / 2)) - 5;
|
|
static const GRect s_time_grects[4] = {GRect(s_x_l, 2, 69, 110), GRect(s_x_r, 2, 69, 110), GRect(s_x_l, 116, 69, 110), GRect(s_x_r, 116, 69, 110)}; // emery
|
|
static const uint8_t s_temp_guage_x_pos = 6;
|
|
static const uint16_t s_fuel_guage_x_pos = PBL_DISPLAY_WIDTH - 23;
|
|
|
|
// settings statics
|
|
static ClaySettings settings;
|
|
static GColor s_applied_time_mg = GColorDarkGray;
|
|
static GColor s_applied_e_f = GColorWhite;
|
|
static GColor s_applied_c_h = GColorWhite;
|
|
static GColor s_applied_time_date = GColorWhite;
|
|
|
|
// bitmap statics
|
|
static GBitmap *s_font_bitmaps[10];
|
|
static GBitmap *s_font_bitmaps_mini[10];
|
|
static GBitmap *s_time_mg_super8;
|
|
static GBitmap *s_time_mg_super8_mini;
|
|
static GBitmap *s_c_icon;
|
|
static GBitmap *s_h_icon;
|
|
static GBitmap *s_e_icon;
|
|
static GBitmap *s_f_icon;
|
|
|
|
// tracking statics
|
|
static bool s_peek_active = false;
|
|
static bool s_first_settings_application = true;
|
|
static bool s_showing_date = false;
|
|
static AppTimer *s_date_timer = NULL;
|
|
static bool s_pkjs_ready = false;
|
|
static bool s_fuel_is_warning = false;
|
|
static int s_batt_level;
|
|
static bool s_temp_is_warning = false;
|
|
static int8_t s_temp_level;
|
|
|
|
// bar statics
|
|
static const uint8_t s_bar_height = 8;
|
|
static const uint8_t s_bar_width = 17;
|
|
static const uint8_t s_bar_spacing = s_bar_height + 1;
|
|
|
|
static void toggle_fuel_warning_state(bool enable_warning, bool force) {
|
|
if (!force && (enable_warning == s_fuel_is_warning)) {
|
|
return;
|
|
}
|
|
GColor dst = enable_warning ? settings.ColorWarning : settings.ColorLetters;
|
|
if (s_first_settings_application && !enable_warning && dst.argb == s_applied_e_f.argb) {
|
|
// at startup, s_applied_e.argb is GColorWhite
|
|
// for those using white fg, do not pointlessly replace white at startup if that is the destination anyway
|
|
return;
|
|
}
|
|
replace_gbitmap_color(s_applied_e_f, dst, s_e_icon, s_e_layer);
|
|
replace_gbitmap_color(s_applied_e_f, dst, s_f_icon, s_f_layer);
|
|
s_applied_e_f = dst;
|
|
s_fuel_is_warning = enable_warning;
|
|
}
|
|
|
|
static void toggle_temp_warning_state(bool enable_warning, bool force) {
|
|
if (!force && (enable_warning == s_temp_is_warning)) {
|
|
return;
|
|
}
|
|
GColor dst = enable_warning ? settings.ColorWarning : settings.ColorLetters;
|
|
if (s_first_settings_application && !enable_warning && dst.argb == s_applied_c_h.argb) {
|
|
// at startup, s_applied_c_h.argb is GColorWhite
|
|
// for those using white fg, do not pointlessly replace white at startup if that is the destination anyway
|
|
return;
|
|
}
|
|
replace_gbitmap_color(s_applied_c_h, dst, s_c_icon, s_c_layer);
|
|
replace_gbitmap_color(s_applied_c_h, dst, s_h_icon, s_h_layer);
|
|
s_applied_c_h = dst;
|
|
s_temp_is_warning = enable_warning;
|
|
}
|
|
|
|
static void bt_callback(bool connected) {
|
|
GColor dst = connected ? settings.ColorHours : settings.ColorWarning;
|
|
if (s_first_settings_application && connected && dst.argb == s_applied_time_date.argb) {
|
|
// at startup, s_applied_time_date.argb is GColorWhite
|
|
// for those using white fg, do not pointlessly replace white at startup if that is the destination anyway
|
|
return;
|
|
}
|
|
for (int i = 0; i < 10; ++i) {
|
|
replace_gbitmap_color(s_applied_time_date, dst, s_font_bitmaps[i], NULL);
|
|
}
|
|
for (int i = 0; i < 4; ++i) {
|
|
layer_mark_dirty(bitmap_layer_get_layer(s_time_fg_layers[i]));
|
|
}
|
|
s_applied_time_date = dst;
|
|
}
|
|
|
|
static void batt_callback(BatteryChargeState state) {
|
|
s_batt_level = state.charge_percent / 5;
|
|
layer_mark_dirty(s_fuel_layer);
|
|
if (state.charge_percent <= settings.LowFuelPercent) {
|
|
toggle_fuel_warning_state(true, false);
|
|
} else {
|
|
toggle_fuel_warning_state(false, false);
|
|
}
|
|
}
|
|
|
|
static void temp_update_proc(Layer *layer, GContext *ctx) {
|
|
graphics_context_set_fill_color(ctx, GColorWhite);
|
|
const uint8_t bar_count = s_temp_level;
|
|
uint16_t bar_bottom_pos = 195;
|
|
|
|
for (uint8_t i = 0; i < bar_count; ++i) {
|
|
graphics_fill_rect(ctx, GRect(0, bar_bottom_pos, s_bar_width, s_bar_height), 0, GCornerNone);
|
|
bar_bottom_pos -= s_bar_spacing;
|
|
}
|
|
}
|
|
|
|
static void fuel_update_proc(Layer *layer, GContext *ctx) {
|
|
graphics_context_set_fill_color(ctx, GColorWhite);
|
|
uint16_t bar_bottom_pos = 195;
|
|
|
|
for (uint8_t i = 0; i < s_batt_level; ++i) {
|
|
graphics_fill_rect(ctx, GRect(0, bar_bottom_pos, s_bar_width, s_bar_height), 0, GCornerNone);
|
|
bar_bottom_pos -= s_bar_spacing;
|
|
}
|
|
}
|
|
|
|
static void temp_fuel_mg_update_proc_helper(Layer *layer, GContext *ctx, bool isFuel) {
|
|
GRect bounds = layer_get_bounds(layer);
|
|
graphics_context_set_fill_color(ctx, settings.ColorMGBars);
|
|
graphics_fill_rect(ctx, bounds, 0, GCornerNone);
|
|
if (isFuel) {
|
|
graphics_context_set_stroke_color(ctx, settings.ColorBarsHot);
|
|
} else {
|
|
graphics_context_set_stroke_color(ctx, settings.ColorBarsCool);
|
|
}
|
|
const uint16_t bottom_color_y = bounds.origin.y + 183;
|
|
graphics_draw_line(ctx, GPoint(bounds.origin.x + 1, bottom_color_y), GPoint(bounds.origin.x + s_bar_width, bottom_color_y));
|
|
if (isFuel) {
|
|
graphics_context_set_stroke_color(ctx, settings.ColorBarsCool);
|
|
} else {
|
|
graphics_context_set_stroke_color(ctx, settings.ColorBarsHot);
|
|
}
|
|
const uint16_t top_color_y = bounds.origin.y + 1;
|
|
graphics_draw_line(ctx, GPoint(bounds.origin.x + 1, top_color_y), GPoint(bounds.origin.x + s_bar_width, top_color_y));
|
|
}
|
|
|
|
static void temp_mg_update_proc(Layer *layer, GContext *ctx) {
|
|
temp_fuel_mg_update_proc_helper(layer, ctx, false);
|
|
}
|
|
|
|
static void fuel_mg_update_proc(Layer *layer, GContext *ctx) {
|
|
temp_fuel_mg_update_proc_helper(layer, ctx, true);
|
|
}
|
|
|
|
static void update_temperature() {
|
|
if (!s_pkjs_ready) {
|
|
return;
|
|
}
|
|
|
|
DictionaryIterator *out;
|
|
AppMessageResult result = app_message_outbox_begin(&out);
|
|
if (result != APP_MSG_OK) {
|
|
toggle_temp_warning_state(true, false);
|
|
return;
|
|
}
|
|
dict_write_int8(out, MESSAGE_KEY_PKJS_TEMP_BAR_COUNT, 1);
|
|
result = app_message_outbox_send();
|
|
if (result != APP_MSG_OK) {
|
|
toggle_temp_warning_state(true, false);
|
|
return;
|
|
}
|
|
toggle_temp_warning_state(false, false);
|
|
}
|
|
|
|
static void update_minute_1() {
|
|
time_t temp = time(NULL);
|
|
struct tm *tick_time = localtime(&temp);
|
|
|
|
uint8_t hour = (uint8_t)tick_time->tm_hour;
|
|
if (!clock_is_24h_style()) {
|
|
hour = hour % 12;
|
|
if (hour == 0) {
|
|
hour = 12;
|
|
}
|
|
}
|
|
uint8_t minute = (uint8_t)tick_time->tm_min;
|
|
|
|
static uint8_t s_time_digits[4];
|
|
s_time_digits[0] = hour / 10;
|
|
s_time_digits[1] = hour % 10;
|
|
s_time_digits[2] = minute / 10;
|
|
s_time_digits[3] = minute % 10;
|
|
|
|
if (!s_peek_active) {
|
|
if (settings.ShowTimeMG) {
|
|
bitmap_layer_set_bitmap(s_time_mg_layers[2], s_time_mg_super8);
|
|
bitmap_layer_set_bitmap(s_time_mg_layers[3], s_time_mg_super8);
|
|
}
|
|
for (int i = 0; i < 4; ++i) {
|
|
bitmap_layer_set_bitmap(s_time_fg_layers[i], s_font_bitmaps[s_time_digits[i]]);
|
|
}
|
|
} else {
|
|
if (settings.ShowTimeMG) {
|
|
bitmap_layer_set_bitmap(s_time_mg_layers[2], s_time_mg_super8_mini);
|
|
bitmap_layer_set_bitmap(s_time_mg_layers[3], s_time_mg_super8_mini);
|
|
}
|
|
bitmap_layer_set_bitmap(s_time_fg_layers[0], s_font_bitmaps[s_time_digits[0]]);
|
|
bitmap_layer_set_bitmap(s_time_fg_layers[1], s_font_bitmaps[s_time_digits[1]]);
|
|
bitmap_layer_set_bitmap(s_time_fg_layers[2], s_font_bitmaps_mini[s_time_digits[2]]);
|
|
bitmap_layer_set_bitmap(s_time_fg_layers[3], s_font_bitmaps_mini[s_time_digits[3]]);
|
|
}
|
|
}
|
|
|
|
static void minute_handler(struct tm *tick_time, TimeUnits units_changed) {
|
|
if (!s_showing_date) {
|
|
update_minute_1();
|
|
}
|
|
if (tick_time->tm_min % 30 == 0) {
|
|
update_temperature();
|
|
}
|
|
}
|
|
|
|
static void date_timeout(void *context) {
|
|
s_showing_date = false;
|
|
s_date_timer = NULL;
|
|
update_minute_1();
|
|
}
|
|
|
|
static void accel_tap_handler(AccelAxisType axis, int32_t direction) {
|
|
time_t temp = time(NULL);
|
|
struct tm *tick_time = localtime(&temp);
|
|
static char s_date_buffer[16];
|
|
strftime(s_date_buffer, sizeof(s_date_buffer), "%m%d", tick_time);
|
|
if (!s_peek_active) {
|
|
for (int i = 0; i < 4; ++i) {
|
|
bitmap_layer_set_bitmap(s_time_fg_layers[i], s_font_bitmaps[s_date_buffer[i] - '0']);
|
|
}
|
|
} else {
|
|
bitmap_layer_set_bitmap(s_time_fg_layers[0], s_font_bitmaps[s_date_buffer[0] - '0']);
|
|
bitmap_layer_set_bitmap(s_time_fg_layers[1], s_font_bitmaps[s_date_buffer[1] - '0']);
|
|
bitmap_layer_set_bitmap(s_time_fg_layers[2], s_font_bitmaps_mini[s_date_buffer[2] - '0']);
|
|
bitmap_layer_set_bitmap(s_time_fg_layers[3], s_font_bitmaps_mini[s_date_buffer[3] - '0']);
|
|
}
|
|
|
|
s_showing_date = true;
|
|
if (s_date_timer) {
|
|
app_timer_cancel(s_date_timer);
|
|
}
|
|
s_date_timer = app_timer_register(settings.DateTimeoutSecs * 1000, date_timeout, NULL);
|
|
}
|
|
|
|
static void peek_will_change(GRect final_unobstructed_screen_area, void *context) {
|
|
// if obstructed, set s_peek_active and run update_minute_1 to use small minutes
|
|
GRect full_bounds = layer_get_bounds(s_window_layer);
|
|
if (!grect_equal(&full_bounds, &final_unobstructed_screen_area)) {
|
|
s_peek_active = true;
|
|
if (!s_showing_date) {
|
|
update_minute_1();
|
|
}
|
|
} else {
|
|
s_peek_active = false;
|
|
}
|
|
}
|
|
|
|
static void peek_change(AnimationProgress progress, void *context) {
|
|
// animate the moving of the minute layers depending on s_peek_active
|
|
if (!s_peek_active) {
|
|
layer_set_frame(bitmap_layer_get_layer(s_time_fg_layers[2]), s_time_grects[2]);
|
|
layer_set_frame(bitmap_layer_get_layer(s_time_fg_layers[3]), s_time_grects[3]);
|
|
if (settings.ShowTimeMG) {
|
|
layer_set_frame(bitmap_layer_get_layer(s_time_mg_layers[2]), s_time_grects[2]);
|
|
layer_set_frame(bitmap_layer_get_layer(s_time_mg_layers[3]), s_time_grects[3]);
|
|
}
|
|
} else {
|
|
uint8_t y = s_time_grects[2].origin.y - 1;
|
|
layer_set_frame(bitmap_layer_get_layer(s_time_fg_layers[2]), GRect(s_time_grects[2].origin.x, y, 69, 54));
|
|
layer_set_frame(bitmap_layer_get_layer(s_time_fg_layers[3]), GRect(s_time_grects[3].origin.x, y, 69, 54));
|
|
if (settings.ShowTimeMG) {
|
|
layer_set_frame(bitmap_layer_get_layer(s_time_mg_layers[2]), GRect(s_time_grects[2].origin.x, y, 69, 54));
|
|
layer_set_frame(bitmap_layer_get_layer(s_time_mg_layers[3]), GRect(s_time_grects[3].origin.x, y, 69, 54));
|
|
}
|
|
}
|
|
}
|
|
|
|
static void peek_did_change(void *context) {
|
|
// if not obstructed, run update_minute_1 to use large minutes
|
|
if (!s_peek_active && !s_showing_date) {
|
|
update_minute_1();
|
|
}
|
|
}
|
|
|
|
static void apply_settings() {
|
|
// LED&BG
|
|
if (settings.UseCustomLED) {
|
|
light_set_color(settings.ColorLED); // no-op on unsupported platforms
|
|
} else {
|
|
light_set_system_color();
|
|
}
|
|
window_set_background_color(s_main_window, settings.ColorBG);
|
|
|
|
// TIME MG
|
|
if (settings.ShowTimeMG) {
|
|
//// load bitmap if not already loaded
|
|
if (!s_time_mg_super8) {
|
|
s_time_mg_super8 = gbitmap_create_with_resource(RESOURCE_ID_SUPER8);
|
|
s_applied_time_mg = GColorWhite;
|
|
}
|
|
//// create and insert any mg layer that does not already exist
|
|
Layer *sibling_layer = NULL;
|
|
if (s_first_settings_application) {
|
|
sibling_layer = s_window_layer;
|
|
} else {
|
|
sibling_layer = bitmap_layer_get_layer(s_time_fg_layers[0]);
|
|
}
|
|
for (int i = 0; i < 4; ++i) {
|
|
if (!s_time_mg_layers[i]) {
|
|
s_time_mg_layers[i] = bitmap_layer_create(s_time_grects[i]);
|
|
bitmap_layer_set_bitmap(s_time_mg_layers[i], s_time_mg_super8);
|
|
bitmap_layer_set_compositing_mode(s_time_mg_layers[i], GCompOpSet);
|
|
if (s_first_settings_application) {
|
|
layer_add_child(sibling_layer, bitmap_layer_get_layer(s_time_mg_layers[i]));
|
|
} else {
|
|
layer_insert_below_sibling(bitmap_layer_get_layer(s_time_mg_layers[i]), sibling_layer);
|
|
}
|
|
}
|
|
}
|
|
//// set bitmap color and mark layers dirty
|
|
if (s_time_mg_super8 && settings.ColorMGTime.argb != s_applied_time_mg.argb) {
|
|
replace_gbitmap_color(s_applied_time_mg, settings.ColorMGTime, s_time_mg_super8, NULL);
|
|
for (int i = 0; i < 4; ++i) {
|
|
if (s_time_mg_layers[i]) {
|
|
layer_mark_dirty(bitmap_layer_get_layer(s_time_mg_layers[i]));
|
|
}
|
|
}
|
|
s_applied_time_mg = settings.ColorMGTime;
|
|
}
|
|
} else {
|
|
if (s_time_mg_super8) {
|
|
for (int i = 0; i < 4; ++i) {
|
|
bitmap_layer_destroy(s_time_mg_layers[i]);
|
|
s_time_mg_layers[i] = NULL;
|
|
}
|
|
gbitmap_destroy(s_time_mg_super8);
|
|
s_time_mg_super8 = NULL;
|
|
}
|
|
}
|
|
|
|
// BAR MG
|
|
layer_mark_dirty(s_temp_mg_layer);
|
|
layer_mark_dirty(s_fuel_mg_layer);
|
|
|
|
// FG & warning indicators
|
|
// time+date (re-sub bt tracking)
|
|
connection_service_unsubscribe();
|
|
if (settings.TrackBTStatus) {
|
|
connection_service_subscribe((ConnectionHandlers){.pebble_app_connection_handler = bt_callback});
|
|
bt_callback(connection_service_peek_pebble_app_connection());
|
|
} else {
|
|
bt_callback(true);
|
|
}
|
|
|
|
// temp (c & h icons)
|
|
toggle_temp_warning_state(s_temp_is_warning, true);
|
|
|
|
// fuel (e icon)
|
|
toggle_fuel_warning_state(s_fuel_is_warning, true);
|
|
|
|
// changes to temperature range
|
|
update_temperature();
|
|
|
|
// changes to low fuel threshold
|
|
batt_callback(battery_state_service_peek());
|
|
|
|
// re-sub accelerometer
|
|
accel_tap_service_unsubscribe();
|
|
if (settings.DateTimeoutSecs != 0) {
|
|
accel_tap_service_subscribe(accel_tap_handler);
|
|
}
|
|
|
|
// re-sub timeline peek and create/destroy resources as needed
|
|
// TODO fix fg and mg color not applying to mini varients; fix time mg color restore on face reload
|
|
unobstructed_area_service_unsubscribe();
|
|
if (settings.EnablePeek) {
|
|
if (!s_font_bitmaps_mini[0]) {
|
|
s_font_bitmaps_mini[0] = gbitmap_create_with_resource(RESOURCE_ID_0_M);
|
|
s_font_bitmaps_mini[1] = gbitmap_create_with_resource(RESOURCE_ID_1_M);
|
|
s_font_bitmaps_mini[2] = gbitmap_create_with_resource(RESOURCE_ID_2_M);
|
|
s_font_bitmaps_mini[3] = gbitmap_create_with_resource(RESOURCE_ID_3_M);
|
|
s_font_bitmaps_mini[4] = gbitmap_create_with_resource(RESOURCE_ID_4_M);
|
|
s_font_bitmaps_mini[5] = gbitmap_create_with_resource(RESOURCE_ID_5_M);
|
|
s_font_bitmaps_mini[6] = gbitmap_create_with_resource(RESOURCE_ID_6_M);
|
|
s_font_bitmaps_mini[7] = gbitmap_create_with_resource(RESOURCE_ID_7_M);
|
|
s_font_bitmaps_mini[8] = gbitmap_create_with_resource(RESOURCE_ID_8_M);
|
|
s_font_bitmaps_mini[9] = gbitmap_create_with_resource(RESOURCE_ID_9_M);
|
|
}
|
|
if (!s_time_mg_super8_mini) {
|
|
if (settings.ShowTimeMG) {
|
|
s_time_mg_super8_mini = gbitmap_create_with_resource(RESOURCE_ID_SUPER8_M);
|
|
}
|
|
} else {
|
|
if (!settings.ShowTimeMG) {
|
|
gbitmap_destroy(s_time_mg_super8_mini);
|
|
s_time_mg_super8_mini = NULL;
|
|
}
|
|
}
|
|
peek_will_change(layer_get_unobstructed_bounds(s_window_layer), NULL);
|
|
peek_change(0, NULL);
|
|
peek_did_change(NULL);
|
|
UnobstructedAreaHandlers peek_handlers = {
|
|
.will_change = peek_will_change,
|
|
.change = peek_change,
|
|
.did_change = peek_did_change,
|
|
};
|
|
unobstructed_area_service_subscribe(peek_handlers, NULL);
|
|
} else {
|
|
peek_will_change(layer_get_bounds(s_window_layer), NULL);
|
|
peek_change(0, NULL);
|
|
peek_did_change(NULL);
|
|
if (s_font_bitmaps_mini[0]) {
|
|
for (int i = 0; i < 10; ++i) {
|
|
gbitmap_destroy(s_font_bitmaps_mini[i]);
|
|
s_font_bitmaps_mini[i] = NULL;
|
|
}
|
|
}
|
|
if (s_time_mg_super8_mini) {
|
|
gbitmap_destroy(s_time_mg_super8_mini);
|
|
s_time_mg_super8_mini = NULL;
|
|
}
|
|
}
|
|
|
|
if (s_first_settings_application) {
|
|
s_first_settings_application = false;
|
|
}
|
|
}
|
|
|
|
static void main_window_load() {
|
|
s_window_layer = window_get_root_layer(s_main_window);
|
|
|
|
s_temp_mg_layer = layer_create(GRect(s_temp_guage_x_pos - 1, 21, s_bar_width + 2, PBL_DISPLAY_HEIGHT - 43));
|
|
layer_set_update_proc(s_temp_mg_layer, temp_mg_update_proc);
|
|
s_fuel_mg_layer = layer_create(GRect(s_fuel_guage_x_pos - 1, 21, s_bar_width + 2, PBL_DISPLAY_HEIGHT - 43));
|
|
layer_set_update_proc(s_fuel_mg_layer, fuel_mg_update_proc);
|
|
|
|
s_c_layer = bitmap_layer_create(GRect(s_temp_guage_x_pos, PBL_DISPLAY_HEIGHT - 18, 17, 15));
|
|
s_h_layer = bitmap_layer_create(GRect(s_temp_guage_x_pos, 3, 17, 14));
|
|
s_e_layer = bitmap_layer_create(GRect(s_fuel_guage_x_pos, PBL_DISPLAY_HEIGHT - 18, 17, 15));
|
|
s_f_layer = bitmap_layer_create(GRect(s_fuel_guage_x_pos, 3, 17, 14));
|
|
bitmap_layer_set_bitmap(s_c_layer, s_c_icon);
|
|
bitmap_layer_set_bitmap(s_h_layer, s_h_icon);
|
|
bitmap_layer_set_bitmap(s_e_layer, s_e_icon);
|
|
bitmap_layer_set_bitmap(s_f_layer, s_f_icon);
|
|
bitmap_layer_set_compositing_mode(s_c_layer, GCompOpSet);
|
|
bitmap_layer_set_compositing_mode(s_h_layer, GCompOpSet);
|
|
bitmap_layer_set_compositing_mode(s_e_layer, GCompOpSet);
|
|
bitmap_layer_set_compositing_mode(s_f_layer, GCompOpSet);
|
|
|
|
apply_settings();
|
|
|
|
for (int i = 0; i < 4; ++i) {
|
|
layer_add_child(s_window_layer, bitmap_layer_get_layer(s_time_fg_layers[i]));
|
|
}
|
|
layer_add_child(s_window_layer, bitmap_layer_get_layer(s_c_layer));
|
|
layer_add_child(s_window_layer, bitmap_layer_get_layer(s_h_layer));
|
|
layer_add_child(s_window_layer, bitmap_layer_get_layer(s_e_layer));
|
|
layer_add_child(s_window_layer, bitmap_layer_get_layer(s_f_layer));
|
|
layer_add_child(s_window_layer, s_temp_mg_layer);
|
|
layer_add_child(s_window_layer, s_temp_layer);
|
|
layer_add_child(s_window_layer, s_fuel_mg_layer);
|
|
layer_add_child(s_window_layer, s_fuel_layer);
|
|
}
|
|
|
|
static void main_window_unload() {
|
|
if (settings.EnablePeek) {
|
|
unobstructed_area_service_unsubscribe();
|
|
for (int i = 0; i < 10; ++i) {
|
|
gbitmap_destroy(s_font_bitmaps_mini[i]);
|
|
}
|
|
}
|
|
connection_service_unsubscribe();
|
|
accel_tap_service_unsubscribe();
|
|
layer_destroy(s_fuel_mg_layer);
|
|
layer_destroy(s_temp_mg_layer);
|
|
bitmap_layer_destroy(s_f_layer);
|
|
bitmap_layer_destroy(s_e_layer);
|
|
bitmap_layer_destroy(s_h_layer);
|
|
bitmap_layer_destroy(s_c_layer);
|
|
if (s_time_mg_super8_mini) {
|
|
gbitmap_destroy(s_time_mg_super8_mini);
|
|
}
|
|
if (s_time_mg_super8) {
|
|
gbitmap_destroy(s_time_mg_super8);
|
|
for (int i = 0; i < 4; ++i) {
|
|
bitmap_layer_destroy(s_time_mg_layers[i]);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void inbox_received_handler(DictionaryIterator *iter, void *context) {
|
|
Tuple *ready_tuple = dict_find(iter, MESSAGE_KEY_PKJS_READY);
|
|
if (ready_tuple) {
|
|
s_pkjs_ready = true;
|
|
update_temperature();
|
|
return;
|
|
}
|
|
|
|
// TEMPERATURE DATA
|
|
Tuple *temp_bar_count = dict_find(iter, MESSAGE_KEY_PKJS_TEMP_BAR_COUNT);
|
|
if (temp_bar_count) {
|
|
int8_t new_temp_level = temp_bar_count->value->int8;
|
|
if (new_temp_level >= 0) {
|
|
s_temp_level = new_temp_level;
|
|
toggle_temp_warning_state(false, false);
|
|
layer_mark_dirty(s_temp_layer);
|
|
} else {
|
|
toggle_temp_warning_state(true, false);
|
|
}
|
|
return;
|
|
}
|
|
|
|
// CLAY SETTINGS
|
|
Tuple *enable_peek_tuple = dict_find(iter, MESSAGE_KEY_CLAY_ENABLE_PEEK);
|
|
Tuple *show_time_mg_tuple = dict_find(iter, MESSAGE_KEY_CLAY_SHOW_TIME_MG);
|
|
Tuple *track_bt_status_tuple = dict_find(iter, MESSAGE_KEY_CLAY_TRACK_BT_STATUS);
|
|
Tuple *date_timeout_secs_tuple = dict_find(iter, MESSAGE_KEY_CLAY_DATE_TIMEOUT_SECS);
|
|
Tuple *low_fuel_percent_tuple = dict_find(iter, MESSAGE_KEY_CLAY_LOW_FUEL_PERCENT);
|
|
Tuple *use_custom_led_tuple = dict_find(iter, MESSAGE_KEY_CLAY_USE_CUSTOM_LED);
|
|
Tuple *color_led_tuple = dict_find(iter, MESSAGE_KEY_CLAY_COLOR_LED);
|
|
Tuple *color_bg_tuple = dict_find(iter, MESSAGE_KEY_CLAY_COLOR_BG);
|
|
Tuple *color_bar_mg_tuple = dict_find(iter, MESSAGE_KEY_CLAY_COLOR_BAR_MG);
|
|
Tuple *color_bar_cool_tuple = dict_find(iter, MESSAGE_KEY_CLAY_COLOR_BAR_COOL);
|
|
Tuple *color_bar_hot_tuple = dict_find(iter, MESSAGE_KEY_CLAY_COLOR_BAR_HOT);
|
|
Tuple *color_time_mg_tuple = dict_find(iter, MESSAGE_KEY_CLAY_COLOR_TIME_MG);
|
|
Tuple *color_letters_tuple = dict_find(iter, MESSAGE_KEY_CLAY_COLOR_LETTERS);
|
|
Tuple *color_hours_tuple = dict_find(iter, MESSAGE_KEY_CLAY_COLOR_HOURS);
|
|
Tuple *color_minutes_tuple = dict_find(iter, MESSAGE_KEY_CLAY_COLOR_MINUTES);
|
|
Tuple *color_warning_tuple = dict_find(iter, MESSAGE_KEY_CLAY_COLOR_WARNING);
|
|
if (enable_peek_tuple) {
|
|
settings.EnablePeek = enable_peek_tuple->value->uint8;
|
|
}
|
|
if (show_time_mg_tuple) {
|
|
settings.ShowTimeMG = show_time_mg_tuple->value->uint8;
|
|
}
|
|
if (track_bt_status_tuple) {
|
|
settings.TrackBTStatus = track_bt_status_tuple->value->uint8;
|
|
}
|
|
if (date_timeout_secs_tuple) {
|
|
settings.DateTimeoutSecs = date_timeout_secs_tuple->value->uint8;
|
|
}
|
|
if (low_fuel_percent_tuple) {
|
|
settings.LowFuelPercent = low_fuel_percent_tuple->value->uint8;
|
|
}
|
|
if (use_custom_led_tuple) {
|
|
settings.UseCustomLED = use_custom_led_tuple->value->uint8;
|
|
}
|
|
if (color_led_tuple) {
|
|
settings.ColorLED = GColorFromHEX(color_led_tuple->value->int32);
|
|
}
|
|
if (color_bg_tuple) {
|
|
settings.ColorBG = GColorFromHEX(color_bg_tuple->value->int32);
|
|
}
|
|
if (color_bar_mg_tuple) {
|
|
settings.ColorMGBars = GColorFromHEX(color_bar_mg_tuple->value->int32);
|
|
}
|
|
if (color_bar_cool_tuple) {
|
|
settings.ColorBarsCool = GColorFromHEX(color_bar_cool_tuple->value->int32);
|
|
}
|
|
if (color_bar_hot_tuple) {
|
|
settings.ColorBarsHot = GColorFromHEX(color_bar_hot_tuple->value->int32);
|
|
}
|
|
if (color_time_mg_tuple) {
|
|
settings.ColorMGTime = GColorFromHEX(color_time_mg_tuple->value->int32);
|
|
}
|
|
if (color_letters_tuple) {
|
|
settings.ColorLetters = GColorFromHEX(color_letters_tuple->value->int32);
|
|
}
|
|
if (color_hours_tuple) {
|
|
settings.ColorHours = GColorFromHEX(color_hours_tuple->value->int32);
|
|
}
|
|
if (color_minutes_tuple) {
|
|
settings.ColorMinutes = GColorFromHEX(color_minutes_tuple->value->int32);
|
|
}
|
|
if (color_warning_tuple) {
|
|
settings.ColorWarning = GColorFromHEX(color_warning_tuple->value->int32);
|
|
}
|
|
persist_write_data(STORAGE_KEY_SETTINGS, &settings, sizeof(settings));
|
|
apply_settings();
|
|
}
|
|
|
|
static void init() {
|
|
// load settings from persist (or set defaults if not present)
|
|
if (persist_exists(STORAGE_KEY_SETTINGS)) {
|
|
persist_read_data(STORAGE_KEY_SETTINGS, &settings, sizeof(settings));
|
|
} else {
|
|
settings.EnablePeek = true;
|
|
settings.TrackBTStatus = false;
|
|
settings.ShowTimeMG = false;
|
|
settings.UseCustomLED = false;
|
|
settings.DateTimeoutSecs = 3;
|
|
settings.LowFuelPercent = 20;
|
|
settings.ColorLED = GColorWhite;
|
|
settings.ColorBG = GColorBlue;
|
|
settings.ColorMGBars = GColorDarkGray;
|
|
settings.ColorBarsCool = GColorDukeBlue;
|
|
settings.ColorBarsHot = GColorRed;
|
|
settings.ColorMGTime = GColorDarkGray;
|
|
settings.ColorLetters = GColorWhite;
|
|
settings.ColorHours = GColorWhite;
|
|
settings.ColorMinutes = GColorWhite;
|
|
settings.ColorWarning = GColorChromeYellow;
|
|
}
|
|
|
|
// load bitmaps
|
|
s_font_bitmaps[0] = gbitmap_create_with_resource(RESOURCE_ID_0);
|
|
s_font_bitmaps[1] = gbitmap_create_with_resource(RESOURCE_ID_1);
|
|
s_font_bitmaps[2] = gbitmap_create_with_resource(RESOURCE_ID_2);
|
|
s_font_bitmaps[3] = gbitmap_create_with_resource(RESOURCE_ID_3);
|
|
s_font_bitmaps[4] = gbitmap_create_with_resource(RESOURCE_ID_4);
|
|
s_font_bitmaps[5] = gbitmap_create_with_resource(RESOURCE_ID_5);
|
|
s_font_bitmaps[6] = gbitmap_create_with_resource(RESOURCE_ID_6);
|
|
s_font_bitmaps[7] = gbitmap_create_with_resource(RESOURCE_ID_7);
|
|
s_font_bitmaps[8] = gbitmap_create_with_resource(RESOURCE_ID_8);
|
|
s_font_bitmaps[9] = gbitmap_create_with_resource(RESOURCE_ID_9);
|
|
s_c_icon = gbitmap_create_with_resource(RESOURCE_ID_C);
|
|
s_h_icon = gbitmap_create_with_resource(RESOURCE_ID_H);
|
|
s_e_icon = gbitmap_create_with_resource(RESOURCE_ID_E);
|
|
s_f_icon = gbitmap_create_with_resource(RESOURCE_ID_F);
|
|
|
|
for (int i = 0; i < 4; ++i) {
|
|
s_time_fg_layers[i] = bitmap_layer_create(s_time_grects[i]);
|
|
bitmap_layer_set_compositing_mode(s_time_fg_layers[i], GCompOpSet);
|
|
}
|
|
s_temp_layer = layer_create(GRect(s_temp_guage_x_pos, 0, s_bar_width, PBL_DISPLAY_HEIGHT));
|
|
layer_set_update_proc(s_temp_layer, temp_update_proc);
|
|
s_fuel_layer = layer_create(GRect(s_fuel_guage_x_pos, 0, s_bar_width, PBL_DISPLAY_HEIGHT));
|
|
layer_set_update_proc(s_fuel_layer, fuel_update_proc);
|
|
|
|
update_minute_1();
|
|
batt_callback(battery_state_service_peek());
|
|
|
|
app_message_register_inbox_received(inbox_received_handler);
|
|
app_message_open(255, 64);
|
|
|
|
s_main_window = window_create();
|
|
window_set_window_handlers(
|
|
s_main_window,
|
|
(WindowHandlers){.load = main_window_load, .unload = main_window_unload});
|
|
window_stack_push(s_main_window, false);
|
|
|
|
tick_timer_service_subscribe(MINUTE_UNIT, minute_handler);
|
|
battery_state_service_subscribe(batt_callback);
|
|
}
|
|
|
|
static void deinit() {
|
|
connection_service_unsubscribe();
|
|
battery_state_service_unsubscribe();
|
|
tick_timer_service_unsubscribe();
|
|
layer_destroy(s_fuel_layer);
|
|
layer_destroy(s_temp_layer);
|
|
gbitmap_destroy(s_f_icon);
|
|
gbitmap_destroy(s_e_icon);
|
|
gbitmap_destroy(s_h_icon);
|
|
gbitmap_destroy(s_c_icon);
|
|
for (int i = 0; i < 4; ++i) {
|
|
bitmap_layer_destroy(s_time_fg_layers[i]);
|
|
}
|
|
for (int i = 0; i < 10; ++i) {
|
|
gbitmap_destroy(s_font_bitmaps[i]);
|
|
}
|
|
window_destroy(s_main_window);
|
|
}
|
|
|
|
int main(void) {
|
|
init();
|
|
app_event_loop();
|
|
deinit();
|
|
}
|