static void prv_goal_reached_sequence_layer_update_proc(Layer *layer, GContext *ctx) { GoalStarGoalEventWindowData *data = window_get_user_data(layer_get_window(layer)); const GRect layer_bounds = layer_get_bounds(layer); GRect sequence_frame = (GRect) { .size = gdraw_command_sequence_get_bounds_size(data->goal_reached_sequence), }; grect_align(&sequence_frame, &layer_bounds, GAlignCenter, true /* clip */); sequence_frame.origin.y -= sequence_frame.origin.y / 4; GDrawCommandFrame *frame = gdraw_command_sequence_get_frame_by_index( data->goal_reached_sequence, data->goal_reached_sequence_frame_index); if (frame) { gdraw_command_frame_draw(ctx, data->goal_reached_sequence, frame, sequence_frame.origin); } const uint32_t num_frames = gdraw_command_sequence_get_num_frames(data->goal_reached_sequence); if (++data->goal_reached_sequence_frame_index >= num_frames) { app_timer_cancel(data->goal_reached_sequence_timer); const uint32_t timeout_ms = goal_star_configuration_get_goal_event_timeout_ms(); if (timeout_ms) { data->goal_reached_sequence_timer = app_timer_register(timeout_ms, prv_goal_reached_wait_timer_handler, data); } } char text[GOAL_STAR_CONFIGURATION_STRING_BUFFER_LENGTH] = {0}; goal_star_configuration_get_goal_summary_string(text); graphics_context_set_text_color(ctx, GColorBlack); const GFont font = fonts_get_system_font(FONT_KEY_GOTHIC_24_BOLD); const int16_t font_height = 24; const GRect text_frame = GRect(0, sequence_frame.origin.y + sequence_frame.size.h, layer_bounds.size.w, font_height); graphics_draw_text(ctx, text, font, text_frame, GTextOverflowModeTrailingEllipsis, GTextAlignmentCenter, NULL); } static void prv_goal_reached_sequence_timer_handler(void *context) { GoalStarGoalEventWindowData *data = context; if (data) { layer_mark_dirty(data->goal_reached_sequence_layer); data->goal_reached_sequence_timer = app_timer_register(ANIMATION_FRAME_INTERVAL_MS, prv_goal_reached_sequence_timer_handler, data); } }
void calendar_single_draw(Layer* layer, GContext* context, int16_t offset) { // Get the current date RootData* data = window_get_user_data(layer_get_window(layer)); time_t t = data->curTime; struct tm* localTime = localtime(&t); char month[20]; strftime(month, 20, "%B %Y", localTime); if(data->days_in_use_valid.month != (unsigned int)localTime->tm_mon+1 || data->days_in_use_valid.year != (unsigned int)(localTime->tm_year + 1900)) { APP_LOG(APP_LOG_LEVEL_INFO, "Requesting new data. %d %d -> %d %d", data->days_in_use_valid.month, data->days_in_use_valid.year, localTime->tm_mon, localTime->tm_year); int rv = 0; rv = devinterface_get_days_used(localTime->tm_mon, localTime->tm_year, daysused_returned, data); if(rv != DEV_STAT_OK) APP_LOG(APP_LOG_LEVEL_WARNING, "devinterface_get_days_used failed %d", rv); } // Get the first day of the month (Mon-Sun) // Get the current day and day of week int curDay = localTime->tm_mday; int dow = localTime->tm_wday; // What's the offset into dow? // Ignoring weeks, this will give us the number of days // since the first of the month int curDowOffset = (curDay - 1 + WEEK_START_OFFSET) % 7; // We then subtract that from the current day of the week // which will yield the dow of the first day of the month. dow -= curDowOffset; if(dow < 0) dow += 7; // Get the number of days to draw int days_month = days_in_month(localTime->tm_mon + 1, localTime->tm_year + 1900); // How many weeks do we need to show? // How many days are there, including the leadin? int totalSlots = (days_month + dow); int lines = totalSlots / 7; // I'm not resorting to the FPU. Check if it had a fractional part if(lines * 7 != totalSlots) lines++; // Create the bounding box for the period GRect contextBound = layer_get_frame(layer); GRect textBounding = contextBound; textBounding.origin.y += offset + MONTHPANE_Y_OFFSET; textBounding.size.h = MONTHPANE_HEIGHT; // Put up the current period graphics_draw_text(context, month, fonts_get_system_font(FONT_KEY_GOTHIC_18_BOLD), textBounding, GTextOverflowModeTrailingEllipsis, GTextAlignmentCenter, NULL); // Compute the height of the calendar box int calHeight = contextBound.size.h - CALENDARPANE_TOP - CALENDARPANE_Y_MARGIN; int calWidth = contextBound.size.w - (CALENDARPANE_X_MARGIN*2); // Draw the calendar box // Top line graphics_draw_line(context, (GPoint){CALENDARPANE_X_MARGIN, CALENDARPANE_TOP + offset}, (GPoint){CALENDARPANE_X_MARGIN + calWidth, CALENDARPANE_TOP + offset}); // Bottom line graphics_draw_line(context, (GPoint){CALENDARPANE_X_MARGIN, CALENDARPANE_TOP + calHeight + offset}, (GPoint){CALENDARPANE_X_MARGIN + calWidth, CALENDARPANE_TOP + calHeight + offset}); // Left line graphics_draw_line(context, (GPoint){CALENDARPANE_X_MARGIN, CALENDARPANE_TOP + offset}, (GPoint){CALENDARPANE_X_MARGIN, CALENDARPANE_TOP + offset + calHeight}); // Right line graphics_draw_line(context, (GPoint){CALENDARPANE_X_MARGIN + calWidth, CALENDARPANE_TOP + offset}, (GPoint){CALENDARPANE_X_MARGIN + calWidth, CALENDARPANE_TOP + offset + calHeight}); // And now the vertical subdivisions. There needs to be 7. int vertSubDiv = calWidth / 7; for(int i = 1; i < 7; i++) { graphics_draw_line(context, (GPoint){CALENDARPANE_X_MARGIN + vertSubDiv*i, CALENDARPANE_TOP + offset}, (GPoint){CALENDARPANE_X_MARGIN + vertSubDiv*i, CALENDARPANE_TOP + offset + calHeight}); } // And now the horizontal subdivisions. int horizSubDiv = calHeight / lines; for(int i = 1; i < lines; i++) { graphics_draw_line(context, (GPoint){CALENDARPANE_X_MARGIN, CALENDARPANE_TOP + offset + horizSubDiv*i}, (GPoint){CALENDARPANE_X_MARGIN + calWidth, CALENDARPANE_TOP + offset + horizSubDiv*i}); } // Now draw the days for(int day = 1; day <= days_month; day++) { int x = (day-1+dow) % 7; int y = (day-1+dow) / 7; char dayStr[3]; snprintf(dayStr, 3, "%d", day); // Is this the current day? if(day == localTime->tm_mday) { // Paint it white GRect dayRectFill; dayRectFill.origin.x = (x * vertSubDiv) + CALENDARPANE_X_MARGIN; dayRectFill.origin.y = (y * horizSubDiv) + CALENDARPANE_TOP + offset; dayRectFill.size.h = horizSubDiv; dayRectFill.size.w = vertSubDiv; graphics_context_set_fill_color(context, GColorWhite); graphics_context_set_text_color(context, GColorBlack); graphics_fill_rect(context, dayRectFill, 0, GCornerNone); } GRect dayRect; dayRect.origin.x = (x * vertSubDiv) + CALENDARPANE_X_MARGIN + CALENDARPANE_NUMBER_X_PAD; dayRect.origin.y = (y * horizSubDiv) + CALENDARPANE_TOP + offset; dayRect.size.h = horizSubDiv; dayRect.size.w = vertSubDiv; if(data->days_in_use_valid.month == (unsigned int)localTime->tm_mon+1 && data->days_in_use_valid.year == (unsigned int)(localTime->tm_year + 1900)) { if(data->days_in_use & (1 << (day - 1))) graphics_draw_text(context, dayStr, fonts_get_system_font(FONT_KEY_GOTHIC_14_BOLD), dayRect, GTextOverflowModeTrailingEllipsis, GTextAlignmentLeft, NULL); else graphics_draw_text(context, dayStr, fonts_get_system_font(FONT_KEY_GOTHIC_14), dayRect, GTextOverflowModeTrailingEllipsis, GTextAlignmentLeft, NULL); } else { graphics_draw_text(context, dayStr, fonts_get_system_font(FONT_KEY_GOTHIC_14), dayRect, GTextOverflowModeTrailingEllipsis, GTextAlignmentLeft, NULL); } if(day == localTime->tm_mday) { graphics_context_set_fill_color(context, GColorBlack); graphics_context_set_text_color(context, GColorWhite); } } }