Example #1
0
 void Visit(const AirspaceWarning& as) {
   if (as.get_warning_state()== AirspaceWarning::WARNING_INSIDE) {
     ids_inside.checked_append(&as.get_airspace());
   } else if (as.get_warning_state()> AirspaceWarning::WARNING_CLEAR) {
     ids_warning.checked_append(&as.get_airspace());
     locs.checked_append(as.get_solution().location);
   }
   if (!as.get_ack_expired()) {
     ids_acked.checked_append(&as.get_airspace());
   }
 }
Example #2
0
bool 
AirspaceWarning::operator<(const AirspaceWarning &other) const
{
  // compare bother.ack
  if (get_ack_expired() != other.get_ack_expired())
    // least expired top
    return get_ack_expired() > other.get_ack_expired();

  // compare bother.state
  if (get_warning_state() != other.get_warning_state())
    // most severe top
    return get_warning_state() > other.get_warning_state();

  // state and ack equal, compare bother.time to intersect
  return get_solution().elapsed_time < other.get_solution().elapsed_time;
}
Example #3
0
static void
OnAirspaceListItemPaint(Canvas &canvas, const PixelRect paint_rc, unsigned i)
{
  TCHAR sTmp[128];
  const int paint_rc_margin = 2;   ///< This constant defines the margin that should be respected for renderring within the paint_rc area.

  bool ack1_vis;
  bool ack2_vis;
  bool ack_vis;
  bool enable_vis;
  bool update_vis = false;

  {
    ProtectedAirspaceWarningManager::Lease lease(*airspace_warnings);
    if (lease->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
      if (i==0) {
        canvas.text(paint_rc.left + IBLSCALE(paint_rc_margin),
                    paint_rc.top + IBLSCALE(paint_rc_margin), _("No Warnings"));
      }
      return;
    }
    
    if (i >= lease->size())
      /* this cannot be an assertion, because another thread may have
         modified the AirspaceWarningManager */
      return;
    
    const AirspaceWarning warning = *(lease->get_warning(i));
    const AbstractAirspace& as = warning.get_airspace();
    const AirspaceInterceptSolution& solution = warning.get_solution();
    
    tstring sName = as.get_name_text(false);
    tstring sTop = as.get_top_text(true);
    tstring sBase = as.get_base_text(true);
    tstring sType = as.get_type_text(true);
    
    const int TextHeight = 12, TextTop = 1;

    const int statusColWidth = canvas.text_width(_T("inside"));     //<-- 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 heightColWidth = canvas.text_width(_T("1888 m AGL")); // <-- "1888" is used in order to have enough space for 4-digit heights with "AGL"


    /// Dynamic columns scaling - "name" column is flexible, altitude and state columns are fixed-width.
    const int Col0LeftScreenCoords = Layout::FastScale(paint_rc_margin),
        Col2LeftScreenCoords = paint_rc.right - Layout::FastScale(paint_rc_margin) - (statusColWidth + 2 * Layout::FastScale(paint_rc_margin)),
        Col1LeftScreenCoords = Col2LeftScreenCoords - Layout::FastScale(paint_rc_margin) - heightColWidth;

    PixelRect rcTextClip;
    
    rcTextClip = paint_rc;
    rcTextClip.right = Col1LeftScreenCoords - Layout::FastScale(paint_rc_margin);
    
    Color old_text_color = canvas.get_text_color();
    if (!warning.get_ack_expired())
      canvas.set_text_color(COLOR_GRAY);
    
    { // name, altitude info
      _stprintf(sTmp, _T("%-20s"), sName.c_str());
      
      canvas.text_clipped(paint_rc.left + Col0LeftScreenCoords,
                          paint_rc.top + IBLSCALE(TextTop),
                          rcTextClip, sTmp);
      
      _stprintf(sTmp, _T("%-20s"), sTop.c_str());
      canvas.text(paint_rc.left + Col1LeftScreenCoords,
                  paint_rc.top + IBLSCALE(TextTop), sTmp);
      
      _stprintf(sTmp, _T("%-20s"), sBase.c_str());
      canvas.text(paint_rc.left + Col1LeftScreenCoords,
                  paint_rc.top + IBLSCALE(TextTop + TextHeight),
                  sTmp);
    }
    
    if (warning.get_warning_state() != AirspaceWarning::WARNING_INSIDE &&
        warning.get_warning_state() > AirspaceWarning::WARNING_CLEAR) {
      
      _stprintf(sTmp, _T("%d secs dist %d m"),
                (int)solution.elapsed_time,
                (int)solution.distance);
      
      canvas.text_clipped(paint_rc.left + Col0LeftScreenCoords,
                          paint_rc.top + IBLSCALE(TextTop + TextHeight),
                          rcTextClip, sTmp);
    }
    
    /* draw the warning state indicator */
    
    Brush *state_brush;
    const TCHAR *state_text;
    
    if (warning.get_warning_state() == AirspaceWarning::WARNING_INSIDE) {
      if (warning.get_ack_expired())
        state_brush = &hBrushInsideBk;
      else
        state_brush = &hBrushInsideAckBk;
      state_text = _T("inside");
    } else if (warning.get_warning_state() > AirspaceWarning::WARNING_CLEAR) {
      if (warning.get_ack_expired())
        state_brush = &hBrushNearBk;
      else
        state_brush = &hBrushNearAckBk;
      state_text = _T("near");
    } else {
      state_brush = NULL;
      state_text = NULL;
    }
    
    const PixelSize state_text_size =
      canvas.text_size(state_text != NULL ? state_text : _T("W"));
    
    if (state_brush != NULL) {
      /* colored background */
      PixelRect rc;
      
      rc.left = paint_rc.left + Col2LeftScreenCoords;
      rc.top = paint_rc.top + Layout::FastScale(paint_rc_margin);
      rc.right = paint_rc.right - Layout::FastScale(paint_rc_margin);
      rc.bottom = paint_rc.bottom - Layout::FastScale(paint_rc_margin);
      
      canvas.fill_rectangle(rc, *state_brush);
    }
    
    if (state_text != NULL) {
      // -- status text will be centered inside its table cell:
      canvas.text(paint_rc.left + Col2LeftScreenCoords + Layout::FastScale(paint_rc_margin) + (statusColWidth / 2)  - (canvas.text_width(state_text) / 2),
                  (paint_rc.bottom + paint_rc.top - state_text_size.cy) / 2,
                  state_text);
    }
    
    if (!warning.get_ack_expired())
      canvas.set_text_color(old_text_color);
        
    if (CursorAirspace == &as) {
      update_vis = true;
      if (!warning.get_ack_expired()) {
        ack1_vis = false;
        ack_vis = false;
      } else {
        if (warning.get_warning_state() == 
            AirspaceWarning::WARNING_INSIDE) {
          ack_vis = true;
          ack1_vis = false;
        } else {
          ack_vis = false;
          ack1_vis = true;
        }
      }
      ack2_vis = !warning.get_ack_day();
      enable_vis = !warning.get_ack_expired();
    }
  } // close scope
  if (update_vis) {
    wbAck1->set_visible(ack1_vis);
    wbAck2->set_visible(ack2_vis);
    wbAck->set_visible(ack_vis);
    wbEnable->set_visible(enable_vis);
  }
}
Example #4
0
static void
OnAirspaceListItemPaint(Canvas &canvas, const RECT paint_rc, unsigned i)
{
  TCHAR sTmp[128];

  ProtectedAirspaceWarningManager::Lease lease(airspace_warnings);
  if (lease->empty()) {
    assert(i == 0);

    canvas.text(paint_rc.left + IBLSCALE(2),
                paint_rc.top + IBLSCALE(2), _("No Warnings"));
    return;
  }

  assert(i < lease->size());

  const AirspaceWarning* _warning = lease->get_warning(i);

  const AirspaceWarning warning = *_warning;

  const AbstractAirspace& as = warning.get_airspace();
  const AirspaceInterceptSolution& solution = warning.get_solution();

  tstring sName = as.get_name_text(false);
  tstring sTop = as.get_top_text(true);
  tstring sBase = as.get_base_text(true);
  tstring sType = as.get_type_text(true);

  const int TextHeight = 12, TextTop = 1;
  const int Col0Left = 3, Col1Left = 120, Col2Left = 200;

  RECT         rcTextClip;
    
  rcTextClip = paint_rc;
  rcTextClip.right = IBLSCALE(Col1Left - 2);

  Color old_text_color = canvas.get_text_color();
  if (!warning.get_ack_expired())
    canvas.set_text_color(Color::GRAY);

  { // name, altitude info
    _stprintf(sTmp, _T("%-20s"), sName.c_str());

    canvas.text_clipped(paint_rc.left + IBLSCALE(Col0Left),
                        paint_rc.top + IBLSCALE(TextTop),
                        rcTextClip, sTmp);
    
    _stprintf(sTmp, _T("%-20s"), sTop.c_str());
    canvas.text(paint_rc.left + IBLSCALE(Col1Left),
                paint_rc.top + IBLSCALE(TextTop), sTmp);
    
    _stprintf(sTmp, _T("%-20s"), sBase.c_str());
    canvas.text(paint_rc.left + IBLSCALE(Col1Left),
                paint_rc.top + IBLSCALE(TextTop + TextHeight),
                sTmp);
  }

  if (warning.get_warning_state() != AirspaceWarning::WARNING_INSIDE &&
      warning.get_warning_state() > AirspaceWarning::WARNING_CLEAR) {

    _stprintf(sTmp, _T("%d secs dist %d m"),
              (int)solution.elapsed_time,
              (int)solution.distance);

    canvas.text_clipped(paint_rc.left + IBLSCALE(Col0Left),
                        paint_rc.top + IBLSCALE(TextTop + TextHeight),
                        rcTextClip, sTmp);
  }

  /* draw the warning state indicator */

  Brush *state_brush;
  const TCHAR *state_text;

  if (warning.get_warning_state() == AirspaceWarning::WARNING_INSIDE) {
    if (warning.get_ack_expired())
      state_brush = &hBrushInsideBk;
    else
      state_brush = &hBrushInsideAckBk;
    state_text = _T("inside");
  } else if (warning.get_warning_state() > AirspaceWarning::WARNING_CLEAR) {
    if (warning.get_ack_expired())
      state_brush = &hBrushNearBk;
    else
      state_brush = &hBrushNearAckBk;
    state_text = _T("near");
  } else {
    state_brush = NULL;
    state_text = NULL;
  }

  const SIZE state_text_size = canvas.text_size(state_text != NULL
                                                ? state_text : _T("W"));

  if (state_brush != NULL) {
    /* colored background */
    RECT rc;

    rc.left = paint_rc.left + Layout::FastScale(Col2Left);
    rc.top = paint_rc.top + Layout::FastScale(2);
    rc.right = rc.left + state_text_size.cx + Layout::FastScale(4);
    rc.bottom = paint_rc.bottom - Layout::FastScale(2);

    canvas.fill_rectangle(rc, *state_brush);
  }

  if (state_text != NULL)
    canvas.text(paint_rc.left + Layout::FastScale(Col2Left + 2),
                (paint_rc.bottom + paint_rc.top - state_text_size.cy) / 2,
                state_text);

/*  
  
  TCHAR sAckIndicator[6] = _T(" -++*");

  if (pAS.Inside){
    
    _stprintf(sTmp, _T("> %c %s"), sAckIndicator[pAS.Acknowledge], sType);
    
  } else {
    
    TCHAR DistanceText[MAX_PATH];
    if (pAS.hDistance == 0) {
      
      // Directly above or below airspace
      
      Units::FormatUserAltitude(fabs((double)pAS.vDistance),DistanceText, 7);
      if (pAS.vDistance > 0) {
        _stprintf(sTmp, _T("< %c %s ab %s"),
                  sAckIndicator[pAS.Acknowledge],
                  sType, DistanceText);
      }
      if (pAS.vDistance < 0) {
        Units::FormatUserAltitude(fabs((double)pAS.vDistance),DistanceText, 7);
        _stprintf(sTmp, _T("< %c %s bl %s"),
                  sAckIndicator[pAS.Acknowledge],
                  sType, DistanceText);
      }
    } else {
      if ((pAS.vDistance == 0) ||
          (pAS.hDistance < abs(pAS.vDistance)*30 )) {
        
        // Close to airspace altitude, horizontally separated
        
        Units::FormatUserDistance(fabs((double)pAS.hDistance),DistanceText, 7);
        _stprintf(sTmp, _T("< %c %s H %s"), sAckIndicator[pAS.Acknowledge],
                  sType, DistanceText);
      } else {
        
        // Effectively above or below airspace, steep climb or descent
        // necessary to enter
        
        Units::FormatUserAltitude(fabs((double)pAS.vDistance),DistanceText, 7);
        if (pAS.vDistance > 0) {
          _stprintf(sTmp, _T("< %c %s ab %s"),
                    sAckIndicator[pAS.Acknowledge],
                    sType, DistanceText);
        } else {
          _stprintf(sTmp, _T("< %c %s bl %s"),
                    sAckIndicator[pAS.Acknowledge], sType,
                    DistanceText);
        }
      }
    }
  }
  canvas.text_clipped(paint_rc.left + IBLSCALE(Col0Left),
                      paint_rc.top + IBLSCALE(TextTop + TextHeight),
                      rcTextClip, sTmp);
*/  

  if (!warning.get_ack_expired())
    canvas.set_text_color(old_text_color);
}