Esempio n. 1
0
void
TeamCodeWidget::Update(const MoreData &basic, const DerivedInfo &calculated)
{
  const TeamInfo &teamcode_info = calculated;
  const TeamCodeSettings &settings =
    CommonInterface::GetComputerSettings().team_code;
  StaticString<100> buffer;

  if (teamcode_info.teammate_available && basic.track_available) {
    FormatAngleDelta(buffer.buffer(), buffer.MAX_SIZE,
                     teamcode_info.teammate_vector.bearing - basic.track);
  } else {
    buffer = _T("---");
  }

  SetText(RELATIVE_BEARING, buffer);

  if (teamcode_info.teammate_available) {
    FormatBearing(buffer.buffer(), buffer.MAX_SIZE,
                  teamcode_info.teammate_vector.bearing);
    SetText(BEARING, buffer);

    FormatUserDistanceSmart(teamcode_info.teammate_vector.distance,
                            buffer.buffer());
    SetText(RANGE, buffer);
  }

  SetText(OWN_CODE, teamcode_info.own_teammate_code.GetCode());
  SetText(MATE_CODE, settings.team_code.GetCode());
  SetText(FLARM_LOCK,
          settings.team_flarm_id.IsDefined()
          ? settings.team_flarm_callsign.c_str()
          : _T(""));
}
Esempio n. 2
0
void
RenderGlidePolarInfo(Canvas &canvas, const PixelRect rc,
                     const ChartLook &chart_look,
                     const GlidePolar &glide_polar)
{
  canvas.Select(chart_look.label_font);

  StaticString<80> text;
  StaticString<20> value;
  canvas.SetBackgroundTransparent();

  FormatUserMass(glide_polar.GetTotalMass(), value.buffer(), true);

  int left = rc.left*0.8 + rc.right*0.2;

  text.Format(_T("%s: %s"), _("Mass"), value.c_str());
  canvas.DrawText(left,
                  rc.bottom - Layout::Scale(50),
                  text);

  double wl = glide_polar.GetWingLoading();
  if (wl != 0) {
    FormatUserWingLoading(wl, value.buffer(), true);

    text.Format(_T("%s: %s"), _("Wing loading"), value.c_str());

    canvas.DrawText(left,
                    rc.bottom - Layout::Scale(35),
                    text);
  }
}
Esempio n. 3
0
    void Set(const TCHAR *_name, const DownloadStatus *_download_status,
             bool _failed) {
      name = _name;

      TCHAR path[MAX_PATH];
      LocalPath(path, name);

      if (File::Exists(path)) {
        FormatByteSize(size.buffer(), size.MAX_SIZE,
                       File::GetSize(path));
#ifdef HAVE_POSIX
        FormatISO8601(last_modified.buffer(),
                      BrokenDateTime::FromUnixTimeUTC(File::GetLastModification(path)));
#else
        // XXX implement
        last_modified.clear();
#endif
      } else {
        size.clear();
        last_modified.clear();
      }

      downloading = _download_status != NULL;
      if (downloading)
        download_status = *_download_status;

      failed = _failed;
    }
Esempio n. 4
0
static void
NewClicked(gcc_unused WndButton &button)
{
  Plane plane = CommonInterface::GetComputerSettings().plane;

  while (dlgPlaneDetailsShowModal(*(SingleWindow*)dialog->get_root_owner(), plane)) {
    if (plane.registration.empty()) {
      MessageBoxX(_("Please enter the registration of the plane!"),
                  _("Error"), MB_OK);
      continue;
    }

    StaticString<42> filename(plane.registration);
    filename += _T(".xcp");

    StaticString<MAX_PATH> path;
    LocalPath(path.buffer(), filename);

    if (File::Exists(path)) {
      StaticString<256> tmp;
      tmp.Format(_("A plane profile \"%s\" already exists. "
                   "Do you want to overwrite it?"),
                   filename.c_str());
      if (MessageBoxX(tmp, _("Overwrite"), MB_YESNO) != IDYES)
        continue;
    }

    PlaneGlue::WriteFile(plane, path);
    UpdateList();
    break;
  }
}
Esempio n. 5
0
static void
Update(const MoreData &basic, const DerivedInfo &calculated)
{
  const TeamInfo &teamcode_info = calculated;
  const TeamCodeSettings &settings =
    CommonInterface::GetComputerSettings().team_code;
  StaticString<100> buffer;

  if (teamcode_info.teammate_available && basic.track_available) {
    FormatAngleDelta(buffer.buffer(), buffer.MAX_SIZE,
                     teamcode_info.teammate_vector.bearing - basic.track);
  } else {
    buffer = _T("---");
  }

  SetFormValue(*wf, _T("prpRelBearing"), buffer);

  if (teamcode_info.teammate_available) {
    LoadFormProperty(*wf, _T("prpBearing"),
                     teamcode_info.teammate_vector.bearing.Degrees());
    LoadFormProperty(*wf, _T("prpRange"), UnitGroup::DISTANCE,
                     teamcode_info.teammate_vector.distance);
  }

  SetFormValue(*wf, _T("prpOwnCode"),
               teamcode_info.own_teammate_code.GetCode());
  SetFormValue(*wf, _T("prpMateCode"), settings.team_code.GetCode());

  SetFormValue(*wf, _T("prpFlarmLock"),
               settings.team_flarm_id.IsDefined()
               ? settings.team_flarm_callsign.c_str()
               : _T(""));
}
Esempio n. 6
0
inline void
PlaneListWidget::NewClicked()
{
  Plane plane = CommonInterface::GetComputerSettings().plane;

  while (dlgPlaneDetailsShowModal(plane)) {
    if (plane.registration.empty()) {
      ShowMessageBox(_("Please enter the registration of the plane!"),
                  _("Error"), MB_OK);
      continue;
    }

    StaticString<42> filename(plane.registration);
    filename += _T(".xcp");

    StaticString<MAX_PATH> path;
    LocalPath(path.buffer(), filename);

    if (File::Exists(path)) {
      StaticString<256> tmp;
      tmp.Format(_("Plane \"%s\" already exists. "
                   "Overwrite it?"),
                   plane.registration.c_str());
      if (ShowMessageBox(tmp, _("Overwrite"), MB_YESNO) != IDYES)
        continue;
    }

    PlaneGlue::WriteFile(plane, path);
    UpdateList();
    break;
  }
}
Esempio n. 7
0
static inline bool
TextEntryDialog(StaticString<N> &text,
                const TCHAR *caption,
                bool default_shift_state)
{
  AllowedCharacters accb=AllowedCharacters();
  return TextEntryDialog(text.buffer(), text.MAX_SIZE,
                         caption, accb, default_shift_state);
}
Esempio n. 8
0
void
FlightStatusPanel::Refresh()
{
  const NMEAInfo &basic = CommonInterface::Basic();
  const DerivedInfo &calculated = CommonInterface::Calculated();

  StaticString<32> buffer;

  if (basic.location_available) {
    FormatGeoPoint(basic.location, buffer.buffer(), buffer.MAX_SIZE);
    SetText(Location, buffer);
  } else
    SetText(Location, _T(""));

  if (basic.gps_altitude_available) {
    FormatUserAltitude(basic.gps_altitude,
                              buffer.buffer(), buffer.MAX_SIZE);
    SetText(Altitude, buffer);
  } else
    SetText(Altitude, _T(""));

  FormatUserAltitude(calculated.max_height_gain,
                            buffer.buffer(), buffer.MAX_SIZE);
  SetText(MaxHeightGain, buffer);

  if (nearest_waypoint) {
    GeoVector vec(basic.location,
                  nearest_waypoint->location);

    SetText(Near, nearest_waypoint->name.c_str());

    FormatBearing(buffer.buffer(), buffer.MAX_SIZE, vec.bearing, _T(""));
    SetText(Bearing, buffer);

    FormatUserDistanceSmart(vec.distance, buffer.buffer(), buffer.MAX_SIZE);
    SetText(Distance, buffer);
  } else {
    SetText(Near, _T("-"));
    SetText(Bearing, _T("-"));
    SetText(Distance, _T("-"));
  }
}
Esempio n. 9
0
inline void
PlaneListWidget::EditClicked()
{
  assert(GetList().GetCursorIndex() < list.size());

  const unsigned index = GetList().GetCursorIndex();
  const TCHAR *old_path = list[index].path;
  const TCHAR *old_filename = list[index].name;

  Plane plane;
  PlaneGlue::ReadFile(plane, old_path);

  while (dlgPlaneDetailsShowModal(plane)) {
    if (plane.registration.empty()) {
      ShowMessageBox(_("Please enter the registration of the plane!"),
                  _("Error"), MB_OK);
      continue;
    }

    StaticString<42> filename(plane.registration);
    filename += _T(".xcp");

    if (filename != old_filename) {
      StaticString<MAX_PATH> path;
      DirName(old_path, path.buffer());
      path += _T(DIR_SEPARATOR_S);
      path += filename;

      if (File::Exists(path)) {
        StaticString<256> tmp;
        tmp.Format(_("Plane \"%s\" already exists. "
                     "Overwrite it?"),
                     plane.registration.c_str());
        if (ShowMessageBox(tmp, _("Overwrite"), MB_YESNO) != IDYES)
          continue;
      }

      File::Delete(old_path);
      PlaneGlue::WriteFile(plane, path);
      if (Profile::GetPathIsEqual("PlanePath", old_path)) {
        list[index].path = path;
        list[index].name = filename;
        Load(index);
      }
    } else {
      PlaneGlue::WriteFile(plane, old_path);
      if (Profile::GetPathIsEqual("PlanePath", old_path))
        Load(index);
    }

    UpdateList();
    break;
  }
}
Esempio n. 10
0
static void
EditClicked(gcc_unused WndButton &button)
{
  assert(plane_list->GetCursorIndex() < list.size());

  const unsigned index = plane_list->GetCursorIndex();
  const TCHAR *old_path = list[index].path;
  const TCHAR *old_filename = list[index].name;

  Plane plane;
  PlaneGlue::ReadFile(plane, old_path);

  while (dlgPlaneDetailsShowModal(*(SingleWindow*)dialog->get_root_owner(), plane)) {
    if (plane.registration.empty()) {
      MessageBoxX(_("Please enter the registration of the plane!"),
                  _("Error"), MB_OK);
      continue;
    }

    StaticString<42> filename(plane.registration);
    filename += _T(".xcp");

    if (filename != old_filename) {
      StaticString<MAX_PATH> path;
      DirName(old_path, path.buffer());
      path += _T(DIR_SEPARATOR_S);
      path += filename;

      if (File::Exists(path)) {
        StaticString<256> tmp;
        tmp.Format(_("A plane profile \"%s\" already exists. "
                     "Do you want to overwrite it?"),
                     filename.c_str());
        if (MessageBoxX(tmp, _("Overwrite"), MB_YESNO) != IDYES)
          continue;
      }

      File::Delete(old_path);
      PlaneGlue::WriteFile(plane, path);
      if (Profile::GetPathIsEqual(_T("PlanePath"), old_path)) {
        list[index].path = path;
        list[index].name = filename;
        Load(index);
      }
    } else {
      PlaneGlue::WriteFile(plane, old_path);
      if (Profile::GetPathIsEqual(_T("PlanePath"), old_path))
        Load(index);
    }

    UpdateList();
    break;
  }
}
Esempio n. 11
0
void
InfoBoxContentNextWaypoint::Update(InfoBoxWindow &infobox)
{
  // use proper non-terminal next task stats

  const Waypoint* way_point = protected_task_manager != NULL
    ? protected_task_manager->getActiveWaypoint()
    : NULL;

  if (!way_point) {
    infobox.SetTitle(_("Next"));
    infobox.SetInvalid();
    return;
  }
  SetTitleFromWaypointName(infobox, way_point);

  // Set Comment
  if (way_point->radio_frequency.IsDefined()) {
    StaticString<128> comment;
    const unsigned freq = way_point->radio_frequency.GetKiloHertz();
    _sntprintf(comment.buffer(), comment.MAX_SIZE, _T("%u.%03u %s"),
               freq / 1000, freq % 1000, way_point->Comment.c_str());
    infobox.SetComment(comment);
  }
  else
    infobox.SetComment(way_point->Comment.c_str());

  const GlideResult &solution_remaining =
    XCSoarInterface::Calculated().task_stats.current_leg.solution_remaining;
  if (!XCSoarInterface::Basic().track_available ||
      !XCSoarInterface::Calculated().task_stats.task_valid ||
      !solution_remaining.defined() ||
      solution_remaining.Vector.Distance <= fixed(10)) {
    infobox.SetValueInvalid();
    return;
  }

  // Set Value
  Angle Value =
    solution_remaining.Vector.Bearing - XCSoarInterface::Basic().track;

  SetValueBearingDifference(infobox, Value);

  // Set Color (blue/black)
  infobox.SetColor(solution_remaining.is_final_glide() ? 2 : 0);
}
Esempio n. 12
0
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);
}
Esempio n. 13
0
bool
LoggerImpl::StartLogger(const NMEAInfo &gps_info,
                        const LoggerSettings &settings,
                        const char *logger_id)
{
  assert(logger_id != NULL);
  assert(strlen(logger_id) == 3);

  /* finish the previous IGC file */
  StopLogger(gps_info);

  assert(writer == NULL);

  LocalPath(filename, _T("logs"));
  Directory::Create(filename);

  const BrokenDate today = gps_info.date_time_utc.IsDatePlausible()
    ? (const BrokenDate &)gps_info.date_time_utc
    : BrokenDate::TodayUTC();

  StaticString<64> name;
  for (int i = 1; i < 99; i++) {
    FormatIGCFilenameLong(name.buffer(), today, "XCS", logger_id, i);

    LocalPath(filename, _T("logs"), name);
    if (!File::Exists(filename))
      break;  // file not exist, we'll use this name
  }

  frecord.Reset();
  writer = new IGCWriter(filename);
  if (!writer->IsOpen()) {
    LogFormat(_T("Failed to create file %s"), filename);
    delete writer;
    writer = nullptr;
    return false;
  }

  LogFormat(_T("Logger Started: %s"), filename);
  return true;
}
Esempio n. 14
0
bool
LoggerImpl::StartLogger(const NMEAInfo &gps_info,
                        const LoggerSettings &settings,
                        const char *logger_id)
{
  assert(logger_id != nullptr);
  assert(strlen(logger_id) == 3);

  /* finish the previous IGC file */
  StopLogger(gps_info);

  assert(writer == nullptr);

  const auto logs_path = MakeLocalPath(_T("logs"));

  const BrokenDate today = gps_info.date_time_utc.IsDatePlausible()
    ? (const BrokenDate &)gps_info.date_time_utc
    : BrokenDate::TodayUTC();

  StaticString<64> name;
  for (int i = 1; i < 99; i++) {
    FormatIGCFilenameLong(name.buffer(), today, "XCS", logger_id, i);

    filename = AllocatedPath::Build(logs_path, name);
    if (!File::Exists(filename))
      break;  // file not exist, we'll use this name
  }

  frecord.Reset();

  try {
    writer = new IGCWriter(filename);
  } catch (...) {
    LogError(std::current_exception());
    return false;
  }

  LogFormat(_T("Logger Started: %s"), filename.c_str());
  return true;
}
Esempio n. 15
0
inline void
ProfileListWidget::NewClicked()
{
  StaticString<64> name;
  name.clear();
  if (!TextEntryDialog(name, _("Profile name")))
      return;

  StaticString<80> filename;
  filename = name;
  filename += _T(".prf");

  StaticString<MAX_PATH> path;
  LocalPath(path.buffer(), filename);

  if (!File::CreateExclusive(path)) {
    ShowMessageBox(name, _("File exists already."), MB_OK|MB_ICONEXCLAMATION);
    return;
  }

  UpdateList();
  SelectPath(path);
}
Esempio n. 16
0
File: Map.hpp Progetto: ppara/XCSoar
 bool Get(const char *key, StaticString<max> &value) const {
   return Get(key, value.buffer(), value.MAX_SIZE);
 }
Esempio n. 17
0
void
GlueMapWindow::DrawMapScale(Canvas &canvas, const PixelRect &rc,
                            const MapWindowProjection &projection) const
{
  StaticString<80> buffer;

  fixed map_width = projection.GetScreenWidthMeters();

  canvas.Select(Fonts::map_bold);
  FormatUserMapScale(map_width, buffer.buffer(), true);
  PixelSize text_size = canvas.CalcTextSize(buffer);

  const PixelScalar text_padding_x = Layout::Scale(2);
  const PixelScalar height = Fonts::map_bold.GetCapitalHeight() + Layout::Scale(2);

  PixelScalar x = 0;
  look.map_scale_left_icon.Draw(canvas, 0, rc.bottom - height);

  x += look.map_scale_left_icon.GetSize().cx;
  canvas.DrawFilledRectangle(x, rc.bottom - height,
                             x + 2 * text_padding_x + text_size.cx,
                             rc.bottom, COLOR_WHITE);

  canvas.SetBackgroundTransparent();
  canvas.SetTextColor(COLOR_BLACK);
  x += text_padding_x;
  canvas.text(x, rc.bottom - Fonts::map_bold.GetAscentHeight() - Layout::Scale(1),
              buffer);

  x += text_padding_x + text_size.cx;
  look.map_scale_right_icon.Draw(canvas, x, rc.bottom - height);

  buffer.clear();
  if (GetMapSettings().auto_zoom_enabled)
    buffer = _T("AUTO ");

  switch (follow_mode) {
  case FOLLOW_SELF:
    break;

  case FOLLOW_PAN:
    buffer += _T("PAN ");
    break;
  }

  const UIState &ui_state = GetUIState();
  if (ui_state.auxiliary_enabled) {
    buffer += ui_state.panel_name;
    buffer += _T(" ");
  }

  if (Basic().gps.replay)
    buffer += _T("REPLAY ");
  else if (Basic().gps.simulator) {
    buffer += _("Simulator");
    buffer += _T(" ");
  }

  if (GetComputerSettings().polar.ballast_timer_active)
    buffer.AppendFormat(
        _T("BALLAST %d LITERS "),
        (int)GetComputerSettings().polar.glide_polar_task.GetBallastLitres());

  if (weather != NULL && weather->GetParameter() > 0) {
    const TCHAR *label = weather->ItemLabel(weather->GetParameter());
    if (label != NULL)
      buffer += label;
  }

  if (!buffer.empty()) {
    int y = rc.bottom - height;

    canvas.Select(Fonts::title);
    canvas.SetBackgroundOpaque();
    canvas.SetBackgroundColor(COLOR_WHITE);

    canvas.text(0, y - canvas.CalcTextSize(buffer).cy, buffer);
  }
}
Esempio n. 18
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());
  }

}
Esempio n. 19
0
void
GlueMapWindow::DrawMapScale(Canvas &canvas, const PixelRect &rc,
                            const MapWindowProjection &projection) const
{
  if (!projection.IsValid())
    return;

  StaticString<80> buffer;

  fixed map_width = projection.GetScreenWidthMeters();

  const Font &font = *look.overlay_font;
  canvas.Select(font);
  FormatUserMapScale(map_width, buffer.buffer(), true);
  PixelSize text_size = canvas.CalcTextSize(buffer);

  const PixelScalar text_padding_x = Layout::GetTextPadding();
  const PixelScalar height = font.GetCapitalHeight()
    + Layout::GetTextPadding();

  PixelScalar x = 0;
  look.map_scale_left_icon.Draw(canvas, 0, rc.bottom - height);

  x += look.map_scale_left_icon.GetSize().cx;
  canvas.DrawFilledRectangle(x, rc.bottom - height,
                             x + 2 * text_padding_x + text_size.cx,
                             rc.bottom, COLOR_WHITE);

  canvas.SetBackgroundTransparent();
  canvas.SetTextColor(COLOR_BLACK);
  x += text_padding_x;
  canvas.DrawText(x,
                  rc.bottom - font.GetAscentHeight() - Layout::Scale(1),
                  buffer);

  x += text_padding_x + text_size.cx;
  look.map_scale_right_icon.Draw(canvas, x, rc.bottom - height);

  buffer.clear();
  if (GetMapSettings().auto_zoom_enabled)
    buffer = _T("AUTO ");

  switch (follow_mode) {
  case FOLLOW_SELF:
    break;

  case FOLLOW_PAN:
    buffer += _T("PAN ");
    break;
  }

  const UIState &ui_state = GetUIState();
  if (ui_state.auxiliary_enabled) {
    buffer += ui_state.panel_name;
    buffer += _T(" ");
  }

  if (Basic().gps.replay)
    buffer += _T("REPLAY ");
  else if (Basic().gps.simulator) {
    buffer += _("Simulator");
    buffer += _T(" ");
  }

  if (GetComputerSettings().polar.ballast_timer_active)
    buffer.AppendFormat(
        _T("BALLAST %d LITERS "),
        (int)GetComputerSettings().polar.glide_polar_task.GetBallastLitres());

  if (weather != nullptr && weather->GetParameter() > 0) {
    const TCHAR *label = weather->ItemLabel(weather->GetParameter());
    if (label != nullptr)
      buffer += label;
  }

  if (!buffer.empty()) {
    int y = rc.bottom - height;

    TextInBoxMode mode;
    mode.vertical_position = TextInBoxMode::VerticalPosition::ABOVE;
    mode.shape = LabelShape::OUTLINED;

    TextInBox(canvas, buffer, 0, y, mode, rc, nullptr);
  }
}
Esempio n. 20
0
void
WaypointInfoWidget::Prepare(ContainerWindow &parent, const PixelRect &rc)
{
  RowFormWidget::Prepare(parent, rc);

  const MoreData &basic = CommonInterface::Basic();
  const DerivedInfo &calculated = CommonInterface::Calculated();
  const ComputerSettings &settings = CommonInterface::GetComputerSettings();

  StaticString<64> buffer;

  if (!waypoint.comment.empty())
    AddMultiLine(waypoint.comment.c_str());

  if (waypoint.radio_frequency.IsDefined() &&
      waypoint.radio_frequency.Format(buffer.buffer(),
                                      buffer.MAX_SIZE) != nullptr) {
    buffer += _T(" MHz");
    AddReadOnly(_("Radio frequency"), nullptr, buffer);
  }

  if (waypoint.runway.IsDirectionDefined())
    buffer.UnsafeFormat(_T("%02u"), waypoint.runway.GetDirectionName());
  else
    buffer.clear();

  if (waypoint.runway.IsLengthDefined()) {
    if (!buffer.empty())
      buffer += _T("; ");

    TCHAR length_buffer[16];
    FormatSmallUserDistance(length_buffer,
                                   fixed(waypoint.runway.GetLength()));
    buffer += length_buffer;
  }

  if (!buffer.empty())
    AddReadOnly(_("Runway"), nullptr, buffer);

  if (FormatGeoPoint(waypoint.location,
                     buffer.buffer(), buffer.MAX_SIZE) != nullptr)
    AddReadOnly(_("Location"), nullptr, buffer);

  FormatUserAltitude(waypoint.elevation,
                            buffer.buffer(), buffer.MAX_SIZE);
  AddReadOnly(_("Elevation"), nullptr, buffer);

  if (basic.time_available && basic.date_time_utc.IsDatePlausible()) {
    const SunEphemeris::Result sun =
      SunEphemeris::CalcSunTimes(waypoint.location, basic.date_time_utc,
                                 settings.utc_offset);

    const BrokenTime sunrise = BreakHourOfDay(sun.time_of_sunrise);
    const BrokenTime sunset = BreakHourOfDay(sun.time_of_sunset);

    buffer.UnsafeFormat(_T("%02u:%02u - %02u:%02u"),
                        sunrise.hour, sunrise.minute,
                        sunset.hour, sunset.minute);
    AddReadOnly(_("Daylight time"), nullptr, buffer);
  }

  if (basic.location_available) {
    const GeoVector vector = basic.location.DistanceBearing(waypoint.location);

    TCHAR distance_buffer[32];
    FormatUserDistanceSmart(vector.distance, distance_buffer,
                                   ARRAY_SIZE(distance_buffer));

    FormatBearing(buffer.buffer(), buffer.MAX_SIZE,
                  vector.bearing, distance_buffer);
    AddReadOnly(_("Bearing and Distance"), nullptr, buffer);
  }

  if (basic.location_available && basic.NavAltitudeAvailable() &&
      settings.polar.glide_polar_task.IsValid()) {
    const GlideState glide_state(basic.location.DistanceBearing(waypoint.location),
                                 waypoint.elevation + settings.task.safety_height_arrival,
                                 basic.nav_altitude,
                                 calculated.GetWindOrZero());

    GlidePolar gp0 = settings.polar.glide_polar_task;
    gp0.SetMC(fixed(0));
    AddGlideResult(_("Alt. diff. MC 0"),
                   MacCready::Solve(settings.task.glide,
                                    gp0, glide_state));

    AddGlideResult(_("Alt. diff. MC safety"),
                   MacCready::Solve(settings.task.glide,
                                    calculated.glide_polar_safety,
                                    glide_state));

    AddGlideResult(_("Alt. diff. MC current"),
                   MacCready::Solve(settings.task.glide,
                                    settings.polar.glide_polar_task,
                                    glide_state));
  }

  if (basic.location_available && basic.NavAltitudeAvailable()) {
    const TaskBehaviour &task_behaviour =
      CommonInterface::GetComputerSettings().task;

    const fixed safety_height = task_behaviour.safety_height_arrival;
    const fixed target_altitude = waypoint.elevation + safety_height;
    const fixed delta_h = basic.nav_altitude - target_altitude;
    if (positive(delta_h)) {
      const fixed distance = basic.location.Distance(waypoint.location);
      const fixed gr = distance / delta_h;
      if (GradientValid(gr)) {
        buffer.UnsafeFormat(_T("%.1f"), (double)gr);
        AddReadOnly(_("Required glide ratio"), nullptr, buffer);
      }
    }
  }
}
Esempio n. 21
0
void
TimesStatusPanel::Refresh()
{
  const NMEAInfo &basic = CommonInterface::Basic();
  const FlyingState &flight = CommonInterface::Calculated().flight;
  const ComputerSettings &settings = CommonInterface::GetComputerSettings();

  StaticString<64> temp;

  if (basic.location_available && basic.date_available) {
    SunEphemeris::Result sun =
      SunEphemeris::CalcSunTimes(basic.location, basic.date_time_utc,
                                 settings.utc_offset);

    const unsigned sunrisehours = (int)sun.time_of_sunrise;
    const unsigned sunrisemins = (int)((sun.time_of_sunrise - fixed(sunrisehours)) * 60);
    const unsigned sunsethours = (int)sun.time_of_sunset;
    const unsigned sunsetmins = (int)((sun.time_of_sunset - fixed(sunsethours)) * 60);

    temp.Format(_T("%02u:%02u - %02u:%02u"), sunrisehours, sunrisemins, sunsethours, sunsetmins);
    SetText(Daylight, temp);
  } else {
    SetText(Daylight, _T(""));
  }

  if (basic.time_available) {
    FormatLocalTimeHHMM(temp.buffer(), (int)basic.time, settings.utc_offset);
    SetText(LocalTime, temp);
    FormatSignedTimeHHMM(temp.buffer(), (int) basic.time);
    SetText(UTCTime, temp);
  } else {
    SetText(LocalTime, _T(""));
    SetText(UTCTime, _T(""));
  }

  if (basic.date_available) {
    temp.Format(_T("%04d-%02d-%02d"), basic.date_time_utc.year,
                basic.date_time_utc.month, basic.date_time_utc.day);
    SetText(UTCDate, temp);
  } else {
    SetText(UTCDate, _T(""));
  }

  if (positive(flight.flight_time)) {
    FormatLocalTimeHHMM(temp.buffer(), (int)flight.takeoff_time,
                        settings.utc_offset);
    SetText(TakeoffTime, temp);
  } else {
    SetText(TakeoffTime, _T(""));
  }

  if (!flight.flying && positive(flight.flight_time)) {
    FormatLocalTimeHHMM(temp.buffer(),
                        int(flight.takeoff_time + flight.flight_time),
                        settings.utc_offset);
    SetText(LandingTime, temp);
  } else {
    SetText(LandingTime, _T(""));
  }

  if (positive(flight.flight_time)) {
    FormatSignedTimeHHMM(temp.buffer(), (int)flight.flight_time);
    SetText(FlightTime, temp);
  } else {
    SetText(FlightTime, _T(""));
  }
}
Esempio n. 22
0
static void
LoadString(const char *bytes, size_t length, StaticString<size> &dest)
{
  return LoadString(bytes, length, dest.buffer(), dest.capacity());
}
Esempio n. 23
0
void
WaypointInfoWidget::Prepare(ContainerWindow &parent, const PixelRect &rc)
{
  RowFormWidget::Prepare(parent, rc);

  const MoreData &basic = CommonInterface::Basic();
  const DerivedInfo &calculated = CommonInterface::Calculated();
  const ComputerSettings &settings = CommonInterface::GetComputerSettings();

  StaticString<64> buffer;

  if (!waypoint.comment.empty())
    AddMultiLine(waypoint.comment.c_str());

  if (waypoint.radio_frequency.IsDefined() &&
      waypoint.radio_frequency.Format(buffer.buffer(),
                                      buffer.MAX_SIZE) != NULL) {
    buffer += _T(" MHz");
    AddReadOnly(_("Radio frequency"), NULL, buffer);
  }

  if (waypoint.runway.IsDirectionDefined())
    buffer.UnsafeFormat(_T("%02u"), waypoint.runway.GetDirectionName());
  else
    buffer.clear();

  if (waypoint.runway.IsLengthDefined()) {
    if (!buffer.empty())
      buffer += _T("; ");

    TCHAR length_buffer[16];
    FormatSmallUserDistance(length_buffer,
                                   fixed(waypoint.runway.GetLength()));
    buffer += length_buffer;
  }

  if (!buffer.empty())
    AddReadOnly(_("Runway"), NULL, buffer);

  if (FormatGeoPoint(waypoint.location,
                     buffer.buffer(), buffer.MAX_SIZE) != NULL)
    AddReadOnly(_("Location"), NULL, buffer);

  FormatUserAltitude(waypoint.elevation,
                            buffer.buffer(), buffer.MAX_SIZE);
  AddReadOnly(_("Elevation"), NULL, buffer);

  if (basic.time_available) {
    const SunEphemeris::Result sun =
      SunEphemeris::CalcSunTimes(waypoint.location, basic.date_time_utc,
                                 fixed(GetUTCOffset()) / 3600);

    const unsigned sunrisehours = (int)sun.time_of_sunrise;
    const unsigned sunrisemins = (int)((sun.time_of_sunrise - fixed(sunrisehours)) * 60);
    const unsigned sunset_hour = (int)sun.time_of_sunset;
    const unsigned sunset_minute = (int)((sun.time_of_sunset - fixed(sunset_hour)) * 60);

    buffer.UnsafeFormat(_T("%02u:%02u - %02u:%02u"), sunrisehours, sunrisemins, sunset_hour, sunset_minute);
    AddReadOnly(_("Daylight time"), NULL, buffer);
  }

  if (basic.location_available) {
    const GeoVector vector = basic.location.DistanceBearing(waypoint.location);

    TCHAR distance_buffer[32];
    FormatUserDistanceSmart(vector.distance, distance_buffer,
                                   ARRAY_SIZE(distance_buffer));

    FormatBearing(buffer.buffer(), buffer.MAX_SIZE,
                  vector.bearing, distance_buffer);
    AddReadOnly(_("Bearing and Distance"), NULL, buffer);
  }

  if (basic.location_available && basic.NavAltitudeAvailable() &&
      settings.polar.glide_polar_task.IsValid()) {
    const GlideState glide_state(basic.location.DistanceBearing(waypoint.location),
                                 waypoint.elevation + settings.task.safety_height_arrival,
                                 basic.nav_altitude,
                                 calculated.GetWindOrZero());

    GlidePolar gp0 = settings.polar.glide_polar_task;
    gp0.SetMC(fixed(0));
    AddGlideResult(_("Alt. diff. MC 0"),
                   MacCready::Solve(settings.task.glide,
                                    gp0, glide_state));

    AddGlideResult(_("Alt. diff. MC safety"),
                   MacCready::Solve(settings.task.glide,
                                    calculated.glide_polar_safety,
                                    glide_state));

    AddGlideResult(_("Alt. diff. MC current"),
                   MacCready::Solve(settings.task.glide,
                                    settings.polar.glide_polar_task,
                                    glide_state));
  }
}
 static inline bool
 Get(const TCHAR *key, StaticString<max> &value)
 {
   return Get(key, value.buffer(), value.MAX_SIZE);
 }