static void hands_update_proc(Layer *layer, GContext *ctx) { GRect bounds = layer_get_bounds(layer); GPoint center = grect_center_point(&bounds); const int16_t second_hand_length = PBL_IF_ROUND_ELSE((bounds.size.w / 2) - 19, bounds.size.w / 2); time_t now = time(NULL); struct tm *t = localtime(&now); // minute/hour hand // 時 graphics_context_set_stroke_color(ctx, s_backColor); graphics_context_set_fill_color(ctx, s_hourHandColor); gpath_rotate_to(s_hour_arrow, (TRIG_MAX_ANGLE * (((t->tm_hour % 12) * 6) + (t->tm_min / 10))) / (12 * 6)); gpath_draw_filled(ctx, s_hour_arrow); // 分 graphics_context_set_fill_color(ctx, s_backColor); gpath_rotate_to(s_minute_arrow, (TRIG_MAX_ANGLE * (t->tm_min * 10 + (t->tm_sec/6)) / (60 * 10))); graphics_context_set_stroke_width(ctx, 2); graphics_context_set_stroke_color(ctx, s_minuteHandColor); gpath_draw_outline(ctx, s_minute_arrow); // 秒 int32_t second_angle = TRIG_MAX_ANGLE * t->tm_sec / 60; GPoint second_hand = { .x = (int16_t)(sin_lookup(second_angle) * (int32_t)second_hand_length / TRIG_MAX_RATIO) + center.x, .y = (int16_t)(-cos_lookup(second_angle) * (int32_t)second_hand_length / TRIG_MAX_RATIO) + center.y, }; if (s_show_seconds_hand){ // second hand graphics_context_set_stroke_width(ctx, 3); graphics_context_set_stroke_color(ctx, s_secondHandColor); graphics_draw_line(ctx, second_hand, center); graphics_context_set_stroke_width(ctx, 1); graphics_context_set_stroke_color(ctx, s_backColor); graphics_draw_line(ctx, second_hand, center); } // dot in the middle // 黒に設定 graphics_context_set_fill_color(ctx, s_backColor); // 円を塗り潰し graphics_fill_circle(ctx, center, 7); // 線の色を白に設定 graphics_context_set_stroke_color(ctx, s_secondHandColor); graphics_context_set_stroke_width(ctx, 1); graphics_draw_circle(ctx, center, 7); graphics_draw_circle(ctx, center, 1); } static void date_update_proc(Layer *layer, GContext *ctx) { time_t now = time(NULL); struct tm *t = localtime(&now); strftime(s_day_buffer, sizeof(s_day_buffer), "%a", t); text_layer_set_text(s_day_label, s_day_buffer); strftime(s_num_buffer, sizeof(s_num_buffer), "%d", t); text_layer_set_text(s_num_label, s_num_buffer); }
static void update_scale(Layer *layer, GContext *context) { GRect bounds = layer_get_bounds(layer); GPoint center = GPoint(bounds.size.w / 2, bounds.size.h / 2); graphics_context_set_stroke_color(context, GColorWhite); GPoint start; GPoint end; for( int i = 0; i < 12; ++i) { int32_t current_angle = TRIG_MAX_ANGLE * i / 12; // create an oval shape indicator start point start.x = (sin_lookup(current_angle) * 65 / TRIG_MAX_RATIO) + center.x; start.y = (-cos_lookup(current_angle) * 75 / TRIG_MAX_RATIO) + center.y; end.x = (sin_lookup(current_angle) * 100 / TRIG_MAX_RATIO) + center.x; end.y = (-cos_lookup(current_angle) * 100 / TRIG_MAX_RATIO) + center.y; if (i % 3 == 0) { // reached a quarter, draw bigger indicator graphics_context_set_stroke_width(context, 6); } else { graphics_context_set_stroke_width(context, 3); } graphics_draw_line(context, start, end); } }
static void prv_draw_seconds_hand(GContext *ctx, const GRect *layer_bounds, const GPoint *center) { const SprinklesConfiguration *configuration = sprinkles_configuration_get_configuration(); const int32_t seconds_angle = s_app_data->current_seconds * TRIG_MAX_ANGLE / 60; graphics_context_set_stroke_color(ctx, configuration->seconds_hand_color); // Draw the thinner front part of the seconds hand const uint8_t seconds_forward_stroke_width = 1; graphics_context_set_stroke_width(ctx, seconds_forward_stroke_width); const GRect seconds_forward_rect = prv_get_seconds_forward_rect(layer_bounds); // Interpolate the seconds forward rect so that the seconds hand grows out to pierce the donut const int16_t inset = (int16_t)prv_interpolate_int64_linear(seconds_forward_rect.size.w / 2, 0, s_app_data->intro_animation_progress); const GRect interpolated_seconds_forward_rect = grect_inset(seconds_forward_rect, GEdgeInsets(inset)); const GPoint seconds_forward_point = gpoint_from_polar(interpolated_seconds_forward_rect, GOvalScaleModeFitCircle, seconds_angle); graphics_draw_line(ctx, (*center), seconds_forward_point); // Draw the thicker back part of the seconds hand const uint8_t seconds_backward_stroke_width = 2; graphics_context_set_stroke_width(ctx, seconds_backward_stroke_width); const GRect seconds_backward_rect = grect_inset( *layer_bounds, GEdgeInsets(seconds_forward_rect.size.w * 43 / 100)); const GPoint seconds_backward_point = gpoint_from_polar(seconds_backward_rect, GOvalScaleModeFitCircle, seconds_angle - (TRIG_MAX_ANGLE / 2)); graphics_draw_line(ctx, (*center), seconds_backward_point); }
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); }
// Layer representing the pet pebble void draw_pet_pebble(Layer *layer, GContext *ctx) { PetPebbleState pet_state = current_pet_state(); GPoint BODY_CENTER = GPoint(90, 120); int EYES_HEIGHT = 115; int EYE_LEFT_CENTER = 80; int EYE_RIGHT_CENTER = 100; uint16_t radius = 30; // Draw the pet pebble body graphics_context_set_stroke_color(ctx, GColorCobaltBlue); graphics_context_set_fill_color(ctx, GColorCyan); graphics_context_set_stroke_width(ctx, 5); graphics_draw_circle(ctx, BODY_CENTER, radius); graphics_fill_circle(ctx, BODY_CENTER, radius); // Draw the pet pebble eyes graphics_context_set_stroke_color(ctx, GColorBlack); graphics_context_set_fill_color(ctx, GColorBlack); graphics_context_set_stroke_width(ctx, 2); radius = 2; if (pet_state == SLEEPING) { graphics_draw_line(ctx, GPoint(EYE_LEFT_CENTER-5, EYES_HEIGHT), GPoint(EYE_LEFT_CENTER+5, EYES_HEIGHT)); graphics_draw_line(ctx, GPoint(EYE_RIGHT_CENTER-5, EYES_HEIGHT), GPoint(EYE_RIGHT_CENTER+5, EYES_HEIGHT)); } else { graphics_draw_circle( ctx, GPoint(EYE_LEFT_CENTER, EYES_HEIGHT),radius); graphics_draw_circle( ctx, GPoint(EYE_RIGHT_CENTER, EYES_HEIGHT), radius); } // Draw the pet pebble mouth if (pet_state == SLEEPING) { graphics_draw_circle(ctx, GPoint((EYE_LEFT_CENTER+EYE_RIGHT_CENTER)/2, EYES_HEIGHT+13), 5); // Draw "Zzzz" to show that the pet pebble is asleep graphics_draw_text(ctx, "Zzzz", fonts_get_system_font(FONT_KEY_ROBOTO_CONDENSED_21), GRect(EYE_RIGHT_CENTER+20, EYES_HEIGHT-40, EYE_RIGHT_CENTER+60, EYES_HEIGHT-20), GTextOverflowModeTrailingEllipsis, GTextAlignmentLeft, NULL); } else { GRect rect_bounds = GRect(EYE_LEFT_CENTER, EYES_HEIGHT+10, EYE_RIGHT_CENTER-EYE_LEFT_CENTER, 5); int32_t angle_start = DEG_TO_TRIGANGLE(85); int32_t angle_end = DEG_TO_TRIGANGLE(275); graphics_draw_arc(ctx, rect_bounds, GOvalScaleModeFillCircle, angle_start, angle_end); } }
static void draw_battery(GContext *ctx, GColor8 color) { graphics_context_set_stroke_width(ctx, 2); graphics_context_set_fill_color(ctx, color); gpath_draw_filled(ctx, battery); graphics_context_set_stroke_color(ctx, GColorFromHEX(0x000000)); gpath_draw_outline(ctx, battery); graphics_context_set_stroke_color(ctx, GColorFromHEX(0xFFFFFF)); graphics_context_set_stroke_width(ctx, 1); gpath_draw_outline(ctx, battery); }
static void canvas_update_proc(Layer *layer, GContext *ctx) { // Custom drawing happens here! Layer *window_layer = window_get_root_layer(s_main_window); GRect bounds = layer_get_bounds(window_layer); int x,y; int left=bounds.size.w/10+2; int right=bounds.size.w-left; int adjusted_steps=steps/(target_steps/5); uint16_t radius = bounds.size.w/8; if(adjusted_steps>4) adjusted_steps=4; printf("adj steps %d", adjusted_steps); y=bounds.size.h/2; x=left; GPoint center = GPoint(x, y); graphics_context_set_stroke_width(ctx, 2); graphics_context_set_stroke_color(ctx, GColorInchworm); graphics_draw_circle(ctx, center, radius); // Draw the outline of a circle for(int i=0;i<adjusted_steps;i++) { x=x+((right-left)/6); center = GPoint(x, y); graphics_draw_circle(ctx, center, radius); } // Fill a circle GPoint p1 = GPoint(center.x-radius, center.y-radius+4); GPoint p2 = GPoint(center.x+radius, center.y-radius+4); graphics_context_set_fill_color(ctx, GColorInchworm); graphics_fill_circle(ctx, center, radius); graphics_context_set_stroke_color(ctx, GColorBlack); graphics_context_set_stroke_width(ctx, 1); graphics_context_set_fill_color(ctx, GColorBlack); for(int i=0;i<2*radius;i+=4) { p1.y=center.y-radius+i; p2.y=center.y-radius+i; graphics_draw_line(ctx, p1, p2); } radius=radius/4; graphics_fill_circle(ctx, center, radius); }
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 windshield_proc(Layer *layer, GContext *ctx) { // fill it first graphics_context_set_fill_color(ctx, jeep_color); gpath_draw_filled(ctx,s_windshield_path); // now stroke it graphics_context_set_stroke_width(ctx, 1); graphics_context_set_stroke_color(ctx, GColorBlack); gpath_draw_outline(ctx, s_windshield_path); // glass graphics_context_set_fill_color(ctx, GColorBlack); graphics_fill_rect(ctx, GRect(4, 4, 136, 50), 3, GCornersAll); graphics_context_set_fill_color(ctx, background_color); graphics_fill_rect(ctx, GRect(5, 5, 134, 48), 3, GCornersAll); // forest // graphics_context_set_compositing_mode(ctx, GCompOpSet); // graphics_draw_bitmap_in_rect(ctx, s_forest_image, GRect( 6, 6, 132, 46)); // logo graphics_context_set_compositing_mode(ctx, GCompOpSet); graphics_draw_bitmap_in_rect(ctx, s_logo_image, GRect( 14, 6, 117, 46)); }
void layer_ring_update_callback(Layer *layer, GContext* ctx) { time_t tt = time(NULL); struct tm *t = localtime(&tt); unsigned int angle = 0; if (t->tm_min != 0) { angle = ( t->tm_min + 1 ) * 6; } GRect bounds = layer_get_bounds(layer); GPoint center = grect_center_point(&bounds); graphics_context_set_fill_color(ctx, s_color_ring_1); graphics_fill_circle(ctx, center, 73); graphics_context_set_fill_color(ctx, s_color_ring_2); for(; angle < 355; angle += 6) { gpath_rotate_to(s_path_ring_segment, (TRIG_MAX_ANGLE / 360) * angle); gpath_draw_filled(ctx, s_path_ring_segment); } graphics_context_set_stroke_color(ctx, s_color_bg_out); graphics_context_set_stroke_width(ctx, 4); graphics_draw_circle(ctx, center, 73); }
static void bluetooth_update_proc(Layer *layer, GContext *ctx) { if (!s_bluetooth_connected) { graphics_context_set_stroke_width(ctx, 3); graphics_context_set_stroke_color(ctx, gcolor_legible_over(background_color)); gpath_draw_outline(ctx, bluetooth_path); } }
static void sun_layer_update(Layer *layer, GContext *ctx) { if (data_loaded) { const GRect entire_screen = GRect(0, 0, 180, 180); const GRect sun_outline_rect = GRect(70, 70, 40, 40); const GRect sun_rect = GRect(72, 72, 36, 36); draw_circle(ctx, entire_screen, GColorVividCerulean, 90, 360); graphics_context_set_stroke_color(ctx, GColorChromeYellow); graphics_context_set_stroke_width(ctx, 2); int i; for (i = 0; i < 360; i += 12) { const GPoint in = gpoint_from_polar( sun_outline_rect, GOvalScaleModeFitCircle, DEG_TO_TRIGANGLE(i) ); const GPoint out = gpoint_from_polar( entire_screen, GOvalScaleModeFitCircle, DEG_TO_TRIGANGLE(i) ); graphics_draw_line(ctx, out, in); } draw_circle(ctx, sun_outline_rect, GColorWindsorTan, 20, 360); draw_circle(ctx, sun_rect, GColorOrange, 18, 360); } }
/* * Function: create_graph * ---------------------------------------------------------------------------- * Creates the graph curve and draws labels for all weekdays. * * ctx: the drawing context * bounds_size_h: the drawing bounds height * builder: the GPathBuilder used to create the curve * ---------------------------------------------------------------------------- */ void create_graph(GContext *ctx, int bounds_size_h, GPathBuilder *builder) { #if PBL_PLATFORM_BASALT // On Pebble Time (Basalt) increase the width of the curve line to make it // more visible graphics_context_set_stroke_width(ctx, 2); #endif int current_day = date_get_weekday()+1; #if APP_DEBUG current_day = DEBUG_DAY+1; #endif if (current_day > 6) {current_day = 0;} int day_shift = -current_day; if (current_day == KEY_MOOD_SUN) { day_shift = current_day; } draw_graph_part_start(ctx, bounds_size_h, get_label_string(current_day), current_day, current_day+1, builder, day_shift); draw_graph_part_parts(ctx, bounds_size_h, get_label_string(current_day+1), current_day+1, current_day+2, builder, day_shift); draw_graph_part_parts(ctx, bounds_size_h, get_label_string(current_day+2), current_day+2, current_day+3, builder, day_shift); draw_graph_part_parts(ctx, bounds_size_h, get_label_string(current_day+3), current_day+3, current_day+4, builder, day_shift); draw_graph_part_parts(ctx, bounds_size_h, get_label_string(current_day+4), current_day+4, current_day+5, builder, day_shift); draw_graph_part_parts(ctx, bounds_size_h, get_label_string(current_day+5), current_day+5, current_day+6, builder, day_shift); draw_graph_part_day(ctx, bounds_size_h, get_label_string(current_day+6), KEY_MOOD_SAT); }
static void ring_layer_update(Layer *layer, GContext *ctx) { if (data_loaded) { const GRect entire_screen = GRect(0, 0, 180, 180); draw_circle(ctx, entire_screen, GColorWhite, 20, 360); graphics_context_set_stroke_color(ctx, GColorOxfordBlue); graphics_context_set_stroke_width(ctx, 10); const GRect time_orbit = GRect(10, 10, 160, 160); int degree_icon = degreeify(hour, minute); int degree_rise = degreeify(hour_rise, minute_rise); int degree_set = degreeify(hour_set, minute_set); GBitmap *icon = degree_icon >= degree_set && degree_icon <= degree_rise ? moon : sun; const GRect icon_space = grect_centered_from_polar( time_orbit, GOvalScaleModeFitCircle, DEG_TO_TRIGANGLE(degree_icon), GSize(18, 18) ); graphics_context_set_compositing_mode(ctx, GCompOpSet); graphics_draw_bitmap_in_rect(ctx, icon, icon_space); } }
static void fill_wedge(GContext *ctx, GPath *wedge, GColor color) { graphics_context_set_fill_color(ctx, color); graphics_context_set_stroke_color(ctx, color); graphics_context_set_stroke_width(ctx, 2); gpath_draw_filled(ctx, wedge); gpath_draw_outline(ctx, wedge); }
/* * Progress line */ EXTFN void progress_layer_update_callback(Layer *layer, GContext *ctx) { graphics_context_set_fill_color(ctx, BACKGROUND_COLOR); graphics_fill_rect(ctx, layer_get_bounds(layer), 0, GCornerNone); graphics_context_set_fill_color(ctx, BAR_CHART_MARKS); graphics_context_set_stroke_color(ctx, BAR_CHART_MARKS); graphics_context_set_stroke_width(ctx, 2); for (uint8_t i = 0; i <= 120; i += 12) { graphics_draw_pixel(ctx, GPoint(i, 8)); graphics_draw_pixel(ctx, GPoint(i, 7)); } for (uint8_t i = 0; i <= get_internal_data()->highest_entry; i++) { if (!get_internal_data()->ignore[i]) { uint16_t height = get_internal_data()->points[i] / 500; uint8_t i2 = i * 2; #ifdef PBL_COLOR graphics_context_set_stroke_color(ctx, bar_color(height)); #endif graphics_draw_line(ctx, GPoint(i2, 8 - height), GPoint(i2, 8)); } } }
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); }
/* * Draw a bar for a particular 10 minute slice */ static void draw_bar_sector(GContext *ctx, GColor color, uint8_t position, int32_t stroke_width) { int32_t x = x_from_position(position); graphics_context_set_stroke_width(ctx, stroke_width); graphics_context_set_stroke_color(ctx, color); graphics_draw_line(ctx, GPoint(x, 0), GPoint(x, bar_height-7)); }
static void canvas_update_proc(Layer *layer, GContext *ctx) { int rect_width = text_layer_get_content_size(s_date_layer).w + 10; GRect rect_bounds = GRect(((180 - rect_width) / 2), 110, rect_width, 25); graphics_context_set_fill_color(ctx, settings.SecondaryColor); int corner_radius = 5; graphics_fill_rect(ctx, rect_bounds, corner_radius, GCornersAll); GPoint circle_center = GPoint(90, 90); uint16_t circle_radius = 75; graphics_context_set_stroke_color(ctx, settings.SecondaryColor); graphics_context_set_stroke_width(ctx, 1); graphics_draw_circle(ctx, circle_center, circle_radius); graphics_context_set_stroke_width(ctx, 3); uint16_t outer_circle_radius = 80; graphics_draw_circle(ctx, circle_center, outer_circle_radius); }
static void mainForegroundUpdateProc(Layer* this_layer, GContext *ctx) { GRect b = layer_get_bounds(this_layer); #ifdef PBL_ROUND b.size.h -= 16; // Because of the time at the top, default position is too low on a round screen #endif // Draw the three lives GPoint lives = GPoint( b.size.w/2 - PIECE_PIXELS, b.size.h - 6); for (int L=0; L<3; ++L) { GColor in; GColor out; if (s_score.lives >= (3 - L)) { if (L == 0) { in = COLOR_FALLBACK(GColorMintGreen, GColorWhite); out = COLOR_FALLBACK(GColorDarkGreen, GColorBlack); } else if (L == 1) { in = COLOR_FALLBACK(GColorRajah, GColorWhite); out = COLOR_FALLBACK(GColorWindsorTan, GColorBlack); } else { in = COLOR_FALLBACK(GColorMelon, GColorWhite); out = COLOR_FALLBACK(GColorDarkCandyAppleRed, GColorBlack); } } else { in = COLOR_FALLBACK(GColorLightGray, GColorBlack); out = COLOR_FALLBACK(GColorDarkGray, GColorBlack); } GPoint p = lives; p.x += PIECE_PIXELS * L; graphics_context_set_stroke_color(ctx, out); graphics_context_set_fill_color(ctx, in); graphics_context_set_stroke_width(ctx, 3); graphics_fill_circle(ctx, p, 3); graphics_draw_circle(ctx, p, 3); // Animation? if (s_spentLifeAnimRadius > 0 && s_score.lives == (3 - L)) { graphics_context_set_stroke_width(ctx, 5); graphics_context_set_stroke_color(ctx, COLOR_FALLBACK(in,out)); graphics_draw_circle(ctx, p, s_spentLifeAnimRadius / SUB_PIXEL ); } } // Draw the game over message if (s_gameOverMessage == true) { static const char txtGame[] = "GAME"; static const char txtOver[] = "OVER"; b.origin.y += 30; draw3DText(ctx, b, fonts_get_system_font(FONT_KEY_BITHAM_42_BOLD), txtGame, 1, GTextAlignmentCenter, true, GColorWhite, GColorBlack); b.origin.y += 40; draw3DText(ctx, b, fonts_get_system_font(FONT_KEY_BITHAM_42_BOLD), txtOver, 1, GTextAlignmentCenter, true, GColorWhite, GColorBlack); } }
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 layer_update_proc(Layer *layer, GContext *ctx) { if (!should_update) { APP_LOG(APP_LOG_LEVEL_INFO, "Skipped update"); return; } GRect bounds = layer_get_bounds(layer); // Draw battery line graphics_context_set_stroke_color(ctx, s_charge_percent <= 30 ? GColorYellow : GColorRed); graphics_context_set_stroke_width(ctx, 3); int lineSegment = (bounds.size.w - 56) * 10/100; for (int i = 0; i < s_charge_percent / 10; i+=1) { graphics_draw_line(ctx, GPoint(28 + i * lineSegment, 120), GPoint(26 + (lineSegment * (i + 1)), 120)); } // Draw arcs for each STEP_DIVS GRect inset_bounds = grect_inset(bounds,GEdgeInsets(1,3,2,2)); graphics_context_set_fill_color(ctx, color_from_active_status(check_active_status())); // Get the sum steps so far today HealthValue steps = health_service_sum_today(HealthMetricStepCount); int lapSteps = steps%STEPS_LAP; int lapSectionAngle = 360 / (STEPS_LAP / STEP_DIVS); int subLapSectionAngle = lapSectionAngle / 10; for (int i = 0; lapSteps > (STEP_DIVS / 10); i++) { if ( lapSteps > STEP_DIVS ) { int32_t add_Degrees = lapSectionAngle - 2; graphics_fill_radial(ctx, inset_bounds, GOvalScaleModeFitCircle, 9, DEG_TO_TRIGANGLE(lapSectionAngle * i), DEG_TO_TRIGANGLE(lapSectionAngle * i + add_Degrees )); lapSteps -= STEP_DIVS; } else { for (int j = 0; lapSteps > (STEP_DIVS / 10); j++) { int32_t add_Degrees = subLapSectionAngle - 1; graphics_fill_radial(ctx, inset_bounds, GOvalScaleModeFitCircle, ((j == 4) ? 13 : 9 ), DEG_TO_TRIGANGLE(lapSectionAngle * i + subLapSectionAngle * j), DEG_TO_TRIGANGLE(lapSectionAngle * i + subLapSectionAngle * j + add_Degrees )); lapSteps -= STEP_DIVS / 10; } } } GRect double_inset = grect_inset(inset_bounds, GEdgeInsets(15)); graphics_context_set_fill_color(ctx, GColorWhite); if (steps < STEPS_LAP) { steps += 150; return; } // draw step lap dots for (int i = 0; i < steps/STEPS_LAP; i++) { GRect xywh = grect_centered_from_polar(double_inset, GOvalScaleModeFitCircle, DEG_TO_TRIGANGLE(6 * i), GSize(5,5)); graphics_fill_radial(ctx, xywh, GOvalScaleModeFitCircle, 5, 0, TRIG_MAX_ANGLE); } steps += 33; }
void batteryLineArc(GContext *ctx, float start_angle, float end_angle, GPoint centre, int radius, int thickness){ float minus_bit = radius - thickness/2 + 0.5;// + (user_battery_colour <= 1 ? 0.5 : 0); //add 0.5 for the int casting, later !!! dark colours like 1.0, light better with 0.5 float add_bit = (radius + thickness/2 + 0.5); graphics_context_set_stroke_width(ctx, 1); if (start_angle == 0) { start_angle = 2.5; // for some reason, 0 seems to start too far to the left....at least for my purposes } for (float i = start_angle; i <= end_angle; i+=0.5) { GPoint inside_point = (GPoint) { .x = (int16_t)(sin_lookup(i * TRIG_MAX_ANGLE / 360) * minus_bit / TRIG_MAX_RATIO) + centre.x, .y = (int16_t)(-cos_lookup(i * TRIG_MAX_ANGLE / 360) * minus_bit / TRIG_MAX_RATIO) + centre.y, }; GPoint outside_point = (GPoint) { .x = (int16_t)(sin_lookup(i * TRIG_MAX_ANGLE / 360) * add_bit / TRIG_MAX_RATIO) + centre.x, .y = (int16_t)(-cos_lookup(i * TRIG_MAX_ANGLE / 360) * add_bit / TRIG_MAX_RATIO) + centre.y, }; graphics_draw_line(ctx, inside_point, outside_point); } } /*************************** AnimationImplementation **************************/ static void animation_started(Animation *anim, void *context) { s_animating = true; } static void animation_stopped(Animation *anim, bool stopped, void *context) { s_animating = false; } static void animate(int duration, int delay, AnimationImplementation *implementation, bool handlers) { Animation *anim = animation_create(); animation_set_duration(anim, duration); animation_set_delay(anim, delay); animation_set_curve(anim, AnimationCurveEaseInOut); animation_set_implementation(anim, implementation); if(handlers) { animation_set_handlers(anim, (AnimationHandlers) { .started = animation_started, .stopped = animation_stopped }, NULL); } animation_schedule(anim); }
static void gui_layer_bg_update(Layer *layer, GContext *ctx) { graphics_context_set_fill_color(ctx, c_bg); graphics_fill_rect(ctx, layer_get_bounds(layer), 0, GCornerNone); int width = layer_get_frame(layer).size.w; int height = layer_get_frame(layer).size.h; graphics_context_set_stroke_color(ctx, PBL_IF_COLOR_ELSE(GColorLightGray, GColorBlack)); graphics_context_set_stroke_width(ctx, 1); graphics_draw_line(ctx, GPoint(PADDING_X, height/2-10), GPoint(width-PADDING_X, height/2-10)); graphics_draw_line(ctx, GPoint(PADDING_X, height/2+10), GPoint(width-PADDING_X, height/2+10)); }
static void hexagon_update_proc( Layer *layer, GContext *context ){ struct _hexagon_layer_data *layer_data = hexagon_get_layer_data(layer); graphics_context_set_fill_color(context, layer_data->color); gpath_draw_filled(context, layer_data->path); if( layer_data->border_path ){ graphics_context_set_stroke_color(context, layer_data->border_color); graphics_context_set_stroke_width(context,(uint8_t)layer_data->border_width); gpath_draw_outline(context, layer_data->border_path); } }
static void score_layer_update(Layer *layer,GContext *ctx){ const uint8_t RADIUS = 60; const uint8_t THICKNESS = 10; graphics_context_set_stroke_color(ctx, GColorDarkGray); graphics_context_set_stroke_width(ctx,THICKNESS); GRect r = layer_get_bounds(layer); GPoint center = grect_center_point(&r); graphics_draw_circle(ctx,center,RADIUS); graphics_draw_arc(ctx,center,RADIUS+ (THICKNESS/2),THICKNESS,angle_270,angle_90,GColorDukeBlue); }
// Draw a thick line on the graphics context static void prv_drawing_thick_line(GContext *ctx, GPoint p0, GPoint p1) { #ifdef PBL_SDK_3 graphics_context_set_stroke_width(ctx, 4); graphics_draw_line(ctx, p0, p1); #else for (int8_t x = -2; x <= 2; x++) { for (int8_t y = -2; y <= 2; y++) { if (abs(x) + abs(y) <= 2) { graphics_draw_line(ctx, GPoint(p0.x + x, p0.y + y), GPoint(p1.x + x, p1.y + y)); } } } #endif }
static void draw_info(Layer *layer, GContext *ctx) { GRect bounds = layer_get_bounds(layer); graphics_context_set_fill_color(ctx, COLOR_FALLBACK(GColorPictonBlue, GColorBlack)); graphics_fill_rect(ctx, layer_get_bounds(layer), 8, GCornersAll); IF_B(graphics_context_set_stroke_width(ctx, 3)); graphics_context_set_stroke_color(ctx, COLOR_FALLBACK(GColorBlueMoon, GColorWhite)); graphics_draw_round_rect(ctx, layer_get_bounds(layer), 8); graphics_context_set_text_color(ctx, COLOR_FALLBACK(GColorBlack, GColorWhite)); GSize text_size = graphics_text_layout_get_content_size(s_info, s_res_gothic_18_bold, GRect(5, 5, bounds.size.w-10, bounds.size.h-10), GTextOverflowModeTrailingEllipsis, GTextAlignmentCenter); graphics_draw_text(ctx, s_info, s_res_gothic_18_bold, GRect(5, ((bounds.size.h-text_size.h)/2)-4, bounds.size.w-10, text_size.h), GTextOverflowModeTrailingEllipsis, GTextAlignmentCenter, NULL); }
static void draw_box(Layer *layer, GContext *ctx, GColor border_color, GColor back_color, GColor text_color, char *text) { GRect bounds = layer_get_bounds(layer); graphics_context_set_fill_color(ctx, back_color); graphics_fill_rect(ctx, layer_get_bounds(layer), PBL_IF_RECT_ELSE(8, 0), GCornersAll); IF_3(graphics_context_set_stroke_width(ctx, 3)); graphics_context_set_stroke_color(ctx, border_color); graphics_draw_round_rect(ctx, layer_get_bounds(layer), PBL_IF_RECT_ELSE(8, 0)); graphics_context_set_text_color(ctx, text_color); GSize text_size = graphics_text_layout_get_content_size(text, s_res_gothic_18_bold, GRect(5, 5, bounds.size.w-10, bounds.size.h-2), GTextOverflowModeTrailingEllipsis, GTextAlignmentCenter); graphics_draw_text(ctx, text, s_res_gothic_18_bold, GRect(5, ((bounds.size.h-text_size.h)/2)-4, bounds.size.w-10, text_size.h), GTextOverflowModeTrailingEllipsis, GTextAlignmentCenter, NULL); }
static void canvas_update_proc(Layer *layer, GContext *ctx) { time_t now = time(NULL); struct tm *t = localtime(&now); int second_angle = ROUND(TRIG_MAX_ANGLE / 60.0 * t->tm_sec); int minute_angle = ROUND(TRIG_MAX_ANGLE / 3600.0 * ( t->tm_min * 60 + t->tm_sec)); int hour_angle = ROUND(TRIG_MAX_ANGLE / 43200.0 * (t->tm_hour % 12 * 3600 + t->tm_min * 60 + t->tm_sec)); GPoint second, minute, hour; second = tick_angle_point(center, second_hand_length, second_angle); minute = tick_angle_point(center, minute_hand_length, minute_angle); hour = tick_angle_point(center, hour_hand_length, hour_angle); graphics_context_set_stroke_color(ctx, GColorWhite); graphics_context_set_fill_color(ctx, GColorWhite); graphics_context_set_stroke_width(ctx, 1); graphics_draw_line(ctx, center, second); graphics_context_set_stroke_width(ctx, 3); graphics_draw_line(ctx, center, minute); graphics_draw_line(ctx, center, hour); }