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);
  }
}
示例#2
0
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);
        }
    }
}