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;
  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.text(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.text(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.text_clipped(left, top2, rc.right - leg_info_width - left,
                      buffer.c_str());

  // Draw waypoint name
  canvas.Select(name_font);
  canvas.text_clipped(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);
}
Beispiel #2
1
static void
DrawBanner(Canvas &canvas, PixelRect &rc)
{
  const unsigned padding = 2;
  const Bitmap logo(IDB_LOGO);
  const unsigned banner_height = logo.GetHeight();

  /* draw the XCSoar logo */
  int x = rc.left + padding;
  canvas.Copy(x, rc.top + padding,
              logo.GetWidth(), logo.GetHeight(),
              logo, 0, 0);

  x += logo.GetWidth() + 8;

  canvas.Select(bold_font);
  canvas.SetTextColor(COLOR_BLACK);
  canvas.SetBackgroundTransparent();

  /* draw the XCSoar banner text with a larger font */
  Font large_font;
  large_font.LoadFile("/opt/xcsoar/share/fonts/VeraBd.ttf", 40);
  canvas.Select(large_font);
  const unsigned name_y = rc.top
    + (banner_height - large_font.GetHeight()) / 2;

  const TCHAR *const name1 = _T("XC");
  canvas.DrawText(x, name_y, name1);
  x += canvas.CalcTextWidth(name1);

  const TCHAR *const name2 = _T("Soar");
  canvas.SetTextColor(COLOR_GRAY);
  canvas.DrawText(x, name_y, name2);
  canvas.SetTextColor(COLOR_BLACK);
  x += canvas.CalcTextWidth(name2) + 30;

  /* some more text */
  const TCHAR *const website = _T("www.xcsoar.org");
  canvas.Select(normal_font);
  canvas.DrawText(x, rc.top + (banner_height - normal_font.GetHeight()) / 2,
                  website);

  const TCHAR *const comment = _T("powered off");
  canvas.DrawText(rc.right - canvas.CalcTextWidth(comment) - padding,
                  rc.top + padding, comment);

  rc.top += banner_height + 8;
}
Beispiel #3
0
void
WifiListWidget::OnPaintItem(Canvas &canvas, const PixelRect rc,
                            unsigned idx)
{
  const DialogLook &look = UIGlobals::GetDialogLook();
  const auto &info = networks[idx];
  const unsigned padding = Layout::GetTextPadding();

  const unsigned x1 = rc.left + padding;
  const unsigned y1 = rc.top + padding;
  const unsigned y2 = y1 + look.text_font->GetHeight() + padding;

  static char wifi_security[][20] = {
    "WPA",
    "WEP",
    "Open",
  };

  canvas.Select(*look.text_font);
  canvas.DrawText(x1, y1, info.ssid);

  canvas.Select(*look.small_font);
  canvas.DrawText(x1, y2, info.bssid);

  const TCHAR *state = nullptr;
  StaticString<40> state_buffer;

  /* found the currently connected wifi network? */
  if (StringIsEqual(info.bssid, status.bssid)) {
    state = _("Connected");

    /* look up ip address for eth0 */
    const auto addr = IPv4Address::GetDeviceAddress("eth0");
    if (addr.IsDefined()) { /* valid address? */
      StaticString<40> addr_str;
      if (addr.ToString(addr_str.buffer(), addr_str.MAX_SIZE) != nullptr) {
        state_buffer.Format(_T("%s (%s)"), state, addr_str.c_str());
        state = state_buffer;
      }
    }
  }
  else if (info.id >= 0)
    state = info.signal_level >= 0
      ? _("Saved and visible")
      : _("Saved, but not visible");
  else if (info.signal_level >= 0)
    state = _("Visible");

  if (state != nullptr) {
    unsigned width = canvas.CalcTextWidth(state);
    canvas.DrawText(rc.right - padding - width, y1, state);
  }

  if (info.signal_level >= 0) {
    StaticString<20> text;
    text.UnsafeFormat(_T("%s %u"), wifi_security[info.security], info.signal_level);
    unsigned width = canvas.CalcTextWidth(text);
    canvas.DrawText(rc.right - padding - width, y2, text);
  }
}
Beispiel #4
0
static void
OnAirspacePaintListItem(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;

  if (color_mode) {
    canvas.SelectWhitePen();
#ifndef HAVE_HATCHED_BRUSH
    canvas.Select(look.solid_brushes[i]);
#else
#ifdef HAVE_ALPHA_BLEND
    if (renderer.transparency && AlphaBlendAvailable()) {
      canvas.Select(look.solid_brushes[i]);
    } else {
#endif
      canvas.SetTextColor(renderer.classes[i].color);
      canvas.SetBackgroundColor(Color(0xFF, 0xFF, 0xFF));
      canvas.Select(look.brushes[renderer.classes[i].brush]);
#ifdef HAVE_ALPHA_BLEND
    }
#endif
#endif
    canvas.Rectangle(rc.left + x0, rc.top + Layout::FastScale(2),
        rc.right - Layout::FastScale(2), rc.bottom - Layout::FastScale(2));
  } else {
    if (computer.warnings.class_warnings[i])
      canvas.text(rc.left + w0 - w1 - w2, rc.top + Layout::FastScale(2),
                  _("Warn"));

    if (renderer.classes[i].display)
      canvas.text(rc.left + w0 - w2, rc.top + Layout::FastScale(2),
                  _("Display"));
  }

  canvas.text_clipped(rc.left + Layout::FastScale(2),
                      rc.top + Layout::FastScale(2), x0 - Layout::FastScale(10),
                      AirspaceFormatter::GetClass((AirspaceClass)i));
}
Beispiel #5
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));
}
void
OptionStartsWidget::OnPaintItem(Canvas &canvas, const PixelRect rc,
                                unsigned DrawListIndex)
{
  assert(DrawListIndex <= task.GetOptionalStartPointCount()
         + (RealStartExists ? 2 : 1));
  assert(GetList().GetLength() ==
         task.GetOptionalStartPointCount() + (RealStartExists ? 2 : 1));

  const unsigned padding = Layout::GetTextPadding();
  const unsigned index_optional_starts = DrawListIndex - (RealStartExists ? 1 : 0);

  if (DrawListIndex == GetList().GetLength() - 1) {
    canvas.DrawText(rc.left + padding, rc.top + padding,
                    _("(Add Alternate Start)"));
  } else {
    RasterPoint pt(rc.left + padding, rc.top + padding);

    const OrderedTaskPoint *tp;
    if (DrawListIndex == 0 && RealStartExists) {
      tp = &task.GetPoint(0);
      canvas.DrawText(pt.x, pt.y, _T("*"));
      pt.x += canvas.CalcTextWidth(_T("*"));
    } else
      tp = &task.GetOptionalStartPoint(index_optional_starts);

    assert(tp != nullptr);

    canvas.DrawText(pt.x, pt.y, tp->GetWaypoint().name.c_str());
  }
}
static void
OnPaintListItem(Canvas &canvas, const PixelRect rc, unsigned i)
{
    if (AirspaceSelectInfo.empty()) {
        assert(i == 0);

        canvas.text(rc.left + Layout::FastScale(2),
                    rc.top + Layout::FastScale(2), _("No Match!"));
        return;
    }

    assert(i < AirspaceSelectInfo.size());

    const AbstractAirspace &airspace = *AirspaceSelectInfo[i].airspace;

    int w0, w1, w2, w3, x1, x2, x3;
    w0 = rc.right - rc.left - Layout::FastScale(4);
    w1 = canvas.CalcTextWidth(_T("XXX"));
    w2 = canvas.CalcTextWidth(_T(" 000km"));
    w3 = canvas.CalcTextWidth(_T(" 000")_T(DEG));

    x1 = w0-w1-w2-w3;

    canvas.text_clipped(rc.left + Layout::FastScale(2),
                        rc.top + Layout::FastScale(2),
                        x1 - Layout::FastScale(5), airspace.GetNameText().c_str());

    // left justified
    canvas.text(rc.left + x1, rc.top + Layout::FastScale(2),
                airspace.GetTypeText(true));

    StaticString<12> sTmp;

    // right justified after airspace type
    sTmp.Format(_T("%d%s"),
                (int)AirspaceSelectInfo[i].Distance,
                Units::GetDistanceName());
    x2 = w0 - w3 - canvas.CalcTextWidth(sTmp);
    canvas.text(rc.left + x2, rc.top + Layout::FastScale(2), sTmp);

    // right justified after distance
    FormatBearing(sTmp.buffer(), sTmp.MAX_SIZE, AirspaceSelectInfo[i].Direction);
    x3 = w0 - canvas.CalcTextWidth(sTmp);
    canvas.text(rc.left + x3, rc.top + Layout::FastScale(2), sTmp);
}
void
AirspaceListRenderer::Draw(Canvas &canvas, const PixelRect rc,
                           const AbstractAirspace &airspace,
                           const TCHAR *comment, const DialogLook &dialog_look,
                           const AirspaceLook &look,
                           const AirspaceRendererSettings &renderer_settings)
{
  const PixelScalar line_height = rc.bottom - rc.top;

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

  PixelScalar left = rc.left + line_height + Layout::FastScale(2);
  canvas.Select(name_font);
  canvas.text_clipped(left, rc.top + Layout::FastScale(2), rc,
                      airspace.GetName());

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

  tstring top = AirspaceFormatter::GetTopShort(airspace);
  PixelScalar altitude_width =
    canvas.CalcTextWidth(top.c_str());
  canvas.text_clipped(rc.right - altitude_width - Layout::FastScale(4),
                      rc.top + name_font.GetHeight() -
                      small_font.GetHeight() + Layout::FastScale(2), rc,
                      top.c_str());

  tstring base = AirspaceFormatter::GetBaseShort(airspace);
  altitude_width = canvas.CalcTextWidth(base.c_str());

  canvas.text_clipped(rc.right - altitude_width - Layout::FastScale(4),
                      rc.top + name_font.GetHeight() + Layout::FastScale(4),
                      rc, base.c_str());

  RasterPoint pt = { PixelScalar(rc.left + line_height / 2),
                     PixelScalar(rc.top + line_height / 2) };
  PixelScalar radius = std::min(PixelScalar(line_height / 2
                                            - Layout::FastScale(4)),
                                Layout::FastScale(10));
  AirspacePreviewRenderer::Draw(canvas, airspace, pt, radius,
                                renderer_settings, look);
}
void
MapItemListRenderer::Draw(Canvas &canvas, const PixelRect rc,
                          const AirspaceMapItem &item,
                          const DialogLook &dialog_look,
                          const AirspaceLook &look,
                          const AirspaceRendererSettings &renderer_settings)
{
  const PixelScalar line_height = rc.bottom - rc.top;

  const AbstractAirspace &airspace = *item.airspace;

  RasterPoint pt = { PixelScalar(rc.left + line_height / 2),
                     PixelScalar(rc.top + line_height / 2) };
  PixelScalar radius = std::min(PixelScalar(line_height / 2
                                            - Layout::FastScale(4)),
                                Layout::FastScale(10));
  AirspacePreviewRenderer::Draw(canvas, airspace, pt, radius,
                                renderer_settings, look);

  const Font &name_font = *dialog_look.list.font;
  const Font &small_font = *dialog_look.small_font;
  canvas.SetTextColor(COLOR_BLACK);

  PixelScalar left = rc.left + line_height + Layout::FastScale(2);
  canvas.Select(name_font);
  canvas.text_clipped(left, rc.top + Layout::FastScale(2), rc,
                      airspace.GetName());

  canvas.Select(small_font);
  canvas.text_clipped(left,
                      rc.top + name_font.GetHeight() + Layout::FastScale(4),
                      rc, airspace.GetTypeText(false));

  PixelScalar altitude_width =
    canvas.CalcTextWidth(airspace.GetTopText(true).c_str());
  canvas.text_clipped(rc.right - altitude_width - Layout::FastScale(4),
                      rc.top + name_font.GetHeight() -
                      small_font.GetHeight() + Layout::FastScale(2), rc,
                      airspace.GetTopText(true).c_str());

  altitude_width = canvas.CalcTextWidth(airspace.GetBaseText(true).c_str());
  canvas.text_clipped(rc.right - altitude_width - Layout::FastScale(4),
                      rc.top + name_font.GetHeight() + Layout::FastScale(4),
                      rc, airspace.GetBaseText(true).c_str());
}
Beispiel #10
0
void
ManagedFileListWidget::OnPaintItem(Canvas &canvas, const PixelRect rc,
                                   unsigned i)
{
  const FileItem &file = items[i];

  const unsigned margin = Layout::GetTextPadding();

  canvas.Select(row_renderer.GetFirstFont());
  row_renderer.DrawFirstRow(canvas, rc, file.name.c_str());

  canvas.Select(row_renderer.GetSecondFont());

  if (file.downloading) {
    StaticString<64> text;
    if (file.download_status.position < 0) {
      text = _("Queued");
    } else if (file.download_status.size > 0) {
      text.Format(_T("%s (%u%%)"), _("Downloading"),
                    unsigned(file.download_status.position * 100
                             / file.download_status.size));
    } else {
      TCHAR size[32];
      FormatByteSize(size, ARRAY_SIZE(size), file.download_status.position);
      text.Format(_T("%s (%s)"), _("Downloading"), size);
    }

    const unsigned width = canvas.CalcTextWidth(text);
    canvas.DrawText(rc.right - width - margin,
                    rc.top + row_renderer.GetFirstY(),
                    text);
  } else if (file.failed) {
    const TCHAR *text = _("Error");
    const unsigned width = canvas.CalcTextWidth(text);
    canvas.DrawText(rc.right - width - margin,
                    rc.top + row_renderer.GetFirstY(),
                    text);
  }

  row_renderer.DrawSecondRow(canvas, rc, file.size.c_str());

  canvas.DrawText((rc.left + rc.right) / 2,
                  rc.top + row_renderer.GetSecondY(),
                  file.last_modified.c_str());
}
Beispiel #11
0
void
ManagedFileListWidget::OnPaintItem(Canvas &canvas, const PixelRect rc,
                                   unsigned i)
{
  const FileItem &file = items[i];

  const UPixelScalar margin = Layout::GetTextPadding();

  canvas.DrawText(rc.left + margin, rc.top + margin, file.name.c_str());

  if (file.downloading) {
    StaticString<64> text;
    if (file.download_status.position < 0) {
      text = _("Queued");
    } else if (file.download_status.size > 0) {
      text.Format(_T("%s (%u%%)"), _("Downloading"),
                    unsigned(file.download_status.position * 100
                             / file.download_status.size));
    } else {
      TCHAR size[32];
      FormatByteSize(size, ARRAY_SIZE(size), file.download_status.position);
      text.Format(_T("%s (%s)"), _("Downloading"), size);
    }

    UPixelScalar width = canvas.CalcTextWidth(text);
    canvas.DrawText(rc.right - width - margin, rc.top + margin, text);
  } else if (file.failed) {
    const TCHAR *text = _("Error");
    UPixelScalar width = canvas.CalcTextWidth(text);
    canvas.DrawText(rc.right - width - margin, rc.top + margin, text);
  }

  canvas.DrawText(rc.left + margin, rc.top + 2 * margin + font_height,
                  file.size.c_str());

  canvas.DrawText((rc.left + rc.right) / 2, rc.top + 2 * margin + font_height,
                  file.last_modified.c_str());
}
Beispiel #12
0
/**
 * Draw right-aligned text.
 */
static void
DrawTextRight(Canvas &canvas, int x, int y, const TCHAR *text)
{
  unsigned width = canvas.CalcTextWidth(text);
  canvas.DrawText(x - width, y, text);
}
Beispiel #13
0
void
TrafficListWidget::OnPaintItem(Canvas &canvas, const PixelRect rc,
                               unsigned index)
{
  assert(index < items.size());
  Item &item = items[index];

  assert(item.IsFlarm()
#ifdef HAVE_SKYLINES_TRACKING_HANDLER
         || item.IsSkyLines()
#endif
         );

  item.AutoLoad();

  const FlarmNetRecord *record = item.record;
  const TCHAR *callsign = item.callsign;

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

  const unsigned text_padding = Layout::GetTextPadding();
  const unsigned frame_padding = text_padding / 2;

  TCHAR tmp_id[10];
  item.id.Format(tmp_id);

  canvas.Select(name_font);

  StaticString<256> tmp;

  if (item.IsFlarm()) {
    if (record != NULL)
      tmp.Format(_T("%s - %s - %s"),
                 callsign, record->registration.c_str(), tmp_id);
    else if (callsign != NULL)
      tmp.Format(_T("%s - %s"), callsign, tmp_id);
    else
      tmp.Format(_T("%s"), tmp_id);
#ifdef HAVE_SKYLINES_TRACKING_HANDLER
  } else if (item.IsSkyLines()) {
    tmp.UnsafeFormat(_T("SkyLines %u"), item.skylines_id);
#endif
  } else {
    tmp = _T("?");
  }

  const int name_x = rc.left + text_padding, name_y = rc.top + text_padding;

  if (item.color != FlarmColor::NONE) {
    const TrafficLook &traffic_look = UIGlobals::GetLook().traffic;

    switch (item.color) {
    case FlarmColor::NONE:
    case FlarmColor::COUNT:
      gcc_unreachable();

    case FlarmColor::GREEN:
      canvas.Select(traffic_look.team_pen_green);
      break;
    case FlarmColor::BLUE:
      canvas.Select(traffic_look.team_pen_blue);
      break;
    case FlarmColor::YELLOW:
      canvas.Select(traffic_look.team_pen_yellow);
      break;
    case FlarmColor::MAGENTA:
      canvas.Select(traffic_look.team_pen_magenta);
      break;
    }

    canvas.SelectHollowBrush();

    const PixelSize size = canvas.CalcTextSize(tmp);
    canvas.Rectangle(name_x - frame_padding,
                     name_y - frame_padding,
                     name_x + size.cx + frame_padding,
                     name_y + size.cy + frame_padding);
  }

  canvas.DrawText(name_x, name_y, tmp);

  if (record != NULL) {
    tmp.clear();

    if (!record->pilot.empty())
      tmp = record->pilot.c_str();

    if (!record->plane_type.empty()) {
      if (!tmp.empty())
        tmp.append(_T(" - "));

      tmp.append(record->plane_type);
    }

    if (!record->airfield.empty()) {
      if (!tmp.empty())
        tmp.append(_T(" - "));

      tmp.append(record->airfield);
    }

    if (!tmp.empty()) {
      canvas.Select(small_font);
      canvas.DrawText(rc.left + text_padding,
                      rc.bottom - small_font.GetHeight() - text_padding,
                      tmp);
    }
  }

  /* draw bearing and distance on the right */
  if (item.vector.IsValid()) {
    FormatUserDistanceSmart(item.vector.distance, tmp.buffer(), true);
    unsigned width = canvas.CalcTextWidth(tmp.c_str());
    canvas.DrawText(rc.right - text_padding - width,
                    name_y +
                    (name_font.GetHeight() - small_font.GetHeight()) / 2,
                    tmp.c_str());

    // Draw leg bearing
    FormatBearing(tmp.buffer(), tmp.MAX_SIZE, item.vector.bearing);
    width = canvas.CalcTextWidth(tmp.c_str());
    canvas.DrawText(rc.right - text_padding - width,
                    rc.bottom - small_font.GetHeight() - text_padding,
                    tmp.c_str());
  }

}
Beispiel #14
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);
}
Beispiel #15
0
void
TaskEditPanel::OnPaintItem(Canvas &canvas, const PixelRect rc,
                           unsigned DrawListIndex)
{
  assert(DrawListIndex <= ordered_task->TaskSize());

  const unsigned padding = Layout::GetTextPadding();
  const unsigned line_height = rc.bottom - rc.top;

  TCHAR buffer[120];

  // Draw "Add turnpoint" label
  if (DrawListIndex == ordered_task->TaskSize()) {
    row_renderer.DrawFirstRow(canvas, rc, _("Add Turnpoint"));
    return;
  }

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

  PixelRect text_rc = rc;
  text_rc.left += line_height + padding;

  if (show_leg_info) {
    // Use small font for details
    canvas.Select(row_renderer.GetSecondFont());

    // Draw leg distance
    FormatUserDistanceSmart(leg.distance, buffer, true);
    unsigned width = canvas.CalcTextWidth(buffer);
    const int x1 = rc.right - padding - width;
    canvas.DrawText(x1, rc.top + row_renderer.GetFirstY(), buffer);

    // Draw leg bearing
    FormatBearing(buffer, ARRAY_SIZE(buffer), leg.bearing);
    width = canvas.CalcTextWidth(buffer);
    const int x2 = rc.right - padding - width;
    canvas.DrawText(x2, rc.top + row_renderer.GetSecondY(), buffer);

    text_rc.right = std::min(x1, x2) - padding;
  }

  // Draw details line
  OrderedTaskPointRadiusLabel(tp.GetObservationZone(), buffer);
  if (!StringIsEmpty(buffer))
    row_renderer.DrawSecondRow(canvas, text_rc, buffer);

  // Draw turnpoint name
  OrderedTaskPointLabel(tp.GetType(), tp.GetWaypoint().name.c_str(),
                        DrawListIndex, buffer);
  row_renderer.DrawFirstRow(canvas, text_rc, buffer);

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

  const unsigned radius = line_height / 2 - padding;
  OZPreviewRenderer::Draw(canvas, tp.GetObservationZone(),
                          pt, radius, task_look,
                          CommonInterface::GetMapSettings().airspace,
                          airspace_look);
}
Beispiel #16
0
void
DigitEntry::OnPaint(Canvas &canvas)
{
    assert(cursor < length);

    const bool focused = HasCursorKeys() && HasFocus();

    if (HaveClipping())
        canvas.Clear(look.background_color);

    canvas.Select(look.text_font);
    canvas.SetBackgroundOpaque();

    const unsigned text_height = look.text_font.GetHeight();
    const int y = (top + bottom - text_height) / 2;

    PixelRect rc;
    rc.top = top;
    rc.bottom = bottom;

    TCHAR buffer[4];

    for (unsigned i = 0; i < length; ++i) {
        const Column &c = columns[i];

        rc.left = c.left;
        rc.right = c.right;

        if (focused && i == cursor) {
            canvas.SetTextColor(look.list.focused.text_color);
            canvas.SetBackgroundColor(look.list.focused.background_color);
        } else if (c.IsEditable()) {
            canvas.SetTextColor(look.list.text_color);
            canvas.SetBackgroundColor(look.list.background_color);
        } else {
            canvas.SetTextColor(look.list.text_color);
            canvas.SetBackgroundColor(look.background_color);
        }

        const TCHAR *text = buffer;
        buffer[1] = _T('\0');

        switch (c.type) {
        case Column::Type::DIGIT:
        case Column::Type::DIGIT6:
            assert(c.value < 10);
            buffer[0] = _T('0') + c.value;
            break;

        case Column::Type::HOUR:
            assert(c.value < 24);
            _stprintf(buffer, _T("%02u"), c.value);
            break;

        case Column::Type::DIGIT36:
            assert(c.value < 36);
            _stprintf(buffer, _T("%02u"), c.value);
            break;

        case Column::Type::DIGIT19:
            assert(c.value < 19);
            _stprintf(buffer, _T("%02u"), c.value);
            break;

        case Column::Type::SIGN:
            buffer[0] = c.IsNegative() ? _T('-') : _T('+');
            break;

        case Column::Type::DECIMAL_POINT:
            buffer[0] = _T('.');
            break;

        case Column::Type::COLON:
            buffer[0] = _T(':');
            break;

        case Column::Type::NORTH_SOUTH:
            buffer[0] = c.IsNegative() ? _T('S') : _T('N');
            break;

        case Column::Type::EAST_WEST:
            buffer[0] = c.IsNegative() ? _T('W') : _T('E');
            break;

        case Column::Type::DEGREES:
            text = _T("°");
            break;

        case Column::Type::APOSTROPHE:
            text = _T("'");
            break;

        case Column::Type::QUOTE:
            text = _T("\"");
            break;

        case Column::Type::UNIT:
            // TODO: render unit symbol?
            text = Units::unit_descriptors[c.value].name;
            break;
        }

        if (c.IsEditable() && !valid)
            buffer[0] = _T('\0');

        const int x = (c.left + c.right - canvas.CalcTextWidth(text)) / 2;

        canvas.DrawOpaqueText(x, y, rc, text);
    }

    canvas.SetBackgroundTransparent();
    canvas.SetTextColor(look.text_color);

    unsigned control_height = Layout::GetMaximumControlHeight();

    PixelRect plus_rc(0, top - control_height, 0, top);
    PixelRect minus_rc(0, bottom, 0, bottom + control_height);

    for (unsigned i = 0; i < length; ++i) {
        const Column &c = columns[i];
        if (!c.IsEditable())
            continue;

        plus_rc.left = minus_rc.left = c.left;
        plus_rc.right = minus_rc.right = c.right;

        button_renderer.DrawButton(canvas, plus_rc, false, false);
        button_renderer.DrawButton(canvas, minus_rc, false, false);

        canvas.SelectNullPen();
        canvas.Select(look.button.standard.foreground_brush);

        SymbolRenderer::DrawArrow(canvas, plus_rc, SymbolRenderer::UP);
        SymbolRenderer::DrawArrow(canvas, minus_rc, SymbolRenderer::DOWN);
    }
}
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);
  }
}