Upload files to "src/c"
This commit is contained in:
625
src/c/basic.c
Normal file
625
src/c/basic.c
Normal file
@@ -0,0 +1,625 @@
|
|||||||
|
#include <pebble.h>
|
||||||
|
#include "basic.h"
|
||||||
|
#include "constants.h"
|
||||||
|
#include "options.h"
|
||||||
|
#include "weather.h"
|
||||||
|
#include "messaging.h"
|
||||||
|
#include "digital_time.h"
|
||||||
|
#include <pebble-bluetooth-icon/pebble-bluetooth-icon.h>
|
||||||
|
|
||||||
|
#define DEBUG_DATE "Sat 02 Jul"
|
||||||
|
#define DEBUG_DAY "Sunday"
|
||||||
|
#define SCREEN_SHOT_HR 20
|
||||||
|
#define SCREEN_SHOT_MIN 38
|
||||||
|
|
||||||
|
Options s_options;
|
||||||
|
|
||||||
|
//stores weather retry counts (incremented in second tick handler).
|
||||||
|
//Stop retry count at DEFAULT_MAX_WEATHER_RETRY_COUNT
|
||||||
|
int g_weather_retry_count = 0;
|
||||||
|
|
||||||
|
static TextLayer *s_hr_layer, *s_min_layer;
|
||||||
|
|
||||||
|
static GFont s_time_font;
|
||||||
|
static GFont s_time_thin_font;
|
||||||
|
static GFont s_time_bold_font;
|
||||||
|
static BitmapLayer *s_background_layer;
|
||||||
|
static GBitmap *s_background_bitmap;
|
||||||
|
|
||||||
|
static BluetoothLayer *s_bluetooth_layer;
|
||||||
|
//static TextLayer *s_bluetooth_battery_text_layer;
|
||||||
|
//static BatteryBarLayer *s_battery_layer;
|
||||||
|
|
||||||
|
static GFont s_date_font;
|
||||||
|
TextLayer *s_date_layer;
|
||||||
|
TextLayer *s_steps_layer;
|
||||||
|
|
||||||
|
AppTimer *temp_display_timer;
|
||||||
|
|
||||||
|
void set_hr_layer_color(GColor textColor) {
|
||||||
|
text_layer_set_text_color(s_hr_layer, textColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_min_layer_color(GColor textColor) {
|
||||||
|
text_layer_set_text_color(s_min_layer, textColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_wsd_layers_color(GColor textColor) {
|
||||||
|
text_layer_set_text_color(weather_layer1, textColor);
|
||||||
|
text_layer_set_text_color(weather_layer2, textColor);
|
||||||
|
text_layer_set_text_color(weather_layer_center, textColor);
|
||||||
|
text_layer_set_text_color(s_steps_layer, textColor);
|
||||||
|
text_layer_set_text_color(s_date_layer, textColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void init_window_background_color(){
|
||||||
|
|
||||||
|
window_set_background_color(s_main_window, GColorBlack);
|
||||||
|
text_layer_set_background_color(s_bluetooth_battery_text_layer, GColorBlack);
|
||||||
|
|
||||||
|
#ifdef PBL_COLOR // If on basalt
|
||||||
|
window_set_background_color(s_main_window, GColorFromHEX(s_options.background_color));
|
||||||
|
text_layer_set_background_color(s_bluetooth_battery_text_layer, GColorFromHEX(s_options.background_color));
|
||||||
|
battery_bar_set_colors(GColorGreen, GColorYellow, GColorRed, GColorWhite);
|
||||||
|
#else
|
||||||
|
if (s_options.background_color == 0xFFFFFF) {
|
||||||
|
window_set_background_color(s_main_window, GColorWhite);//white
|
||||||
|
text_layer_set_background_color(s_bluetooth_battery_text_layer, GColorWhite);//white
|
||||||
|
battery_bar_set_colors(GColorBlack, GColorBlack, GColorBlack, GColorBlack);
|
||||||
|
}
|
||||||
|
else if (s_options.background_color == 0x000000) {//black
|
||||||
|
window_set_background_color(s_main_window, GColorBlack);
|
||||||
|
text_layer_set_background_color(s_bluetooth_battery_text_layer, GColorBlack);
|
||||||
|
battery_bar_set_colors(GColorWhite, GColorWhite, GColorWhite, GColorWhite);
|
||||||
|
}
|
||||||
|
else { //didn't select white or black, default to white
|
||||||
|
window_set_background_color(s_main_window, GColorBlack);
|
||||||
|
text_layer_set_background_color(s_bluetooth_battery_text_layer, GColorBlack);
|
||||||
|
battery_bar_set_colors(GColorWhite, GColorWhite, GColorWhite, GColorWhite);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
layer_mark_dirty(text_layer_get_layer(s_bluetooth_battery_text_layer));
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_static_row(TextLayer *label, GFont font) {
|
||||||
|
text_layer_set_background_color(label, GColorClear);
|
||||||
|
text_layer_set_text_color(label, GColorWhite);
|
||||||
|
text_layer_set_text_color(label, GColorFromHEX(s_options.wsd_color));
|
||||||
|
|
||||||
|
if (font) {
|
||||||
|
text_layer_set_font(label, font);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void bt_handler(bool isConnected) {
|
||||||
|
|
||||||
|
int current_bluetooth_state = 0; //default bluetooth disconnected
|
||||||
|
if (isConnected) {
|
||||||
|
current_bluetooth_state = 1; //bluetooth connected
|
||||||
|
}
|
||||||
|
|
||||||
|
//if bluetooth was previously disconnected and is now connected
|
||||||
|
if (s_options.bluetooth_state == 0 &&
|
||||||
|
current_bluetooth_state == 1) {
|
||||||
|
|
||||||
|
//clear weather conditions and reset weather retry count to force weather update
|
||||||
|
memset(s_options.conditions, 0,sizeof(s_options.conditions));
|
||||||
|
s_options.condition_code = DEFAULT_CONDITION_CODE;
|
||||||
|
g_weather_retry_count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//store bluetooth state
|
||||||
|
s_options.bluetooth_state = current_bluetooth_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
void on_animation_stopped(Animation *anim, bool finished, void *context) {
|
||||||
|
//Free the memory used by the Animation
|
||||||
|
property_animation_destroy((PropertyAnimation*) anim);
|
||||||
|
}
|
||||||
|
|
||||||
|
void animate_grect_layer(Layer *layer, GRect *start, GRect *finish, int duration, int delay) {
|
||||||
|
//Declare animation
|
||||||
|
PropertyAnimation *anim = property_animation_create_layer_frame(layer, start, finish);
|
||||||
|
|
||||||
|
//Set characteristics
|
||||||
|
animation_set_duration((Animation*) anim, duration);
|
||||||
|
animation_set_delay((Animation*) anim, delay);
|
||||||
|
|
||||||
|
//Set stopped handler to free memory
|
||||||
|
AnimationHandlers handlers = {
|
||||||
|
//The reference to the stopped handler is the only one in the array
|
||||||
|
.stopped = (AnimationStoppedHandler) on_animation_stopped
|
||||||
|
};
|
||||||
|
animation_set_handlers((Animation*) anim, handlers, NULL);
|
||||||
|
|
||||||
|
//Start animation!
|
||||||
|
animation_schedule((Animation*) anim);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void animate_text_layers_round() {
|
||||||
|
|
||||||
|
// Steps moves in from bottom
|
||||||
|
GRect sins = GRect(20, 180, 60, 24);
|
||||||
|
GRect sinf = GRect(20, 122, 60, 24);
|
||||||
|
animate_grect_layer(text_layer_get_layer(s_steps_layer), &sins, &sinf, 1000, 0);
|
||||||
|
|
||||||
|
GRect souts = GRect(20, 122, 60, 24);
|
||||||
|
GRect soutf = GRect(20, 180, 60, 24);
|
||||||
|
animate_grect_layer(text_layer_get_layer(s_steps_layer), &souts, &soutf, 1000, 5000);
|
||||||
|
|
||||||
|
// Date moves in from bottom
|
||||||
|
GRect dins = GRect(100, 180, 60, 24);
|
||||||
|
GRect dinf = GRect(100, 122, 60, 24);
|
||||||
|
animate_grect_layer(text_layer_get_layer(s_date_layer), &dins, &dinf, 1000, 0);
|
||||||
|
|
||||||
|
GRect douts = GRect(100, 122, 60, 24);
|
||||||
|
GRect doutf = GRect(100, 180, 60, 24);
|
||||||
|
animate_grect_layer(text_layer_get_layer(s_date_layer), &douts, &doutf, 1000, 5000);
|
||||||
|
|
||||||
|
// Bluetooth & battery layers revealed at top
|
||||||
|
GRect bbins = GRect(0, 5, 200, 47);
|
||||||
|
GRect bbinf = GRect(0, -47, 200, 47);
|
||||||
|
animate_grect_layer(text_layer_get_layer(s_bluetooth_battery_text_layer), &bbins, &bbinf, 1000, 0);
|
||||||
|
|
||||||
|
GRect bbouts = GRect(0, -47, 200, 47);
|
||||||
|
GRect bboutf = GRect(0, 5, 200, 47);
|
||||||
|
animate_grect_layer(text_layer_get_layer(s_bluetooth_battery_text_layer), &bbouts, &bboutf, 1000, 5000);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void animate_text_layers() {
|
||||||
|
|
||||||
|
// Steps moves in from bottom
|
||||||
|
GRect sins = GRect(2, 180, 80, 24);
|
||||||
|
GRect sinf = GRect(2, 151, 80, 24);
|
||||||
|
animate_grect_layer(text_layer_get_layer(s_steps_layer), &sins, &sinf, 1000, 0);
|
||||||
|
|
||||||
|
GRect souts = GRect(2, 151, 80, 24);
|
||||||
|
GRect soutf = GRect(2, 180, 80, 24);
|
||||||
|
animate_grect_layer(text_layer_get_layer(s_steps_layer), &souts, &soutf, 1000, 5000);
|
||||||
|
|
||||||
|
// Date moves in from bottom
|
||||||
|
GRect dins = GRect(82, 180, 60, 24);
|
||||||
|
GRect dinf = GRect(82, 151, 60, 24);
|
||||||
|
animate_grect_layer(text_layer_get_layer(s_date_layer), &dins, &dinf, 1000, 0);
|
||||||
|
|
||||||
|
GRect douts = GRect(82, 151, 60, 24);
|
||||||
|
GRect doutf = GRect(82, 180, 60, 24);
|
||||||
|
animate_grect_layer(text_layer_get_layer(s_date_layer), &douts, &doutf, 1000, 5000);
|
||||||
|
|
||||||
|
// Bluetooth & battery layers revealed at top
|
||||||
|
GRect bbins = GRect(0, 0, 200, 35);
|
||||||
|
GRect bbinf = GRect(0, -35, 200, 35);
|
||||||
|
animate_grect_layer(text_layer_get_layer(s_bluetooth_battery_text_layer), &bbins, &bbinf, 1000, 0);
|
||||||
|
|
||||||
|
GRect bbouts = GRect(0, -35, 200, 35);
|
||||||
|
GRect bboutf = GRect(0, 0, 200, 35);
|
||||||
|
animate_grect_layer(text_layer_get_layer(s_bluetooth_battery_text_layer), &bbouts, &bboutf, 1000, 5000);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void update_time(struct tm *tick_time, TimeUnits units_changed) {
|
||||||
|
static char date_buffer[16];
|
||||||
|
const char *current_date_layer;
|
||||||
|
|
||||||
|
// Create a long-lived buffer
|
||||||
|
static char hr_buffer[] = "00";
|
||||||
|
static char min_buffer[] = "00";
|
||||||
|
|
||||||
|
// Write the current hours and minutes into the buffer
|
||||||
|
if(clock_is_24h_style() == true) {
|
||||||
|
//Use 2h hour format
|
||||||
|
strftime(hr_buffer, sizeof("00"), "%H", tick_time);
|
||||||
|
} else {
|
||||||
|
//Use 12 hour format
|
||||||
|
strftime(hr_buffer, sizeof("00"), "%I", tick_time);
|
||||||
|
}
|
||||||
|
strftime(min_buffer, sizeof("00"), "%M", tick_time);
|
||||||
|
|
||||||
|
// Display this time on the TextLayer
|
||||||
|
text_layer_set_text(s_hr_layer, hr_buffer);
|
||||||
|
|
||||||
|
// Display the seconds on the TextLayer
|
||||||
|
text_layer_set_text(s_min_layer, min_buffer);
|
||||||
|
|
||||||
|
//add date layer
|
||||||
|
current_date_layer = text_layer_get_text(s_date_layer);
|
||||||
|
|
||||||
|
if (current_date_layer != date_buffer) {
|
||||||
|
//get current date
|
||||||
|
strftime(date_buffer, sizeof(date_buffer), "%a %d %b", tick_time);
|
||||||
|
#if DEBUG
|
||||||
|
strftime(date_buffer, sizeof(date_buffer), DEBUG_DATE, tick_time); //for screen shots
|
||||||
|
#endif
|
||||||
|
text_layer_set_text(s_date_layer, date_buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//every five seconds
|
||||||
|
static void handle_5second_tick(struct tm *tick_time, TimeUnits units_changed) {
|
||||||
|
|
||||||
|
//if conditions blank (no current weather info)
|
||||||
|
if(strlen(s_options.conditions) == 0 &&
|
||||||
|
g_weather_retry_count < DEFAULT_MAX_WEATHER_RETRY_COUNT) {
|
||||||
|
|
||||||
|
//add one to weather retry count - stop trying this app session at DEFAULT_MAX_WEATHER_RETRY_COUNT
|
||||||
|
++g_weather_retry_count;
|
||||||
|
|
||||||
|
//reset time since last forecast timer
|
||||||
|
s_options.min_since_last_forecast = 0;
|
||||||
|
|
||||||
|
//get updated weather
|
||||||
|
send(KEY_GET_WEATHER, 1, KEY_WEATHER_USE_GPS, s_options.weather_use_GPS, KEY_WEATHER_LOCATION, s_options.weather_location);
|
||||||
|
|
||||||
|
//update weather layer
|
||||||
|
update_weather_layer();
|
||||||
|
}
|
||||||
|
//APP_LOG(APP_LOG_LEVEL_DEBUG, "heap_bytes_free:heap_bytes_used %zu: %zu", heap_bytes_free(), heap_bytes_used());
|
||||||
|
}
|
||||||
|
|
||||||
|
static void update_steps() {
|
||||||
|
HealthMetric metric = HealthMetricStepCount;
|
||||||
|
time_t start = time_start_of_today();
|
||||||
|
time_t end = time(NULL);
|
||||||
|
static char steps_buffer[32];
|
||||||
|
|
||||||
|
// Check the metric has data available for today
|
||||||
|
HealthServiceAccessibilityMask mask = health_service_metric_accessible(metric,
|
||||||
|
start, end);
|
||||||
|
|
||||||
|
if(mask & HealthServiceAccessibilityMaskAvailable) {
|
||||||
|
// Data is available!
|
||||||
|
snprintf(steps_buffer, sizeof(steps_buffer), "s: %d", (int)health_service_sum_today(metric));
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
snprintf(steps_buffer, sizeof(steps_buffer), "s: 1%d", (int)health_service_sum_today(metric));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
APP_LOG(APP_LOG_LEVEL_INFO, "Steps today: %d",
|
||||||
|
(int)health_service_sum_today(metric));
|
||||||
|
// Display to user in correct units
|
||||||
|
text_layer_set_text(s_steps_layer, steps_buffer);
|
||||||
|
} else {
|
||||||
|
// No data recorded yet today
|
||||||
|
APP_LOG(APP_LOG_LEVEL_ERROR, "Data unavailable!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void timer_callback(void *context) {
|
||||||
|
APP_LOG(APP_LOG_LEVEL_INFO, "Timer elapsed!");
|
||||||
|
|
||||||
|
if (s_options.shake_for_lohi == 1) {
|
||||||
|
//Display Lo Hi temp info;
|
||||||
|
display_lohi_weather_info();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tap_handler(AccelAxisType axis, int32_t direction) {
|
||||||
|
update_steps();
|
||||||
|
#if defined(PBL_ROUND)
|
||||||
|
animate_text_layers_round();
|
||||||
|
#else
|
||||||
|
animate_text_layers();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Schedule the timer
|
||||||
|
app_timer_register(2500, timer_callback, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void main_window_load(Window *window) {
|
||||||
|
|
||||||
|
//set-retrieve watchface options
|
||||||
|
init_options();
|
||||||
|
|
||||||
|
//add weather and date layers
|
||||||
|
GRect layer_frame = layer_get_frame(window_get_root_layer(s_main_window));
|
||||||
|
const int16_t width = layer_frame.size.w;
|
||||||
|
const int16_t height = layer_frame.size.h;
|
||||||
|
|
||||||
|
//Create GFont
|
||||||
|
|
||||||
|
s_time_font = fonts_load_custom_font(resource_get_handle(RESOURCE_ID_FONT_ROBOTO_REGULAR_48));
|
||||||
|
s_time_thin_font = fonts_load_custom_font(resource_get_handle(RESOURCE_ID_FONT_ROBOTO_LIGHT_48));
|
||||||
|
s_time_bold_font = fonts_load_custom_font(resource_get_handle(RESOURCE_ID_FONT_ROBOTO_BOLD_48));
|
||||||
|
|
||||||
|
// Create time TextLayer
|
||||||
|
#if defined(PBL_ROUND)
|
||||||
|
s_hr_layer = text_layer_create(GRect(35, 57, 57, 48));
|
||||||
|
#else
|
||||||
|
s_hr_layer = text_layer_create(GRect(15, 50, 57, 48));
|
||||||
|
#endif
|
||||||
|
text_layer_set_background_color(s_hr_layer, GColorClear);
|
||||||
|
text_layer_set_text_color(s_hr_layer, GColorFromHEX(s_options.hr_color));
|
||||||
|
text_layer_set_text_alignment(s_hr_layer, GTextAlignmentRight);
|
||||||
|
text_layer_set_text(s_hr_layer, "00");
|
||||||
|
|
||||||
|
if (s_options.hourFont == 2) {
|
||||||
|
text_layer_set_font(s_hr_layer, s_time_bold_font);
|
||||||
|
}
|
||||||
|
else if(s_options.hourFont == 0) {
|
||||||
|
text_layer_set_font(s_hr_layer, s_time_thin_font);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
text_layer_set_font(s_hr_layer, s_time_font);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add it as a child layer to the Window's root layer
|
||||||
|
layer_add_child(window_get_root_layer(window), text_layer_get_layer(s_hr_layer));
|
||||||
|
|
||||||
|
#if defined(PBL_ROUND)
|
||||||
|
s_min_layer = text_layer_create(GRect(95, 57, 57, 48));
|
||||||
|
#else
|
||||||
|
s_min_layer = text_layer_create(GRect(75, 50, 57, 48));
|
||||||
|
#endif
|
||||||
|
text_layer_set_background_color(s_min_layer, GColorClear);
|
||||||
|
text_layer_set_text_alignment(s_min_layer, GTextAlignmentLeft);
|
||||||
|
text_layer_set_text_color(s_min_layer, GColorFromHEX(s_options.min_color));
|
||||||
|
|
||||||
|
if (s_options.minutesFont == 2) {
|
||||||
|
text_layer_set_font(s_min_layer, s_time_bold_font);
|
||||||
|
}
|
||||||
|
else if(s_options.minutesFont == 0) {
|
||||||
|
text_layer_set_font(s_min_layer, s_time_thin_font);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
text_layer_set_font(s_min_layer, s_time_font);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add it as a child layer to the Window's root layer
|
||||||
|
layer_add_child(window_get_root_layer(window), text_layer_get_layer(s_min_layer));
|
||||||
|
|
||||||
|
//add Bluetooth layer
|
||||||
|
s_bluetooth_layer = bluetooth_layer_create();
|
||||||
|
#if defined(PBL_ROUND)
|
||||||
|
bluetooth_set_position(GPoint(42, 31));
|
||||||
|
#else
|
||||||
|
bluetooth_set_position(GPoint(2, 2));
|
||||||
|
#endif
|
||||||
|
layer_add_child(window_get_root_layer(window), s_bluetooth_layer);
|
||||||
|
|
||||||
|
//add battery layer
|
||||||
|
s_battery_layer = battery_bar_layer_create();
|
||||||
|
battery_bar_set_percent_hidden(true);
|
||||||
|
battery_bar_set_icon_hidden(false);
|
||||||
|
#ifdef PBL_COLOR // If on basalt
|
||||||
|
battery_bar_set_colors(GColorGreen, GColorYellow, GColorRed, GColorWhite);
|
||||||
|
#endif
|
||||||
|
#if defined(PBL_ROUND)
|
||||||
|
battery_bar_set_position(GPoint(102, 32));
|
||||||
|
#else
|
||||||
|
battery_bar_set_position(GPoint(102, 3));
|
||||||
|
#endif
|
||||||
|
layer_add_child(window_get_root_layer(window), s_battery_layer);
|
||||||
|
|
||||||
|
//add weather and digital layers
|
||||||
|
add_weather_layers(window_get_root_layer(s_main_window), width, height);
|
||||||
|
add_digital_time_layer(window_get_root_layer(s_main_window), width, height);
|
||||||
|
|
||||||
|
#if defined(PBL_ROUND)
|
||||||
|
s_bluetooth_battery_text_layer = text_layer_create(GRect(0, 5, 200, 45));
|
||||||
|
#else
|
||||||
|
s_bluetooth_battery_text_layer = text_layer_create(GRect(0, 0, 200, 35));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(PBL_ROUND)
|
||||||
|
s_bluetooth_battery_text_layer = text_layer_create(GRect(0, 5, 200, 45));
|
||||||
|
#else
|
||||||
|
s_bluetooth_battery_text_layer = text_layer_create(GRect(0, 0, 200, 35));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
init_window_background_color();
|
||||||
|
layer_add_child(window_get_root_layer(window), text_layer_get_layer(s_bluetooth_battery_text_layer));
|
||||||
|
|
||||||
|
/*
|
||||||
|
//text_layer_set_background_color(s_bluetooth_battery_text_layer, GColorClear);
|
||||||
|
#ifdef PBL_COLOR // If on basalt
|
||||||
|
text_layer_set_background_color(s_bluetooth_battery_text_layer, GColorFromHEX(s_options.background_color));
|
||||||
|
#else
|
||||||
|
if (s_options.background_color == 0xFFFFFF) {
|
||||||
|
text_layer_set_background_color(s_bluetooth_battery_text_layer, GColorWhite);//white
|
||||||
|
}
|
||||||
|
else if (s_options.background_color == 0x000000) {//black
|
||||||
|
text_layer_set_background_color(s_bluetooth_battery_text_layer, GColorBlack);
|
||||||
|
}
|
||||||
|
else { //didn't select white or black, default to white
|
||||||
|
text_layer_set_background_color(s_bluetooth_battery_text_layer, GColorBlack);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
*/
|
||||||
|
|
||||||
|
//date layer
|
||||||
|
#if defined(PBL_ROUND)
|
||||||
|
s_date_layer = text_layer_create(GRect(100, 180, 60, 24));
|
||||||
|
#else
|
||||||
|
s_date_layer = text_layer_create(GRect(82, 180, 60, 24));
|
||||||
|
#endif
|
||||||
|
text_layer_set_background_color(s_date_layer, GColorClear);
|
||||||
|
text_layer_set_text_color(s_date_layer, GColorFromHEX(s_options.wsd_color));
|
||||||
|
text_layer_set_text_alignment(s_date_layer, GTextAlignmentRight);
|
||||||
|
s_date_font = fonts_get_system_font(FONT_KEY_GOTHIC_14);
|
||||||
|
//s_date_font = fonts_load_custom_font(resource_get_handle(RESOURCE_ID_FONT_DIGITAL_SEVEN_14));
|
||||||
|
|
||||||
|
//Apply to TextLayer
|
||||||
|
text_layer_set_font(s_date_layer, s_date_font);
|
||||||
|
layer_add_child(window_get_root_layer(window), text_layer_get_layer(s_date_layer));
|
||||||
|
|
||||||
|
//steps layer
|
||||||
|
#if defined(PBL_ROUND)
|
||||||
|
s_steps_layer = text_layer_create(GRect(20, 180, 60, 24));
|
||||||
|
#else
|
||||||
|
s_steps_layer = text_layer_create(GRect(2, 180, 80, 24));
|
||||||
|
#endif
|
||||||
|
text_layer_set_background_color(s_steps_layer, GColorClear);
|
||||||
|
text_layer_set_text_color(s_steps_layer, GColorFromHEX(s_options.wsd_color));
|
||||||
|
text_layer_set_text_alignment(s_steps_layer, GTextAlignmentLeft);
|
||||||
|
s_date_font = fonts_get_system_font(FONT_KEY_GOTHIC_14);
|
||||||
|
//s_steps_font = fonts_load_custom_font(resource_get_handle(RESOURCE_ID_FONT_DIGITAL_SEVEN_14));
|
||||||
|
|
||||||
|
//Apply to TextLayer
|
||||||
|
text_layer_set_font(s_steps_layer, s_date_font);
|
||||||
|
layer_add_child(window_get_root_layer(window), text_layer_get_layer(s_steps_layer));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void main_window_unload(Window *window) {
|
||||||
|
|
||||||
|
//Destroy Bluetooth layer
|
||||||
|
bluetooth_layer_destroy(s_bluetooth_layer);
|
||||||
|
|
||||||
|
//Destroy battery layer
|
||||||
|
battery_bar_layer_destroy(s_battery_layer);
|
||||||
|
|
||||||
|
//Destroy GBitmap
|
||||||
|
gbitmap_destroy(s_background_bitmap);
|
||||||
|
|
||||||
|
//Destroy BitmapLayer
|
||||||
|
bitmap_layer_destroy(s_background_layer);
|
||||||
|
|
||||||
|
// Destroy TextLayers
|
||||||
|
text_layer_destroy(s_hr_layer);
|
||||||
|
text_layer_destroy(s_min_layer);
|
||||||
|
text_layer_destroy(s_bluetooth_battery_text_layer);
|
||||||
|
|
||||||
|
text_layer_destroy(weather_layer1);
|
||||||
|
text_layer_destroy(weather_layer_center);
|
||||||
|
text_layer_destroy(weather_layer2);
|
||||||
|
text_layer_destroy(digital_time_layer);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void health_handler(HealthEventType event, void *context) {
|
||||||
|
// Which type of event occurred?
|
||||||
|
switch(event) {
|
||||||
|
case HealthEventSignificantUpdate:
|
||||||
|
//update_steps();
|
||||||
|
APP_LOG(APP_LOG_LEVEL_INFO,
|
||||||
|
"New HealthService HealthEventSignificantUpdate event");
|
||||||
|
break;
|
||||||
|
case HealthEventMovementUpdate:
|
||||||
|
//update_steps();
|
||||||
|
APP_LOG(APP_LOG_LEVEL_INFO,
|
||||||
|
"New HealthService HealthEventMovementUpdate event");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HealthEventMetricAlert:
|
||||||
|
APP_LOG(APP_LOG_LEVEL_INFO,
|
||||||
|
"New HealthService HealthEventMetricAlert event");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HealthEventHeartRateUpdate:
|
||||||
|
APP_LOG(APP_LOG_LEVEL_INFO,
|
||||||
|
"New HealthService HealthEventHeartRateUpdate event");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case HealthEventSleepUpdate:
|
||||||
|
APP_LOG(APP_LOG_LEVEL_INFO,
|
||||||
|
"New HealthService HealthEventSleepUpdate event");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_minute_tick(struct tm *tick_time, TimeUnits units_changed) {
|
||||||
|
update_time(tick_time, units_changed);
|
||||||
|
|
||||||
|
//get minutes since last weather update
|
||||||
|
time_t t = time(NULL);
|
||||||
|
int min_since_last_update = (difftime(t, s_options.last_update) / 60) + 1;
|
||||||
|
|
||||||
|
APP_LOG(APP_LOG_LEVEL_DEBUG, " (Last update %s) min_since_last_update:weather_frequency - %d:%d", s_options.last_weather_update24hr, min_since_last_update, s_options.weather_frequency);
|
||||||
|
//APP_LOG(APP_LOG_LEVEL_DEBUG, "handle_minute_tick strlen(s_options.conditions): %zu", strlen(s_options.conditions));
|
||||||
|
//if min_since_last_forecast greater than or equal to weatherUpdateFrequency
|
||||||
|
if(min_since_last_update >= s_options.weather_frequency ||
|
||||||
|
strlen(s_options.conditions) == 0) {
|
||||||
|
|
||||||
|
s_options.min_since_last_forecast = 0;
|
||||||
|
|
||||||
|
//get updated weather
|
||||||
|
send(KEY_GET_WEATHER, 1, KEY_WEATHER_USE_GPS, s_options.weather_use_GPS, KEY_WEATHER_LOCATION, s_options.weather_location);
|
||||||
|
|
||||||
|
//update weather layer
|
||||||
|
update_weather_layer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_tick(struct tm *tick_time, TimeUnits units_changed) {
|
||||||
|
|
||||||
|
if (units_changed & SECOND_UNIT) {
|
||||||
|
if (tick_time->tm_sec % 5 == 0) {
|
||||||
|
handle_5second_tick(tick_time, units_changed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (units_changed & MINUTE_UNIT) {
|
||||||
|
handle_minute_tick(tick_time, units_changed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void init() {
|
||||||
|
// Create main Window element and assign to pointer
|
||||||
|
s_main_window = window_create();
|
||||||
|
|
||||||
|
// Set handlers to manage the elements inside the Window
|
||||||
|
window_set_window_handlers(s_main_window, (WindowHandlers) {
|
||||||
|
.load = main_window_load,
|
||||||
|
.unload = main_window_unload
|
||||||
|
});
|
||||||
|
|
||||||
|
// Show the Window on the watch, with animated=true
|
||||||
|
window_stack_push(s_main_window, true);
|
||||||
|
|
||||||
|
app_message_register_inbox_received(inbox_received_callback);
|
||||||
|
app_message_register_inbox_dropped(message_dropped);
|
||||||
|
app_message_register_outbox_sent(message_out_success);
|
||||||
|
app_message_register_outbox_failed(message_out_failed);
|
||||||
|
|
||||||
|
#if defined(PBL_BW)
|
||||||
|
app_message_open(175, 250);
|
||||||
|
#else
|
||||||
|
app_message_open(app_message_inbox_size_maximum(), app_message_outbox_size_maximum());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
update_digital_time_layer(); //update digital_time_layer
|
||||||
|
update_weather_layer(); //update weather layer
|
||||||
|
|
||||||
|
time_t t = time(NULL);
|
||||||
|
struct tm *time_now = localtime(&t);
|
||||||
|
#if DEBUG
|
||||||
|
time_now->tm_hour = SCREEN_SHOT_HR; //for screen shots
|
||||||
|
time_now->tm_min = SCREEN_SHOT_MIN;
|
||||||
|
#endif
|
||||||
|
handle_tick(time_now, MINUTE_UNIT);
|
||||||
|
|
||||||
|
// Subscribe to Bluetooth updates
|
||||||
|
connection_service_subscribe((ConnectionHandlers) {
|
||||||
|
.pebble_app_connection_handler = bt_handler
|
||||||
|
});
|
||||||
|
|
||||||
|
// Check current bluetooth connection state
|
||||||
|
bt_handler(connection_service_peek_pebble_app_connection());
|
||||||
|
|
||||||
|
#if defined(PBL_HEALTH)
|
||||||
|
// Attempt to subscribe
|
||||||
|
if(!health_service_events_subscribe(health_handler, NULL)) {
|
||||||
|
APP_LOG(APP_LOG_LEVEL_ERROR, "Health not available!");
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
APP_LOG(APP_LOG_LEVEL_ERROR, "Health not available!");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
accel_tap_service_subscribe(tap_handler);
|
||||||
|
|
||||||
|
// Register with TickTimerService
|
||||||
|
tick_timer_service_subscribe(MINUTE_UNIT | SECOND_UNIT, handle_tick);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void deinit() {
|
||||||
|
//save watchface options
|
||||||
|
persist_write_data(KEY_OPTIONS, &s_options, sizeof(s_options));
|
||||||
|
|
||||||
|
|
||||||
|
// Destroy Window
|
||||||
|
window_destroy(s_main_window);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
init();
|
||||||
|
app_event_loop();
|
||||||
|
deinit();
|
||||||
|
}
|
||||||
50
src/c/basic.h
Normal file
50
src/c/basic.h
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
#include <pebble.h>
|
||||||
|
#include <pebble-battery-bar/pebble-battery-bar.h>
|
||||||
|
|
||||||
|
TextLayer *weather_layer1, *weather_layer2, *weather_layer_center;
|
||||||
|
TextLayer *s_bluetooth_battery_text_layer;
|
||||||
|
TextLayer *date_layer1, *date_layer2, *date_layer_center;
|
||||||
|
TextLayer *digital_time_layer;
|
||||||
|
TextLayer *battery_layer;
|
||||||
|
AppTimer *lohi_display_timer;
|
||||||
|
BatteryBarLayer *s_battery_layer;
|
||||||
|
|
||||||
|
void init_static_row(TextLayer *label, GFont font); //creates/configures static (weather/date) display lines
|
||||||
|
void set_text_layers_color(GColor textColor); //sets color for text (weather, date, digital time) elements
|
||||||
|
|
||||||
|
void set_hr_layer_color(GColor textColor);
|
||||||
|
void set_min_layer_color(GColor textColor);
|
||||||
|
void set_wsd_layers_color(GColor textColor);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int shake_for_lohi;
|
||||||
|
int tempF;
|
||||||
|
int tempFLo;
|
||||||
|
int tempFHi;
|
||||||
|
int tempC;
|
||||||
|
int tempCLo;
|
||||||
|
int tempCHi;
|
||||||
|
int display_weather;
|
||||||
|
int weather_use_GPS;
|
||||||
|
char weather_location[64];
|
||||||
|
int use_celsius;
|
||||||
|
int weather_frequency;
|
||||||
|
int min_since_last_forecast;
|
||||||
|
int condition_code;
|
||||||
|
int display_digital_time;
|
||||||
|
int pebble_js_ready;
|
||||||
|
int hr_color;
|
||||||
|
int min_color;
|
||||||
|
int wsd_color;
|
||||||
|
int background_color;
|
||||||
|
int hourFont;
|
||||||
|
int minutesFont;
|
||||||
|
bool bluetooth_state;
|
||||||
|
time_t last_update;
|
||||||
|
char conditions[32];
|
||||||
|
char last_weather_update12hr[16];
|
||||||
|
char last_weather_update24hr[16];
|
||||||
|
} Options;
|
||||||
|
|
||||||
|
Window *s_main_window;
|
||||||
|
Layer *s_canvas_layer;
|
||||||
40
src/c/constants.c
Normal file
40
src/c/constants.c
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
#include <pebble.h>
|
||||||
|
#include "constants.h"
|
||||||
|
|
||||||
|
const int DEFAULT_SHAKE_FOR_LOHI = 1; //True - shake to show Lo Hi Temps
|
||||||
|
const int DEFAULT_DISPLAY_LOHI_TIMER = 5000; //length time (milliseconds) to display Lo Hi Temps
|
||||||
|
const int DEFAULT_MIN_SINCE_WEATHER_UPDATE = 0; //weather just updated
|
||||||
|
const char DEFAULT_LAST_WEATHER_UPDATE[16] = "--:--"; //default last update "time" display
|
||||||
|
const char DEFAULT_ERROR_WEATHER_UPDATE[16] = "---"; //default text display upon weather update error
|
||||||
|
const int DEFAULT_CONDITION_CODE = -99; //Invalid condition code to force weather update
|
||||||
|
const int DEFAULT_DISPLAY_WEATHER = 1; //true
|
||||||
|
const int DEFAULT_WEATHER_FREQUENCY = 30; //minutes
|
||||||
|
const int DEFAULT_WEATHER_USE_GPS = 1; //true
|
||||||
|
const int DEFAULT_USE_CELSIUS = 0; //false
|
||||||
|
const int DEFAULT_DISPLAY_DIGITAL_TIME = 0; //false
|
||||||
|
const int DEFAULT_HR_COLOR = 0xFFFFFF; //white
|
||||||
|
const int DEFAULT_MIN_COLOR = 0xFF5500; //orange
|
||||||
|
const int DEFAULT_WSD_COLOR = 0xFFFFFF; //white
|
||||||
|
const int DEFAULT_BACKGROUND_COLOR = 0x000000; //black
|
||||||
|
const int DEFAULT_HOUR_FONT = 1; //regular
|
||||||
|
const int DEFAULT_MINUTES_FONT = 1; //regular
|
||||||
|
|
||||||
|
const int DEFAULT_MAX_WEATHER_RETRY_COUNT = 5; //max (seconds) weather retry counts
|
||||||
|
const uint MAX_CHALK_SINGLE_LINE_CONDITIONS_LEN = 6; //max length for weather conditions to display on single line. longer split to two lines
|
||||||
|
|
||||||
|
const int DEFAULT_CHALK_TIME_X_OFFSET = 20; //X-axis adjustment for time display on Chalk (Pebble Time Round)
|
||||||
|
const int DEFAULT_CHALK_TIME_Y_OFFSET = 10; //Y-axis adjustment for time display on Chalk (Pebble Time Round)
|
||||||
|
const int DEFAULT_MARKERS_X_OFFSET = 7; //X-axix adjustment for when displaying hour/minute markers
|
||||||
|
|
||||||
|
const int DEFAULT_CHALK_WEATHER1_Y_OFFSET = 5; //Y-axis adjustment for weather display on Chalk (Pebble Time Round)
|
||||||
|
const int DEFAULT_CHALK_WEATHER2_Y_OFFSET = 5; //Y-axis adjustment for weather display on Chalk (Pebble Time Round)
|
||||||
|
const int DEFAULT_CHALK_WEATHER_CENTER_Y_OFFSET = 10; //Y-axis adjustment for weather display on Chalk (Pebble Time Round)
|
||||||
|
|
||||||
|
const int DEFAULT_DATE_Y_OFFSET_READABILITY = 4; //Y-axis adjustment for increased readability font options
|
||||||
|
|
||||||
|
const int DEFAULT_DIGITAL_TIME_Y_OFFSET_READABILITY = 5; //Y-axis adjustment for increased readability font options
|
||||||
|
const int DEFAULT_MARKERS_Y_OFFSET = 12; //Y-axix adjustment for when displaying hour/minute markers
|
||||||
|
const int DEFAULT_CHALK_DIGITAL_TIME_Y_OFFSET = 12; //Y-axis adjustment for digital time display on Chalk (Pebble Time Round)
|
||||||
|
|
||||||
|
const int DEFAULT_CHALK_BATTERY_X_OFFSET = 5; //X-axis adjustment for battery display on Chalk (Pebble Time Round)
|
||||||
|
const int DEFAULT_BATTERY_OFFSET_READABILITY = 5; //Y-axis adjustment for increased readability font options
|
||||||
58
src/c/constants.h
Normal file
58
src/c/constants.h
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define DEBUG 0
|
||||||
|
|
||||||
|
#define KEY_TEMPERATURE_IN_C 1
|
||||||
|
#define KEY_CONDITIONS 2
|
||||||
|
#define KEY_WEATHER_FREQUENCY 3
|
||||||
|
#define KEY_USE_CELSIUS 4
|
||||||
|
#define KEY_DISPLAY_WEATHER 5
|
||||||
|
#define KEY_MIN_SINCE_WEATHER_UPDATE 6
|
||||||
|
#define KEY_GET_WEATHER 7
|
||||||
|
#define KEY_TEMPERATURE 8
|
||||||
|
#define KEY_TEMPERATURE_LO 9
|
||||||
|
#define KEY_TEMPERATURE_HI 10
|
||||||
|
#define KEY_TEMPERATURE_IN_C_LO 11
|
||||||
|
#define KEY_TEMPERATURE_IN_C_HI 12
|
||||||
|
#define KEY_CONDITION_CODE 13
|
||||||
|
#define KEY_SHAKE_FOR_LOHI 14
|
||||||
|
#define KEY_DISPLAY_DIGITAL_TIME 15
|
||||||
|
#define KEY_WEATHER_USE_GPS 16
|
||||||
|
#define KEY_WEATHER_LOCATION 17
|
||||||
|
#define KEY_JS_READY 18
|
||||||
|
#define KEY_HR_COLOR 19
|
||||||
|
#define KEY_MIN_COLOR 20
|
||||||
|
#define KEY_WSD_COLOR 21
|
||||||
|
#define KEY_BACKGROUND_COLOR 22
|
||||||
|
#define KEY_HOUR_FONT 23
|
||||||
|
#define KEY_MINUTES_FONT 24
|
||||||
|
#define KEY_OPTIONS 99
|
||||||
|
|
||||||
|
extern const int DEFAULT_SHAKE_FOR_LOHI;
|
||||||
|
extern const int DEFAULT_DISPLAY_LOHI_TIMER;
|
||||||
|
extern const int DEFAULT_MIN_SINCE_WEATHER_UPDATE;
|
||||||
|
extern const char DEFAULT_LAST_WEATHER_UPDATE[16];
|
||||||
|
extern const char DEFAULT_ERROR_WEATHER_UPDATE[16];
|
||||||
|
extern const int DEFAULT_CONDITION_CODE;
|
||||||
|
extern const int DEFAULT_DISPLAY_WEATHER;
|
||||||
|
extern const int DEFAULT_WEATHER_FREQUENCY;
|
||||||
|
extern const int DEFAULT_WEATHER_USE_GPS;
|
||||||
|
extern const int DEFAULT_USE_CELSIUS;
|
||||||
|
extern const int DEFAULT_DISPLAY_DIGITAL_TIME;
|
||||||
|
extern const int DEFAULT_HR_COLOR;
|
||||||
|
extern const int DEFAULT_MIN_COLOR;
|
||||||
|
extern const int DEFAULT_WSD_COLOR;
|
||||||
|
extern const int DEFAULT_BACKGROUND_COLOR;
|
||||||
|
extern const int DEFAULT_HOUR_FONT;
|
||||||
|
extern const int DEFAULT_MINUTES_FONT;
|
||||||
|
extern const int DEFAULT_MAX_WEATHER_RETRY_COUNT;
|
||||||
|
extern const uint MAX_CHALK_SINGLE_LINE_CONDITIONS_LEN;
|
||||||
|
extern const int DEFAULT_CHALK_TIME_X_OFFSET;
|
||||||
|
extern const int DEFAULT_CHALK_WEATHER1_Y_OFFSET;
|
||||||
|
extern const int DEFAULT_CHALK_WEATHER2_Y_OFFSET;
|
||||||
|
extern const int DEFAULT_CHALK_WEATHER_CENTER_Y_OFFSET;
|
||||||
|
extern const int DEFAULT_CHALK_TIME_Y_OFFSET;
|
||||||
|
extern const int DEFAULT_CHALK_DIGITAL_TIME_Y_OFFSET;
|
||||||
|
extern const int DEFAULT_MARKERS_Y_OFFSET;
|
||||||
|
extern const int DEFAULT_MARKERS_X_OFFSET;
|
||||||
|
extern const int DEFAULT_CHALK_BATTERY_X_OFFSET;
|
||||||
66
src/c/digital_time.c
Normal file
66
src/c/digital_time.c
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
#include <pebble.h>
|
||||||
|
#include "digital_time.h"
|
||||||
|
#include "constants.h"
|
||||||
|
#include "basic.h"
|
||||||
|
|
||||||
|
#define SCREEN_SHOT_HR 10
|
||||||
|
#define SCREEN_SHOT_MIN 22
|
||||||
|
|
||||||
|
extern Options s_options;
|
||||||
|
|
||||||
|
//checks/updates date display line
|
||||||
|
void update_digital_time_layer() {
|
||||||
|
static char digital_time_buffer[16];
|
||||||
|
const char *current_digital_time_layer;
|
||||||
|
|
||||||
|
//if displaying digital time
|
||||||
|
if (s_options.display_digital_time) {
|
||||||
|
|
||||||
|
//get current date_layer text
|
||||||
|
current_digital_time_layer = text_layer_get_text(digital_time_layer);
|
||||||
|
|
||||||
|
//get digital time
|
||||||
|
time_t temp = time(NULL);
|
||||||
|
struct tm *tick_time = localtime(&temp);
|
||||||
|
#if DEBUG
|
||||||
|
tick_time->tm_hour = SCREEN_SHOT_HR; //for screen shots
|
||||||
|
tick_time->tm_min = SCREEN_SHOT_MIN;
|
||||||
|
#endif
|
||||||
|
if (clock_is_24h_style()) {
|
||||||
|
strftime(digital_time_buffer, sizeof(digital_time_buffer), "%H:%M", tick_time);
|
||||||
|
} else {
|
||||||
|
strftime(digital_time_buffer, sizeof(digital_time_buffer), "%l:%M %P", tick_time);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (current_digital_time_layer != digital_time_buffer) {
|
||||||
|
text_layer_set_text(digital_time_layer, digital_time_buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
text_layer_set_text(digital_time_layer, "");
|
||||||
|
}
|
||||||
|
#if DEBUG
|
||||||
|
APP_LOG(APP_LOG_LEVEL_DEBUG, "update_digital_time_layer: text_layer_set_text digital_time_layer: %s", digital_time_buffer);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
//adds/configures display digital time line
|
||||||
|
void add_digital_time_layer(Layer *window_layer, int16_t width, int16_t height) {
|
||||||
|
|
||||||
|
GFont digital_time_font;
|
||||||
|
int chalk_digital_time_y_offset = 0;
|
||||||
|
|
||||||
|
#if defined(PBL_ROUND)
|
||||||
|
chalk_digital_time_y_offset = DEFAULT_CHALK_DIGITAL_TIME_Y_OFFSET;
|
||||||
|
#else
|
||||||
|
chalk_digital_time_y_offset = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
digital_time_font = fonts_get_system_font(FONT_KEY_GOTHIC_14);
|
||||||
|
|
||||||
|
digital_time_layer = text_layer_create(GRect(0, 15 + chalk_digital_time_y_offset, width, 20));
|
||||||
|
text_layer_set_text_alignment(digital_time_layer, GTextAlignmentCenter);
|
||||||
|
text_layer_set_background_color(digital_time_layer, GColorWhite);
|
||||||
|
init_static_row(digital_time_layer, digital_time_font);
|
||||||
|
layer_add_child(window_layer, text_layer_get_layer(digital_time_layer));
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user