static void shape(GContext *ctx,uint16_t ang,int16_t ox,int16_t oy,int16_t mx,int16_t my,GPathInfo *gp,int func) { // draw 'shape' rotated to 'ang' and translated by 'ox' and 'oy' // use this instead of the library functions as they have shit precision GPoint *oldpoints=gp->points; gp->points=malloc(sizeof(GPoint)*gp->num_points); for(uint16_t i=0;i<gp->num_points;i++) { gp->points[i].x=((oldpoints[i].x*mx)>>FRACBITS)+ox; gp->points[i].y=((oldpoints[i].y*my)>>FRACBITS)+oy; rotate(ang,&gp->points[i]); gp->points[i].x=(gp->points[i].x>>FRACBITS)+CENTREX; gp->points[i].y=(gp->points[i].y>>FRACBITS)+CENTREY; } GPath *pptr=gpath_create(gp); switch(func) { case 0: // std filled in gpath_draw_outline(ctx,pptr); gpath_draw_filled(ctx,pptr); break; case 1: // open line draw #ifdef PBL_COLOR gpath_draw_outline_open(ctx,pptr); #else gpath_draw_outline(ctx,pptr); #endif break; } gpath_destroy(pptr); free(gp->points); gp->points=oldpoints; }
void battery_layer_update_callback(Layer *layer, GContext* ctx) { BatteryChargeState battery = battery_state_service_peek(); graphics_context_set_stroke_color(ctx, FG_COLOR); gpath_draw_outline(ctx, battery_path); int width = battery.charge_percent * 10 / 100; #ifdef PBL_BW graphics_context_set_fill_color(ctx, FG_COLOR); #else graphics_context_set_fill_color(ctx, battery.is_plugged ? (width < 3 ? GColorRed : GColorGreen) : FG_COLOR); #endif graphics_fill_rect(ctx, GRect(9, 2, width, 5), 0, GCornerNone); if (battery.is_plugged) gpath_draw_outline_open(ctx, charge_path); }
static void menuDrawRow(GContext *ctx, const Layer *cell_layer, MenuIndex *cell_index, void *callback_context) { if (cell_index->row >= activeListCount) return; GRect cell_bounds = layer_get_bounds(cell_layer); if (isRound) { // Add some padding so text is not clipped cell_bounds.origin.x += 6; cell_bounds.size.w -= 12; } if (activeList[cell_index->row].status == STATUS_BOUGHT) { graphics_context_set_stroke_width(ctx, 3); if (menu_cell_layer_is_highlighted(cell_layer)) { graphics_context_set_stroke_color(ctx, GColorWhite); } else { graphics_context_set_stroke_color(ctx, GColorBlack); } GPoint pt; pt.x = cell_bounds.origin.x + 2; pt.y = cell_bounds.size.h / 2 - 8; gpath_move_to(checkboxPath, pt); gpath_draw_outline_open(ctx, checkboxPath); cell_bounds.origin.x += 20; cell_bounds.size.w -= 20; } graphics_draw_text(ctx, activeList[cell_index->row].name, font, cell_bounds, GTextOverflowModeTrailingEllipsis, GTextAlignmentLeft, NULL); }
/* * Function: canvas_update_proc * ---------------------------------------------------------------------------- * Draws the mood graph on the screen. * * this_layer: the layer on which to draw on * ctx: the drawing context * ---------------------------------------------------------------------------- */ void canvas_update_proc(Layer *this_layer, GContext *ctx) { if (s_path) { gpath_destroy(s_path); } GRect bounds = layer_get_bounds(this_layer); int bounds_size_w = bounds.size.w; int bounds_size_h = bounds.size.h; GPathBuilder *builder = gpath_builder_create(MAX_POINTS); // Draw a black filled rectangle with sharp corners graphics_context_set_fill_color(ctx, GColorBlack); graphics_fill_rect(ctx, bounds, 0, GCornerNone); // Draw the mood lines graphics_context_set_fill_color(ctx, GColorWhite); // Draw the Mood (color) coding rectangles draw_mood_areas(ctx, bounds_size_w); #if PBL_PLATFORM_BASALT graphics_context_set_stroke_width(ctx, 1); #endif // Create the mood data graph create_graph(ctx, bounds_size_h, builder); // Set the graph line color to white graphics_context_set_stroke_color(ctx, GColorWhite); #ifdef PBL_PLATFORM_BASALT // On Pebble Time (Basalt) create path from builder s_path = gpath_builder_create_path(builder); #endif gpath_builder_destroy(builder); #ifdef PBL_PLATFORM_APLITE //gpath_draw_outline(ctx, s_path); #elif PBL_PLATFORM_BASALT gpath_draw_outline_open(ctx, s_path); #endif }
static void draw_bt(Layer* layer, GContext* ctx) { if (bluetooth_connection_service_peek()) { graphics_context_set_stroke_color(ctx, GColorWhite); gpath_draw_outline_open(ctx, s_bt_path); } }
static void graph_layer_update_proc(Layer *layer, GContext *ctx) { int orig_x = CIRCLE_RADIUS; int orig_y = graph_bounds.size.h - CIRCLE_RADIUS; events = current_history_batch * HISTORY_BATCH_SIZE + history[current_history_batch].last_event + 1; // APP_LOG(APP_LOG_LEVEL_DEBUG, "Total %d events in history", events); GRect bounds = layer_get_bounds(graph_layer); GRect frame = layer_get_frame(graph_layer); // APP_LOG(APP_LOG_LEVEL_DEBUG, "Bounds: %d, %d, %d, %d", bounds.origin.x, bounds.origin.y, bounds.size.w, bounds.size.h); // APP_LOG(APP_LOG_LEVEL_DEBUG, "Frame: %d, %d, %d, %d", frame.origin.x, frame.origin.y, frame.size.w, frame.size.h); // min_visible_x = bounds.origin.x GPoint points[events]; int b = 0; int e = 0; int num_points = 0; if (start_time == 0) { APP_LOG(APP_LOG_LEVEL_WARNING, "Invalid data in history, start time of first event is 0!"); return; } for (int i=0; i<events; i++) { if (e == HISTORY_BATCH_SIZE) { b++; e = 0; } if ((int) history[b].event_time[e] < start_time) { // should not happen APP_LOG(APP_LOG_LEVEL_WARNING, "Invalid event time %d (before start time %d)", (int) history[b].event_time[e], start_time); e++; continue; } int seconds = (int) (history[b].event_time[e] - start_time); int x = orig_x + seconds / seconds_per_pixel + CIRCLE_RADIUS; // APP_LOG(APP_LOG_LEVEL_DEBUG, "X is %d", x); int y = orig_y - history[b].mood[e] * PIXELS_PER_MOOD_LEVEL; points[num_points] = GPoint(x, y); if ((x+bounds.origin.x < (frame.origin.x-CIRCLE_RADIUS)) || (x+bounds.origin.x > (frame.size.w+CIRCLE_RADIUS))) { // APP_LOG(APP_LOG_LEVEL_DEBUG, "Not printing %d/%d: %d", e, b, x); // APP_LOG(APP_LOG_LEVEL_DEBUG, "%d is less than %d or greater than %d", x+bounds.origin.x, frame.origin.x-CIRCLE_RADIUS, frame.size.w+CIRCLE_RADIUS); e++; num_points++; continue; } else { // APP_LOG(APP_LOG_LEVEL_DEBUG, "Printing %d/%d: %d (%d)", e, b, x, history[b].mood[e]); graphics_context_set_fill_color(ctx, Mood_colors[history[b].mood[e]]); text_box = GRect(x-72, 0, 144, 20); int radius = CIRCLE_RADIUS; if ((b == selected.b) && (e == selected.e)) { radius += radius/2; graphics_context_set_text_color(ctx, GColorLightGray); struct tm *lt = localtime(&history[b].event_time[e]); strftime(timestr, sizeof(timestr), "%a %b %e %k:%M", lt); snprintf(event_text, sizeof(event_text), "%s\n%s", Moods[history[b].mood[e]], timestr); } // APP_LOG(APP_LOG_LEVEL_DEBUG, "Feeling %d at %d (%d/%d)", history[b].mood[e], (int) history[b].event_time[e], e, b); graphics_fill_circle(ctx, points[num_points], radius); if ((b == selected.b) && (e == selected.e)) { graphics_draw_text(ctx, event_text, text_font, text_box, GTextOverflowModeWordWrap, GTextAlignmentCenter, NULL); } num_points++; e++; } } // APP_LOG(APP_LOG_LEVEL_DEBUG, "%d points in line", num_points); /* for (int p=0; p<num_points; p++) { APP_LOG(APP_LOG_LEVEL_DEBUG, "point %d: %d, %d)", p, points[p].x, points[p].y); } */ GPathInfo line_info = { .num_points = num_points, .points = points }; line = gpath_create(&line_info); graphics_context_set_stroke_color(ctx, GColorLightGray); graphics_context_set_stroke_width(ctx, 3); gpath_draw_outline_open(ctx, line); }