X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FGUI%2FWaypointList.cxx;h=5b010f0d2690a7e6a9b14fce8dc0df9149b6510a;hb=4befe0e6ea6b5f21119364f1175a0b6c8e97395c;hp=4f9d68b13af2cecd50797d313752d6b4d1147f90;hpb=f938a23d7c96fe704930d323dac69e81c9f46f36;p=flightgear.git diff --git a/src/GUI/WaypointList.cxx b/src/GUI/WaypointList.cxx index 4f9d68b13..5b010f0d2 100644 --- a/src/GUI/WaypointList.cxx +++ b/src/GUI/WaypointList.cxx @@ -11,7 +11,6 @@ #include -#include #include #include @@ -19,8 +18,14 @@ #include
#include +#include #include +// select if the widget grabs keys necessary to fly aircraft from the keyboard, +// or not. See http://code.google.com/p/flightgear-bugs/issues/detail?id=338 +// for discussion about why / what is going on. +#define AVOID_FLIGHT_KEYS 1 + using namespace flightgear; enum { @@ -32,34 +37,37 @@ enum { static const double BLINK_TIME = 0.3; static const int DRAG_START_DISTANCE_PX = 5; -class RouteManagerWaypointModel : +class FlightPlanWaypointModel : public WaypointList::Model, public SGPropertyChangeListener { public: - RouteManagerWaypointModel() - { - _rm = static_cast(globals->get_subsystem("route-manager")); - + FlightPlanWaypointModel(flightgear::FlightPlan* fp) : + _fp(fp) + { SGPropertyNode* routeEdited = fgGetNode("/autopilot/route-manager/signals/edited", true); + SGPropertyNode* flightplanChanged = fgGetNode("/autopilot/route-manager/signals/flightplan-changed", true); routeEdited->addChangeListener(this); + flightplanChanged->addChangeListener(this); } - virtual ~RouteManagerWaypointModel() + ~FlightPlanWaypointModel() { SGPropertyNode* routeEdited = fgGetNode("/autopilot/route-manager/signals/edited", true); + SGPropertyNode* flightplanChanged = fgGetNode("/autopilot/route-manager/signals/flightplan-changed", true); routeEdited->removeChangeListener(this); + flightplanChanged->removeChangeListener(this); } // implement WaypointList::Model virtual unsigned int numWaypoints() const { - return _rm->numWaypts(); + return _fp->numLegs(); } virtual int currentWaypoint() const { - return _rm->currentIndex(); + return _fp->currentIndex(); } virtual flightgear::Waypt* waypointAt(unsigned int index) const @@ -68,12 +76,17 @@ public: return NULL; } - return _rm->wayptAtIndex(index); + return _fp->legAtIndex(index)->waypoint(); } + virtual flightgear::FlightPlan* flightplan() const + { + return _fp; + } + virtual void deleteAt(unsigned int index) { - _rm->removeWayptAtIndex(index); + _fp->deleteIndex(index); } virtual void moveWaypointToIndex(unsigned int srcIndex, unsigned int destIndex) @@ -83,14 +96,15 @@ public: --destIndex; } - unsigned int currentWpIndex = currentWaypoint(); - WayptRef w(_rm->removeWayptAtIndex(srcIndex)); - SG_LOG(SG_GENERAL, SG_INFO, "wpt:" << w->ident()); - _rm->insertWayptAtIndex(w, destIndex); + int currentWpIndex = currentWaypoint(); + + WayptRef w = _fp->legAtIndex(srcIndex)->waypoint(); + _fp->deleteIndex(srcIndex); + _fp->insertWayptAtIndex(w, destIndex); - if (srcIndex == currentWpIndex) { + if ((signed int) srcIndex == currentWpIndex) { // current waypoint was moved - _rm->jumpToIndex(destIndex); + _fp->setCurrentIndex(destIndex); } } @@ -102,12 +116,19 @@ public: // implement SGPropertyChangeListener void valueChanged(SGPropertyNode *prop) { - if (_cb) { - (*_cb)(); + if (prop->getNameString() == "edited") { + if (_cb) { + (*_cb)(); + } + } + + if (prop->getNameString() == "flightplan-changed") { + _fp = + static_cast(globals->get_subsystem("route-manager"))->flightPlan(); } } private: - FGRouteMgr* _rm; + flightgear::FlightPlan* _fp; SGCallback* _cb; }; @@ -147,7 +168,9 @@ WaypointList::WaypointList(int x, int y, int width, int height) : { // pretend to be a list, so fgPopup doesn't mess with our mouse events type |= PUCLASS_LIST; - setModel(new RouteManagerWaypointModel()); + flightgear::FlightPlan* fp = + static_cast(globals->get_subsystem("route-manager"))->flightPlan(); + setModel(new FlightPlanWaypointModel(fp)); setSize(width, height); setValue(-1); @@ -247,7 +270,7 @@ void WaypointList::handleDrag(int x, int y) _dragSourceRow = rowForY(y - abox.min[1]); Waypt* wp = _model->waypointAt(_dragSourceRow); - if (!wp || wp->flag(WPT_GENERATED)) { + if (!wp || wp->flag(WPT_GENERATED) || (wp->type() == "discontinuity")) { return; // don't allow generated points to be dragged } @@ -355,8 +378,11 @@ void WaypointList::draw( int dx, int dy ) y -= (_scrollPx % rowHeight); // partially draw the first row _arrowWidth = legendFont.getStringWidth(">"); + + RoutePath path(_model->flightplan()); + for ( ; row <= final; ++row, y += rowHeight) { - drawRow(dx, dy, row, y); + drawRow(dx, dy, row, y, path); } // of row drawing iteration glDisable(GL_SCISSOR_TEST); @@ -375,14 +401,15 @@ void WaypointList::draw( int dx, int dy ) } } -void WaypointList::drawRow(int dx, int dy, int rowIndex, int y) +void WaypointList::drawRow(int dx, int dy, int rowIndex, int y, + const RoutePath& path) { flightgear::Waypt* wp(_model->waypointAt(rowIndex)); bool isSelected = (rowIndex == getSelected()); bool isCurrent = (rowIndex == _model->currentWaypoint()); bool isDragSource = (_dragging && (rowIndex == _dragSourceRow)); - + puBox bkgBox = abox; bkgBox.min[1] = abox.max[1] - y; bkgBox.max[1] = bkgBox.min[1] + rowHeightPx(); @@ -394,12 +421,12 @@ void WaypointList::drawRow(int dx, int dy, int rowIndex, int y) if (wp->flag(WPT_MISS)) { drawBox = true; puSetColor(col, 1.0, 0.0, 0.0, 0.3); // red - } else if (wp->flag(WPT_ARRIVAL)) { + } else if (wp->flag(WPT_ARRIVAL) || wp->flag(WPT_DEPARTURE)) { drawBox = true; puSetColor(col, 0.0, 0.0, 0.0, 0.3); - } else if (wp->flag(WPT_DEPARTURE)) { + } else if (wp->flag(WPT_APPROACH)) { drawBox = true; - puSetColor(col, 0.0, 0.0, 0.0, 0.3); + puSetColor(col, 0.0, 0.0, 0.1, 0.3); } if (isDragSource) { @@ -426,64 +453,94 @@ void WaypointList::drawRow(int dx, int dy, int rowIndex, int y) int x = xx; x += _arrowWidth + PUSTR_LGAP; - - // row textual data + drawRowText(x, yy, rowIndex, path); - char buffer[128]; - int count = ::snprintf(buffer, 128, "%03d %-5s", rowIndex, wp->ident().c_str()); - - FGPositioned* src = wp->source(); - if (src && !src->name().empty() && (src->name() != wp->ident())) { - // append name if present, and different to id - ::snprintf(buffer + count, 128 - count, " (%s)", src->name().c_str()); - } - drawClippedString(legendFont, buffer, x, yy, 300); - x += 300 + PUSTR_LGAP; - - if (_showLatLon) { - SGGeod p(wp->position()); - char ns = (p.getLatitudeDeg() > 0.0) ? 'N' : 'S'; - char ew = (p.getLongitudeDeg() > 0.0) ? 'E' : 'W'; - - ::snprintf(buffer, 128 - count, "%4.2f%c %4.2f%c", - fabs(p.getLongitudeDeg()), ew, fabs(p.getLatitudeDeg()), ns); - } else if (rowIndex > 0) { - double courseDeg; - double distanceM; - Waypt* prev = _model->waypointAt(rowIndex - 1); - boost::tie(courseDeg, distanceM) = wp->courseAndDistanceFrom(prev->position()); - - ::snprintf(buffer, 128 - count, "%03.0f %5.1fnm", - courseDeg, distanceM * SG_METER_TO_NM); + if (isDragSource) { + puSetColor(col, 1.0, 0.5, 0.0, 0.5); + bkgBox.draw(dx, dy, PUSTYLE_PLAIN, &col, false, 0); } +} + +void WaypointList::drawRowText(int x, int baseline, int rowIndex, const RoutePath& path) +{ + flightgear::Waypt* wp(_model->waypointAt(rowIndex)); + const bool isDiscontinuity = (wp->type() == "discontinuity"); + const bool isVia = (wp->type() == "via"); - f->drawString(buffer, x, yy); + char buffer[128]; + int count; + + if (isVia) { + // VIA has long ident but no name + count = ::snprintf(buffer, 128, "%03d %s", rowIndex, wp->ident().c_str()); + drawClippedString(legendFont, buffer, x, baseline, 300); + x += 300 + PUSTR_LGAP; + } else { + count = ::snprintf(buffer, 128, "%03d %-5s", rowIndex, wp->ident().c_str()); + + FGPositioned* src = wp->source(); + if (src && !src->name().empty() && (src->name() != wp->ident())) { + // append name if present, and different to id + ::snprintf(buffer + count, 128 - count, " (%s)", src->name().c_str()); + } + + drawClippedString(legendFont, buffer, x, baseline, 300); + x += 300 + PUSTR_LGAP; + + if (isDiscontinuity) { + return; + } + + if (_showLatLon) { + // only show for non-dynamic waypoints + if (!wp->flag(WPT_DYNAMIC)) { + SGGeod p(wp->position()); + char ns = (p.getLatitudeDeg() > 0.0) ? 'N' : 'S'; + char ew = (p.getLongitudeDeg() > 0.0) ? 'E' : 'W'; + + ::snprintf(buffer, 128 - count, "%4.2f%c %4.2f%c", + fabs(p.getLongitudeDeg()), ew, fabs(p.getLatitudeDeg()), ns); + } else { + buffer[0] = 0; + } + } else if (rowIndex > 0) { + double courseDeg = path.trackForIndex(rowIndex); + double distanceM = path.distanceForIndex(rowIndex); + ::snprintf(buffer, 128 - count, "%03.0f %5.1fnm", + courseDeg, distanceM * SG_METER_TO_NM); + } + } // of is not a VIA waypoint + + puFont* f = &legendFont; + f->drawString(buffer, x, baseline); x += 100 + PUSTR_LGAP; - + if (wp->altitudeRestriction() != RESTRICT_NONE) { + char aboveAtBelow = ' '; + if (wp->altitudeRestriction() == RESTRICT_ABOVE) { + aboveAtBelow = 'A'; + } else if (wp->altitudeRestriction() == RESTRICT_BELOW) { + aboveAtBelow = 'B'; + } + int altHundredFt = (wp->altitudeFt() + 50) / 100; // round to nearest 100ft if (altHundredFt < 100) { - count = ::snprintf(buffer, 128, "%d'", altHundredFt * 100); + count = ::snprintf(buffer, 128, "%d'%c", altHundredFt * 100, aboveAtBelow); } else { // display as a flight-level - count = ::snprintf(buffer, 128, "FL%d", altHundredFt); + count = ::snprintf(buffer, 128, "FL%d%c", altHundredFt, aboveAtBelow); } - - f->drawString(buffer, x, yy); + + f->drawString(buffer, x, baseline); } // of valid wp altitude x += 60 + PUSTR_LGAP; - + if (wp->speedRestriction() == SPEED_RESTRICT_MACH) { count = ::snprintf(buffer, 126, "%03.2fM", wp->speedMach()); - f->drawString(buffer, x, yy); + f->drawString(buffer, x, baseline); } else if (wp->speedRestriction() != RESTRICT_NONE) { count = ::snprintf(buffer, 126, "%dKts", (int) wp->speedKts()); - f->drawString(buffer, x, yy); - } - - if (isDragSource) { - puSetColor(col, 1.0, 0.5, 0.0, 0.5); - bkgBox.draw(dx, dy, PUSTYLE_PLAIN, &col, false, 0); + f->drawString(buffer, x, baseline); } } @@ -659,6 +716,10 @@ int WaypointList::checkKey (int key, int updown ) if ((updown == PU_UP) || !isVisible () || !isActive () || (window != puGetWindow())) { return FALSE ; } + +#ifdef AVOID_FLIGHT_KEYS + return FALSE; +#endif switch (key) {