void handle_tick(struct tm *tick_time, TimeUnits units_changed) { static char date_text[] = "00 XXX"; static char time_text[] = "00:00"; clock_copy_time_string(time_text,sizeof time_text); APP_LOG(APP_LOG_LEVEL_DEBUG, "TICK @%s: (%d) %s%s%s%s", time_text, stale, (units_changed & DAY_UNIT) ? "D" : "-", (units_changed & HOUR_UNIT) ? "H" : "-", (units_changed & MINUTE_UNIT) ? "M" : "-", (units_changed & SECOND_UNIT) ? "S" : "-" ); if (units_changed & MINUTE_UNIT) { clock_copy_time_string(time_text,sizeof time_text); text_layer_set_text(time_layer,time_text); } if (units_changed & DAY_UNIT) { strftime(date_text, sizeof(date_text), "%a %e", tick_time); text_layer_set_text(date_layer,date_text); } if (units_changed & HOUR_UNIT) { if (bluetooth_ok) { request_weather(); } } }
void format_terminal_message(TerminalData *data, TerminalText *text) { struct tm *local = localtime(&(data->time)); char date_string[20]; char day_string[20]; char time_string[20]; format_date(date_string, 20, local); strftime(day_string, 20, "%A", local); clock_copy_time_string(time_string, 20); make_upper_case(date_string, 20); make_upper_case(day_string, 20); make_upper_case(time_string, 20); const char * format_string = "%s\n" //City "%s\n" //Temperature "%s\n" //Forecast "%s\n" //Date "%s\n" //Day of week "BATTERY %u\n" //Battery "%u STEPS\n" //Step count "%s"; //Time snprintf(text->text_buffer, TERMINAL_BUFFER_SIZE, format_string, data->city, data->temperature, data->forecast, date_string, day_string, data->battery_level, data->step_count, time_string); }
// Initialise UI static void init(void) { srand(time(NULL)); inverter_timer = app_timer_register(INVERTER_TIMEOUT, inverter_timer_callback, 0); time_timer = app_timer_register(TIME_TIMEOUT, update_time, 0); window = window_create(); window_set_fullscreen(window, true); window_stack_push(window, false); // Assign resources s_res_tv_image = gbitmap_create_with_resource(RESOURCE_ID_TV_IMAGE); s_res_static_1_image = gbitmap_create_with_resource(RESOURCE_ID_STATIC_2_IMAGE); s_res_bitham_42_bold = fonts_get_system_font(FONT_KEY_BITHAM_42_BOLD); s_res_gothic_14 = fonts_get_system_font(FONT_KEY_GOTHIC_14); // tv_bitmap tv_bitmap = bitmap_layer_create(GRect(0,0,144,168)); bitmap_layer_set_bitmap(tv_bitmap, s_res_tv_image); bitmap_layer_set_background_color(tv_bitmap, GColorClear); bitmap_layer_set_compositing_mode(tv_bitmap, GCompOpAssign); layer_add_child(window_get_root_layer(window), (Layer *) tv_bitmap); // static_1_bitmap static_1_bitmap = bitmap_layer_create(GRect(14, 42, 115, 87)); bitmap_layer_set_bitmap(static_1_bitmap, s_res_static_1_image); bitmap_layer_set_compositing_mode(static_1_bitmap, GCompOpOr); layer_add_child(window_get_root_layer(window), (Layer *)static_1_bitmap); // inverter_layer static_inverter_layer = inverter_layer_create(GRect(14, 42, 115, 0)); layer_add_child(window_get_root_layer(window), (Layer *)static_inverter_layer); layer_set_hidden(inverter_layer_get_layer(static_inverter_layer), false); // Screen On layer screen_on_layer = text_layer_create(GRect(14, 42, 115, 87)); text_layer_set_background_color(screen_on_layer, GColorWhite); layer_set_hidden(text_layer_get_layer(screen_on_layer), true); layer_add_child(window_get_root_layer(window), text_layer_get_layer(screen_on_layer)); // ch_layer ch_layer = text_layer_create(GRect(102, 46, 24, 14)); text_layer_set_background_color(ch_layer, GColorClear); text_layer_set_text(ch_layer, "Ch 3"); text_layer_set_font(ch_layer, s_res_gothic_14); layer_add_child(window_get_root_layer(window), text_layer_get_layer(ch_layer)); // time_layer clock_copy_time_string(buffer, 12); time_layer = text_layer_create(GRect(0, 56, 144, 42)); text_layer_set_background_color(time_layer, GColorClear); text_layer_set_text(time_layer, buffer); text_layer_set_text_alignment(time_layer, GTextAlignmentCenter); text_layer_set_font(time_layer, s_res_bitham_42_bold); layer_set_hidden(text_layer_get_layer(time_layer), true); layer_add_child(window_get_root_layer(window), (Layer *)time_layer); accel_tap_service_subscribe(tap_handler); // Subcribe to the tap event service }
static void handle_tick(struct tm *tick_time, TimeUnits units_changed) { if (units_changed & MINUTE_UNIT) { // Update the time - Deal with 12 / 24 format clock_copy_time_string(time_text, sizeof(time_text)); text_layer_set_text(time_layer, time_text); } if (units_changed & DAY_UNIT) { // Update the date - Without a leading 0 on the day of the month char day_text[4]; strftime(day_text, sizeof(day_text), "%a", tick_time); snprintf(date_text, sizeof(date_text), "%s %i", day_text, tick_time->tm_mday); text_layer_set_text(date_layer, date_text); } // Update the bottom half of the screen: icon and temperature static int animation_step = 0; if (weather_data->updated == 0 && weather_data->error == WEATHER_E_OK) { // 'Animate' loading icon until the first successful weather request if (animation_step == 0) { weather_layer_set_icon(weather_layer, WEATHER_ICON_LOADING1); } else if (animation_step == 1) { weather_layer_set_icon(weather_layer, WEATHER_ICON_LOADING2); } else if (animation_step >= 2) { weather_layer_set_icon(weather_layer, WEATHER_ICON_LOADING3); } animation_step = (animation_step + 1) % 3; } else { // Update the weather icon and temperature if (weather_data->error) { weather_layer_set_icon(weather_layer, WEATHER_ICON_PHONE_ERROR); } else { // Show the temperature as 'stale' if it has not been updated in 30 minutes bool stale = false; if (weather_data->updated > time(NULL) + 1800) { stale = true; } weather_layer_set_temperature(weather_layer, weather_data->temperature, stale); // Figure out if it's day or night. Not the best way to do this but the webservice // does not seem to return this info. bool night_time = false; if (tick_time->tm_hour >= 19 || tick_time->tm_hour < 7) night_time = true; weather_layer_set_icon(weather_layer, weather_icon_for_condition(weather_data->condition, night_time)); } } // Refresh the weather info every 15 minutes if (units_changed & MINUTE_UNIT && (tick_time->tm_min % 15) == 0) { request_weather(); } }
/* Update the text layer for the clock */ void qtp_update_time(bool mark_dirty) { static char time_text[10]; clock_copy_time_string(time_text, sizeof(time_text)); text_layer_set_text(qtp_time_layer, time_text); if (mark_dirty) { layer_mark_dirty(text_layer_get_layer(qtp_time_layer)); } }
static inline void setText() { time_t now = time(NULL); struct tm *theTime = localtime(&now); clock_copy_time_string(hourText, 6); #if defined(SHOWDATE) strftime(dateText, sizeof(dateText), "%a %e %b", theTime); #endif }
static void in_received_handler(DictionaryIterator *iter, void *context) { Tuple *message_tuple = dict_find(iter, WEATHER_MESSAGE_KEY); Tuple *icon_tuple = dict_find(iter, WEATHER_ICON_KEY); Tuple *temperature_tuple = dict_find(iter, WEATHER_TEMPERATURE_KEY); Tuple *city_tuple = dict_find(iter, WEATHER_CITY_KEY); Tuple *time_tuple = dict_find(iter, WEATHER_TIME_KEY); message_time = time(NULL); clock_copy_time_string(message_time_text,sizeof message_time_text); if (message_tuple) { strcpy(message,message_tuple->value->cstring); } else { return; } if (strcmp(message,"ready") == 0) { jsready = true; APP_LOG(APP_LOG_LEVEL_DEBUG, "RECEVIED ready message from PEBBLEJS"); request_weather(); } else if (strcmp(message,"weather") == 0) { stale = false; bitmap_layer_set_bitmap(notify_layer, icon_waiting); weather_icon = icon_tuple->value->uint8; weather_temperature = temperature_tuple->value->int8; strcpy(weather_city,city_tuple->value->cstring); weather_time = time_tuple->value->uint32; struct tm *tmpvar = localtime(&weather_time); if( clock_is_24h_style() ) { strftime(weather_time_text, sizeof(weather_time_text), "%H:%M", tmpvar); } else { strftime(weather_time_text, sizeof(weather_time_text), "%I:%M", tmpvar); } APP_LOG(APP_LOG_LEVEL_DEBUG, "%s ICON: %d, TEMPERATURE: %d, CITY: %s, TIME: %s", message_time_text, weather_icon, weather_temperature, weather_city, weather_time_text ); update_weather_display(); } else if (strcmp(message,"error") == 0) { stale = true; bitmap_layer_set_bitmap(notify_layer, icon_error); strcpy(weather_city, dict_find(iter, WEATHER_ERROR_KEY)->value->cstring); update_weather_display(); APP_LOG(APP_LOG_LEVEL_DEBUG, "WEATHER REQUEST FAILED!"); } }
/* * Perform the clock update */ static void update_clock() { static char time_text[6]; clock_copy_time_string(time_text, sizeof(time_text)); if (time_text[4] == ' ') time_text[4] = '\0'; text_layer_set_text(ui.text_time_layer, time_text); #ifdef PBL_COLOR text_layer_set_text(ui.text_time_shadow_layer, time_text); #endif analogue_minute_tick(); last_clock_update = time(NULL); }
static void update_watchface(Layer *me, GContext* ctx) { char current_time[10]; graphics_context_set_fill_color(ctx, GColorBlack ); graphics_fill_rect(ctx, GRect(0, 0, 144, 168), 0, GCornerNone); clock_copy_time_string(current_time, 10); graphics_context_set_text_color(ctx, GColorWhite); graphics_draw_text(ctx, current_time, fonts_get_system_font(FONT_KEY_BITHAM_42_BOLD), GRect( 2, 2, 140, 164), GTextOverflowModeWordWrap, GTextAlignmentLeft, NULL); }
static void prv_layer_update_proc(Layer *layer, GContext *ctx) { GoalStarStatusBarLayer *status_bar_layer = (GoalStarStatusBarLayer *)layer; if (!status_bar_layer) { return; } char clock_text[10] = {0}; clock_copy_time_string(clock_text, sizeof(clock_text)); GFont font = fonts_get_system_font(PBL_IF_RECT_ELSE(FONT_KEY_GOTHIC_18_BOLD, FONT_KEY_GOTHIC_24_BOLD)); graphics_context_set_text_color(ctx, GColorBlack); graphics_draw_text(ctx, clock_text, font, layer_get_bounds(layer), GTextOverflowModeTrailingEllipsis, GTextAlignmentCenter, NULL); }
static void tick_handler(struct tm *tick_time, TimeUnits units_changed) { clock_copy_time_string(time_buffer, sizeof(time_buffer)/sizeof(*time_buffer)); text_layer_set_text(s_text_time, time_buffer); layer_set_hidden((Layer *)s_bitmap_panda_eye, true); uint32_t timeout = 600; bool hidden = false; for (int i = 0; i < 5; i++) { AppTimerCallback callback = (hidden ? app_timer_callback_open_panda_eye : app_timer_callback_close_panda_eye); app_timer_register(timeout, callback, NULL); hidden = !hidden; timeout += 150; } }
void tick_handler(struct tm *tick_time, TimeUnits units_changed){ clock_copy_time_string(time_string,sizeof(time_string)); layer_mark_dirty(text_layer_get_layer(time_outline_layer)); layer_mark_dirty(text_layer_get_layer(time_text_layer)); }
static void tick_handler(struct tm *tick_time, TimeUnits units_changed){ static char buffer[16]; clock_copy_time_string(buffer, sizeof(buffer)); text_layer_set_text(s_time_layer,buffer); }
// Method handles changing the clock every minute static void handle_second_tick(struct tm *tick_time, TimeUnits units_changed) { if (units_changed & MINUTE_UNIT) { // Update the time every minute clock_copy_time_string(s_time_text, sizeof(s_time_text)); text_layer_set_text(s_time_layer,s_time_text); } }
static void layer_update_callback(Layer *me, GContext* ctx) { // preparations GRect bounds = layer_get_bounds(me); uint16_t width = bounds.size.w; uint16_t height = bounds.size.h; uint16_t stride = (bounds.size.w + 31) / 32 * 32; uint16_t max = (height - 1) * stride + width; uint16_t shake = stride - width; uint16_t shake_stride = shake * stride; // handle shake if (do_shake) { do_shake = false; light_enable_interaction(); for (uint16_t i = 0, j = rand(); i < NUM_FLAKES; i++, j+=31) { for (uint16_t k = 0; k < 2; k++, j+=31) { uint16_t next = flakes[i] + j % (max * 2) - max; if (next < max && next % stride < width && get_pixel(ctx, next) == GColorBlack) { flakes[i] = next; break; } } } last_time = 0; } // update time text time_t t = time(NULL); if (t / UPDATE_S > last_time) { last_time = t / UPDATE_S; char time_text[6]; clock_copy_time_string(time_text, sizeof(time_text)); graphics_context_set_fill_color(ctx, GColorBlack); graphics_fill_rect(ctx, bounds, 0, GCornerNone); GRect rect = (GRect) {{0, 60}, {width, 50}}; GFont font = fonts_get_system_font(FONT_KEY_BITHAM_42_BOLD); graphics_draw_text(ctx, time_text, font, rect, GTextOverflowModeTrailingEllipsis, GTextAlignmentCenter, NULL); graphics_context_set_stroke_color(ctx, GColorWhite); for (uint16_t i = 0, j = rand(); i < NUM_FLAKES; i++) { if (get_pixel(ctx, flakes[i]) == GColorBlack) { graphics_draw_pixel(ctx, GPoint(flakes[i] % stride, flakes[i] / stride)); } else { for (uint16_t k = 0; k < 8; k++, j++) { uint16_t next = flakes[i] + (j % 9 / 3 - 1) * shake_stride + (j % 3 - 1) * shake; if (next < max && next % stride < width && get_pixel(ctx, next) == GColorBlack) { flakes[i] = next; graphics_draw_pixel(ctx, GPoint(flakes[i] % stride, flakes[i] / stride)); break; } } } } } // apply physics AccelData accel = {.x = 0, .y = 0, .z = 0}; accel_service_peek(&accel); uint16_t absx = accel.x < 0 ? -accel.x : accel.x; uint16_t absy = accel.y < 0 ? -accel.y : accel.y; uint16_t span = (absx + absy + 10) * SPEED; for (uint16_t i = 0, j = rand(), k = rand(), l = rand(); i < span; i++, j++, k++, l++) { uint16_t index = j % NUM_FLAKES; uint16_t next = flakes[index]; int16_t sideway = k % 3 == 0 ? l % 5 - 2 : 0; int16_t accx = accel.x + accel.y * sideway; int16_t accy = accel.y - accel.x * sideway; absx = accx < 0 ? -accx : accx; absy = accy < 0 ? -accy : accy; if (absx > absy || k % absy < absx) { if (accx > 0) { next++; } else { next--; } } if (absy > absx || l % absx < absy) { if (accy > 0) { next -= stride; } else { next += stride; } } if (next < max && next % stride < width && get_pixel(ctx, next) == GColorBlack) { graphics_context_set_stroke_color(ctx, GColorBlack); graphics_draw_pixel(ctx, GPoint(flakes[index] % stride, flakes[index] / stride)); graphics_context_set_stroke_color(ctx, GColorWhite); graphics_draw_pixel(ctx, GPoint(next % stride, next / stride)); flakes[index] = next; } } if (!timer) timer = app_timer_register(UPDATE_MS, timer_callback, NULL); } static void handle_accel(AccelData *accel_data, uint32_t num_samples) { // or else I will crash } static void accel_tap_handler(AccelAxisType axis, int32_t direction) { do_shake = true; } static void root_update_callback(Layer *me, GContext* ctx) { // hack to prevent screen cleaning } static void window_load(Window *window) { Layer *window_layer = window_get_root_layer(window); layer_set_update_proc(window_layer, root_update_callback); GRect bounds = layer_get_bounds(window_layer); layer = layer_create(bounds); layer_set_update_proc(layer, layer_update_callback); layer_add_child(window_layer, layer); uint16_t width = bounds.size.w; uint16_t height = bounds.size.h; uint16_t stride = (bounds.size.w + 31) / 32 * 32; for (uint16_t i = 0; i < NUM_FLAKES; i++) { flakes[i] = rand() % height * stride + rand() % width; } }
static void timeHandler(void *data) { static BatteryChargeState charge; step++; switch (step) { case 1: APP_LOG(APP_LOG_LEVEL_DEBUG, "timeHandler: backlight=%d", backlight); if (backlight) { light_enable(true); } // Show hour clock_copy_time_string(info, 20); centerTextLayer(info); layer_set_hidden(text_layer_get_layer(textLayer), false); app_timer_register(INFO_DURATION, timeHandler, NULL); break; case 2: // Show Date centerTextLayer(date); app_timer_register(INFO_DURATION, timeHandler, NULL); break; case 3: // Show Phone connection status if (bluetooth_connection_service_peek()) { strcpy(info, "phone ok"); } else { strcpy(info, "phone failed"); } centerTextLayer(info); app_timer_register(INFO_DURATION, timeHandler, NULL); break; case 4: // Show battery percentage charge = battery_state_service_peek(); snprintf(info, 10, "batt %d%%", (int)charge.charge_percent); centerTextLayer(info); app_timer_register(INFO_DURATION, timeHandler, NULL); break; case 5: // Hide textLayer, reset it to Date if (backlight) { light_enable(false); } layer_set_hidden(text_layer_get_layer(textLayer), true); centerTextLayer(date); step = 0; break; case 101: // Display config saved message if (backlight) { light_enable(true); } strcpy(info, "config saved"); centerTextLayer(info); layer_set_hidden(text_layer_get_layer(textLayer), false); app_timer_register(INFO_LONG_DURATION, timeHandler, NULL); break; case 102: // Hide textLayer, reset it to Date if (backlight) { light_enable(false); } layer_set_hidden(text_layer_get_layer(textLayer), true); centerTextLayer(date); step = 0; break; } }
void update_clock() { clock_copy_time_string(current_time, sizeof(current_time)); text_layer_set_text(clock_layer, current_time); }
// Updates the clock time void update_clock() { clock_copy_time_string(current_time, sizeof(current_time)); layer_mark_dirty(clock_layer); }
// Updates the time text static void update_time(void *data) { clock_copy_time_string(buffer, 12); text_layer_set_text(time_layer, buffer); time_timer = app_timer_register(TIME_TIMEOUT, update_time, 0); }