static void prv_draw_menu_row(GContext *ctx, const Layer *cell_layer, MenuIndex *cell_index, void *callback_context) {
  char time_buf[6];
  char state_buf[13];
  char number_buf[4];
  TrainTrip trip;
  
  TrainTime *time = &s_times[cell_index->row];
  
  trip_get(time->trip, &trip);
  snprintf(number_buf, sizeof(number_buf), "%d", trip.trip_name);
  train_time_format_minutes(time->time, sizeof(time_buf), time_buf);
  train_time_format_state(time, sizeof(state_buf), state_buf);
  
  graphics_context_set_text_color(ctx, GColorBlack);
  graphics_draw_text(ctx, time_buf, fonts_get_system_font(FONT_KEY_BITHAM_34_MEDIUM_NUMBERS), GRect(0, -5, 114, 43), GTextOverflowModeFill, GTextAlignmentLeft, NULL);
  graphics_draw_text(ctx, number_buf, fonts_get_system_font(FONT_KEY_GOTHIC_24), GRect(114, -4, 27, 20), GTextOverflowModeFill, GTextAlignmentRight, NULL);
}
static void prv_draw_menu_row(GContext *ctx, const Layer *cell_layer, MenuIndex *cell_index, void *menu) {
  char time_buf[6];
  char state_buf[13];
  char number_buf[4];
  TrainTrip trip;
  
  TrainTime *time = &s_times[cell_index->row];
  
  trip_get(time->trip, &trip);
  snprintf(number_buf, sizeof(number_buf), "%d", trip.trip_name);
  train_time_format_minutes(time->time, sizeof(time_buf), time_buf);
  train_time_format_state(time, sizeof(state_buf), state_buf);
  
  menu_hack_set_colours(ctx, menu, cell_index);
  
  graphics_fill_rect(ctx, layer_get_bounds(cell_layer), 0, GCornerNone);
  graphics_draw_text(ctx, time_buf, fonts_get_system_font(FONT_KEY_BITHAM_34_MEDIUM_NUMBERS), GRect(0, -5, 114, 43), GTextOverflowModeFill, GTextAlignmentLeft, NULL);
  graphics_draw_text(ctx, number_buf, fonts_get_system_font(FONT_KEY_GOTHIC_24), GRect(114, -6, 27, 20), GTextOverflowModeFill, GTextAlignmentRight, NULL);
  
  #ifdef PBL_COLOR
    graphics_context_set_fill_color(ctx, trip_get_colour(&trip));
    graphics_fill_circle(ctx, GPoint(135, 26), 5);
  #endif
}
static void prv_draw_menu_row(GContext *ctx, const Layer *cell_layer, MenuIndex *cell_index, void *menu) {
  char time_buf[17];
  char minutes_buf[6];
  char zone_buf[7];
  TrainStop stop;
  
  TrainTime *time = &s_times[cell_index->row];
  
  stop_get(time->stop, &stop);
  snprintf(zone_buf, sizeof(zone_buf), "Zone %d", stop.zone);
  train_time_format_minutes(time->time, sizeof(minutes_buf), minutes_buf);
  int16_t time_diff = time->time - s_times[s_index].time;
  if(time_diff > 0) {
    snprintf(time_buf, sizeof(time_buf), "%s (%d min)", minutes_buf, time_diff);
  } else {
    strncpy(time_buf, minutes_buf, sizeof(time_buf));
  }
  
  menu_hack_set_colours(ctx, menu, cell_index);
  
  graphics_fill_rect(ctx, layer_get_bounds(cell_layer), 0, GCornerNone);
  
  graphics_draw_text(ctx, stop.name, fonts_get_system_font(FONT_KEY_GOTHIC_24_BOLD), GRect(13, -7, 131, 29), GTextOverflowModeFill, GTextAlignmentLeft, NULL);
  graphics_draw_text(ctx, zone_buf, fonts_get_system_font(FONT_KEY_GOTHIC_18), GRect(14, 16, 129, 20), GTextOverflowModeFill, GTextAlignmentLeft, NULL);
  graphics_draw_text(ctx, time_buf, fonts_get_system_font(FONT_KEY_GOTHIC_18), GRect(14, 16, 129, 20), GTextOverflowModeFill, GTextAlignmentRight, NULL);
  
  // Draw in map thing in the left margin.
  const bool is_start = (cell_index->row == 0);
  const bool is_end = (cell_index->row == s_time_count - 1);
  graphics_context_set_fill_color(ctx, COLOUR_ROUTE_FILLED);
  graphics_context_set_stroke_color(ctx, COLOUR_ROUTE_OUTLINE);
  if(time->sequence < s_sequence) { // Empty section because the train has already gone past here.
    int16_t top = -1;
    int16_t bottom = 41;
    // Avoid drawing past either end.
    if(is_start) {
      top = 20;
    } else if(is_end) {
      bottom = 20;
    }
    graphics_context_set_fill_color(ctx, COLOUR_ROUTE_EMPTY);
    graphics_fill_rect(ctx, GRect(3, top, 7, bottom - top), 0, GCornerNone);
    graphics_draw_rect(ctx, GRect(3, top, 7, bottom - top));
    graphics_fill_circle(ctx, GPoint(6, 20), 6); // Fill white and draw black outline to avoid intersecting tracks.
    graphics_draw_circle(ctx, GPoint(6, 20), 6);
  } else if(time->sequence > s_sequence) { // Filled section; we haven't gone here yet.
    GRect rect = GRect(3, -1, 7, 41);
    // Avoid drawing past either end.
    if(is_end) {
      rect.size.h = 21;
    } else if(is_start) {
      rect.size.h = 21;
      rect.origin.y = 20;
    }
    graphics_fill_rect(ctx, rect, 0, GCornerNone);
    graphics_fill_circle(ctx, GPoint(6, 20), 6);
  } else { // Half-filled; we're here, and heading in one direction.
           // Which direction we fill depends on which direction we're going in.
    if(!is_start) {
      if(s_trip.direction == TrainDirectionSouthbound) {
        graphics_context_set_fill_color(ctx, COLOUR_ROUTE_EMPTY);
      } else {
        graphics_context_set_fill_color(ctx, COLOUR_ROUTE_FILLED);
      }
      graphics_fill_rect(ctx, GRect(3, -1, 7, 21), 0, GCornerNone);
      graphics_draw_rect(ctx, GRect(3, -1, 7, 21));
    }
    if(!is_end) {
      if(s_trip.direction == TrainDirectionSouthbound) {
        graphics_context_set_fill_color(ctx, COLOUR_ROUTE_FILLED);
      } else {
        graphics_context_set_fill_color(ctx, COLOUR_ROUTE_EMPTY);
      }
      graphics_fill_rect(ctx, GRect(3, 20, 7, 21), 0, GCornerNone);
      graphics_draw_rect(ctx, GRect(3, -1, 7, 21));
    }
    graphics_context_set_fill_color(ctx, COLOUR_ROUTE_FILLED);
    graphics_fill_circle(ctx, GPoint(6, 20), 6);
    graphics_draw_circle(ctx, GPoint(6, 20), 6);
  }
}