X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FGUI%2FWaypointList.cxx;h=4f9d68b13af2cecd50797d313752d6b4d1147f90;hb=9bd00a62facf50830e4eeccfbf8ce57f4c1f444f;hp=5498076e54572bc73906fa84a72f50a76e3d5c8b;hpb=cfd243bd957c692eae26555dae8a6fa8a693430f;p=flightgear.git diff --git a/src/GUI/WaypointList.cxx b/src/GUI/WaypointList.cxx index 5498076e5..4f9d68b13 100644 --- a/src/GUI/WaypointList.cxx +++ b/src/GUI/WaypointList.cxx @@ -7,6 +7,8 @@ #include "WaypointList.hxx" #include +#include + #include #include @@ -16,14 +18,18 @@ #include
#include
+#include #include +using namespace flightgear; + enum { SCROLL_NO = 0, SCROLL_UP, SCROLL_DOWN }; +static const double BLINK_TIME = 0.3; static const int DRAG_START_DISTANCE_PX = 5; class RouteManagerWaypointModel : @@ -48,37 +54,44 @@ public: // implement WaypointList::Model virtual unsigned int numWaypoints() const { - return _rm->size(); + return _rm->numWaypts(); } virtual int currentWaypoint() const { - return _rm->currentWaypoint(); + return _rm->currentIndex(); } - virtual SGWayPoint waypointAt(unsigned int index) const + virtual flightgear::Waypt* waypointAt(unsigned int index) const { - return _rm->get_waypoint(index); + if (index >= numWaypoints()) { + return NULL; + } + + return _rm->wayptAtIndex(index); } virtual void deleteAt(unsigned int index) { - _rm->pop_waypoint(index); - } - - virtual void setWaypointTargetAltitudeFt(unsigned int index, int altFt) - { - _rm->setWaypointTargetAltitudeFt(index, altFt); + _rm->removeWayptAtIndex(index); } virtual void moveWaypointToIndex(unsigned int srcIndex, unsigned int destIndex) { + SG_LOG(SG_GENERAL, SG_INFO, "moveWaypoint: from " << srcIndex << " to " << destIndex); if (destIndex > srcIndex) { --destIndex; } - SGWayPoint wp = _rm->pop_waypoint(srcIndex); - _rm->add_waypoint(wp, destIndex); + unsigned int currentWpIndex = currentWaypoint(); + WayptRef w(_rm->removeWayptAtIndex(srcIndex)); + SG_LOG(SG_GENERAL, SG_INFO, "wpt:" << w->ident()); + _rm->insertWayptAtIndex(w, destIndex); + + if (srcIndex == currentWpIndex) { + // current waypoint was moved + _rm->jumpToIndex(destIndex); + } } virtual void setUpdateCallback(SGCallback* cb) @@ -129,13 +142,16 @@ WaypointList::WaypointList(int x, int y, int width, int height) : _showLatLon(false), _model(NULL), _updateCallback(NULL), - _scrollCallback(NULL) + _scrollCallback(NULL), + _blink(false) { // pretend to be a list, so fgPopup doesn't mess with our mouse events type |= PUCLASS_LIST; setModel(new RouteManagerWaypointModel()); setSize(width, height); setValue(-1); + + _blinkTimer.stamp(); } WaypointList::~WaypointList() @@ -230,6 +246,11 @@ void WaypointList::handleDrag(int x, int y) } _dragSourceRow = rowForY(y - abox.min[1]); + Waypt* wp = _model->waypointAt(_dragSourceRow); + if (!wp || wp->flag(WPT_GENERATED)) { + return; // don't allow generated points to be dragged + } + _dragging = true; _dragScroll = SCROLL_NO; } @@ -255,20 +276,26 @@ void WaypointList::doDrop(int x, int y) _dragging = false; puDeactivateWidget(); + SG_LOG(SG_GENERAL, SG_INFO, "doDrop"); + if ((y < abox.min[1]) || (y >= abox.max[1])) { + SG_LOG(SG_GENERAL, SG_INFO, "y out of bounds:" << y); return; } - if (_dragSourceRow != _dragTargetRow) { - _model->moveWaypointToIndex(_dragSourceRow, _dragTargetRow); - - // keep row indexes linged up when moving an item down the list - if (_dragSourceRow < _dragTargetRow) { - --_dragTargetRow; - } - - setSelected(_dragTargetRow); + if (_dragSourceRow == _dragTargetRow) { + SG_LOG(SG_GENERAL, SG_INFO, "source and target row match"); + return; + } + + _model->moveWaypointToIndex(_dragSourceRow, _dragTargetRow); + + // keep row indexes linged up when moving an item down the list + if (_dragSourceRow < _dragTargetRow) { + --_dragTargetRow; } + + setSelected(_dragTargetRow); } void WaypointList::invokeDownCallback(void) @@ -302,6 +329,12 @@ void WaypointList::draw( int dx, int dy ) doDragScroll(); } + double dt = (SGTimeStamp::now() - _blinkTimer).toSecs(); + if (dt > BLINK_TIME) { + _blinkTimer.stamp(); + _blink = !_blink; + } + glEnable(GL_SCISSOR_TEST); GLint sx = (int) abox.min[0], sy = abox.min[1]; @@ -321,6 +354,7 @@ void WaypointList::draw( int dx, int dy ) y -= (_scrollPx % rowHeight); // partially draw the first row + _arrowWidth = legendFont.getStringWidth(">"); for ( ; row <= final; ++row, y += rowHeight) { drawRow(dx, dy, row, y); } // of row drawing iteration @@ -343,6 +377,8 @@ void WaypointList::draw( int dx, int dy ) void WaypointList::drawRow(int dx, int dy, int rowIndex, int y) { + flightgear::Waypt* wp(_model->waypointAt(rowIndex)); + bool isSelected = (rowIndex == getSelected()); bool isCurrent = (rowIndex == _model->currentWaypoint()); bool isDragSource = (_dragging && (rowIndex == _dragSourceRow)); @@ -351,62 +387,103 @@ void WaypointList::drawRow(int dx, int dy, int rowIndex, int y) bkgBox.min[1] = abox.max[1] - y; bkgBox.max[1] = bkgBox.min[1] + rowHeightPx(); - puColour currentColor; - puSetColor(currentColor, 1.0, 1.0, 0.0, 0.5); + puColour col; + puFont* f = &legendFont; + bool drawBox = false; + + if (wp->flag(WPT_MISS)) { + drawBox = true; + puSetColor(col, 1.0, 0.0, 0.0, 0.3); // red + } else if (wp->flag(WPT_ARRIVAL)) { + drawBox = true; + puSetColor(col, 0.0, 0.0, 0.0, 0.3); + } else if (wp->flag(WPT_DEPARTURE)) { + drawBox = true; + puSetColor(col, 0.0, 0.0, 0.0, 0.3); + } if (isDragSource) { // draw later, on *top* of text string - } else if (isCurrent) { - bkgBox.draw(dx, dy, PUSTYLE_PLAIN, ¤tColor, false, 0); } else if (isSelected) { // -PLAIN means selected, apparently bkgBox.draw(dx, dy, -PUSTYLE_PLAIN, colour, false, 0); + } else if (drawBox) { + bkgBox.draw(dx, dy, PUSTYLE_PLAIN, &col, false, 0); + } + + if (isCurrent) { + glColor4f (1.0, 0.5, 0.0, 1.0) ; + } else { + glColor4fv ( colour [ PUCOL_LEGEND ] ) ; } int xx = dx + abox.min[0] + PUSTR_LGAP; int yy = dy + abox.max[1] - y ; yy += 4; // center text in row height + if (isCurrent) { + f->drawString(">", xx, yy); + } + + int x = xx; + x += _arrowWidth + PUSTR_LGAP; + // row textual data - const SGWayPoint wp(_model->waypointAt(rowIndex)); + char buffer[128]; - int count = ::snprintf(buffer, 128, "%03d %-5s", rowIndex, wp.get_id().c_str()); - - if (wp.get_name().size() > 0 && (wp.get_name() != wp.get_id())) { + 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)", wp.get_name().c_str()); + ::snprintf(buffer + count, 128 - count, " (%s)", src->name().c_str()); } - - glColor4fv ( colour [ PUCOL_LEGEND ] ) ; - drawClippedString(legendFont, buffer, xx, yy, 300); + + drawClippedString(legendFont, buffer, x, yy, 300); + x += 300 + PUSTR_LGAP; if (_showLatLon) { - char ns = (wp.get_target_lat() > 0.0) ? 'N' : 'S'; - char ew = (wp.get_target_lon() > 0.0) ? 'E' : 'W'; + 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(wp.get_target_lon()), ew, fabs(wp.get_target_lat()), ns); - } else { + 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", - wp.get_track(), wp.get_distance() * SG_METER_TO_NM); + courseDeg, distanceM * SG_METER_TO_NM); } - legendFont.drawString(buffer, xx + 300 + PUSTR_LGAP, yy); + f->drawString(buffer, x, yy); + x += 100 + PUSTR_LGAP; - int altFt = (int) wp.get_target_alt() * SG_METER_TO_FEET; - if (altFt > -9990) { - int altHundredFt = (altFt + 50) / 100; // round to nearest 100ft + if (wp->altitudeRestriction() != RESTRICT_NONE) { + int altHundredFt = (wp->altitudeFt() + 50) / 100; // round to nearest 100ft if (altHundredFt < 100) { count = ::snprintf(buffer, 128, "%d'", altHundredFt * 100); } else { // display as a flight-level count = ::snprintf(buffer, 128, "FL%d", altHundredFt); } - legendFont.drawString(buffer, xx + 400 + PUSTR_LGAP, yy); + f->drawString(buffer, x, yy); } // 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); + } else if (wp->speedRestriction() != RESTRICT_NONE) { + count = ::snprintf(buffer, 126, "%dKts", (int) wp->speedKts()); + f->drawString(buffer, x, yy); + } if (isDragSource) { - puSetColor(currentColor, 1.0, 0.5, 0.0, 0.5); - bkgBox.draw(dx, dy, PUSTYLE_PLAIN, ¤tColor, false, 0); + puSetColor(col, 1.0, 0.5, 0.0, 0.5); + bkgBox.draw(dx, dy, PUSTYLE_PLAIN, &col, false, 0); } } @@ -613,22 +690,34 @@ int WaypointList::checkKey (int key, int updown ) case '-': if (getSelected() >= 0) { - int newAlt = wayptAltFtHundreds(getSelected()) - 10; - if (newAlt < 0) { - _model->setWaypointTargetAltitudeFt(getSelected(), -9999); - } else { - _model->setWaypointTargetAltitudeFt(getSelected(), newAlt * 100); + Waypt* wp = _model->waypointAt(getSelected()); + if (wp->flag(WPT_GENERATED)) { + break; + } + + if (wp->altitudeRestriction() != RESTRICT_NONE) { + int curAlt = (static_cast(wp->altitudeFt()) + 50) / 100; + if (curAlt <= 0) { + wp->setAltitude(0, RESTRICT_NONE); + } else { + wp->setAltitude((curAlt - 10) * 100, wp->altitudeRestriction()); + } } } break; case '=': if (getSelected() >= 0) { - int newAlt = wayptAltFtHundreds(getSelected()) + 10; - if (newAlt < 0) { - _model->setWaypointTargetAltitudeFt(getSelected(), 0); + flightgear::Waypt* wp = _model->waypointAt(getSelected()); + if (wp->flag(WPT_GENERATED)) { + break; + } + + if (wp->altitudeRestriction() == RESTRICT_NONE) { + wp->setAltitude(1000, RESTRICT_AT); } else { - _model->setWaypointTargetAltitudeFt(getSelected(), newAlt * 100); + int curAlt = (static_cast(wp->altitudeFt()) + 50) / 100; + wp->setAltitude((curAlt + 10) * 100, wp->altitudeRestriction()); } } break; @@ -636,6 +725,11 @@ int WaypointList::checkKey (int key, int updown ) case 0x7f: // delete if (getSelected() >= 0) { int index = getSelected(); + Waypt* wp = _model->waypointAt(getSelected()); + if (wp->flag(WPT_GENERATED)) { + break; + } + _model->deleteAt(index); setSelected(index - 1); } @@ -648,17 +742,6 @@ int WaypointList::checkKey (int key, int updown ) return TRUE ; } -int WaypointList::wayptAltFtHundreds(int index) const -{ - double alt = _model->waypointAt(index).get_target_alt(); - if (alt < -9990.0) { - return -9999; - } - - int altFt = (int) alt * SG_METER_TO_FEET; - return (altFt + 50) / 100; // round to nearest 100ft -} - void WaypointList::modelUpdateCallback() { // local stuff @@ -744,6 +827,7 @@ void ScrolledWaypointList::setScrollPercent(float v) void ScrolledWaypointList::setSize(int w, int h) { updateWantsScroll(w, h); + puGroup::setSize(w, h); } void ScrolledWaypointList::updateWantsScroll(int w, int h)