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); }
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(); } }
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); }
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(); } }
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(); } }
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); }
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); }
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); }
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); }
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()); }
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); }
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); }
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); }
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(); }
void UpdateInfoBoxFreeRAM(InfoBoxData &data) { // used to be implemented on WinCE data.SetInvalid(); }
void UpdateInfoBoxExperimental2(InfoBoxData &data) { // Set Value data.SetInvalid(); }
void InfoBoxContentSpeedMacCready::Update(InfoBoxData &data) { const CommonStats &common_stats = CommonInterface::Calculated().common_stats; data.SetValueFromSpeed(common_stats.V_block, false); }
void InfoBoxContentThermalBand::Update(InfoBoxData &data) { data.SetCustom(); }
void InfoBoxContentTaskProgress::Update(InfoBoxData &data) { data.SetCustom(); }
void UpdateInfoBoxStartOpenArrival(InfoBoxData &data) { const NMEAInfo &basic = CommonInterface::Basic(); const auto &calculated = CommonInterface::Calculated(); const TaskStats &task_stats = calculated.ordered_task_stats; const GlideResult ¤t_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")); } }
void InfoBoxContentExperimental2::Update(InfoBoxData &data) { // Set Value data.SetInvalid(); }