예제 #1
0
void
PlaneListWidget::OnPaintItem(Canvas &canvas, const PixelRect rc, unsigned i)
{
  assert(i < list.size());

  const DialogLook &look = UIGlobals::GetDialogLook();
  const Font &name_font = *look.list.font_bold;
  const Font &details_font = *look.small_font;

  canvas.Select(name_font);

  if (Profile::GetPathIsEqual("PlanePath", list[i].path)) {
    StaticString<256> buffer;
    buffer.Format(_T("%s - %s"), list[i].name.c_str(), _("Active"));
    canvas.DrawClippedText(rc.left + Layout::GetTextPadding(),
                           rc.top + Layout::GetTextPadding(), rc, buffer);
  } else
    canvas.DrawClippedText(rc.left + Layout::GetTextPadding(),
                           rc.top + Layout::GetTextPadding(), rc, list[i].name);

  canvas.Select(details_font);

  canvas.DrawClippedText(rc.left + Layout::GetTextPadding(),
                         rc.top + name_font.GetHeight() + Layout::FastScale(4),
                         rc, list[i].path);
}
예제 #2
0
void
MapItemListRenderer::Draw(Canvas &canvas, const PixelRect rc,
                          const MarkerMapItem &item,
                          const DialogLook &dialog_look,
                          const MarkerLook &look)
{
  const PixelScalar line_height = rc.bottom - rc.top;

  const Marker &marker = item.marker;

  const RasterPoint pt(rc.left + line_height / 2,
                       rc.top + line_height / 2);

  look.icon.Draw(canvas, pt);

  const Font &name_font = *dialog_look.list.font_bold;
  const Font &small_font = *dialog_look.small_font;

  PixelScalar left = rc.left + line_height + Layout::FastScale(2);

  StaticString<256> buffer;
  buffer.Format(_T("%s #%d"), _("Marker"), item.id + 1);
  canvas.Select(name_font);
  canvas.DrawClippedText(left, rc.top + Layout::FastScale(2), rc, buffer);

  TCHAR time_buffer[32], timespan_buffer[32];
  FormatSignedTimeHHMM(time_buffer, TimeLocal(marker.time.GetSecondOfDay()));
  FormatTimespanSmart(timespan_buffer, BrokenDateTime::NowUTC() - marker.time);
  buffer.Format(_("dropped %s ago"), timespan_buffer);
  buffer.AppendFormat(_T(" (%s)"), time_buffer);
  canvas.Select(small_font);
  canvas.DrawClippedText(left,
                         rc.top + name_font.GetHeight() + Layout::FastScale(4),
                         rc, buffer);
}
예제 #3
0
void
MapItemListRenderer::Draw(Canvas &canvas, const PixelRect rc,
                          const SelfMapItem &item,
                          const DialogLook &dialog_look,
                          const AircraftLook &look,
                          const MapSettings &settings)
{
  const PixelScalar line_height = rc.bottom - rc.top;

  const Font &name_font = *dialog_look.list.font_bold;
  const Font &small_font = *dialog_look.small_font;

  PixelScalar left = rc.left + line_height + Layout::FastScale(2);
  canvas.Select(name_font);
  canvas.DrawClippedText(left, rc.top + Layout::FastScale(2), rc,
                         _("Your Position"));

  TCHAR buffer[128];
  FormatGeoPoint(item.location, buffer, 128);

  canvas.Select(small_font);
  canvas.DrawClippedText(left,
                         rc.top + name_font.GetHeight() + Layout::FastScale(4),
                         rc, buffer);

  RasterPoint pt = { (PixelScalar)(rc.left + line_height / 2),
                     (PixelScalar)(rc.top + line_height / 2) };
  AircraftRenderer::Draw(canvas, settings, look, item.bearing, pt);
}
예제 #4
0
void
WaypointListRenderer::Draw(Canvas &canvas, const PixelRect rc,
                           const Waypoint &waypoint, fixed distance,
                           fixed arrival_altitude,
                           const DialogLook &dialog_look,
                           const WaypointLook &look,
                           const WaypointRendererSettings &settings)
{
  const PixelScalar line_height = rc.bottom - rc.top;

  const Font &name_font = *dialog_look.list.font_bold;
  const Font &small_font = *dialog_look.small_font;

  // Y-Coordinate of the second row
  PixelScalar top2 = rc.top + name_font.GetHeight() + Layout::FastScale(4);

  // Use small font for details
  canvas.Select(small_font);

  // Draw distance and arrival altitude
  StaticString<256> buffer;
  TCHAR dist[20], alt[20], radio[20];
  FormatUserDistanceSmart(distance, dist, true);
  FormatRelativeUserAltitude(arrival_altitude, alt, true);
  buffer.Format(_T("%s: %s - %s: %s"), _("Distance"), dist,
                _("Arrival Alt"), alt);

  if (waypoint.radio_frequency.IsDefined()) {
    waypoint.radio_frequency.Format(radio, ARRAY_SIZE(radio));
    buffer.AppendFormat(_T(" - %s MHz"), radio);
  }

  UPixelScalar left = rc.left + line_height + Layout::FastScale(2);
  canvas.DrawClippedText(left, top2, rc, buffer);

  // Draw waypoint name
  canvas.Select(name_font);
  canvas.DrawClippedText(left, rc.top + Layout::FastScale(2), rc,
                         waypoint.name.c_str());

  // Draw icon
  const RasterPoint pt(rc.left + line_height / 2,
                       rc.top + line_height / 2);

  WaypointIconRenderer::Reachability reachable =
      positive(arrival_altitude) ?
      WaypointIconRenderer::ReachableTerrain : WaypointIconRenderer::Unreachable;

  WaypointIconRenderer wir(settings, look, canvas);
  wir.Draw(waypoint, pt, reachable);
}
예제 #5
0
void
TwoTextRowsRenderer::DrawSecondRow(Canvas &canvas, const PixelRect &rc,
                                   const TCHAR *text) const
{
  canvas.Select(*second_font);
  canvas.DrawClippedText(rc.left + x, rc.top + second_y, rc, text);
}
예제 #6
0
void
MapItemListRenderer::Draw(Canvas &canvas, const PixelRect rc,
                          const TaskOZMapItem &item,
                          const DialogLook &dialog_look,
                          const TaskLook &look, const AirspaceLook &airspace_look,
                          const AirspaceRendererSettings &airspace_settings)
{
  const PixelScalar line_height = rc.bottom - rc.top;

  const ObservationZonePoint &oz = *item.oz;
  const Waypoint &waypoint = item.waypoint;

  const Font &name_font = *dialog_look.list.font_bold;
  const Font &small_font = *dialog_look.small_font;

  TCHAR buffer[256];

  // Y-Coordinate of the second row
  UPixelScalar top2 = rc.top + name_font.GetHeight() + Layout::FastScale(4);

  // Use small font for details
  canvas.Select(small_font);

  // Draw details line
  UPixelScalar left = rc.left + line_height + Layout::FastScale(2);
  OrderedTaskPointRadiusLabel(*item.oz, buffer);
  if (!StringIsEmpty(buffer))
    canvas.DrawClippedText(left, top2, rc.right - left, buffer);

  // Draw waypoint name
  canvas.Select(name_font);
  OrderedTaskPointLabel(item.tp_type, waypoint.name.c_str(),
                        item.index, buffer);
  canvas.DrawClippedText(left, rc.top + Layout::FastScale(2),
                         rc.right - left, buffer);

  const RasterPoint pt(rc.left + line_height / 2,
                       rc.top + line_height / 2);
  PixelScalar radius = std::min(PixelScalar(line_height / 2
                                            - Layout::FastScale(4)),
                                Layout::FastScale(10));
  OZPreviewRenderer::Draw(canvas, oz, pt, radius, look,
                          airspace_settings, airspace_look);

}
예제 #7
0
void
TextRowRenderer::DrawTextRow(Canvas &canvas, const PixelRect &rc,
                             const TCHAR *text) const
{
    canvas.DrawClippedText(rc.left + left_padding,
                           rc.top + top_padding,
                           rc,
                           text);
}
예제 #8
0
void
MapItemListRenderer::Draw(Canvas &canvas, const PixelRect rc,
                          const ThermalMapItem &item,
                          const DialogLook &dialog_look,
                          const MapLook &look)
{
  const PixelScalar line_height = rc.bottom - rc.top;

  const ThermalSource &thermal = item.thermal;

  const RasterPoint pt(rc.left + line_height / 2,
                       rc.top + line_height / 2);

  look.thermal_source_icon.Draw(canvas, pt);

  const Font &name_font = *dialog_look.list.font_bold;
  const Font &small_font = *dialog_look.small_font;

  PixelScalar left = rc.left + line_height + Layout::FastScale(2);

  canvas.Select(name_font);
  canvas.DrawClippedText(left, rc.top + Layout::FastScale(2),
                         rc, _("Thermal"));

  StaticString<256> buffer;
  TCHAR lift_buffer[32], time_buffer[32], timespan_buffer[32];
  FormatUserVerticalSpeed(thermal.lift_rate, lift_buffer, 32);
  FormatSignedTimeHHMM(time_buffer, TimeLocal((int)thermal.time));

  int timespan = BrokenDateTime::NowUTC().GetSecondOfDay() - (int)thermal.time;
  if (timespan < 0)
    timespan += 24 * 60 * 60;

  FormatTimespanSmart(timespan_buffer, timespan);

  buffer.Format(_T("%s: %s"), _("Avg. lift"), lift_buffer);
  buffer.append(_T(" - "));
  buffer.AppendFormat(_("left %s ago"), timespan_buffer);
  buffer.AppendFormat(_T(" (%s)"), time_buffer);
  canvas.Select(small_font);
  canvas.DrawClippedText(left,
                         rc.top + name_font.GetHeight() + Layout::FastScale(4),
                         rc, buffer);
}
예제 #9
0
void
MapItemListRenderer::Draw(Canvas &canvas, const PixelRect rc,
                          const LocationMapItem &item,
                          const DialogLook &dialog_look)
{
  const Font &name_font = *dialog_look.list.font_bold;
  const Font &small_font = *dialog_look.small_font;

  PixelScalar left = rc.left + Layout::FastScale(2);

  TCHAR info_buffer[256], distance_buffer[32], direction_buffer[32];
  if (item.vector.IsValid()) {
    FormatUserDistanceSmart(item.vector.distance, distance_buffer, 32);
    FormatBearing(direction_buffer, ARRAY_SIZE(direction_buffer),
                  item.vector.bearing);
    _stprintf(info_buffer, _T("%s: %s, %s: %s"),
              _("Distance"), distance_buffer,
              _("Direction"), direction_buffer);
  } else {
    _stprintf(info_buffer, _T("%s: %s, %s: %s"),
              _("Distance"), _T("???"), _("Direction"), _T("???"));
  }

  canvas.Select(name_font);

  canvas.DrawClippedText(left, rc.top + Layout::FastScale(2), rc, info_buffer);


  TCHAR elevation_buffer[32];
  if (!RasterBuffer::IsSpecial(item.elevation)) {
    FormatUserAltitude(fixed(item.elevation), elevation_buffer, 32);
    _stprintf(info_buffer, _T("%s: %s"), _("Elevation"), elevation_buffer);
  } else {
    _stprintf(info_buffer, _T("%s: %s"), _("Elevation"), _T("???"));
  }

  canvas.Select(small_font);
  canvas.DrawClippedText(left,
                         rc.top + name_font.GetHeight() + Layout::FastScale(4),
                         rc, info_buffer);
}
예제 #10
0
void
ProfileListWidget::OnPaintItem(Canvas &canvas, const PixelRect rc, unsigned i)
{
  assert(i < list.size());

  const DialogLook &look = UIGlobals::GetDialogLook();
  const Font &name_font = *look.list.font;

  canvas.Select(name_font);

  canvas.DrawClippedText(rc.left + Layout::GetTextPadding(),
                         rc.top + Layout::GetTextPadding(), rc, list[i].name);
}
예제 #11
0
void
AirspaceSettingsListWidget::OnPaintItem(Canvas &canvas, const PixelRect rc,
                                         unsigned i)
{
  assert(i < AIRSPACECLASSCOUNT);

  const AirspaceComputerSettings &computer =
    CommonInterface::GetComputerSettings().airspace;
  const AirspaceRendererSettings &renderer =
    CommonInterface::GetMapSettings().airspace;
  const AirspaceLook &look = CommonInterface::main_window->GetLook().map.airspace;

  PixelScalar w0 = rc.right - rc.left - Layout::FastScale(4);

  PixelScalar w1 = canvas.CalcTextWidth(_("Warn")) + Layout::FastScale(10);
  PixelScalar w2 = canvas.CalcTextWidth(_("Display")) + Layout::FastScale(10);
  PixelScalar x0 = w0 - w1 - w2;

  const unsigned padding = Layout::GetTextPadding();

  if (color_mode) {
    if (AirspacePreviewRenderer::PrepareFill(
        canvas, (AirspaceClass)i, look, renderer)) {
      canvas.Rectangle(rc.left + x0, rc.top + padding,
                       rc.right - padding,
                       rc.bottom - padding);
      AirspacePreviewRenderer::UnprepareFill(canvas);
    }
    if (AirspacePreviewRenderer::PrepareOutline(
        canvas, (AirspaceClass)i, look, renderer)) {
      canvas.Rectangle(rc.left + x0, rc.top + padding,
                       rc.right - padding,
                       rc.bottom - padding);
    }
  } else {
    if (computer.warnings.class_warnings[i])
      canvas.DrawText(rc.left + w0 - w1 - w2, rc.top + padding,
                      _("Warn"));

    if (renderer.classes[i].display)
      canvas.DrawText(rc.left + w0 - w2, rc.top + padding,
                      _("Display"));
  }

  canvas.DrawClippedText(rc.left + padding,
                         rc.top + padding,
                         x0 - Layout::FastScale(10),
                         AirspaceFormatter::GetClass((AirspaceClass)i));
}
예제 #12
0
void
TaskEditPanel::OnPaintItem(Canvas &canvas, const PixelRect rc,
                           unsigned DrawListIndex)
{
  assert(DrawListIndex <= ordered_task->TaskSize());

  const PixelScalar line_height = rc.bottom - rc.top;

  TCHAR buffer[120];

  const Font &name_font = *dialog.GetLook().list.font_bold;
  const Font &small_font = *dialog.GetLook().small_font;

  // Draw "Add turnpoint" label
  if (DrawListIndex == ordered_task->TaskSize()) {
    canvas.Select(name_font);
    canvas.SetTextColor(COLOR_BLACK);
    _stprintf(buffer, _T("  (%s)"), _("Add Turnpoint"));
    canvas.DrawText(rc.left + line_height + Layout::FastScale(2),
                    rc.top + line_height / 2 - name_font.GetHeight() / 2,
                    buffer);
    return;
  }

  const OrderedTaskPoint &tp = ordered_task->GetTaskPoint(DrawListIndex);
  GeoVector leg = tp.GetNominalLegVector();
  bool show_leg_info = leg.distance > fixed(0.01);

  // Draw icon
  const RasterPoint pt(rc.left + line_height / 2,
                       rc.top + line_height / 2);

  PixelScalar radius = std::min(PixelScalar(line_height / 2
                                            - Layout::FastScale(4)),
                                Layout::FastScale(10));

  OZPreviewRenderer::Draw(canvas, tp.GetObservationZone(),
                          pt, radius, task_look,
                          CommonInterface::GetMapSettings().airspace,
                          airspace_look);

  // Y-Coordinate of the second row
  PixelScalar top2 = rc.top + name_font.GetHeight() + Layout::FastScale(4);

  // Use small font for details
  canvas.Select(small_font);
  canvas.SetTextColor(COLOR_BLACK);

  UPixelScalar leg_info_width = 0;
  if (show_leg_info) {
    // Draw leg distance
    FormatUserDistanceSmart(leg.distance, buffer, true);
    UPixelScalar width = leg_info_width = canvas.CalcTextWidth(buffer);
    canvas.DrawText(rc.right - Layout::FastScale(2) - width,
                    rc.top + Layout::FastScale(2) +
                    (name_font.GetHeight() - small_font.GetHeight()) / 2,
                    buffer);

    // Draw leg bearing
    FormatBearing(buffer, ARRAY_SIZE(buffer), leg.bearing);
    width = canvas.CalcTextWidth(buffer);
    canvas.DrawText(rc.right - Layout::FastScale(2) - width, top2, buffer);

    if (width > leg_info_width)
      leg_info_width = width;

    leg_info_width += Layout::FastScale(2);
  }

  // Draw details line
  PixelScalar left = rc.left + line_height + Layout::FastScale(2);
  OrderedTaskPointRadiusLabel(tp.GetObservationZone(), buffer);
  if (!StringIsEmpty(buffer))
    canvas.DrawClippedText(left, top2, rc.right - leg_info_width - left,
                           buffer);

  // Draw turnpoint name
  canvas.Select(name_font);
  OrderedTaskPointLabel(tp.GetType(), tp.GetWaypoint().name.c_str(),
                        DrawListIndex, buffer);
  canvas.DrawClippedText(left, rc.top + Layout::FastScale(2),
                         rc.right - leg_info_width - left, buffer);
}
예제 #13
0
void
AirspaceWarningListHandler::OnPaintItem(Canvas &canvas,
                                        const PixelRect paint_rc, unsigned i)
{
  TCHAR buffer[128];

  // This constant defines the margin that should be respected
  // for renderring within the paint_rc area.
  const int padding = 2;

  if (i == 0 && warning_list.empty()) {
    /* the warnings were emptied between the opening of the dialog and
       this refresh, so only need to display "No Warnings" for top
       item, otherwise exit immediately */
    canvas.DrawText(paint_rc.left + Layout::Scale(padding),
                    paint_rc.top + Layout::Scale(padding), _("No Warnings"));
    return;
  }

  assert(i < warning_list.size());

  const WarningItem &warning = warning_list[i];
  const AbstractAirspace &airspace = *warning.airspace;
  const AirspaceInterceptSolution &solution = warning.solution;

  const UPixelScalar text_height = 12, text_top = 1;

  // word "inside" is used as the etalon, because it is longer than "near" and
  // currently (9.4.2011) there is no other possibility for the status text.
  const int status_width = canvas.CalcTextWidth(_T("inside"));
  // "1888" is used in order to have enough space for 4-digit heights with "AGL"
  const int altitude_width = canvas.CalcTextWidth(_T("1888 m AGL"));

  // Dynamic columns scaling - "name" column is flexible, altitude and state
  // columns are fixed-width.
  const PixelScalar left0 = Layout::FastScale(padding),
    left2 = paint_rc.right - Layout::FastScale(padding) - (status_width + 2 * Layout::FastScale(padding)),
    left1 = left2 - Layout::FastScale(padding) - altitude_width;

  PixelRect rc_text_clip = paint_rc;
  rc_text_clip.right = left1 - Layout::FastScale(padding);

  if (!warning.ack_expired)
    canvas.SetTextColor(COLOR_GRAY);

  { // name, altitude info
    _sntprintf(buffer, 21, _T("%s %s"),
               airspace.GetName(),
               AirspaceFormatter::GetClass(airspace));

    canvas.DrawClippedText(paint_rc.left + left0,
                           paint_rc.top + Layout::Scale(text_top),
                           rc_text_clip, buffer);

    AirspaceFormatter::FormatAltitudeShort(buffer, airspace.GetTop());
    canvas.DrawText(paint_rc.left + left1,
                    paint_rc.top + Layout::Scale(text_top), buffer);

    AirspaceFormatter::FormatAltitudeShort(buffer, airspace.GetBase());
    canvas.DrawText(paint_rc.left + left1,
                    paint_rc.top + Layout::Scale(text_top + text_height),
                    buffer);
  }

  if (warning.state != AirspaceWarning::WARNING_INSIDE &&
      warning.state > AirspaceWarning::WARNING_CLEAR &&
      solution.IsValid()) {

    _stprintf(buffer, _T("%d secs"),
              (int)solution.elapsed_time);

    if (positive(solution.distance))
      _stprintf(buffer + _tcslen(buffer), _T(" dist %d m"),
                (int)solution.distance);
    else {
      /* the airspace is right above or below us - show the vertical
         distance */
      _tcscat(buffer, _T(" vertical "));

      fixed delta = solution.altitude - CommonInterface::Basic().nav_altitude;
      FormatRelativeUserAltitude(delta, buffer + _tcslen(buffer), true);
    }

    canvas.DrawClippedText(paint_rc.left + left0,
                           paint_rc.top + Layout::Scale(text_top + text_height),
                           rc_text_clip, buffer);
  }

  /* draw the warning state indicator */

  Color state_color;
  const TCHAR *state_text;

  if (warning.state == AirspaceWarning::WARNING_INSIDE) {
    state_color = warning.ack_expired ? inside_color : inside_ack_color;
    state_text = _T("inside");
  } else if (warning.state > AirspaceWarning::WARNING_CLEAR) {
    state_color = warning.ack_expired ? near_color : near_ack_color;
    state_text = _T("near");
  } else {
    state_color = COLOR_WHITE;
    state_text = NULL;
  }

  const PixelSize state_text_size =
    canvas.CalcTextSize(state_text != NULL ? state_text : _T("W"));

  if (state_color != COLOR_WHITE) {
    /* colored background */
    PixelRect rc;

    rc.left = paint_rc.left + left2;
    rc.top = paint_rc.top + Layout::FastScale(padding);
    rc.right = paint_rc.right - Layout::FastScale(padding);
    rc.bottom = paint_rc.bottom - Layout::FastScale(padding);

    canvas.DrawFilledRectangle(rc, state_color);

    /* on this background we just painted, we must use black color for
       the state text; our caller might have selected a different
       color, override it here */
    canvas.SetTextColor(COLOR_BLACK);
  }

  if (state_text != NULL) {
    // -- status text will be centered inside its table cell:
    canvas.DrawText(paint_rc.left + left2 + Layout::FastScale(padding) + (status_width / 2)  - (canvas.CalcTextWidth(state_text) / 2),
                    (paint_rc.bottom + paint_rc.top - state_text_size.cy) / 2,
                    state_text);
  }
}
예제 #14
0
void
MapItemListRenderer::Draw(Canvas &canvas, const PixelRect rc,
                          const TrafficMapItem &item,
                          const DialogLook &dialog_look,
                          const TrafficLook &traffic_look,
                          const TrafficList *traffic_list)
{
  const PixelScalar line_height = rc.bottom - rc.top;
  const FlarmTraffic *traffic = traffic_list == NULL ? NULL :
      traffic_list->FindTraffic(item.id);

  // Now render the text information
  const Font &name_font = *dialog_look.list.font_bold;
  const Font &small_font = *dialog_look.small_font;
  PixelScalar left = rc.left + line_height + Layout::FastScale(2);

  const FlarmNetRecord *record = FlarmDetails::LookupRecord(item.id);

  StaticString<256> title_string;
  if (record && !StringIsEmpty(record->pilot))
    title_string = record->pilot.c_str();
  else
    title_string = _("FLARM Traffic");

  // Append name to the title, if it exists
  const TCHAR *callsign = FlarmDetails::LookupCallsign(item.id);
  if (callsign != NULL && !StringIsEmpty(callsign)) {
    title_string.append(_T(", "));
    title_string.append(callsign);
  }

  canvas.Select(name_font);
  canvas.DrawClippedText(left, rc.top + Layout::FastScale(2),
                         rc, title_string);

  StaticString<256> info_string;
  if (record && !StringIsEmpty(record->plane_type))
    info_string = record->plane_type;
  else if (traffic != NULL)
    info_string = FlarmTraffic::GetTypeString(traffic->type);
  else
    info_string = _("Unknown");

  // Generate the line of info about the target, if it's available
  if (traffic != NULL) {
    if (traffic->altitude_available) {
      TCHAR tmp[15];
      FormatUserAltitude(traffic->altitude, tmp, 15);
      info_string.AppendFormat(_T(", %s: %s"), _("Altitude"), tmp);
    }
    if (traffic->climb_rate_avg30s_available) {
      TCHAR tmp[15];
      FormatUserVerticalSpeed(traffic->climb_rate_avg30s, tmp, 15);
      info_string.AppendFormat(_T(", %s: %s"), _("Vario"), tmp);
    }
  }
  canvas.Select(small_font);
  canvas.DrawClippedText(left,
                         rc.top + name_font.GetHeight() + Layout::FastScale(4),
                         rc, info_string);

  RasterPoint pt = { (PixelScalar)(rc.left + line_height / 2),
                     (PixelScalar)(rc.top + line_height / 2) };

  // Render the representation of the traffic icon
  if (traffic != NULL)
    TrafficRenderer::Draw(canvas, traffic_look, *traffic, traffic->track,
                          item.color, pt);
}
예제 #15
0
void
MapItemListRenderer::Draw(Canvas &canvas, const PixelRect rc,
                          const ArrivalAltitudeMapItem &item,
                          const DialogLook &dialog_look,
                          const FinalGlideBarLook &look)
{
  const UPixelScalar line_height = rc.bottom - rc.top;

  bool elevation_available =
      !RasterBuffer::IsSpecial((short)item.elevation);

  bool reach_relevant = item.reach.IsReachRelevant();

  RoughAltitude arrival_altitude =
    item.reach.terrain_valid == ReachResult::Validity::VALID
    ? item.reach.terrain
    : item.reach.direct;
  if (elevation_available)
    arrival_altitude -= item.elevation;

  bool reachable =
    item.reach.terrain_valid != ReachResult::Validity::UNREACHABLE &&
    arrival_altitude.IsPositive();

  // Draw final glide arrow icon

  RasterPoint pt = { (PixelScalar)(rc.left + line_height / 2),
                     (PixelScalar)(rc.top + line_height / 2) };

  RasterPoint arrow[] = {
      { -7, -3 }, { 0, 4 }, { 7, -3 }
  };

  Angle arrow_angle = reachable ? Angle::HalfCircle() : Angle::Zero();
  PolygonRotateShift(arrow, ARRAY_SIZE(arrow), pt.x, pt.y, arrow_angle, 100);

  if (reachable) {
    canvas.Select(look.brush_above);
    canvas.Select(look.pen_above);
  } else {
    canvas.Select(look.brush_below);
    canvas.Select(look.pen_below);
  }
  canvas.DrawPolygon(arrow, ARRAY_SIZE(arrow));


  const Font &name_font = *dialog_look.list.font_bold;
  const Font &small_font = *dialog_look.small_font;

  PixelScalar left = rc.left + line_height + Layout::FastScale(2);


  // Format title row

  TCHAR altitude_buffer[32];
  StaticString<256> buffer;
  buffer.clear();

  if (elevation_available) {
    RoughAltitude relative_arrival_altitude =
      item.reach.direct - item.elevation;

    FormatRelativeUserAltitude(fixed((short)relative_arrival_altitude),
                               altitude_buffer, ARRAY_SIZE(altitude_buffer));

    buffer.AppendFormat(_T("%s %s, "), altitude_buffer, _("AGL"));
  }

  FormatUserAltitude(fixed(item.reach.direct),
                     altitude_buffer, ARRAY_SIZE(altitude_buffer));

  buffer.AppendFormat(_T("%s %s"), altitude_buffer, _("MSL"));

  // Draw title row

  canvas.Select(name_font);
  canvas.DrawClippedText(left, rc.top + Layout::FastScale(2), rc, buffer);

  // Format comment row

  if (reach_relevant) {
    buffer.Format(_T("%s: "), _("around terrain"));

    if (elevation_available) {
      RoughAltitude relative_arrival_altitude =
          item.reach.terrain - item.elevation;

      FormatRelativeUserAltitude(fixed((short)relative_arrival_altitude),
                                 altitude_buffer, ARRAY_SIZE(altitude_buffer));

     buffer.AppendFormat(_T("%s %s, "), altitude_buffer, _("AGL"));
    }

    FormatUserAltitude(fixed(item.reach.terrain),
                       altitude_buffer, ARRAY_SIZE(altitude_buffer));

    buffer.AppendFormat(_T("%s %s, "), altitude_buffer, _("MSL"));
  } else if (elevation_available &&
             (int)item.reach.direct >= (int)item.elevation &&
             item.reach.terrain_valid == ReachResult::Validity::UNREACHABLE) {
    buffer.UnsafeFormat(_T("%s "), _("Unreachable due to terrain."));
  } else {
    buffer.clear();
  }

  buffer += _("Arrival altitude incl. safety height");

  // Draw comment row

  canvas.Select(small_font);
  canvas.DrawClippedText(left,
                         rc.top + name_font.GetHeight() + Layout::FastScale(4),
                         rc, buffer);
}
예제 #16
0
void
WaypointListRenderer::Draw(Canvas &canvas, const PixelRect rc,
                           const Waypoint &waypoint, const GeoVector *vector,
                           const DialogLook &dialog_look,
                           const WaypointLook &look,
                           const WaypointRendererSettings &settings)
{
  const PixelScalar line_height = rc.bottom - rc.top;

  const Font &name_font = *dialog_look.list.font_bold;
  const Font &small_font = *dialog_look.small_font;

  Buffer buffer;

  // Y-Coordinate of the second row
  PixelScalar top2 = rc.top + name_font.GetHeight() + Layout::FastScale(4);

  // Use small font for details
  canvas.Select(small_font);

  // Draw leg distance
  UPixelScalar leg_info_width = 0;
  if (vector) {
    FormatUserDistanceSmart(vector->distance, buffer.buffer(), true);
    UPixelScalar width = leg_info_width = canvas.CalcTextWidth(buffer.c_str());
    canvas.DrawText(rc.right - Layout::FastScale(2) - width,
                    rc.top + Layout::FastScale(2) +
                    (name_font.GetHeight() - small_font.GetHeight()) / 2,
                    buffer.c_str());

    // Draw leg bearing
    FormatBearing(buffer.buffer(), buffer.MAX_SIZE, vector->bearing);
    width = canvas.CalcTextWidth(buffer.c_str());
    canvas.DrawText(rc.right - Layout::FastScale(2) - width, top2,
                    buffer.c_str());

    if (width > leg_info_width)
      leg_info_width = width;

    leg_info_width += Layout::FastScale(2);
  }

  // Draw details line
  FormatWaypointDetails(buffer, waypoint);

  PixelScalar left = rc.left + line_height + Layout::FastScale(2);
  canvas.DrawClippedText(left, top2, rc.right - leg_info_width - left,
                         buffer.c_str());

  // Draw waypoint name
  canvas.Select(name_font);
  canvas.DrawClippedText(left, rc.top + Layout::FastScale(2),
                         rc.right - leg_info_width - left,
                         waypoint.name.c_str());

  // Draw icon
  RasterPoint pt = { (PixelScalar)(rc.left + line_height / 2),
                     (PixelScalar)(rc.top + line_height / 2) };
  WaypointIconRenderer wir(settings, look, canvas);
  wir.Draw(waypoint, pt);
}
예제 #17
0
//------------------------------------------------------------------------------
int
main(int argc, char *argv[])
  {
  QApplication app(argc, argv);
  Canvas c;
  Pen(Pen::SOLID, 1, Color(0, 0, 0));
    {
    c.Select(Brush(Color(128, 128, 0, Color::TRANSPARENT)));
    c.DrawKeyhole(200, 100, 50, 100, Angle::Degrees(-20), Angle::Degrees(20));
    c.DrawKeyhole(400, 100, 50, 100, Angle::Degrees(70), Angle::Degrees(110));
    c.DrawKeyhole(200, 300, 50, 100, Angle::Degrees(160), Angle::Degrees(200));
    c.DrawKeyhole(400, 300, 50, 100, Angle::Degrees(-110), Angle::Degrees(-70));
    c.show();
    app.exec();
    }
    {
    c.Clear();
    c.DrawKeyhole(200, 100, 50, 100, Angle::Degrees(35), Angle::Degrees(55));
    c.DrawKeyhole(400, 100, 50, 100, Angle::Degrees(125), Angle::Degrees(145));
    c.DrawKeyhole(200, 300, 50, 100, Angle::Degrees(215), Angle::Degrees(235));
    c.DrawKeyhole(400, 300, 50, 100, Angle::Degrees(305), Angle::Degrees(325));
    c.show();
    app.exec();
    }
    {
    c.Clear();
    c.DrawFilledRectangle(0, 0, 100, 100, Color(128, 128, 128,
                                                Color::TRANSPARENT));
    c.DrawFilledRectangle(100, 100, 200, 200, Color(128, 0, 0,
                                                    Color::TRANSPARENT));
    c.DrawFilledRectangle(150, 150, 250, 250, Color(0, 128, 0,
                                                    Color::TRANSPARENT));
    c.DrawFilledRectangle(200, 200, 300, 300, Color(0, 0, 128,
                                                    Color::TRANSPARENT));
    c.DrawTransparentText(0, 0, "0");
    c.DrawTransparentText(0, 100, "100");
    c.DrawTransparentText(0, 200, "200");
    c.DrawTransparentText(0, 300, "300");
    c.DrawTransparentText(0, 400, "400");
    c.DrawTransparentText(0, 500, "500");
    c.DrawTransparentText(100, c.GetFontHeight(), "100");
    c.DrawTransparentText(200, c.GetFontHeight(), "200");
    c.DrawTransparentText(300, c.GetFontHeight(), "300");
    c.DrawTransparentText(400, c.GetFontHeight(), "400");
    c.DrawTransparentText(500, c.GetFontHeight(), "500");
    c.show();
    app.exec();
    }
    {
    c.Clear();
    c.DrawOutlineRectangle(100, 100, 200, 200, Color(255, 0, 0));
    c.show();
    app.exec();
    }
    {
    c.Clear();
    c.DrawRoundRectangle(100, 100, 200, 200, 10, 10);
    c.DrawRoundRectangle(200, 200, 300, 300, 100, 100);
    c.DrawRoundRectangle(300, 300, 400, 400, 50, 50);
    c.show();
    app.exec();
    }
    {
    c.Clear();
    PixelRect rc;
    rc.left   = 100;
    rc.top    = 100;
    rc.right  = 200;
    rc.bottom = 200;
    c.DrawRaisedEdge(rc);
    c.show();
    app.exec();
    }
    {
    c.Clear();
    RasterPoint rp[4];
    rp[0] = {100, 100};
    rp[1] = {200, 200};
    rp[2] = {200, 300};
    rp[3] = {300, 400};
    c.DrawPolyline(rp, 4);
    c.show();
    app.exec();
    }
    {
    c.Clear();
    RasterPoint rp[6];
    rp[0] = {100, 100};
    rp[1] = {150,  50};
    rp[2] = {200, 100};
    rp[3] = {200, 200};
    rp[4] = {150, 200};
    rp[5] = {100, 100};
    c.DrawPolygon(rp, 6);
    c.show();
    app.exec();
    }
    {
    c.Clear();
    RasterPoint rp[4];
    rp[0] = {100, 100};
    rp[1] = {200,  50};
    rp[2] = {200, 150};
    rp[3] = {150, 200};
    c.DrawTriangleFan(rp, 4);
    c.show();
    app.exec();
    }
    {
    c.Clear();
    c.DrawHLine(100, 200, 100, Color(255, 0, 0));
    c.DrawHLine(100, 200, 200, Color(0, 255, 0));
    c.DrawHLine(100, 200, 300, Color(0, 0, 255));
    c.show();
    app.exec();
    }
    {
    c.Clear();
    c.DrawLine(100, 100, 200, 200);
    c.DrawCircle(250, 250, 50);
    c.DrawSegment(100, 250, 50, Angle::Degrees(10), Angle::Degrees(30), false);
    c.show();
    app.exec();
    }
    {
    c.Clear();
    c.DrawAnnulus(100, 100, 50, 100, Angle::Degrees(10), Angle::Degrees(60));
    c.DrawAnnulus(300, 100, 50, 100, Angle::Degrees(0),  Angle::Degrees(360));
    c.DrawAnnulus(100, 300, 50, 100, Angle::Degrees(0),  Angle::Degrees(0));
    c.show();
    app.exec();
    }
    {
    PixelSize rc = c.CalcTextSize("Hello");
    std::cout << "Size of \"Hello\": " << rc.cx << ", " << rc.cy << std::endl;
    c.DrawClippedText(100, 100, rc.cx / 2, "Hello");
    c.show();
    app.exec();
    }
    {
    std::cout << "Height of font: " << c.GetFontHeight() << std::endl;
    }
    {
    c.Clear();
    c.DrawText(0, 50, "50");
    c.Clear();
    c.show();
    return app.exec();
    }
  }
예제 #18
0
 virtual void OnPaintItem(Canvas &canvas, const PixelRect rc,
                          unsigned i) override {
   canvas.DrawClippedText(rc.left + padding,
                          rc.top + padding, rc,
                          combo_list[i].StringValueFormatted);
 }