Example #1
0
/**
 * Paints the basic info for the selected target on the given canvas
 * @param canvas The canvas to paint on
 */
void
FlarmTrafficControl::PaintTrafficInfo(Canvas &canvas) const
{
  // Don't paint numbers if no plane selected
  if (selection == -1)
    return;

  assert(data.FLARM_Traffic[selection].defined());

  // Temporary string
  TCHAR tmp[20];
  // Temporary string size
  SIZE sz;
  // Shortcut to the selected traffic
  FLARM_TRAFFIC traffic;
  if (WarningMode())
    traffic = data.FLARM_Traffic[warning];
  else
    traffic = data.FLARM_Traffic[selection];

  assert(traffic.defined());

  RECT rc;
  rc.left = padding;
  rc.top = padding;
  rc.right = canvas.get_width() - padding;
  rc.bottom = canvas.get_height() - padding;

  // Set the text color and background
  switch (traffic.AlarmLevel) {
  case 1:
    canvas.set_text_color(hcWarning);
    break;
  case 2:
  case 3:
    canvas.set_text_color(hcAlarm);
    break;
  case 4:
  case 0:
  default:
    canvas.set_text_color(hcStandard);
    break;
  }
  canvas.background_transparent();

  // Climb Rate
  if (!WarningMode()) {
    Units::FormatUserVSpeed(traffic.Average30s, tmp, 20);
    canvas.select(hfInfoValues);
    sz = canvas.text_size(tmp);
    canvas.text(rc.right - sz.cx, rc.top + hfInfoLabels.get_height(), tmp);

    canvas.select(hfInfoLabels);
    sz = canvas.text_size(_("Vario:"));
    canvas.text(rc.right - sz.cx, rc.top, _("Vario:"));
  }

  // Distance
  Units::FormatUserDistance(hypot(traffic.RelativeEast, traffic.RelativeNorth),
                            tmp, 20);
  canvas.select(hfInfoValues);
  sz = canvas.text_size(tmp);
  canvas.text(rc.left, rc.bottom - sz.cy, tmp);

  canvas.select(hfInfoLabels);
  canvas.text(rc.left,
              rc.bottom - hfInfoValues.get_height() - hfInfoLabels.get_height(),
              _("Distance:"));

  // Relative Height
  Units::FormatUserArrival(traffic.RelativeAltitude, tmp, 20);
  canvas.select(hfInfoValues);
  sz = canvas.text_size(tmp);
  canvas.text(rc.right - sz.cx, rc.bottom - sz.cy, tmp);

  canvas.select(hfInfoLabels);
  sz = canvas.text_size(_("Rel. Alt.:"));
  canvas.text(rc.right - sz.cx,
              rc.bottom - hfInfoValues.get_height() - hfInfoLabels.get_height(),
              _("Rel. Alt.:"));

  // ID / Name
  if (traffic.HasName()) {
    canvas.select(hfCallSign);
    if (!traffic.HasAlarm()) {
      if (settings.TeamFlarmTracking &&
          traffic.ID == settings.TeamFlarmIdTarget)
        canvas.set_text_color(hcTeam);
      else
        canvas.set_text_color(hcSelection);
    }
    _tcscpy(tmp, traffic.Name);
  } else {
    traffic.ID.format(tmp);
  }
  canvas.text(rc.left, rc.top, tmp);
}
Example #2
0
/**
 * Paints the traffic symbols on the given canvas
 * @param canvas The canvas to paint on
 */
void
FlarmTrafficWindow::PaintRadarTarget(Canvas &canvas,
                                     const FLARM_TRAFFIC &traffic,
                                     unsigned i)
{
  // Save relative East/North
  fixed x, y;
  x = traffic.RelativeEast;
  y = -traffic.RelativeNorth;

  // Calculate the distance in meters
  fixed d = hypot(x, y);

  // Calculate the distance in pixels
  fixed scale = RangeScale(d);

  // Don't display distracting, far away targets in WarningMode
  if (WarningMode() && !traffic.HasAlarm() && scale == fixed(radius))
    return;

  // x and y are not between 0 and 1 (distance will be handled via scale)
  if (positive(d)) {
    x /= d;
    y /= d;
  } else {
    x = fixed_zero;
    y = fixed_zero;
  }

  // Rotate x and y to have a track up display
  FastRotation::Pair p = fr.Rotate(x, y);
  x = fixed(p.first);
  y = fixed(p.second);

  // Calculate screen coordinates
  sc[i].x = radar_mid.x + iround(x * scale);
  sc[i].y = radar_mid.y + iround(y * scale);

  // Set the arrow color depending on alarm level
  switch (traffic.AlarmLevel) {
  case 1:
    canvas.hollow_brush();
    canvas.select(hpWarning);
    canvas.circle(sc[i].x, sc[i].y, Layout::FastScale(small ? 8 : 16));
    canvas.select(hbWarning);
    break;
  case 2:
  case 3:
    canvas.hollow_brush();
    canvas.select(hpAlarm);
    canvas.circle(sc[i].x, sc[i].y, Layout::FastScale(small ? 8 : 16));
    canvas.circle(sc[i].x, sc[i].y, Layout::FastScale(small ? 10 : 19));
    canvas.select(hbAlarm);
    break;
  case 0:
  case 4:
    if (WarningMode()) {
      canvas.hollow_brush();
      canvas.select(hpPassive);
    } else {
      if (!small && static_cast<unsigned> (selection) == i) {
        canvas.select(hpSelection);
        canvas.select(hbSelection);
      } else {
        canvas.hollow_brush();
        if (traffic.Type != FLARM_TRAFFIC::acGlider
            && traffic.Type != FLARM_TRAFFIC::acHangGlider
            && traffic.Type != FLARM_TRAFFIC::acParaGlider)
          canvas.select(hpPassive);
        else
          canvas.select(hpStandard);
      }
      if (settings.TeamFlarmTracking &&
          traffic.ID == settings.TeamFlarmIdTarget) {
        canvas.select(hbTeam);
      }
    }
    break;
  }

  // Create an arrow polygon
  POINT Arrow[5];
  if (small) {
    Arrow[0].x = -3;
    Arrow[0].y = 4;
    Arrow[1].x = 0;
    Arrow[1].y = -5;
    Arrow[2].x = 3;
    Arrow[2].y = 4;
    Arrow[3].x = 0;
    Arrow[3].y = 2;
    Arrow[4].x = -3;
    Arrow[4].y = 4;
  } else {
    Arrow[0].x = -6;
    Arrow[0].y = 8;
    Arrow[1].x = 0;
    Arrow[1].y = -10;
    Arrow[2].x = 6;
    Arrow[2].y = 8;
    Arrow[3].x = 0;
    Arrow[3].y = 5;
    Arrow[4].x = -6;
    Arrow[4].y = 8;
  }

  // Rotate and shift the arrow
  PolygonRotateShift(Arrow, 5, sc[i].x, sc[i].y,
                     traffic.TrackBearing - direction);

  // Draw the polygon
  canvas.polygon(Arrow, 5);

  if (small) {
    if (WarningMode() && !traffic.HasAlarm())
      return;

    const short relalt =
        iround(Units::ToUserAltitude(traffic.RelativeAltitude / 100));

    // if (relative altitude is other than zero)
    if (relalt == 0)
      return;

    // Write the relativ altitude devided by 100 to the Buffer
    TCHAR Buffer[10];
    _stprintf(Buffer, _T("%d"), abs(relalt));

    // Select font
    canvas.background_transparent();
    canvas.select(hfSideInfo);
    canvas.set_text_color(Color::BLACK);

    // Calculate size of the output string
    SIZE tsize = canvas.text_size(Buffer);

    int dist = Layout::FastScale(traffic.HasAlarm() ? 12 : 8);

    // Draw string
    canvas.text(sc[i].x + dist,
                sc[i].y - tsize.cy / 2,
                Buffer);

    // Set black brush for the up/down arrow
    canvas.black_brush();
    canvas.null_pen();

    // Prepare the triangular polygon
    POINT triangle[4];
    triangle[0].x = 0;
    triangle[0].y = -4;
    triangle[1].x = 3;
    triangle[1].y = 0;
    triangle[2].x = -3;
    triangle[2].y = 0;

    // Flip = -1 for arrow pointing downwards
    short flip = 1;
    if (relalt < 0)
      flip = -1;

    // Shift the arrow to the right position
    for (int j = 0; j < 3; j++) {
      triangle[j].x = Layout::FastScale(triangle[j].x);
      triangle[j].y = Layout::FastScale(triangle[j].y);

      triangle[j].x = sc[i].x + dist + triangle[j].x + tsize.cx / 2;
      triangle[j].y = sc[i].y + flip * (triangle[j].y  - tsize.cy / 2);
    }
    triangle[3].x = triangle[0].x;
    triangle[3].y = triangle[0].y;

    // Draw the arrow
    canvas.polygon(triangle, 4);

    return;
  }

  // if warning exists -> don't draw vertical speeds
  if (WarningMode())
    return;

  // if vertical speed to small or negative -> skip this one
  if (side_display_type == 1 && (traffic.Average30s < fixed(0.5)
        || (traffic.Type != FLARM_TRAFFIC::acGlider
            && traffic.Type != FLARM_TRAFFIC::acHangGlider
            && traffic.Type != FLARM_TRAFFIC::acParaGlider)))
      return;

  // Select font
  canvas.background_transparent();
  canvas.select(hfSideInfo);

  // Format string
  TCHAR tmp[10];

  if (side_display_type == 1)
    Units::FormatUserVSpeed(traffic.Average30s, tmp, 10, false);
  else
    Units::FormatUserArrival(traffic.RelativeAltitude, tmp, 10, true);

  SIZE sz = canvas.text_size(tmp);

  // Draw vertical speed shadow
  canvas.set_text_color(Color::WHITE);
  canvas.text(sc[i].x + Layout::FastScale(11) + 1,
              sc[i].y - sz.cy / 2 + 1, tmp);
  canvas.text(sc[i].x + Layout::FastScale(11) - 1,
              sc[i].y - sz.cy / 2 - 1, tmp);

  // Select color
  if (static_cast<unsigned> (selection) == i)
    canvas.set_text_color(hcSelection);
  else
    canvas.set_text_color(hcStandard);

  // Draw vertical speed
  canvas.text(sc[i].x + Layout::FastScale(11), sc[i].y - sz.cy / 2, tmp);
}