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); } }
static void offscreen_layer_update(Layer* layer, GContext *ctx) { if (data_loaded) { GRect bounds = layer_get_bounds(layer); // Draw the night slice const GRect entire_screen = GRect(0, 0, 180, 180); graphics_context_set_fill_color(ctx, GColorWhite); graphics_fill_radial( ctx, entire_screen, GOvalScaleModeFillCircle, 90, DEG_TO_TRIGANGLE(degreeify(hour_set, minute_set)), DEG_TO_TRIGANGLE(degreeify(hour_rise, minute_rise)) ); // Capture the graphics context framebuffer GBitmap *framebuffer = graphics_capture_frame_buffer(ctx); bitmap_make_transparent(stars, framebuffer); // Release the framebuffer now that we are free to modify it graphics_release_frame_buffer(ctx, framebuffer); } }
static void battery_update_proc(Layer *layer, GContext *ctx) { GRect bounds = layer_get_bounds(layer); // Find the width of the bar float percent = ((float)s_battery_level / 100.0F); int width = (int)(float)(percent * bounds.size.w); // Draw the background GColor bgcolor = GColorFromHEX(persist_read_int(MESSAGE_KEY_BackgroundColor)); GColor batterycolor; //graphics_context_set_fill_color(ctx, GColorClear); //graphics_fill_rect(ctx, bounds, 0, GCornerNone); // Draw the bar int g = (255 * percent); int r = (255 * (1 - percent)); int b = 0; int rgb = createRGB(r, g, b); if (s_battery_level == 100) { r = 85; g = 255; } if (s_battery_level == 50) { rgb = 0xFFAA00; } int x = persist_read_int(MESSAGE_KEY_Battery); APP_LOG(APP_LOG_LEVEL_INFO, "Battery Preference: %d", x); if (persist_read_int(MESSAGE_KEY_Battery) != 102) { APP_LOG(APP_LOG_LEVEL_INFO, "RGB"); batterycolor = GColorFromHEX(rgb); } else { batterycolor = gcolor_legible_over(bgcolor); } PBL_IF_BW_ELSE(graphics_context_set_fill_color(ctx, batterycolor), graphics_context_set_fill_color(ctx, batterycolor)); //APP_LOG(APP_LOG_LEVEL_INFO, GColorFromHEX(rgb)); /* if (s_battery_level <= 20) { graphics_context_set_fill_color(ctx, PBL_IF_BW_ELSE(GColorBlack, GColorRed)); } else if (s_battery_level == 100) { graphics_context_set_fill_color(ctx, PBL_IF_BW_ELSE(GColorBlack, GColorBrightGreen)); } */ GRect frame = grect_inset(bounds, GEdgeInsets(10)); //graphics_context_set_fill_color(ctx, GColorBlack); PBL_IF_ROUND_ELSE(graphics_fill_radial(ctx, frame, GOvalScaleModeFitCircle, 5, DEG_TO_TRIGANGLE(125+((1-percent)*110)), DEG_TO_TRIGANGLE(235)), graphics_fill_rect(ctx, GRect(0, 0, width, bounds.size.h), 0, GCornerNone)); }
static void draw_circle(GContext *ctx, GRect rect, GColor color, int r, int deg) { graphics_context_set_fill_color(ctx, color); graphics_fill_radial( ctx, rect, GOvalScaleModeFillCircle, r, DEG_TO_TRIGANGLE(0), deg % 360 == 0 ? TRIG_MAX_ANGLE : DEG_TO_TRIGANGLE(deg) ); }
// 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); } }
void bipercent_draw_circle(Layer *layer, GContext *ctx) { BipercentLayerData *data = (BipercentLayerData*) layer_get_data(layer); int end_angle = data->percent * 360 / 100; GRect rect = layer_get_bounds(layer); graphics_fill_radial(ctx, rect, GOvalScaleModeFitCircle, RADIAL_R, DEG_TO_TRIGANGLE(0), DEG_TO_TRIGANGLE(end_angle)); graphics_draw_arc(ctx, rect, GOvalScaleModeFitCircle, DEG_TO_TRIGANGLE(end_angle), DEG_TO_TRIGANGLE(360)); graphics_draw_arc(ctx, grect_inset(layer_get_bounds(layer), GEdgeInsets(RADIAL_R)) , GOvalScaleModeFitCircle, DEG_TO_TRIGANGLE(end_angle), DEG_TO_TRIGANGLE(360)); }
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); } }
// Draw the vertically stacked spots that indicate how many devices there are and which one is selected static void spots_draw(Layer *layer, GContext *ctx) { GRect rect = layer_get_frame(layer); graphics_context_set_stroke_color(ctx, GColorWhite); graphics_context_set_fill_color(ctx, GColorWhite); for (int y = 0; y < g_device_count; y++) { #ifdef PBL_ROUND GPoint spot = gpoint_from_polar(GRect(rect.origin.x+((rect.size.w-DEV_LAYER_WIDTH)/4), rect.origin.y+((rect.size.h-DEV_LAYER_HEIGHT)/4), rect.size.w-((rect.size.w-DEV_LAYER_WIDTH)/2), rect.size.h-((rect.size.h-DEV_LAYER_HEIGHT)/2)), GOvalScaleModeFitCircle, DEG_TO_TRIGANGLE(270+ ((((SPOT_RADIUS*2)*g_device_count)+(SPOT_SPACING*(g_device_count-1)))/2) - (y*((SPOT_RADIUS*2)+SPOT_SPACING)+3))); #else GPoint spot = GPoint((rect.size.w/2), (rect.size.h/2)-((((SPOT_RADIUS*2)*g_device_count)+(SPOT_SPACING*(g_device_count-1)))/2) + (y*((SPOT_RADIUS*2)+SPOT_SPACING)+3)); #endif if (g_device_selected == y) graphics_fill_circle(ctx, spot, SPOT_RADIUS); else graphics_draw_circle(ctx, spot, SPOT_RADIUS); } }
//draw dots static void layer_update_proc(Layer *layer, GContext *ctx) { GRect bounds = layer_get_bounds(layer); GRect frame = grect_inset(bounds, GEdgeInsets(3)); // Adjust geometry variables for inner ring frame = grect_inset(frame, GEdgeInsets(3 * DOTS_RADIUS)); // For loop that determines dot placement, color and prints dots for(int i = 0; i < vDOTS; i++) { int dot_angle = get_angle_for_dots(i); GPoint pos = gpoint_from_polar(frame, GOvalScaleModeFitCircle, DEG_TO_TRIGANGLE(dot_angle)); if (dot_angle <= 60){ graphics_context_set_fill_color(ctx, DOTS_COLOR1); } else if (dot_angle <= 120){ graphics_context_set_fill_color(ctx, DOTS_COLOR2); } else if (dot_angle <= 180){ graphics_context_set_fill_color(ctx, DOTS_COLOR3); } else if (dot_angle <= 240){ graphics_context_set_fill_color(ctx, DOTS_COLOR4); } else if (dot_angle <= 300){ graphics_context_set_fill_color(ctx, DOTS_COLOR5); } else { graphics_context_set_fill_color(ctx, DOTS_COLOR6); } graphics_fill_circle(ctx, pos, DOTS_RADIUS); } }
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 prv_draw_pupil(GContext *ctx, const GRect *eye_rect, const GPoint *perimeter_point) { const int16_t pupil_radius = 3; const GSize pupil_size = GSize(pupil_radius * 2, pupil_radius * 2); const GRect pupil_container_rect = grect_inset((*eye_rect), GEdgeInsets(2 * pupil_radius)); const GPoint pupil_center = grect_center_point(&pupil_container_rect); const int32_t pupil_angle = atan2_lookup(perimeter_point->y - pupil_center.y, perimeter_point->x - pupil_center.x) + DEG_TO_TRIGANGLE(90); const GRect pupil_rect = grect_centered_from_polar(pupil_container_rect, GOvalScaleModeFitCircle, pupil_angle, pupil_size); graphics_fill_radial(ctx, pupil_rect, GOvalScaleModeFitCircle, pupil_radius, 0, TRIG_MAX_ANGLE); }
static void dial_widget_layer_update(DialWidgetLayer *dial_widget_layer, GContext *ctx) { GRect bounds = layer_get_bounds(dial_widget_layer); DialWidgetData *data = (DialWidgetData*)layer_get_data(dial_widget_layer); uint16_t direction = data->vec->direction; // string formatting char center_text[MAX_CENTER_TEXT]; snprintf(center_text, MAX_CENTER_TEXT*sizeof(char), "%u\n%s", data->vec->magnitude, data->units); graphics_context_set_fill_color(ctx, GColorCobaltBlue); graphics_context_set_stroke_color(ctx, GColorBlack); // draw the dial outline graphics_draw_arc(ctx, grect_inset(bounds, GEdgeInsets(1)), GOvalScaleModeFitCircle, 0, DEG_TO_TRIGANGLE(360)); graphics_draw_arc(ctx, grect_inset(bounds, GEdgeInsets(8)), GOvalScaleModeFitCircle, 0, DEG_TO_TRIGANGLE(360)); // draw the arrow graphics_fill_radial(ctx, bounds, GOvalScaleModeFitCircle, 8, DEG_TO_TRIGANGLE(direction - 15), DEG_TO_TRIGANGLE(direction + 15)); // draw the center text GFont font = fonts_get_system_font(FONT_KEY_GOTHIC_14); graphics_context_set_text_color(ctx, GColorBlack); graphics_draw_text(ctx, center_text, font, grect_inset(bounds, GEdgeInsets(8)), GTextOverflowModeWordWrap, GTextAlignmentCenter, NULL); }
static void show_round_meter(GContext *ctx, GRect *bounds) { // radial GRect frame = grect_inset((*bounds), GEdgeInsets(0)); int minute_angle = (int)(360.0 * s_meter_time.minutes / 60.0); int32_t start_break = minute_angle + 360 * (CONCENTRATION_TIME) / 60 / 60; // 150 == 360 * 25 / 60 int32_t end_break = start_break + 360 * (REST_TIME) / 60 / 60; // 30 == 360 * 5 / 60 graphics_context_set_fill_color(ctx, CONCENTRATION_COLOR); graphics_fill_radial(ctx, frame, GOvalScaleModeFitCircle, METER_THICKNESS, DEG_TO_TRIGANGLE(minute_angle), DEG_TO_TRIGANGLE(start_break)); graphics_context_set_fill_color(ctx, REST_COLOR); graphics_fill_radial(ctx, frame, GOvalScaleModeFitCircle, METER_THICKNESS, DEG_TO_TRIGANGLE(start_break), DEG_TO_TRIGANGLE(end_break)); // hour dots static int s_hour_dot_radius = 2; frame = grect_inset(frame, GEdgeInsets(5 * s_hour_dot_radius)); for(int i = 0; i < 12; i++) { int hour_angle = i * 360 / 12; GPoint pos = gpoint_from_polar(frame, GOvalScaleModeFitCircle, DEG_TO_TRIGANGLE(hour_angle)); graphics_context_set_fill_color(ctx, GColorWhite); graphics_fill_circle(ctx, pos, s_hour_dot_radius); } }
void get_data(DictionaryIterator *iterator, void *context) { Tuple *tuple = dict_read_first(iterator); while (tuple) { if (tuple -> key) { friendNames[tuple->key-1] = tuple->value->cstring; } else { nFriends = tuple->length; for (int i = 0; i < nFriends; i++) friendDirections[i] = DEG_TO_TRIGANGLE(tuple->value->data[i]); } tuple = dict_read_next(iterator); } layer_mark_dirty(window_get_root_layer(window)); }
static void bg_update_proc(struct Layer *layer, GContext *ctx){ GRect bounds = layer_get_bounds(layer); graphics_draw_bitmap_in_rect(ctx, s_bitmap, gbitmap_get_bounds(s_bitmap)); gpath_rotate_to(s_arrow_path, DEG_TO_TRIGANGLE(s_mood_level * 180 / 100)); // Fill the path: graphics_context_set_fill_color(ctx, GColorRed); gpath_draw_filled(ctx, s_arrow_path); // Stroke the path: graphics_context_set_stroke_width(ctx, 3); graphics_context_set_stroke_color(ctx, GColorBlack); gpath_draw_outline(ctx, s_arrow_path); graphics_context_set_fill_color(ctx, GColorBlack); graphics_fill_circle(ctx, (GPoint){PBL_IF_ROUND_ELSE(100,89), bounds.size.h/2}, 32); graphics_fill_rect(ctx, (GRect){.origin={PBL_IF_ROUND_ELSE(100,89),bounds.size.h/2-32},.size={64,65}}, 0, 0);
static void arc_update_proc(Layer *layer, GContext *ctx) { GRect bounds = layer_get_bounds(layer); Arc *arc = (Arc*) layer_get_data(layer); GRect rect = GRect( bounds.size.w / 2 - arc->radius, bounds.size.h / 2 - arc->radius - MARGIN, arc->radius * 2, arc->radius * 2 ); graphics_context_set_stroke_color(ctx, INVERT_COLOURS ? GColorBlack : GColorWhite); graphics_context_set_stroke_width(ctx, CIRCLE_THICKNESS); graphics_draw_arc( ctx, rect, GOvalScaleModeFitCircle, 0, DEG_TO_TRIGANGLE(360 * arc->percent) ); }
static void my_hand_draw(Layer *layer, GContext *ctx) { GRect bounds = layer_get_bounds(layer); time_t temp = time(NULL); struct tm *tick_time = localtime(&temp); int bhour = tick_time->tm_hour; int bmin = tick_time->tm_min; float angle = 30 * ((float)(bhour % 12) + ((float)bmin / 60)); if (debug) angle = 12 * tick_time->tm_sec; ; graphics_context_set_stroke_width(ctx, 2); graphics_context_set_stroke_color(ctx, GColorRed); graphics_draw_line(ctx, gpoint_from_polar(grect_crop(bounds, 60), GOvalScaleModeFitCircle , DEG_TO_TRIGANGLE(angle)), gpoint_from_polar(bounds, GOvalScaleModeFitCircle, DEG_TO_TRIGANGLE(angle+180))); //GPoint textLocation = gpoint_from_polar(grect_crop(bounds, 50), GOvalScaleModeFitCircle , DEG_TO_TRIGANGLE(angle)); // layer_set_frame((Layer *)s_battery_layer, // GRect(textLocation.x-10, textLocation.y-10, 20, 200)); }
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 tick_handler(struct tm *tick_time, TimeUnits units_changed) { update_time(); layer_mark_dirty(s_hand_layer); int bhour = tick_time->tm_hour; int bmin = tick_time->tm_min; float angle = 30 * ((float)(bhour % 12) + ((float)bmin / 60)); if (debug) angle = 12 * tick_time->tm_sec; GRect frame = layer_get_frame(s_face_layer); GRect frame2 = layer_get_frame(s_hand_layer); float size = (frame.size.w + frame2.size.w) / 2; GPoint origin = gpoint_from_polar(grect_inset(frame2, GEdgeInsets(-150)), GOvalScaleModeFitCircle , DEG_TO_TRIGANGLE(angle + 180)); frame.origin = origin; frame.origin.x -= frame.size.w / 2; frame.origin.y -= frame.size.w / 2; layer_set_frame(s_face_layer, frame); }
static void my_face_draw(Layer *layer, GContext *ctx) { GRect bounds = layer_get_bounds(layer); // Draw a white filled circle a radius of half the layer height graphics_context_set_fill_color(ctx, GColorWhite); const int16_t half_h = bounds.size.h / 2; graphics_draw_circle (ctx, GPoint(half_h, half_h), 90); graphics_context_set_stroke_width(ctx, 2); graphics_context_set_text_color(ctx, GColorBlack); GPoint center = grect_center_point(&bounds); for(int i=0; i<12; i++) { int angle = i * 30; static char buf[] = "000"; /* <-- implicit NUL-terminator at the end here */ snprintf(buf, sizeof(buf), "%02d", i==0?12:i); int ascender = 8; GPoint text_point = gpoint_from_polar(grect_crop(bounds, 50), GOvalScaleModeFitCircle, DEG_TO_TRIGANGLE(angle)); GRect text_rect = GRect(text_point.x - 24, text_point.y - 24, 48, 48); GSize size = graphics_text_layout_get_content_size(buf, fonts_get_system_font(FONT_KEY_GOTHIC_24_BOLD), text_rect, GTextOverflowModeWordWrap, GTextAlignmentLeft); ///graphics_draw_bitmap_in_rect(ctx, image, layer_get_bounds(layer)); text_rect.size = size; text_rect.size.h -= ascender; text_rect.origin = GPoint(text_point.x - size.w/2, text_point.y -size.h/2); graphics_draw_text(ctx, buf, fonts_get_system_font(FONT_KEY_GOTHIC_24_BOLD), grect_inset(text_rect, GEdgeInsets4(-8, 0, 0, 0)), GTextOverflowModeWordWrap, GTextAlignmentRight, NULL); //graphics_draw_rect(ctx, text_rect); // Draw hour graphics_context_set_stroke_color(ctx, GColorBlack); graphics_context_set_stroke_width(ctx, 2); graphics_draw_line(ctx, gpoint_from_polar(grect_crop(bounds, 30), GOvalScaleModeFitCircle , DEG_TO_TRIGANGLE(angle)), gpoint_from_polar(bounds, GOvalScaleModeFitCircle, DEG_TO_TRIGANGLE(angle))); angle += 15; // Draw half hour graphics_context_set_stroke_color(ctx, GColorDarkGray); graphics_context_set_stroke_width(ctx, 2); graphics_draw_line(ctx, gpoint_from_polar(grect_crop(bounds, 10), GOvalScaleModeFitCircle , DEG_TO_TRIGANGLE(angle)), gpoint_from_polar(bounds, GOvalScaleModeFitCircle, DEG_TO_TRIGANGLE(angle))); angle += 7.5; // Draw quarter hours graphics_context_set_stroke_color(ctx, GColorDarkGray); graphics_context_set_stroke_width(ctx, 2); graphics_draw_line(ctx, gpoint_from_polar(grect_crop(bounds, 10), GOvalScaleModeFitCircle , DEG_TO_TRIGANGLE(angle)), gpoint_from_polar(bounds, GOvalScaleModeFitCircle, DEG_TO_TRIGANGLE(angle))); angle -= 15; graphics_draw_line(ctx, gpoint_from_polar(grect_crop(bounds, 10), GOvalScaleModeFitCircle , DEG_TO_TRIGANGLE(angle)), gpoint_from_polar(bounds, GOvalScaleModeFitCircle, DEG_TO_TRIGANGLE(angle))); } }
//----------------------------------------------------------------------------------------------------------------------- static void face_update_proc(Layer *layer, GContext *ctx) { GRect bounds = layer_get_bounds(layer); GPoint center = grect_center_point(&bounds), clock_center = GPoint(200, 200); //Draw Mask #if defined(PBL_RECT) if (CfgData.circle) graphics_draw_bitmap_in_rect(ctx, bmp_mask, bounds); #endif graphics_context_set_stroke_color(ctx, CfgData.circle || CfgData.inv ? GColorBlack : GColorWhite); graphics_context_set_text_color(ctx, CfgData.circle || CfgData.inv ? GColorBlack : GColorWhite); graphics_context_set_fill_color(ctx, CfgData.circle || CfgData.inv ? GColorBlack : GColorWhite); //TRIG_MAX_ANGLE * t->tm_sec / 60 int32_t angle = (TRIG_MAX_ANGLE * (((aktHH % 12) * 60) + (aktMM / 1))) / (12 * 60), sinl = sin_lookup(angle), cosl = cos_lookup(angle); int16_t radV = 144, radD = 175, radT = 135; GPoint sub_center, ptLin, ptDot; sub_center.x = (int16_t)(sinl * (int32_t)radV / TRIG_MAX_RATIO) + clock_center.x; sub_center.y = (int16_t)(-cosl * (int32_t)radV / TRIG_MAX_RATIO) + clock_center.y; GRect sub_rect = { .origin = GPoint(sub_center.x - bounds.size.w / 2, sub_center.y - bounds.size.h / 2), .size = bounds.size }; for (int32_t i = 1; i<=72; i++) { int32_t angleC = TRIG_MAX_ANGLE * i / 72, sinC = sin_lookup(angleC), cosC = cos_lookup(angleC); ptLin.x = (int16_t)(sinC * (int32_t)(radD) / TRIG_MAX_RATIO) + clock_center.x - sub_rect.origin.x; ptLin.y = (int16_t)(-cosC * (int32_t)(radD) / TRIG_MAX_RATIO) + clock_center.y - sub_rect.origin.y; if (ptLin.x > -40 && ptLin.x < bounds.size.w+40 && ptLin.y > -40 && ptLin.y < bounds.size.h+40) { if ((i % 6) == 0) { gpath_move_to(hour_path, ptLin); gpath_rotate_to(hour_path, angleC); gpath_draw_filled(ctx, hour_path); int16_t nHrPnt = i/6; if (clock_is_24h_style()) if ((aktHH > 9 && aktHH < 21 && nHrPnt > 0 && nHrPnt < 6) || (((aktHH > 15 && aktHH <= 23) || (aktHH >= 0 && aktHH < 3)) && nHrPnt >= 6 && nHrPnt <= 12)) nHrPnt += 12; snprintf(hhBuffer, sizeof(hhBuffer), "%d", nHrPnt); GSize txtSize = graphics_text_layout_get_content_size(hhBuffer, fonts_get_system_font(FONT_KEY_DROID_SERIF_28_BOLD), bounds, GTextOverflowModeWordWrap, GTextAlignmentCenter); ptDot.x = (int16_t)(sinC * (int32_t)radT / TRIG_MAX_RATIO) + clock_center.x - sub_rect.origin.x; ptDot.y = (int16_t)(-cosC * (int32_t)radT / TRIG_MAX_RATIO) + clock_center.y - sub_rect.origin.y; graphics_draw_text(ctx, hhBuffer, fonts_get_system_font(FONT_KEY_DROID_SERIF_28_BOLD), GRect(ptDot.x-txtSize.w/2, ptDot.y-txtSize.h/2, txtSize.w, txtSize.h), GTextOverflowModeWordWrap, GTextAlignmentCenter, NULL); } else if ((i % 3) == 0) { gpath_move_to(mins_path, ptLin); gpath_rotate_to(mins_path, angleC); gpath_draw_filled(ctx, mins_path); } else { gpath_move_to(secs_path, ptLin); gpath_rotate_to(secs_path, angleC); gpath_draw_filled(ctx, secs_path); } } } //Draw Hand Path ptLin.x = (int16_t)(sinl * (int32_t)(radV+111) / TRIG_MAX_RATIO) + clock_center.x - sub_rect.origin.x; ptLin.y = (int16_t)(-cosl * (int32_t)(radV+111) / TRIG_MAX_RATIO) + clock_center.y - sub_rect.origin.y; #ifdef PBL_COLOR graphics_context_set_fill_color(ctx, GColorOrange); #else graphics_context_set_fill_color(ctx, CfgData.circle || CfgData.inv ? GColorBlack : GColorWhite); #endif gpath_move_to(hand_path, ptLin); gpath_rotate_to(hand_path, angle); gpath_draw_filled(ctx, hand_path); //Only if no Mask... if (!CfgData.circle) { graphics_context_set_stroke_color(ctx, CfgData.inv ? GColorWhite : GColorBlack); gpath_draw_outline(ctx, hand_path); } //Draw Separator Lines graphics_context_set_stroke_color(ctx, CfgData.inv ? GColorBlack : GColorWhite); #if defined(PBL_RECT) if (CfgData.sep && !CfgData.circle) graphics_draw_line(ctx, GPoint(10, bounds.size.h-1), GPoint(bounds.size.w-10, bounds.size.h-1)); #elif defined(PBL_ROUND) //Radio & Battery graphics_context_set_fill_color(ctx, CfgData.inv ? GColorWhite : GColorBlack); if (CfgData.smart) { graphics_fill_radial(ctx, GRect(-20, center.y-20, 40, 40), GOvalScaleModeFitCircle, 20, DEG_TO_TRIGANGLE(5), DEG_TO_TRIGANGLE(175)); graphics_fill_radial(ctx, GRect(bounds.size.w-20, center.y-20, 40, 40), GOvalScaleModeFitCircle, 20, DEG_TO_TRIGANGLE(185), DEG_TO_TRIGANGLE(355)); if (CfgData.sep) { graphics_draw_arc(ctx, GRect(-20, center.y-20, 40, 40), GOvalScaleModeFitCircle, DEG_TO_TRIGANGLE(5), DEG_TO_TRIGANGLE(175)); graphics_draw_arc(ctx, GRect(bounds.size.w-20, center.y-20, 40, 40), GOvalScaleModeFitCircle, DEG_TO_TRIGANGLE(190), DEG_TO_TRIGANGLE(350)); } } //DateTime if (!CfgData.fsm) { graphics_fill_radial(ctx, GRect(center.x-100, bounds.size.h-n_bottom_margin-5, 200, 200), GOvalScaleModeFitCircle, n_bottom_margin+5, DEG_TO_TRIGANGLE(275), DEG_TO_TRIGANGLE(445)); graphics_draw_text(ctx, ddmmyyyyBuffer, digitS, GRect(0, bounds.size.h-n_bottom_margin-5, bounds.size.w, n_bottom_margin), GTextOverflowModeWordWrap, GTextAlignmentCenter, NULL); if (CfgData.sep) graphics_draw_arc(ctx, GRect(center.x-100, bounds.size.h-n_bottom_margin-5, 200, 200), GOvalScaleModeFitCircle, DEG_TO_TRIGANGLE(275), DEG_TO_TRIGANGLE(445)); } #endif } //----------------------------------------------------------------------------------------------------------------------- static void handle_tick(struct tm *tick_time, TimeUnits units_changed) { if (b_initialized) { aktHH = tick_time->tm_hour; aktMM = tick_time->tm_min; layer_mark_dirty(face_layer); } #if defined(PBL_RECT) strftime(ddmmyyyyBuffer, sizeof(ddmmyyyyBuffer), //true ? "%a %d.%b" : CfgData.datefmt == 1 ? "%d-%m-%Y" : CfgData.datefmt == 2 ? "%d/%m/%Y" : CfgData.datefmt == 3 ? "%m/%d/%Y" : CfgData.datefmt == 4 ? "%Y-%m-%d" : CfgData.datefmt == 5 ? "%d.%m.%y" : CfgData.datefmt == 6 ? "%d-%m-%y" : CfgData.datefmt == 7 ? "%d/%m/%y" : CfgData.datefmt == 8 ? "%m/%d/%y" : CfgData.datefmt == 9 ? "%y-%m-%d" : CfgData.datefmt == 10 ? "%a %d.%m." : CfgData.datefmt == 11 ? "%a %d.%b" : "%d.%m.%Y", tick_time); #elif defined(PBL_ROUND) strftime(ddmmyyyyBuffer, sizeof(ddmmyyyyBuffer), //true ? "%a %d." : CfgData.datefmt == 1 ? "%d-%m" : CfgData.datefmt == 2 ? "%d/%m" : CfgData.datefmt == 3 ? "%m/%d" : CfgData.datefmt == 4 ? "%m-%d" : CfgData.datefmt == 5 ? "%d.%m" : CfgData.datefmt == 6 ? "%d-%m" : CfgData.datefmt == 7 ? "%d/%m" : CfgData.datefmt == 8 ? "%m/%d" : CfgData.datefmt == 9 ? "%m-%d" : CfgData.datefmt == 10 ? "%a %d." : CfgData.datefmt == 11 ? "%a %d." : "%d.%m", tick_time); #endif /* snprintf(ddmmyyyyBuffer, sizeof(ddmmyyyyBuffer), CfgData.datefmt == 1 ? "%d-%d-%d" : CfgData.datefmt == 2 ? "%d/%d/%d" : CfgData.datefmt == 3 ? "%d/%d/%d" : CfgData.datefmt == 4 ? "%d-%d-%d" : "%d.%d.%d", 88, 88, 8888); */ //strcpy(ddmmyyyyBuffer, "00000"); text_layer_set_text(date_layer, ddmmyyyyBuffer); //Hourly vibrate if (CfgData.vibr && tick_time->tm_min == 0) vibes_enqueue_custom_pattern(vibe_pat_hr); } //----------------------------------------------------------------------------------------------------------------------- static void timerCallback(void *data) { if ((int)data == TIMER_ANIM_FACE && !b_initialized) { time_t temp = time(NULL); struct tm *t = localtime(&temp); if ((aktHH % 12) != (t->tm_hour % 12) || aktMM != t->tm_min) { int16_t nStep = (aktHH % 12) != (t->tm_hour % 12) ? 5 : 1; if ((t->tm_hour % 12) < 6) { //Initial Value? Set correct initial if (aktHH == 0 && aktMM == 0) { aktHH = t->tm_hour >= 12 ? 12 : 0; aktMM = 0; } if (aktMM < 60-nStep) aktMM += nStep; else { aktMM = 0; aktHH++; } } else { //Initial Value? Set correct initial if (aktHH == 0 && aktMM == 0) { aktHH = t->tm_hour > 12 ? 23 : 11; aktMM = 60; } if (aktMM > nStep) aktMM -= nStep; else { aktMM = 60; aktHH--; } //Little workaround if time is close to the 12 o'clock if ((aktHH % 12) == (t->tm_hour % 12) && aktMM < t->tm_min) aktMM = t->tm_min; } layer_mark_dirty(face_layer); timer_face = app_timer_register(TIMER_ANIM_FACE_MS, timerCallback, (void*)TIMER_ANIM_FACE); } else b_initialized = true; } else if ((int)data == TIMER_ANIM_BATT && b_charging) { int nImage = 10 - (aktBattAnim / 10); bitmap_layer_set_bitmap(battery_layer, NULL); gbitmap_destroy(bmp_batt); bmp_batt = gbitmap_create_as_sub_bitmap(batteryAll, GRect(10*nImage, 0, 10, 20)); bitmap_layer_set_bitmap(battery_layer, bmp_batt); aktBattAnim += 10; if (aktBattAnim > 100) aktBattAnim = aktBatt; timer_batt = app_timer_register(TIMER_ANIM_BATT_MS, timerCallback, (void*)TIMER_ANIM_BATT); } } //----------------------------------------------------------------------------------------------------------------------- void battery_state_service_handler(BatteryChargeState charge_state) { int nImage = 0; aktBatt = charge_state.charge_percent; if (charge_state.is_charging) { if (!b_charging) { nImage = 10; b_charging = true; aktBattAnim = aktBatt; timer_batt = app_timer_register(TIMER_ANIM_BATT_MS, timerCallback, (void*)TIMER_ANIM_BATT); } } else { nImage = 10 - (aktBatt / 10); b_charging = false; } bmp_batt = gbitmap_create_as_sub_bitmap(batteryAll, GRect(10*nImage, 0, 10, 20)); bitmap_layer_set_bitmap(battery_layer, bmp_batt); }
static void select_click_handler(ClickRecognizerRef recognizer, void *context) { if(s_energychanged_handler) { s_energychanged_handler(s_energy_level); } } static void click_config_provider(void *context) { window_single_repeating_click_subscribe(BUTTON_ID_UP,50,up_click_handler); window_single_click_subscribe(BUTTON_ID_SELECT, select_click_handler); window_single_repeating_click_subscribe(BUTTON_ID_DOWN,50,down_click_handler); } static void layer_update_proc(Layer *layer, GContext *ctx) { #ifdef PBL_ROUND graphics_draw_bitmap_in_rect(ctx, s_bitmap, (GRect){.origin={73,10},.size={73,160}}); gpath_rotate_to(s_my_path_ptr, DEG_TO_TRIGANGLE(25 + s_energy_level * 130 / ENERGY_LEVEL_MAX)); #else graphics_draw_bitmap_in_rect(ctx, s_bitmap, (GRect){.origin={51,3},.size={63,162}}); gpath_rotate_to(s_my_path_ptr, DEG_TO_TRIGANGLE(15 + s_energy_level * 150 / ENERGY_LEVEL_MAX)); #endif // Fill the path: graphics_context_set_fill_color(ctx, GColorWhite); gpath_draw_filled(ctx, s_my_path_ptr); // Stroke the path: graphics_context_set_stroke_width(ctx, 3); graphics_context_set_stroke_color(ctx, GColorBlack); gpath_draw_outline(ctx, s_my_path_ptr); graphics_context_set_fill_color(ctx, GColorBlack);
GPoint tick_point(GPoint center, int radius, int degrees) { int angle = DEG_TO_TRIGANGLE(degrees); return tick_angle_point(center, radius, angle); }
static float getRadius(int a, int b, int theta) { float s = (float)sin_lookup(DEG_TO_TRIGANGLE(theta))/TRIG_MAX_RATIO; float c = (float)cos_lookup(DEG_TO_TRIGANGLE(theta))/TRIG_MAX_RATIO; return (a * b) / (my_sqrt((a*a)*(s*s)+(b*b)*(c*c))); }
static void draw_watchface(Layer *layer, GContext *ctx) { GRect bounds = layer_get_bounds(layer); uint16_t width = bounds.size.w - (2 * PADDING); uint16_t max_height = bounds.size.h - (2 * PADDING); //set the colour graphics_context_set_fill_color(ctx, COLOR_FALLBACK(GColorRed, GColorWhite)); //display the seconds graphics_fill_rect(ctx, GRect(((s_sec * width)/60) + PADDING, 84 - 10, 2, 19), 0 ,0); //display the hours //left hours------------------------------ int8_t cur_hours = s_hour % 12; if (cur_hours == 0) { cur_hours = 12; } int8_t left_hours = cur_hours; if (cur_hours > 6) { left_hours = 6; } GPathInfo HOURS_LEFT_PATH_INFO = { .num_points = 4, .points = (GPoint []) {{0,0},{(left_hours*width/12) + 2,0},{(left_hours*width/12) + 2,27},{0,27}} }; GPath *s_hours_path_left = gpath_create(&HOURS_LEFT_PATH_INFO); gpath_rotate_to(s_hours_path_left, DEG_TO_TRIGANGLE(-45)); gpath_move_to(s_hours_path_left, GPoint(3,32 + PADDING)); gpath_draw_filled(ctx, s_hours_path_left); //right hours------------------------------ int8_t right_hours = cur_hours; if (cur_hours < 6) { right_hours = 0; } else { right_hours = cur_hours - 6; } GPathInfo HOURS_RIGHT_PATH_INFO = { .num_points = 4, .points = (GPoint []) {{0,0},{(right_hours*width/12) + 2,0},{(right_hours*width/12) + 2,27},{0,27}} }; GPath *s_hours_path_right = gpath_create(&HOURS_RIGHT_PATH_INFO); gpath_rotate_to(s_hours_path_right, DEG_TO_TRIGANGLE(45)); gpath_move_to(s_hours_path_right, GPoint(width - 32 + 8, 1)); gpath_draw_filled(ctx, s_hours_path_right); //display the minutes //left minutes------------------------------ int8_t left_mins = s_min; if (s_min > 30) { left_mins = 30; } GPathInfo MINS_LEFT_PATH_INFO = { .num_points = 4, .points = (GPoint []) {{0,0},{(left_mins*width/60) + 1,0},{(left_mins*width/60) + 1, 27},{0,27}} }; GPath *s_mins_path_left = gpath_create(&MINS_LEFT_PATH_INFO); gpath_rotate_to(s_mins_path_left, DEG_TO_TRIGANGLE(45)); gpath_move_to(s_mins_path_left, GPoint(PADDING + 10, max_height - 32 - 11)); gpath_draw_filled(ctx, s_mins_path_left); //right minutes------------------------------ int8_t right_mins = s_min; if (s_min < 30) { right_mins = 0; } else { right_mins = s_min - 30; } GPathInfo MINS_RIGHT_PATH_INFO = { .num_points = 4, .points = (GPoint []) {{0,0},{(right_mins*width/60) + 1,0},{(right_mins*width/60) + 1, 27},{0,27}} }; GPath *s_mins_path_right = gpath_create(&MINS_RIGHT_PATH_INFO); gpath_rotate_to(s_mins_path_right, DEG_TO_TRIGANGLE(-45)); gpath_move_to(s_mins_path_right, GPoint(width - 32 - PADDING + 1, max_height)); gpath_draw_filled(ctx, s_mins_path_right); } static void set_background_color(int color) { GColor background_color = GColorFromHEX(color); window_set_background_color(window, background_color); } static void inbox_received_handler(DictionaryIterator *iter, void *context) { APP_LOG(APP_LOG_LEVEL_DEBUG, "inbox received handler"); Tuple *background_color_t = dict_find(iter, KEY_BACKGROUND_COLOR); if (background_color_t) { int background_color = background_color_t->value->int32; if (background_color == 0) { //quick fix so that black colour persists background_color++; } persist_write_int(KEY_BACKGROUND_COLOR, background_color); set_background_color(background_color); APP_LOG(APP_LOG_LEVEL_DEBUG, "background color: %d", background_color); } } static void window_load(Window *window) { Layer *window_layer = window_get_root_layer(window); GRect bounds = layer_get_bounds(window_layer); s_layer = layer_create(layer_get_bounds(window_get_root_layer(window))); layer_add_child(window_get_root_layer(window), s_layer); layer_set_update_proc(s_layer, draw_watchface); uint16_t width = bounds.size.w - (2 * PADDING); uint16_t max_height = bounds.size.h - (2 * PADDING); //create the ternary seconds image s_ternary_seconds_bitmap = gbitmap_create_with_resource(RESOURCE_ID_IMAGE_SECONDS_TERNARY_REFLECT); s_ternary_seconds_layer = bitmap_layer_create(GRect(PADDING, 0, width + 1, 168)); bitmap_layer_set_background_color(s_ternary_seconds_layer, GColorClear); bitmap_layer_set_bitmap(s_ternary_seconds_layer, s_ternary_seconds_bitmap); bitmap_layer_set_compositing_mode(s_ternary_seconds_layer, GCompOpSet); layer_add_child(window_get_root_layer(window), bitmap_layer_get_layer(s_ternary_seconds_layer)); //create the left hours image s_unary_hours_bitmap = gbitmap_create_with_resource(RESOURCE_ID_IMAGE_6_SINGLE_BLOCKS); s_unary_hours_layer_left = rot_bitmap_layer_create(s_unary_hours_bitmap); rot_bitmap_layer_set_corner_clip_color(s_unary_hours_layer_left, GColorClear); rot_bitmap_set_compositing_mode(s_unary_hours_layer_left, GCompOpSet); rot_bitmap_layer_set_angle(s_unary_hours_layer_left, DEG_TO_TRIGANGLE(-45)); //position the frame GRect r = layer_get_frame((Layer *) s_unary_hours_layer_left); r.origin.x = 2; layer_set_frame((Layer *) s_unary_hours_layer_left, r); layer_add_child(window_get_root_layer(window), (Layer *) s_unary_hours_layer_left); //create the right hours image s_unary_hours_layer_right = rot_bitmap_layer_create(s_unary_hours_bitmap); rot_bitmap_layer_set_corner_clip_color(s_unary_hours_layer_right, GColorClear); rot_bitmap_set_compositing_mode(s_unary_hours_layer_right, GCompOpSet); rot_bitmap_layer_set_angle(s_unary_hours_layer_right, DEG_TO_TRIGANGLE(45)); //position the frame r = layer_get_frame((Layer *) s_unary_hours_layer_right); r.origin.x = width - 32 - PADDING; layer_set_frame((Layer *) s_unary_hours_layer_right, r); layer_add_child(window_get_root_layer(window), (Layer *) s_unary_hours_layer_right); //create the left minutes image s_ternary_minutes_bitmap = gbitmap_create_with_resource(RESOURCE_ID_IMAGE_30_TERNARY); s_ternary_minutes_layer_left = rot_bitmap_layer_create(s_ternary_minutes_bitmap); rot_bitmap_layer_set_corner_clip_color(s_ternary_minutes_layer_left, GColorClear); rot_bitmap_set_compositing_mode(s_ternary_minutes_layer_left, GCompOpSet); rot_bitmap_layer_set_angle(s_ternary_minutes_layer_left, DEG_TO_TRIGANGLE(45)); //position the frame r = layer_get_frame((Layer *) s_ternary_minutes_layer_left); r.origin.x = 2; r.origin.y = max_height - 32 - PADDING; layer_set_frame((Layer *) s_ternary_minutes_layer_left, r); layer_add_child(window_get_root_layer(window), (Layer *) s_ternary_minutes_layer_left); //create the right minutes image s_ternary_minutes_layer_right = rot_bitmap_layer_create(s_ternary_minutes_bitmap); rot_bitmap_layer_set_corner_clip_color(s_ternary_minutes_layer_right, GColorClear); rot_bitmap_set_compositing_mode(s_ternary_minutes_layer_right, GCompOpSet); rot_bitmap_layer_set_angle(s_ternary_minutes_layer_right, DEG_TO_TRIGANGLE(-45)); //position the frame r = layer_get_frame((Layer *) s_ternary_minutes_layer_right); r.origin.x = width - 32 - PADDING; r.origin.y = max_height - 32 - PADDING; layer_set_frame((Layer *) s_ternary_minutes_layer_right, r); layer_add_child(window_get_root_layer(window), (Layer *) s_ternary_minutes_layer_right); if (persist_read_int(KEY_BACKGROUND_COLOR)) { set_background_color(persist_read_int(KEY_BACKGROUND_COLOR)); } } static void window_unload(Window *window) { gbitmap_destroy(s_ternary_seconds_bitmap); bitmap_layer_destroy(s_ternary_seconds_layer); gbitmap_destroy(s_unary_hours_bitmap); rot_bitmap_layer_destroy(s_unary_hours_layer_left); rot_bitmap_layer_destroy(s_unary_hours_layer_right); gbitmap_destroy(s_ternary_minutes_bitmap); rot_bitmap_layer_destroy(s_ternary_minutes_layer_left); rot_bitmap_layer_destroy(s_ternary_minutes_layer_right); }
static void bg_update_proc(Layer *layer, GContext *ctx) { GRect bounds = layer_get_bounds(layer); GRect frame = grect_inset(bounds, GEdgeInsets(4 * INSET)); GRect inner_hour_frame = grect_inset(bounds, GEdgeInsets((4 * INSET) + 8)); GRect inner_minute_frame = grect_inset(bounds, GEdgeInsets((4 * INSET) + 6)); graphics_context_set_stroke_color(ctx, gcolor_hour_marks); graphics_context_set_stroke_width(ctx, 3); // Hours marks for(int i = 0; i < 12; i++) { int hour_angle = get_angle_for_hour(i); GPoint p0 = gpoint_from_polar(frame, GOvalScaleModeFitCircle, DEG_TO_TRIGANGLE(hour_angle)); GPoint p1 = gpoint_from_polar(inner_hour_frame, GOvalScaleModeFitCircle, DEG_TO_TRIGANGLE(hour_angle)); graphics_draw_line(ctx, p0, p1); } // Minute Marks graphics_context_set_stroke_color(ctx, gcolor_minute_marks); graphics_context_set_stroke_width(ctx, 1); for(int i = 0; i < 60; i++) { if (i % 5) { int minute_angle = get_angle_for_minute(i); GPoint p0 = gpoint_from_polar(frame, GOvalScaleModeFitCircle, DEG_TO_TRIGANGLE(minute_angle)); GPoint p1 = gpoint_from_polar(inner_minute_frame, GOvalScaleModeFitCircle, DEG_TO_TRIGANGLE(minute_angle)); graphics_draw_line(ctx, p0, p1); } } // numbers if (b_show_numbers) { graphics_context_set_text_color(ctx, gcolor_numbers); #ifdef PBL_RECT graphics_draw_text(ctx, "12", fonts_get_system_font(FONT_KEY_GOTHIC_24_BOLD), GRect(63, 18, 20, 20), GTextOverflowModeWordWrap, GTextAlignmentCenter, NULL); graphics_draw_text(ctx, "1", fonts_get_system_font(FONT_KEY_GOTHIC_24_BOLD), GRect(85, 23, 20, 20), GTextOverflowModeWordWrap, GTextAlignmentRight, NULL); graphics_draw_text(ctx, "2", fonts_get_system_font(FONT_KEY_GOTHIC_24_BOLD), GRect(104, 43, 20, 20), GTextOverflowModeWordWrap, GTextAlignmentRight, NULL); graphics_draw_text(ctx, "3", fonts_get_system_font(FONT_KEY_GOTHIC_24_BOLD), GRect(112, 68, 20, 20), GTextOverflowModeWordWrap, GTextAlignmentRight, NULL); graphics_draw_text(ctx, "4", fonts_get_system_font(FONT_KEY_GOTHIC_24_BOLD), GRect(104, 93, 20, 20), GTextOverflowModeWordWrap, GTextAlignmentRight, NULL); graphics_draw_text(ctx, "5", fonts_get_system_font(FONT_KEY_GOTHIC_24_BOLD), GRect(85, 110, 20, 20), GTextOverflowModeWordWrap, GTextAlignmentRight, NULL); graphics_draw_text(ctx, "6", fonts_get_system_font(FONT_KEY_GOTHIC_24_BOLD), GRect(62, 118, 20, 20), GTextOverflowModeWordWrap, GTextAlignmentCenter, NULL); graphics_draw_text(ctx, "7", fonts_get_system_font(FONT_KEY_GOTHIC_24_BOLD), GRect(39, 110, 20, 20), GTextOverflowModeWordWrap, GTextAlignmentLeft, NULL); graphics_draw_text(ctx, "8", fonts_get_system_font(FONT_KEY_GOTHIC_24_BOLD), GRect(20, 93, 20, 20), GTextOverflowModeWordWrap, GTextAlignmentLeft, NULL); graphics_draw_text(ctx, "9", fonts_get_system_font(FONT_KEY_GOTHIC_24_BOLD), GRect(14, 68, 20, 20), GTextOverflowModeWordWrap, GTextAlignmentLeft, NULL); graphics_draw_text(ctx, "10", fonts_get_system_font(FONT_KEY_GOTHIC_24_BOLD), GRect(20, 43, 20, 20), GTextOverflowModeWordWrap, GTextAlignmentLeft, NULL); graphics_draw_text(ctx, "11", fonts_get_system_font(FONT_KEY_GOTHIC_24_BOLD), GRect(39, 23, 20, 20), GTextOverflowModeWordWrap, GTextAlignmentLeft, NULL); #else graphics_draw_text(ctx, "12", fonts_get_system_font(FONT_KEY_GOTHIC_24_BOLD), GRect(80, 10, 20, 20), GTextOverflowModeWordWrap, GTextAlignmentCenter, NULL); graphics_draw_text(ctx, "1", fonts_get_system_font(FONT_KEY_GOTHIC_24_BOLD), GRect(107, 20, 20, 20), GTextOverflowModeWordWrap, GTextAlignmentRight, NULL); graphics_draw_text(ctx, "2", fonts_get_system_font(FONT_KEY_GOTHIC_24_BOLD), GRect(130, 43, 20, 20), GTextOverflowModeWordWrap, GTextAlignmentRight, NULL); graphics_draw_text(ctx, "3", fonts_get_system_font(FONT_KEY_GOTHIC_24_BOLD), GRect(140, 74, 20, 20), GTextOverflowModeWordWrap, GTextAlignmentRight, NULL); graphics_draw_text(ctx, "4", fonts_get_system_font(FONT_KEY_GOTHIC_24_BOLD), GRect(130, 106, 20, 20), GTextOverflowModeWordWrap, GTextAlignmentRight, NULL); graphics_draw_text(ctx, "5", fonts_get_system_font(FONT_KEY_GOTHIC_24_BOLD), GRect(107, 126, 20, 20), GTextOverflowModeWordWrap, GTextAlignmentRight, NULL); graphics_draw_text(ctx, "6", fonts_get_system_font(FONT_KEY_GOTHIC_24_BOLD), GRect(81, 136, 20, 20), GTextOverflowModeWordWrap, GTextAlignmentCenter, NULL); graphics_draw_text(ctx, "7", fonts_get_system_font(FONT_KEY_GOTHIC_24_BOLD), GRect(53, 124, 20, 20), GTextOverflowModeWordWrap, GTextAlignmentLeft, NULL); graphics_draw_text(ctx, "8", fonts_get_system_font(FONT_KEY_GOTHIC_24_BOLD), GRect(29, 106, 20, 20), GTextOverflowModeWordWrap, GTextAlignmentLeft, NULL); graphics_draw_text(ctx, "9", fonts_get_system_font(FONT_KEY_GOTHIC_24_BOLD), GRect(20, 74, 20, 20), GTextOverflowModeWordWrap, GTextAlignmentLeft, NULL); graphics_draw_text(ctx, "10", fonts_get_system_font(FONT_KEY_GOTHIC_24_BOLD), GRect(28, 42, 20, 20), GTextOverflowModeWordWrap, GTextAlignmentLeft, NULL); graphics_draw_text(ctx, "11", fonts_get_system_font(FONT_KEY_GOTHIC_24_BOLD), GRect(50, 22, 20, 20), GTextOverflowModeWordWrap, GTextAlignmentLeft, NULL); #endif } }