static void analog_update_proc(Layer *layer, GContext *ctx) { time_t now = time(NULL); struct tm *t = localtime(&now); // Draw ticks behind draw_ticks(layer, ctx); // minute/hour hand graphics_context_set_compositing_mode(ctx, GCompOpSet); graphics_context_set_antialiased(ctx, true); gpath_rotate_to(minute_arrow, TRIG_MAX_ANGLE * t->tm_min / 60); gpath_rotate_to(minute_fill, TRIG_MAX_ANGLE * t->tm_min / 60); gpath_rotate_to(hour_arrow, (TRIG_MAX_ANGLE * (((t->tm_hour % 12) * 6) + (t->tm_min / 10)))/(12 * 6)); gpath_rotate_to(hour_fill, (TRIG_MAX_ANGLE * (((t->tm_hour % 12) * 6) + (t->tm_min / 10)))/(12 * 6)); // Draw minute hand background graphics_context_set_stroke_color(ctx, GColorBlack); graphics_context_set_stroke_width(ctx, 6); gpath_draw_outline(ctx, minute_arrow); // Draw minute hand foreground graphics_context_set_stroke_color(ctx, GColorWhite); graphics_context_set_fill_color(ctx, GColorWhite); graphics_context_set_stroke_width(ctx, 3); gpath_draw_outline(ctx, minute_arrow); gpath_draw_filled(ctx, minute_fill); // Draw hour hand background graphics_context_set_stroke_color(ctx, GColorBlack); graphics_context_set_stroke_width(ctx, 6); gpath_draw_outline(ctx, hour_arrow); // Draw hour hand foreground graphics_context_set_stroke_color(ctx, GColorWhite); graphics_context_set_fill_color(ctx, GColorWhite); graphics_context_set_stroke_width(ctx, 3); gpath_draw_outline(ctx, hour_arrow); gpath_draw_filled(ctx, hour_fill); // Draw a black peg in the center graphics_context_set_antialiased(ctx, false); graphics_context_set_fill_color(ctx, GColorBlack); graphics_context_set_stroke_color(ctx, GColorBlack); graphics_context_set_stroke_width(ctx, 1); gpath_draw_filled(ctx, peg_fill); }
static void draw_ticks(Layer *layer, GContext *ctx) { graphics_context_set_antialiased(ctx, true); graphics_context_set_fill_color(ctx, GColorWhite); graphics_context_set_stroke_color(ctx, GColorBlack); graphics_context_set_stroke_width(ctx, 5); gpath_draw_outline(ctx, tick_path_1); gpath_draw_filled(ctx, tick_path_1); gpath_draw_outline(ctx, tick_path_3); gpath_draw_filled(ctx, tick_path_3); gpath_draw_outline(ctx, tick_path_5); gpath_draw_filled(ctx, tick_path_5); gpath_draw_outline(ctx, tick_path_7); gpath_draw_filled(ctx, tick_path_7); gpath_draw_outline(ctx, tick_path_9); gpath_draw_filled(ctx, tick_path_9); gpath_draw_outline(ctx, tick_path_11); gpath_draw_filled(ctx, tick_path_11); draw_hour(2); draw_hour(4); draw_hour(6); draw_hour(8); draw_hour(10); draw_hour(12); }
static void icon_layer_update_proc(Layer *layer, GContext *ctx) { switch (current_mood) { case TERRIBLE: mood_icon = gdraw_command_image_create_with_resource(RESOURCE_ID_ICON_TERRIBLE); break; case BAD: mood_icon = gdraw_command_image_create_with_resource(RESOURCE_ID_ICON_BAD); break; case GREAT: mood_icon = gdraw_command_image_create_with_resource(RESOURCE_ID_ICON_GREAT); break; case AWESOME: mood_icon = gdraw_command_image_create_with_resource(RESOURCE_ID_ICON_AWESOME); break; default: case OK: mood_icon = gdraw_command_image_create_with_resource(RESOURCE_ID_ICON_OK); } if (!mood_icon) { return; } GDrawCommandImage *temp_copy = gdraw_command_image_clone(mood_icon); graphics_context_set_antialiased(ctx, true); gdraw_command_image_draw(ctx, temp_copy, GPoint(0, 0)); free(temp_copy); free(mood_icon); return; }
// Chalk Circle Battery Line void RoundBatteryLayer_update_callback(Layer *RoundBatteryLayer, GContext* Roundctx) { graphics_context_set_antialiased(Roundctx, true); graphics_context_set_fill_color(Roundctx, GColorBlack); graphics_fill_radial(Roundctx, GRect(0, 0, 180, 180), GOvalScaleModeFillCircle, 10 /*thickness*/, 0, TRIG_MAX_ANGLE); if (batterycharging == 1) { graphics_context_set_fill_color(Roundctx, GColorBlue); graphics_fill_radial(Roundctx, GRect(0, 0, 180, 180), GOvalScaleModeFillCircle, 8 /*thickness*/, 0, TRIG_MAX_ANGLE); } else if (batterychargepct > 20) { graphics_context_set_fill_color(Roundctx, GColorGreen); graphics_fill_radial(Roundctx, GRect(0, 0, 180, 180), GOvalScaleModeFillCircle, 8 /*thickness*/, 0, batterychargepct * 0.01 * TRIG_MAX_ANGLE); } else { graphics_context_set_fill_color(Roundctx, GColorRed); graphics_fill_radial(Roundctx, GRect(0, 0, 180, 180), GOvalScaleModeFillCircle, 8 /*thickness*/, 0, batterychargepct * 0.01 * TRIG_MAX_ANGLE); } //Battery % indicators graphics_context_set_fill_color(Roundctx, GColorWhite); graphics_fill_radial(Roundctx, GRect(0, 0, 180, 180), GOvalScaleModeFillCircle, 8, (TRIG_MAX_ANGLE / 11.0), (TRIG_MAX_ANGLE / 10) * 1); //10% graphics_fill_radial(Roundctx, GRect(0, 0, 180, 180), GOvalScaleModeFillCircle, 8, (TRIG_MAX_ANGLE / 5.25), (TRIG_MAX_ANGLE / 10) * 2); //20% graphics_fill_radial(Roundctx, GRect(0, 0, 180, 180), GOvalScaleModeFillCircle, 8, (TRIG_MAX_ANGLE / 3.43), (TRIG_MAX_ANGLE / 10) * 3); //30% graphics_fill_radial(Roundctx, GRect(0, 0, 180, 180), GOvalScaleModeFillCircle, 8, (TRIG_MAX_ANGLE / 2.55), (TRIG_MAX_ANGLE / 10) * 4); //40% graphics_fill_radial(Roundctx, GRect(0, 0, 180, 180), GOvalScaleModeFillCircle, 8, (TRIG_MAX_ANGLE / 2.03), (TRIG_MAX_ANGLE / 10) * 5); //50% graphics_fill_radial(Roundctx, GRect(0, 0, 180, 180), GOvalScaleModeFillCircle, 8, (TRIG_MAX_ANGLE / 1.69), (TRIG_MAX_ANGLE / 10) * 6); //60% graphics_fill_radial(Roundctx, GRect(0, 0, 180, 180), GOvalScaleModeFillCircle, 8, (TRIG_MAX_ANGLE / 1.445), (TRIG_MAX_ANGLE / 10) * 7); //70% graphics_fill_radial(Roundctx, GRect(0, 0, 180, 180), GOvalScaleModeFillCircle, 8, (TRIG_MAX_ANGLE / 1.265), (TRIG_MAX_ANGLE / 10) * 8); //80% graphics_fill_radial(Roundctx, GRect(0, 0, 180, 180), GOvalScaleModeFillCircle, 8, (TRIG_MAX_ANGLE / 1.12), (TRIG_MAX_ANGLE / 10) * 9); //90% graphics_fill_radial(Roundctx, GRect(0, 0, 180, 180), GOvalScaleModeFillCircle, 8, (TRIG_MAX_ANGLE / 1.01), TRIG_MAX_ANGLE); //100% }
void draw_hand_layer(Layer* l, GContext* ctx) { GColor foreground_color = gcolor_legible_over(s_background_color); GRect bounds = layer_get_frame(l); GPoint center = GPoint(bounds.size.w / 2, bounds.size.h / 2); graphics_context_set_antialiased(ctx, true); graphics_context_set_stroke_color(ctx, foreground_color); graphics_context_set_fill_color(ctx, foreground_color); graphics_context_set_stroke_width(ctx, 3); time_t ts = time(NULL); struct tm* now = localtime(&ts); GRect reduced_bounds = bounds; int arc_offset = PBL_IF_ROUND_ELSE(24, 18); reduced_bounds.origin.x += arc_offset; reduced_bounds.origin.y += arc_offset; reduced_bounds.size.w -= (arc_offset << 1); reduced_bounds.size.h -= (arc_offset << 1); // initially, angle is relative to top (wrong) int angle = TRIG_MAX_ANGLE * (now->tm_hour * 60 + now->tm_min) / 1440; // make 0 at the bottom angle = (angle + TRIG_MAX_ANGLE / 2) % TRIG_MAX_ANGLE; graphics_context_set_fill_color(ctx, s_complementary_color); int hand_length = MIN(reduced_bounds.size.h, reduced_bounds.size.w) / 2; int radial_inset = ((hand_length - 20) * inset_pct) / 100; if (angle < TRIG_MAX_ANGLE / 2) { // first draw the bottom half graphics_fill_radial(ctx, reduced_bounds, GOvalScaleModeFitCircle, radial_inset, TRIG_MAX_ANGLE / 2, TRIG_MAX_ANGLE); graphics_draw_arc(ctx, reduced_bounds, GOvalScaleModeFitCircle, TRIG_MAX_ANGLE / 2, TRIG_MAX_ANGLE); // then the rest graphics_fill_radial(ctx, reduced_bounds, GOvalScaleModeFitCircle, radial_inset, 0, angle); graphics_draw_arc(ctx, reduced_bounds, GOvalScaleModeFitCircle, 0, angle); } else { graphics_fill_radial(ctx, reduced_bounds, GOvalScaleModeFitCircle, radial_inset, TRIG_MAX_ANGLE / 2, angle); graphics_draw_arc(ctx, reduced_bounds, GOvalScaleModeFitCircle, TRIG_MAX_ANGLE / 2, angle); } graphics_context_set_stroke_width(ctx, 2); GPoint hand_end; hand_end.y = (-cos_lookup(angle) * hand_length / TRIG_MAX_RATIO) + center.y; hand_end.x = (sin_lookup(angle) * hand_length / TRIG_MAX_RATIO) + center.x; graphics_draw_line(ctx, center, hand_end); GPoint sm_end = GPoint(center.x, center.y + hand_length); GPoint sm_start = GPoint(center.x, sm_end.y - radial_inset); graphics_draw_line(ctx, sm_start, sm_end); }
static void update_main_proc(Layer *layer, GContext *ctx) { GRect bounds = layer_get_bounds(s_main_layer); graphics_context_set_fill_color(ctx, GColorBlack); graphics_fill_rect(ctx, bounds, 0, GCornerNone); if(s_is_running) { show_round_meter(ctx, &bounds); } graphics_context_set_antialiased(ctx, ANTIALIASING); Time mode_time; srand(time(NULL)); time_t t = time(NULL); struct tm *time_now = localtime(&t); mode_time.hours = time_now->tm_hour; mode_time.minutes = time_now->tm_min; // Adjust for minutes through the hour float minute_angle = TRIG_MAX_ANGLE * mode_time.minutes / 60; float hour_angle = TRIG_MAX_ANGLE * mode_time.hours / 12; hour_angle += (minute_angle / TRIG_MAX_ANGLE) * (TRIG_MAX_ANGLE / 12); // Plot hands GPoint minute_hand = (GPoint) { .x = (int16_t)(sin_lookup(TRIG_MAX_ANGLE * mode_time.minutes / 60 ) * (int32_t)(HAND_RADIUS - HAND_MARGIN) / TRIG_MAX_RATIO) + s_center.x, .y = (int16_t)(-cos_lookup(TRIG_MAX_ANGLE * mode_time.minutes / 60) * (int32_t)(HAND_RADIUS - HAND_MARGIN) / TRIG_MAX_RATIO) + s_center.y, }; GPoint hour_hand = (GPoint) { .x = (int16_t)(sin_lookup(hour_angle) * (int32_t)(HAND_RADIUS - (2 * HAND_MARGIN)) / TRIG_MAX_RATIO) + s_center.x, .y = (int16_t)(-cos_lookup(hour_angle) * (int32_t)(HAND_RADIUS - (2 * HAND_MARGIN)) / TRIG_MAX_RATIO) + s_center.y, }; graphics_context_set_stroke_color(ctx, GColorWhite); graphics_context_set_stroke_width(ctx, 4); // Draw hands with positive length only if(HAND_RADIUS > 2 * HAND_MARGIN) { graphics_draw_line(ctx, s_center, hour_hand); } if(HAND_RADIUS > HAND_MARGIN) { graphics_draw_line(ctx, s_center, minute_hand); } // center dot graphics_context_set_fill_color(ctx, GColorWhite); graphics_fill_circle(ctx, s_center, 7); } static void main_select_click_handler(ClickRecognizerRef recognizer, void *context) { window_stack_push(s_menu_window, false); } static void main_click_config_provider(void *context) { window_single_click_subscribe(BUTTON_ID_SELECT, main_select_click_handler); }
static void update_hands(Layer *layer, GContext *context) { // Get a tm structure time_t temp = time(NULL); struct tm *tick_time = localtime(&temp); GRect bounds = layer_get_bounds(layer); GPoint layer_center_point = GPoint(bounds.size.w / 2, bounds.size.h / 2); graphics_context_set_antialiased(context, true); graphics_context_set_compositing_mode(context, GCompOpSet); int his_angle = (tick_time->tm_min - hand_his_correction) / 60.0f * TRIG_MAX_ANGLE; graphics_draw_rotated_bitmap(context, hand_his, hand_his_rotation_center, his_angle, layer_center_point); float hours = tick_time->tm_hour + tick_time->tm_min / 60.0f; int her_angle = (hours - hand_her_correction) / 12.0f * TRIG_MAX_ANGLE; graphics_draw_rotated_bitmap(context, hand_her, hand_her_rotation_center, her_angle, layer_center_point); GRect batch_rect = GRect(layer_center_point.x - 14, layer_center_point.y - 15, 30, 30); graphics_draw_bitmap_in_rect(context, batch, batch_rect); }
// Updates the graphic drawing on the screen static void update_proc(Layer *layer, GContext *ctx) { graphics_context_set_antialiased(ctx, S_TRUE); // Circle layer points int16_t x; int16_t y; char *buf = getTimeBuffer(); char buf1[2]; // circle for (int16_t i = 0; i < 4; i++){ if (i<2) { y = 48; } else { y = 120; } x = 36 + i%2*72; GPoint s_center = {x,y}; int j; if( i<=1 ) { j = i; } else { j = i +1; } buf1[0]=buf[j]; buf1[1]='\0'; int idx = atoi( buf1 ); // Fill circle with color graphics_context_set_fill_color(ctx, (GColor8)allColors[settings.colorIdx[idx]]); graphics_fill_circle(ctx, s_center, s_radius); } //Remember to FREE memory free( buf ); }
static void update_proc(Layer *layer, GContext *ctx) { // Don't use current time while animating Time mode_time = (s_animating) ? s_anim_time : s_last_time; s_radius = s_animating ? s_radius : FINAL_RADIUS; // Get a tm structure time_t temp = time(NULL); struct tm *tick_time = localtime(&temp); graphics_context_set_antialiased(ctx, ANTIALIASING); // hour text if (!s_animating) { // Create a long-lived buffer static char buffer[] = "00"; // Write the current hours and minutes into the buffer if(clock_is_24h_style() == true) { // Use 24 hour format strftime(buffer, sizeof("00"), "%H", tick_time); } else { // Use 12 hour format strftime(buffer, sizeof("00"), "%I", tick_time); } if (!clock_is_24h_style() && mode_time.hours > 0 && mode_time.hours < 10) { // remove the leading "0" snprintf(buffer, 2, "%d", mode_time.hours); } else if (!clock_is_24h_style() && mode_time.hours == 0) { // stupid time, of course we want "12" snprintf(buffer, 4, "%s", "12"); } // Display this time on the TextLayer text_layer_set_text_color(s_hour_digit, (GColor)all_colours[user_hour_text_colour]); text_layer_set_text(s_hour_digit, buffer); } // Color background for first colour main_colour = all_colours[user_time_colour[s_colour_a]]; //all_colours[s_colour_a]; graphics_context_set_fill_color(ctx, (GColor)main_colour); graphics_fill_rect(ctx, GRect(0, 0, 144, 168), 0, GCornerNone); // Plot minute line GPoint minute_hand = (GPoint) { .x = (int16_t)(sin_lookup(TRIG_MAX_ANGLE * mode_time.minutes / 60) * (int32_t)MINUTE_RADIUS / TRIG_MAX_RATIO) + s_center.x, .y = (int16_t)(-cos_lookup(TRIG_MAX_ANGLE * mode_time.minutes / 60) * (int32_t)MINUTE_RADIUS / TRIG_MAX_RATIO) + s_center.y, }; // Fill in minute color (aka s_colour_b) -- basic is a triangle in the first eighth of the clock (< 7 minutes) GPathInfo s_min_points = { .num_points = 3, .points = (GPoint []) { screen_top_centre, screen_centre, {minute_hand.x, minute_hand.y} } }; if (mode_time.minutes > 7 && mode_time.minutes < 23) { // add in the top-right corner s_min_points.num_points = 4; s_min_points.points = (GPoint []) { screen_top_centre, screen_centre, {minute_hand.x, minute_hand.y}, screen_top_right }; } else if (mode_time.minutes > 22 && mode_time.minutes < 38) { // add in bottom-right and top-right s_min_points.num_points = 5, s_min_points.points = (GPoint []) { screen_top_centre, screen_centre, {minute_hand.x, minute_hand.y}, screen_bottom_right, screen_top_right }; }
static void canvas_update_proc(Layer *this_layer, GContext *ctx) { GRect bounds = layer_get_bounds(this_layer); uint16_t ms_start = time_ms(NULL, NULL); graphics_context_set_antialiased(ctx, true); if (!isBtConnected) { graphics_context_set_fill_color(ctx, GColorDukeBlue); graphics_fill_rect(ctx, bounds, 0, GCornerNone); } else { graphics_context_set_fill_color(ctx, GColorBlack); graphics_fill_rect(ctx, bounds, 0, GCornerNone); } graphics_context_set_fill_color(ctx, GColorBlack); uint16_t ms_fill = time_ms(NULL, NULL); graphics_context_set_stroke_color(ctx, COLOR_FALLBACK(GColorRed, GColorWhite)); #if defined(PBL_PLATFORM_APLITE) || defined(PBL_PLATFORM_DIORITE) graphics_context_set_stroke_width(ctx, 1); #else graphics_context_set_stroke_width(ctx, 3); #endif graphics_draw_line(ctx, GPoint(bounds.size.w/2, 0), GPoint(bounds.size.w/2, bounds.size.h)); graphics_context_set_stroke_color(ctx, GColorWhite); int hour_loc = bounds.size.h/2; if(ctick_time->tm_min < 20) draw_hour(this_layer, ctx, -1, tz2, hour_loc, FONT_KEY_ROBOTO_BOLD_SUBSET_49, 49); draw_hour(this_layer, ctx, 0, tz2, hour_loc, FONT_KEY_ROBOTO_BOLD_SUBSET_49, 49); draw_hour(this_layer, ctx, 1, tz2, hour_loc, FONT_KEY_ROBOTO_BOLD_SUBSET_49, 49); if(ctick_time->tm_min > 50) draw_hour(this_layer, ctx, 2, tz2, hour_loc, FONT_KEY_ROBOTO_BOLD_SUBSET_49, 49); graphics_context_set_stroke_width(ctx, 1); uint16_t ms_hour = time_ms(NULL, NULL); draw_minutes(this_layer, ctx, bounds.size.h/2+49/2+5); uint16_t ms_day = time_ms(NULL, NULL); int day_loc = bounds.size.h/2-49/2-12; draw_day(this_layer, ctx, -1, day_loc); draw_day(this_layer, ctx, 0, day_loc); draw_day(this_layer, ctx, 1, day_loc); draw_day(this_layer, ctx, 2, day_loc); draw_day_ticks(this_layer, ctx, bounds.size.h/2-49/2-12); if (temp != INVALID_TEMP) { draw_temp(this_layer, ctx, bounds.size.h/2+75); } getWeather(); getForecast(); uint16_t ms_end = time_ms(NULL, NULL); draw_bat(this_layer, ctx, 0); #if defined(PBL_HEALTH) // Check step data is available HealthServiceAccessibilityMask mask = health_service_metric_accessible(HealthMetricStepCount, time_start_of_today(), cur_time); if(mask & HealthServiceAccessibilityMaskAvailable) { // Data is available! int total_steps = (int)health_service_sum_today(HealthMetricStepCount); draw_step(this_layer, ctx, 22, total_steps); } time_t end_time = time(NULL); time_t start_time = end_time - 600; HealthServiceAccessibilityMask hr = health_service_metric_accessible(HealthMetricHeartRateBPM, start_time, end_time); if (hr & HealthServiceAccessibilityMaskAvailable) { uint32_t bpm = health_service_peek_current_value(HealthMetricHeartRateBPM); APP_LOG(APP_LOG_LEVEL_INFO, "HR: %d", (int)bpm); draw_bpm(this_layer, ctx, 9, bpm); } #endif static int repaints = 0; ++repaints; ms_fill = ms_fill < ms_start ? ms_fill + 1000 : ms_fill; ms_hour = ms_hour < ms_start ? ms_hour + 1000 : ms_hour; ms_day = ms_day < ms_start ? ms_day + 1000 : ms_day; ms_end = ms_end < ms_start ? ms_end + 1000 : ms_end; static uint16_t tt_max = 0; if ((ms_end-ms_start) > tt_max) tt_max = ms_end-ms_start; }
static void updateScreen(Layer *layer, GContext *ctx) { custom_draw_arc(ctx, center, radius, lower_thickness, start_angle, end_angle, GColorDarkGray); custom_draw_arc_from_config(ctx, center, radius+2, lower_thickness*4+1, counter_config, GColorPurple); graphics_context_set_antialiased(ctx, true); }
/*Update Drawing Handler*/ static void hands_update_proc(Layer *layer, GContext *ctx) { graphics_context_set_antialiased(ctx, true); int16_t scale = _12HScaleFactor*60; if ( clock_is_24h_style() ) { scale = _24HScaleFactor*60; } GRect bounds = layer_get_bounds(layer); GPoint center = grect_center_point(&bounds); GPoint secondHand; GPoint hourHand1, hourHand2; time_t now = time(NULL); struct tm* t = localtime(&now); int16_t ms = time_ms(NULL, NULL); const int16_t second_hand_length = PBL_IF_ROUND_ELSE((bounds.size.w / 2) - 19, (bounds.size.w / 2) - 2); const int16_t hour_tick_length = PBL_IF_ROUND_ELSE((bounds.size.w / 2) - 28, bounds.size.w / 2); //const int16_t hour_hand_length = PBL_IF_ROUND_ELSE((bounds.size.w / 2) - 60, bounds.size.w / 2); calculate_pointer_end((t->tm_sec*100)+ms/10, second_hand_length, ¢er, &secondHand, 60*100, 0); // minute/hour hand graphics_context_set_fill_color(ctx, GColorWhite); graphics_context_set_stroke_color(ctx, GColorBlack); gpath_rotate_to(s_minute_arrow, TRIG_MAX_ANGLE * t->tm_min / 60); gpath_draw_filled(ctx, s_minute_arrow); gpath_draw_outline(ctx, s_minute_arrow); //graphics_draw_line(ctx, minuteHand, center); graphics_context_set_stroke_color(ctx, GColorWhite); //gpath_rotate_to(s_hour_arrow, (TRIG_MAX_ANGLE * (((t->tm_hour % 12) * 6) + (t->tm_min / 10))) / (12 * 6)); gpath_rotate_to(s_hour_arrow, (TRIG_MAX_ANGLE * (t->tm_hour*60+t->tm_min ))/ scale); gpath_draw_filled(ctx, s_hour_arrow); gpath_draw_outline(ctx, s_hour_arrow); // draw hour lines int hours = clock_is_24h_style() ? _24HScaleFactor : _12HScaleFactor; for (int h = 0; h < hours; h++) { calculate_pointer_end(h, hour_tick_length, ¢er, &hourHand1, hours, 0); if (h % 3 == 0) { calculate_pointer_end(h, hour_tick_length-11, ¢er, &hourHand2, hours, 0); } else { calculate_pointer_end(h, hour_tick_length-7, ¢er, &hourHand2, hours, 0); } graphics_context_set_fill_color(ctx, GColorWhite); graphics_context_set_stroke_color(ctx, GColorWhite); graphics_draw_line(ctx, hourHand1, hourHand2); } // draw second ticks for (int i = 0; i < t->tm_sec; i++) { calculate_pointer_end(i, second_hand_length, ¢er, &secondHand, 60, 0); graphics_context_set_fill_color(ctx, GColorWhite); graphics_fill_rect(ctx, GRect(secondHand.x, secondHand.y, 3, 3), 0, GCornerNone); } // dot in the middle graphics_context_set_fill_color(ctx, GColorBlack); graphics_fill_rect(ctx, GRect(bounds.size.w / 2 - 1, bounds.size.h / 2 - 1, 3, 3), 0, GCornerNone); }
static void hands_update_proc(Layer *layer, GContext *ctx) { time_t now = time(NULL); struct tm *t = localtime(&now); graphics_context_set_stroke_color(ctx, hand_color); #ifdef PBL_COLOR graphics_context_set_antialiased(ctx, false); #endif GRect bounds = layer_get_bounds(layer); GPoint center = grect_center_point(&bounds); //minute hand int16_t hand_length = bounds.size.w / 2 ; int32_t angle = TRIG_MAX_ANGLE * t->tm_min / 60; GPoint hand = { .x = (int16_t)(sin_lookup(angle) * (int32_t)hand_length / TRIG_MAX_RATIO) + center.x, .y = (int16_t)(-cos_lookup(angle) * (int32_t)hand_length / TRIG_MAX_RATIO) + center.y, }; #ifdef PBL_COLOR graphics_context_set_stroke_width(ctx, 3); #endif graphics_draw_line(ctx, hand, center); //hour hand hand_length = hand_length - 25; angle = (TRIG_MAX_ANGLE * (((t->tm_hour % 12) * 6) + (t->tm_min / 10))) / (12 * 6); hand = (GPoint){ .x = (int16_t)(sin_lookup(angle) * (int32_t)hand_length / TRIG_MAX_RATIO) + center.x, .y = (int16_t)(-cos_lookup(angle) * (int32_t)hand_length / TRIG_MAX_RATIO) + center.y, }; #ifdef PBL_COLOR graphics_context_set_stroke_width(ctx, 5); #endif graphics_draw_line(ctx, hand, center); #ifndef PBL_RECT graphics_context_set_fill_color(ctx, hand_color); graphics_fill_circle(ctx, center, 7); #endif } static void handle_second_tick(struct tm *tick_time, TimeUnits units_changed) { #ifndef PBL_COLOR memset(aplite_visited, 0, 168*20); #endif //adjusting shadow direction according to minute hand location if (tick_time->tm_min >= 0 && tick_time->tm_min < 15) { s_effect_offset.offset_x = SHADOW_LENGTH; s_effect_offset.offset_y = SHADOW_LENGTH; } else if (tick_time->tm_min >= 15 && tick_time->tm_min < 30) { s_effect_offset.offset_x = -SHADOW_LENGTH; s_effect_offset.offset_y = SHADOW_LENGTH; } else if (tick_time->tm_min >= 30 && tick_time->tm_min < 45) { s_effect_offset.offset_x = -SHADOW_LENGTH; s_effect_offset.offset_y = -SHADOW_LENGTH; } else { s_effect_offset.offset_x = SHADOW_LENGTH; s_effect_offset.offset_y = -SHADOW_LENGTH; } layer_mark_dirty(window_get_root_layer(window)); } static void window_load(Window *window) { Layer *window_layer = window_get_root_layer(window); GRect bounds = layer_get_bounds(window_layer); s_hands_layer = layer_create(bounds); layer_set_update_proc(s_hands_layer, hands_update_proc); layer_add_child(window_layer, s_hands_layer); //creating shadow layer s_effect_offset = (EffectOffset){ .orig_color = hand_color, .offset_color = shadow_color, .option = 1 // creating array for "visited" pixels and assigning it to shadow effect parameter #ifndef PBL_COLOR , .aplite_visited = aplite_visited #endif }; s_effect_layer = effect_layer_create(bounds); effect_layer_add_effect(s_effect_layer, effect_shadow, &s_effect_offset); effect_layer_add_effect(s_effect_layer, effect_blur, (void*)1); layer_add_child(window_layer, effect_layer_get_layer(s_effect_layer)); } static void window_unload(Window *window) { layer_destroy(s_hands_layer); }
static void update_proc(Layer *layer, GContext *ctx) { int padding; PBL_IF_ROUND_ELSE(padding = 16, padding = 12); HOURS_TRACK_RADIUS = (window_bounds.size.w - padding) / 2; //66 HOURS_TRACK_STROKE = 2; MINUTES_TRACK_RADIUS = HOURS_TRACK_RADIUS - 10; //56 MINUTES_TRACK_STROKE = 2; SECONDS_TRACK_RADIUS = HOURS_TRACK_RADIUS - 20; //46 SECONDS_TRACK_STROKE = 2; SECONDS_HAND_RADIUS = 2; MINUTES_HAND_RADIUS = 3; HOURS_HAND_RADIUS = 4; // Color background graphics_context_set_fill_color(ctx, GColorBlack); graphics_fill_rect(ctx, window_bounds, 0, GCornerNone); //APP_LOG(APP_LOG_LEVEL_DEBUG, "bounds: %d %d %d %d", window_bounds.origin.x, window_bounds.origin.y, window_bounds.size.h, window_bounds.size.w ); //set colour for tracks graphics_context_set_stroke_color(ctx, GColorWhite ); graphics_context_set_antialiased(ctx, ANTIALIASING); // Don't use current time while animating Time mode_time = s_last_time; // generate position of hands GPoint second_hand = (GPoint) { .x = (int16_t)(sin_lookup(TRIG_MAX_ANGLE * mode_time.seconds / 60) * (int32_t)(SECONDS_TRACK_RADIUS) / TRIG_MAX_RATIO) + s_center.x, .y = (int16_t)(-cos_lookup(TRIG_MAX_ANGLE * mode_time.seconds / 60) * (int32_t)(SECONDS_TRACK_RADIUS) / TRIG_MAX_RATIO) + s_center.y, }; float minutes, hours; if (SWEEP_MINUTES == true) { minutes = mode_time.minutes + (float)mode_time.seconds / 60; } else { minutes = mode_time.minutes; } GPoint minute_hand = (GPoint) { .x = (int16_t)(sin_lookup(TRIG_MAX_ANGLE * minutes / 60) * (int32_t)(MINUTES_TRACK_RADIUS) / TRIG_MAX_RATIO) + s_center.x, .y = (int16_t)(-cos_lookup(TRIG_MAX_ANGLE * minutes/ 60) * (int32_t)(MINUTES_TRACK_RADIUS) / TRIG_MAX_RATIO) + s_center.y, }; if( SWEEP_HOURS == true) { hours = mode_time.hours + (float)mode_time.minutes / 60; } else { hours = mode_time.hours; } GPoint hour_hand = (GPoint) { .x = (int16_t)(sin_lookup(TRIG_MAX_ANGLE * hours / 12) * (int32_t)(HOURS_TRACK_RADIUS) / TRIG_MAX_RATIO) + s_center.x, .y = (int16_t)(-cos_lookup(TRIG_MAX_ANGLE * hours / 12) * (int32_t)(HOURS_TRACK_RADIUS) / TRIG_MAX_RATIO) + s_center.y, }; graphics_context_set_fill_color(ctx, GColorWhite); GRect seconds_rect = GRect(s_center.x - SECONDS_TRACK_RADIUS, s_center.y - SECONDS_TRACK_RADIUS, SECONDS_TRACK_RADIUS * 2, SECONDS_TRACK_RADIUS * 2); GRect minutes_rect = GRect(s_center.x - MINUTES_TRACK_RADIUS, s_center.y - MINUTES_TRACK_RADIUS, MINUTES_TRACK_RADIUS * 2, MINUTES_TRACK_RADIUS * 2); GRect hours_rect = GRect(s_center.x - HOURS_TRACK_RADIUS, s_center.y - HOURS_TRACK_RADIUS, HOURS_TRACK_RADIUS * 2, HOURS_TRACK_RADIUS * 2); //---------------------------------- int seconds_start_angle, seconds_end_angle; int seconds_delta = 12; int minutes_delta = 12; int hours_delta = 12; get_angles_60(mode_time.seconds, 0, seconds_delta, &seconds_start_angle, &seconds_end_angle); //---------------------------------- //int minutes_angle = mode_time.minutes * 360 / 60; int minutes_start_angle, minutes_end_angle; get_angles_60(mode_time.minutes, (SWEEP_MINUTES == true) ? mode_time.seconds : 0, minutes_delta, &minutes_start_angle, &minutes_end_angle); //get_angles_60(mode_time.minutes, mode_time.seconds, minutes_delta, &minutes_start_angle, &minutes_end_angle); //---------------------------------- //int hours_angle = mode_time.hours * 360 / 12; int hours_start_angle, hours_end_angle; get_angles_12(mode_time.hours,(SWEEP_HOURS == true) ? mode_time.minutes : 0, hours_delta, &hours_start_angle, &hours_end_angle); //APP_LOG(APP_LOG_LEVEL_DEBUG, "seconds: %d, start: %d, end: %d", mode_time.seconds, seconds_start_angle, seconds_end_angle); //set colour for arcs and "hands" graphics_context_set_fill_color(ctx, GColorWhite ); //draw seconds arc graphics_fill_radial(ctx, seconds_rect, GOvalScaleModeFitCircle, SECONDS_TRACK_STROKE, DEG_TO_TRIGANGLE(seconds_start_angle), DEG_TO_TRIGANGLE(seconds_end_angle)); //draw minutes arc graphics_fill_radial(ctx, minutes_rect, GOvalScaleModeFitCircle, MINUTES_TRACK_STROKE, DEG_TO_TRIGANGLE(minutes_start_angle), DEG_TO_TRIGANGLE(minutes_end_angle)); //draw hours arc graphics_fill_radial(ctx, hours_rect, GOvalScaleModeFitCircle, HOURS_TRACK_STROKE, DEG_TO_TRIGANGLE(hours_start_angle), DEG_TO_TRIGANGLE(hours_end_angle)); //draw minute hand graphics_fill_circle(ctx, minute_hand, MINUTES_HAND_RADIUS); //draw hour hand graphics_fill_circle(ctx, hour_hand, HOURS_HAND_RADIUS); //draw second hand graphics_context_set_fill_color(ctx, GColorRed ); graphics_fill_circle(ctx, second_hand, SECONDS_HAND_RADIUS); update_time(); } static void window_load(Window *window) { Layer *window_layer = window_get_root_layer(window); window_bounds = layer_get_bounds(window_layer); //APP_LOG(APP_LOG_LEVEL_DEBUG, "bounds: %d %d %d %d", window_bounds.origin.x, window_bounds.origin.y, window_bounds.size.h, window_bounds.size.w ); s_center = grect_center_point(&window_bounds); s_canvas_layer = layer_create(window_bounds); layer_set_update_proc(s_canvas_layer, update_proc); layer_add_child(window_layer, s_canvas_layer); // Create time TextLayer int font_height; PBL_IF_ROUND_ELSE(font_height = 45, font_height = 36); //fudge factor to get text vertically centred s_time_layer = text_layer_create(GRect(window_bounds.origin.x, (window_bounds.size.h-font_height)/2, window_bounds.size.w, font_height)); //s_center.y - MINUTES_TRACK_RADIUS + 18 + 18; s_day_layer = text_layer_create(GRect(0, s_center.y - 18 - 18 , window_bounds.size.w, 18)); //need to calculate proper y-location s_month_layer = text_layer_create(GRect(0, s_center.y +36 , window_bounds.size.w, 18)); //need to calculate proper y-location text_layer_set_background_color(s_day_layer, GColorRed); text_layer_set_text_color(s_day_layer, GColorLightGray ); text_layer_set_text(s_day_layer, "00"); text_layer_set_background_color(s_time_layer, GColorClear); text_layer_set_text_color(s_time_layer, GColorWhite); text_layer_set_text(s_time_layer, "00:00"); text_layer_set_background_color(s_month_layer, GColorClear); text_layer_set_text_color(s_month_layer, GColorLightGray ); text_layer_set_text(s_month_layer, "XXX"); PBL_IF_ROUND_ELSE(s_custom_font = fonts_load_custom_font(resource_get_handle(RESOURCE_ID_FONT_DOSIS_SEMIBOLD_40)), s_custom_font = fonts_load_custom_font(resource_get_handle(RESOURCE_ID_FONT_DOSIS_SEMIBOLD_30))); text_layer_set_font(s_time_layer, s_custom_font); text_layer_set_text_alignment(s_time_layer, GTextAlignmentCenter); text_layer_set_font(s_day_layer, fonts_load_custom_font(resource_get_handle(RESOURCE_ID_FONT_DOSIS_SEMIBOLD_18))); text_layer_set_text_alignment(s_day_layer, GTextAlignmentCenter); text_layer_set_font(s_month_layer, fonts_load_custom_font(resource_get_handle(RESOURCE_ID_FONT_DOSIS_SEMIBOLD_18))); text_layer_set_text_alignment(s_month_layer, GTextAlignmentCenter); // 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_time_layer)); layer_add_child(window_get_root_layer(window), text_layer_get_layer(s_day_layer)); layer_add_child(window_get_root_layer(window), text_layer_get_layer(s_month_layer)); // Make sure the time is displayed from the start update_time(); } static void window_unload(Window *window) { layer_destroy(s_canvas_layer); // Destroy TextLayer text_layer_destroy(s_time_layer); text_layer_destroy(s_day_layer); text_layer_destroy(s_month_layer); fonts_unload_custom_font(s_custom_font); } /*********************************** App **************************************/ static void init() { srand(time(NULL)); time_t t = time(NULL); struct tm *time_now = localtime(&t); tick_handler(time_now, SECOND_UNIT); s_main_window = window_create(); window_set_window_handlers(s_main_window, (WindowHandlers) { .load = window_load, .unload = window_unload, });
static void boardUpdateProc(Layer* this_layer, GContext *ctx) { GRect b = layer_get_bounds(this_layer); graphics_context_set_antialiased(ctx, 0); // Fill grey back (white on BW) graphics_context_set_fill_color(ctx, COLOR_FALLBACK(GColorLightGray, GColorWhite)); graphics_context_set_stroke_color(ctx, GColorBlack); graphics_fill_rect(ctx, b, 0, GCornersAll); // Frame highlight around currently selected square colours is gray w white highlight, BW is wite w black highight graphics_context_set_fill_color(ctx, COLOR_FALLBACK(GColorDarkGray, GColorWhite)); graphics_context_set_stroke_color(ctx, COLOR_FALLBACK(GColorWhite, GColorBlack)); GRect highlightR = GRect(s_cursor.x*PIECE_PIXELS, s_cursor.y*PIECE_PIXELS, PIECE_PIXELS+1, PIECE_PIXELS+1); graphics_fill_rect(ctx, highlightR, 0, GCornersAll); graphics_draw_rect(ctx, highlightR); // Draw all board shapes for (int x = 0; x < BOARD_PIECES_X; ++x) { for (int y = 0; y < BOARD_PIECES_Y; ++y) { int xy = XY(x,y); if (s_gameState == kFlashRemoved && (s_pieces[xy].match != kUnmatched || s_pieces[XY(x,y)].exploded == true)) { // Highlight squares which have just been matched GColor highlight = COLOR_FALLBACK(GColorRed, GColorBlack); if (s_pieces[xy].match == kMatchedTwice) highlight = COLOR_FALLBACK(GColorDarkCandyAppleRed, GColorBlack); graphics_context_set_fill_color(ctx, highlight); graphics_context_set_stroke_color(ctx, COLOR_FALLBACK(GColorBlack, GColorLightGray)); highlightR = GRect((s_pieces[xy].loc.x/SUB_PIXEL), (s_pieces[xy].loc.y/SUB_PIXEL), PIECE_PIXELS+1, PIECE_PIXELS+1); graphics_fill_rect(ctx, highlightR, 0, GCornersAll); graphics_draw_rect(ctx, highlightR); } // Draw the shape itself graphics_context_set_fill_color(ctx, COLOURS[ s_pieces[xy].colour ]); if (getShape( s_pieces[xy].colour ) != NULL) { static const bool bw = PBL_IF_BW_ELSE(true,false); if (bw == false && s_pieces[xy].colour == kBlack ) { graphics_context_set_stroke_color(ctx, GColorWhite); } else if (bw == true && (s_pieces[xy].match != kUnmatched || s_pieces[XY(x,y)].exploded == true) && COLOURS[ s_pieces[xy].colour ].argb != GColorWhite.argb ) { graphics_context_set_stroke_color(ctx, GColorWhite); } else { graphics_context_set_stroke_color(ctx, GColorBlack); } gpath_move_to(getShape( s_pieces[xy].colour ), GPoint(s_pieces[xy].loc.x/SUB_PIXEL, s_pieces[xy].loc.y/SUB_PIXEL)); gpath_draw_filled(ctx, getShape( s_pieces[xy].colour )); gpath_draw_outline(ctx, getShape( s_pieces[xy].colour )); } else { // White rectangle of debug - we should not have the case where we render a NULL square graphics_fill_rect(ctx, GRect((s_pieces[xy].loc.x/SUB_PIXEL)+2, (s_pieces[xy].loc.y/SUB_PIXEL)+2, PIECE_PIXELS-3, PIECE_PIXELS-3), 2, GCornersAll); } } } // Move Arrows if (s_flashArrows == true && s_gameState == kAwaitingDirection) { graphics_context_set_fill_color(ctx, GColorWhite); for (int d = 0; d < N_CARDINAL; ++d) { gpath_move_to(getArrow(d), GPoint(s_cursor.x * PIECE_PIXELS, s_cursor.y * PIECE_PIXELS)); gpath_draw_filled(ctx, getArrow(d)); gpath_draw_outline(ctx, getArrow(d)); } } // Cursor if (s_tiltMode > 0) { graphics_context_set_fill_color(ctx, GColorWhite); graphics_context_set_stroke_color(ctx, GColorBlack); graphics_fill_circle(ctx, GPoint(s_motionCursor.x/SUB_PIXEL,s_motionCursor.y/SUB_PIXEL), 3); graphics_draw_circle(ctx, GPoint(s_motionCursor.x/SUB_PIXEL,s_motionCursor.y/SUB_PIXEL), 3); } // Next move if (s_hintOn && s_availableMove.x != -1 && s_gameState == kIdle && s_hintStatus == true) { graphics_context_set_stroke_color(ctx, COLOR_FALLBACK(GColorDarkCandyAppleRed,GColorBlack) ); graphics_context_set_stroke_width(ctx, 3); graphics_draw_circle(ctx, GPoint(s_availableMove.x*PIECE_PIXELS + PIECE_PIXELS/2, s_availableMove.y*PIECE_PIXELS + PIECE_PIXELS/2), PIECE_PIXELS); graphics_context_set_stroke_width(ctx, 1); } // Redo border graphics_context_set_stroke_color(ctx, GColorBlack); graphics_draw_rect(ctx, b); }