Example #1
0
void
InfoBoxContentTaskAATime::Update(InfoBoxData &data)
{
  const TaskStats &task_stats = XCSoarInterface::Calculated().task_stats;
  const CommonStats &common_stats = XCSoarInterface::Calculated().common_stats;

  if (!common_stats.ordered_has_targets ||
      !task_stats.task_valid || !task_stats.total.IsAchievable()) {
    data.SetInvalid();
    return;
  }

  TCHAR value[32];
  TCHAR comment[32];
  FormatTimeTwoLines(value, comment,
                         abs((int) common_stats.aat_time_remaining));

  data.UnsafeFormatValue(negative(common_stats.aat_time_remaining) ?
                            _T("-%s") : _T("%s"), value);
  data.SetValueColor(negative(common_stats.aat_time_remaining) ? 1 : 0);

  data.SetComment(comment);
}
Example #2
0
void
InfoBoxContentNextLD::Update(InfoBoxData &data)
{
  // pilots want this to be assuming terminal flight to this wp, and this
  // is what current_leg gradient does.

  if (!XCSoarInterface::Calculated().task_stats.task_valid) {
    data.SetInvalid();
    return;
  }

  fixed gradient = XCSoarInterface::Calculated().task_stats.current_leg.gradient;

  if (!positive(gradient)) {
    data.SetValue(_T("+++"));
    return;
  }
  if (::GradientValid(gradient)) {
    data.UnsafeFormatValue(_T("%d"), (int)gradient);
  } else {
    data.SetInvalid();
  }
}
Example #3
0
void
UpdateInfoBoxNextETA(InfoBoxData &data)
{
  // use proper non-terminal next task stats

  const TaskStats &task_stats = CommonInterface::Calculated().task_stats;
  const BrokenTime &now_local = CommonInterface::Calculated().date_time_local;

  if (!task_stats.task_valid || !task_stats.current_leg.IsAchievable() ||
      !now_local.IsPlausible()) {
    data.SetInvalid();
    return;
  }

  const BrokenTime t = now_local +
    unsigned(task_stats.current_leg.solution_remaining.time_elapsed);

  // Set Value
  data.UnsafeFormatValue(_T("%02u:%02u"), t.hour, t.minute);

  // Set Comment
  data.UnsafeFormatComment(_T("%02u"), t.second);
}
Example #4
0
void
UpdateInfoBoxNextGR(InfoBoxData &data)
{
  // pilots want this to be assuming terminal flight to this wp, and this
  // is what current_leg gradient does.

  if (!CommonInterface::Calculated().task_stats.task_valid) {
    data.SetInvalid();
    return;
  }

  fixed gradient = CommonInterface::Calculated().task_stats.current_leg.gradient;

  if (!positive(gradient)) {
    data.SetValue(_T("+++"));
    return;
  }
  if (::GradientValid(gradient)) {
    data.SetValueFromGlideRatio(gradient);
  } else {
    data.SetInvalid();
  }
}
Example #5
0
void
InfoBoxContentFlightLevel::Update(InfoBoxData &data)
{
  const NMEAInfo &basic = CommonInterface::Basic();
  const ComputerSettings &settings_computer =
    CommonInterface::GetComputerSettings();

  if (basic.pressure_altitude_available) {
    fixed Altitude = Units::ToUserUnit(basic.pressure_altitude, Unit::FEET);

    // Title color black
    data.SetTitleColor(0);

    // Set Value
    data.UnsafeFormatValue(_T("%03d"), iround(Altitude / 100));

    // Set Comment
    data.UnsafeFormatComment(_T("%dft"), iround(Altitude));

  } else if (basic.gps_altitude_available &&
             settings_computer.pressure_available) {
    // Take gps altitude as baro altitude. This is inaccurate but still fits our needs.
    const AtmosphericPressure &qnh = settings_computer.pressure;
    fixed Altitude = Units::ToUserUnit(qnh.QNHAltitudeToPressureAltitude(basic.gps_altitude), Unit::FEET);

    // Title color red
    data.SetTitleColor(1);

    // Set Value
    data.UnsafeFormatValue(_T("%03d"), iround(Altitude / 100));

    // Set Comment
    data.UnsafeFormatComment(_T("%dft"), iround(Altitude));

  } else if ((basic.baro_altitude_available || basic.gps_altitude_available) &&
             !settings_computer.pressure_available) {
    data.SetInvalid();
    data.SetComment(_("no QNH"));
  } else {
    data.SetInvalid();
  }
}
Example #6
0
void
UpdateInfoBoxTaskAATime(InfoBoxData &data)
{
  const auto &calculated = CommonInterface::Calculated();
  const TaskStats &task_stats = calculated.ordered_task_stats;
  const CommonStats &common_stats = calculated.common_stats;

  if (!task_stats.has_targets ||
      !task_stats.total.IsAchievable()) {
    data.SetInvalid();
    return;
  }

  TCHAR value[32];
  TCHAR comment[32];
  FormatTimeTwoLines(value, comment,
                         abs((int) common_stats.aat_time_remaining));

  data.UnsafeFormatValue(common_stats.aat_time_remaining < 0 ?
                            _T("-%s") : _T("%s"), value);
  data.SetValueColor(common_stats.aat_time_remaining < 0 ? 1 : 0);

  data.SetComment(comment);
}
Example #7
0
void
InfoBoxContentBearingDiff::Update(InfoBoxData &data)
{
  const NMEAInfo &basic = CommonInterface::Basic();
  const TaskStats &task_stats = CommonInterface::Calculated().task_stats;
  const GeoVector &vector_remaining = task_stats.current_leg.vector_remaining;
  if (!basic.track_available || !task_stats.task_valid ||
      !vector_remaining.IsValid() || vector_remaining.distance <= fixed(10)) {
    data.SetInvalid();
    return;
  }

  Angle Value = vector_remaining.bearing - basic.track;
  SetValueBearingDifference(data, Value);
}
Example #8
0
void
InfoBoxContentTaskAADistanceMin::Update(InfoBoxData &data)
{
  const TaskStats &task_stats = XCSoarInterface::Calculated().task_stats;
  const CommonStats &common_stats = XCSoarInterface::Calculated().common_stats;

  if (!common_stats.ordered_has_targets ||
      !task_stats.task_valid) {
    data.SetInvalid();
    return;
  }

  // Set Value
  SetValueFromDistance(data, task_stats.distance_min);
}
Example #9
0
void
InfoBoxContentNextWaypoint::Update(InfoBoxData &data)
{
  // use proper non-terminal next task stats

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

  if (!way_point) {
    data.SetTitle(_("Next"));
    data.SetInvalid();
    return;
  }

  data.SetTitle(way_point->name.c_str());

  // Set Comment
  if (way_point->radio_frequency.IsDefined()) {
    const unsigned freq = way_point->radio_frequency.GetKiloHertz();
    data.FormatComment(_T("%u.%03u %s"),
                       freq / 1000, freq % 1000, way_point->comment.c_str());
  }
  else
    data.SetComment(way_point->comment.c_str());

  const NMEAInfo &basic = CommonInterface::Basic();
  const TaskStats &task_stats = CommonInterface::Calculated().task_stats;
  const GlideResult &solution_remaining =
    task_stats.current_leg.solution_remaining;
  const GeoVector &vector_remaining = task_stats.current_leg.vector_remaining;
  if (!basic.track_available || !task_stats.task_valid ||
      !vector_remaining.IsValid()) {
    data.SetValueInvalid();
    return;
  }

  // Set Value
  Angle Value = vector_remaining.bearing - basic.track;
  data.SetValueFromBearingDifference(Value);

  // Set Color (blue/black)
  data.SetValueColor(solution_remaining.IsFinalGlide() ? 2 : 0);
}
Example #10
0
void
InfoBoxContentFinalDistance::Update(InfoBoxData &data)
{
  const TaskStats &task_stats = XCSoarInterface::Calculated().task_stats;

  if (!task_stats.task_valid ||
      !task_stats.current_leg.vector_remaining.IsValid() ||
      !task_stats.total.remaining.IsDefined()) {
    data.SetInvalid();
    return;
  }

  const CommonStats &common_stats = XCSoarInterface::Calculated().common_stats;

  // Set Value
  SetValueFromDistance(data, common_stats.task_finished
                       ? task_stats.current_leg.vector_remaining.distance
                       : task_stats.total.remaining.get_distance());
}
Example #11
0
void
InfoBoxContentAlternateName::Update(InfoBoxData &data)
{
  if (protected_task_manager == NULL) {
    data.SetInvalid();
    return;
  }

  ProtectedTaskManager::Lease lease(*protected_task_manager);
  const AlternateList &alternates = lease->GetAlternates();

  const AlternatePoint *alternate;
  if (!alternates.empty()) {
    if (index >= alternates.size())
      index = alternates.size() - 1;

    alternate = &alternates[index];
  } else {
    alternate = NULL;
  }

  data.FormatTitle(_("Altn %d"), index + 1);

  if (alternate == NULL || !CommonInterface::Basic().track_available) {
    data.SetInvalid();
    return;
  }

  data.SetComment(alternate->waypoint.name.c_str());

  // Set Value
  Angle Value = alternate->solution.vector.bearing -
    CommonInterface::Basic().track;

  data.SetValueFromBearingDifference(Value);

  // Set Color (blue/black)
  data.SetValueColor(alternate->solution.IsFinalGlide() ? 2 : 0);
}
Example #12
0
void
UpdateInfoBoxCircleDiameter(InfoBoxData &data)
{
  if (!CommonInterface::Basic().airspeed_available.IsValid()) {
    data.SetInvalid();
    return;
  }

  const Angle turn_rate =
    CommonInterface::Calculated().turn_rate_heading_smoothed.Absolute();

  // deal with div zero and small turn rates
  if (turn_rate < Angle::Degrees(1)) {
    data.SetInvalid();
    return;
  }

  const fixed circle_diameter = CommonInterface::Basic().true_airspeed
     / turn_rate.Radians()
     * fixed(2); // convert turn rate to radians/s and double it to get estimated circle diameter

  if (circle_diameter > fixed (2000)){ // arbitrary estimated that any diameter bigger than 2km will not be interesting
    data.SetInvalid();
    return;
  }

  TCHAR buffer[32];
  Unit unit = FormatSmallUserDistance(buffer, circle_diameter, false, 0);
  data.SetValue (buffer);
  data.SetValueUnit(unit);

  const fixed circle_duration =
    Angle::FullCircle().Native() / turn_rate.Native();

  StaticString<16> duration_buffer;
  duration_buffer.Format(_T("%u s"), int(circle_duration));
  _tcscpy (buffer, duration_buffer);
  data.SetComment (buffer);
}
Example #13
0
void
UpdateInfoBoxTeamDistance(InfoBoxData &data)
{
  const TeamCodeSettings &settings =
    CommonInterface::GetComputerSettings().team_code;
  const TeamInfo &teamcode_info = CommonInterface::Calculated();

  // Set Value
  if (teamcode_info.teammate_available)
    data.SetValueFromDistance(teamcode_info.teammate_vector.distance);
  else
    data.SetValueInvalid();

  // Set Comment
  if (!settings.team_flarm_id.IsDefined())
    data.SetCommentInvalid();
  else if (!StringIsEmpty(settings.team_flarm_callsign))
    data.SetComment(settings.team_flarm_callsign);
  else
    data.SetComment(_T("???"));

  data.SetCommentColor(teamcode_info.flarm_teammate_code_current ? 2 : 1);
}
Example #14
0
void
UpdateInfoBoxBattery(InfoBoxData &data)
{
#ifdef HAVE_BATTERY
  bool DisplaySupplyVoltageAsValue=false;
  switch (Power::External::Status) {
    case Power::External::OFF:
      if (CommonInterface::Basic().battery_level_available)
        data.UnsafeFormatComment(_T("%s; %d%%"),
                                 _("AC Off"),
                                 (int)CommonInterface::Basic().battery_level);
      else
        data.SetComment(_("AC Off"));
      break;
    case Power::External::ON:
      if (!CommonInterface::Basic().voltage_available)
        data.SetComment(_("AC ON"));
      else{
        DisplaySupplyVoltageAsValue = true;
        data.SetValueFromVoltage(CommonInterface::Basic().voltage);
      }
      break;
    case Power::External::UNKNOWN:
    default:
      data.SetCommentInvalid();
  }
#ifndef ANDROID
  switch (Power::Battery::Status){
    case Power::Battery::HIGH:
    case Power::Battery::LOW:
    case Power::Battery::CRITICAL:
    case Power::Battery::CHARGING:
      if (Power::Battery::RemainingPercentValid){
#endif
        if (!DisplaySupplyVoltageAsValue)
          data.SetValueFromPercent(Power::Battery::RemainingPercent);
        else
          data.SetCommentFromPercent(Power::Battery::RemainingPercent);
#ifndef ANDROID
      }
      else
        if (!DisplaySupplyVoltageAsValue)
          data.SetValueInvalid();
        else
          data.SetCommentInvalid();
      break;
    case Power::Battery::NOBATTERY:
    case Power::Battery::UNKNOWN:
      if (!DisplaySupplyVoltageAsValue)
        data.SetValueInvalid();
      else
        data.SetCommentInvalid();
  }
#endif
  return;

#endif

  if (CommonInterface::Basic().voltage_available) {
    data.SetValueFromVoltage(CommonInterface::Basic().voltage);
    return;
  } else if (CommonInterface::Basic().battery_level_available) {
    data.SetValueFromPercent(CommonInterface::Basic().battery_level);
    return;
  }

  data.SetInvalid();
}
Example #15
0
void
UpdateInfoBoxFreeRAM(InfoBoxData &data)
{
  // used to be implemented on WinCE
  data.SetInvalid();
}
Example #16
0
void
UpdateInfoBoxExperimental2(InfoBoxData &data)
{
  // Set Value
  data.SetInvalid();
}
Example #17
0
void
InfoBoxContentSpeedMacCready::Update(InfoBoxData &data)
{
  const CommonStats &common_stats = CommonInterface::Calculated().common_stats;
  data.SetValueFromSpeed(common_stats.V_block, false);
}
Example #18
0
void
InfoBoxContentThermalBand::Update(InfoBoxData &data)
{
  data.SetCustom();
}
Example #19
0
void
InfoBoxContentTaskProgress::Update(InfoBoxData &data)
{
  data.SetCustom();
}
Example #20
0
void
UpdateInfoBoxStartOpenArrival(InfoBoxData &data)
{
  const NMEAInfo &basic = CommonInterface::Basic();
  const auto &calculated = CommonInterface::Calculated();
  const TaskStats &task_stats = calculated.ordered_task_stats;
  const GlideResult &current_remaining =
    task_stats.current_leg.solution_remaining;
  const CommonStats &common_stats = CommonInterface::Calculated().common_stats;
  const RoughTimeSpan &open = common_stats.start_open_time_span;

  /* reset color that may have been set by a previous call */
  data.SetValueColor(0);

  if (!basic.time_available || !task_stats.task_valid ||
      common_stats.ordered_summary.active != 0 ||
      !open.IsDefined() ||
      !current_remaining.IsOk()) {
    data.SetInvalid();
    return;
  }

  const unsigned arrival_s(basic.time + current_remaining.time_elapsed);
  const RoughTime arrival = RoughTime::FromSecondOfDayChecked(arrival_s);

  if (open.HasEnded(arrival)) {
    data.SetValueInvalid();
    data.SetComment(_("Closed"));
  } else if (open.HasBegun(arrival)) {
    if (open.GetEnd().IsValid()) {
      unsigned seconds = SecondsUntil(arrival_s, open.GetEnd());
      data.UnsafeFormatValue(_T("%02u:%02u"), seconds / 60, seconds % 60);
      data.SetValueColor(3);
    } else
      data.SetValueInvalid();

    data.SetComment(_("Open"));
  } else {
    unsigned seconds = SecondsUntil(arrival_s, open.GetStart());
    data.UnsafeFormatValue(_T("%02u:%02u"), seconds / 60, seconds % 60);
    data.SetValueColor(2);
    data.SetComment(_("Waiting"));
  }
}
Example #21
0
void
InfoBoxContentExperimental2::Update(InfoBoxData &data)
{
  // Set Value
  data.SetInvalid();
}