Skip to content

Commit

Permalink
fix #14390, fix #14457
Browse files Browse the repository at this point in the history
  • Loading branch information
namdre committed Mar 4, 2024
1 parent a825648 commit 7c9c43a
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 72 deletions.
8 changes: 8 additions & 0 deletions src/guisim/GUIEdge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -661,4 +661,12 @@ GUIEdge::getPendingEmits() const {
return MSNet::getInstance()->getInsertionControl().getPendingEmits(getLanes()[0]);
}

double
GUIEdge::getClickPriority() const {
if (!MSGlobals::gUseMesoSim) {
// do not select edgse in meso mode
return INVALID_PRIORITY;
}
return GLO_EDGE;
}
/****************************************************************************/
2 changes: 2 additions & 0 deletions src/guisim/GUIEdge.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@ class GUIEdge : public MSEdge, public GUIGlObject {
void drawGL(const GUIVisualizationSettings& s) const override;
//@}

double getClickPriority() const override;

void addTransportable(MSTransportable* t) const override {
FXMutexLock locker(myLock);
MSEdge::addTransportable(t);
Expand Down
2 changes: 1 addition & 1 deletion src/guisim/GUILane.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1595,7 +1595,7 @@ double
GUILane::getClickPriority() const {
if (MSGlobals::gUseMesoSim) {
// do not select lanes in meso mode
return -std::numeric_limits<double>::max();
return INVALID_PRIORITY;
}
if (myEdge->isCrossing()) {
return GLO_CROSSING;
Expand Down
1 change: 1 addition & 0 deletions src/utils/gui/globjects/GUIGlObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ StringBijection<GUIGlObjectType>::Entry GUIGlObject::GUIGlObjectTypeNamesInitial

StringBijection<GUIGlObjectType> GUIGlObject::TypeNames(GUIGlObjectTypeNamesInitializer, GLO_MAX);
const GUIGlID GUIGlObject::INVALID_ID = 0;
const double GUIGlObject::INVALID_PRIORITY(-std::numeric_limits<double>::max());

// ===========================================================================
// method definitions
Expand Down
1 change: 1 addition & 0 deletions src/utils/gui/globjects/GUIGlObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ class GUIGlObject {
/// @brief associates object types with strings
static StringBijection<GUIGlObjectType> TypeNames;
static const GUIGlID INVALID_ID;
static const double INVALID_PRIORITY;

/** @brief Constructor
*
Expand Down
93 changes: 22 additions & 71 deletions src/utils/gui/windows/GUISUMOAbstractView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1207,6 +1207,18 @@ GUISUMOAbstractView::onMouseLeft(FXObject*, FXSelector, void* /*data*/) {
return 1;
}

std::vector<GUIGlObject*>
GUISUMOAbstractView::filterContextObjects(const std::vector<GUIGlObject*>& objects) {
// assume input is sorted with ComparatorClickPriority
std::vector<GUIGlObject*> result;
for (GUIGlObject* o : objects) {
if (o->getClickPriority() != GUIGlObject::INVALID_PRIORITY && (result.empty() || result.back() != o)) {
result.push_back(o);
}
}
return result;
}


void
GUISUMOAbstractView::openObjectDialogAtCursor(const FXEvent* ev) {
Expand All @@ -1216,80 +1228,19 @@ GUISUMOAbstractView::openObjectDialogAtCursor(const FXEvent* ev) {
const bool altKeyPressed = ((ev->state & ALTMASK) != 0);
// check if SUMO is enabled, initialised and Make OpenGL context current
if (isEnabled() && myAmInitialised && makeCurrent()) {
// get all objects under cusor
auto objectsUnderCursor = getGUIGlObjectsUnderCursor();
// filter elements
std::vector<GUIGlObject*> filteredObjectsUnderCursor;
std::vector<GUIGlObject*> filteredVehiclesUnderCursor;
std::vector<GUIGlObject*> filteredPersonsUnderCursor;
std::vector<GUIGlObject*> filteredContainersUnderCursor;
std::vector<GUIGlObject*> filteredTLSUnderCursor;
for (const auto& GLObject : objectsUnderCursor) {
// avoid edges
if (GLObject->getType() == GLO_EDGE) {
continue;
}
// avoid duplicated lanes
if (std::find(filteredObjectsUnderCursor.begin(), filteredObjectsUnderCursor.end(), GLObject) != filteredObjectsUnderCursor.end()) {
continue;
}
// filter vehicles, person and containers
if ((GLObject->getType() == GLO_PERSON) || (GLObject->getType() == GLO_PERSONFLOW)) {
filteredPersonsUnderCursor.push_back(GLObject);
}
if ((GLObject->getType() == GLO_CONTAINER) || (GLObject->getType() == GLO_CONTAINERFLOW)) {
filteredContainersUnderCursor.push_back(GLObject);
}
if ((GLObject->getType() == GLO_VEHICLE) || (GLObject->getType() == GLO_TRIP) ||
(GLObject->getType() == GLO_FLOW) || (GLObject->getType() == GLO_ROUTEFLOW)) {
filteredVehiclesUnderCursor.push_back(GLObject);
}
// filter TLSs
if (GLObject->getType() == GLO_TLLOGIC) {
filteredTLSUnderCursor.push_back(GLObject);
}
filteredObjectsUnderCursor.push_back(GLObject);
}
// filter demand elements (persons, container and vehicles)
std::vector<GUIGlObject*> filteredDemandElements;
for (auto person : filteredPersonsUnderCursor) {
filteredDemandElements.push_back(person);
}
for (auto container : filteredContainersUnderCursor) {
filteredContainersUnderCursor.push_back(container);
}
for (auto vehicle : filteredVehiclesUnderCursor) {
filteredVehiclesUnderCursor.push_back(vehicle);
}
// filter internal lanes
filteredObjectsUnderCursor = filterInternalLanes(filteredObjectsUnderCursor);
// remove duplicated elements using an unordered set
auto itDuplicated = filteredObjectsUnderCursor.begin();
std::unordered_set<GUIGlObject*> unorderedSet;
for (auto itElement = filteredObjectsUnderCursor.begin(); itElement != filteredObjectsUnderCursor.end(); itElement++) {
if (unorderedSet.insert(*itElement).second) {
*itDuplicated++ = *itElement;
}
}
filteredObjectsUnderCursor.erase(itDuplicated, filteredObjectsUnderCursor.end());
// continue depending of number of objects
if (filteredObjectsUnderCursor.empty()) {
// if filteredObjectsUnderCursor, inspect net
openObjectDialog({GUIGlObjectStorage::gIDStorage.getNetObject()}, true);
} else if (altKeyPressed) {
// inspect all objects under cursor
openObjectDialog(filteredObjectsUnderCursor, false);
} else if (filteredDemandElements.size() > 0) {
// inspect only demand elements
openObjectDialog(filteredDemandElements, true);
} else if (filteredTLSUnderCursor.size() > 0) {
// inspect only TLSs
openObjectDialog(filteredTLSUnderCursor, true);
if (objectsUnderCursor.empty()) {
myPopup = GUIGlObjectStorage::gIDStorage.getNetObject()->getPopUpMenu(*myApp, *this);
} else {
// inspect objects under cursor
openObjectDialog(filteredObjectsUnderCursor, true);
std::sort(objectsUnderCursor.begin(), objectsUnderCursor.end(), ComparatorClickPriority());
if (altKeyPressed && objectsUnderCursor.size() > 1) {
// open dialog for picking among objects (without duplicates)
myPopup = new GUICursorDialog(GUIGLObjectPopupMenu::PopupType::PROPERTIES, this, filterContextObjects(objectsUnderCursor));
} else {
myPopup = objectsUnderCursor.front()->getPopUpMenu(*myApp, *this);
}
}
// Make OpenGL context non current
openPopupDialog();
makeNonCurrent();
}
}
Expand Down
16 changes: 16 additions & 0 deletions src/utils/gui/windows/GUISUMOAbstractView.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,19 @@ class GUIDialog_ViewSettings;
class GUIVisualizationSettings;
class GUILane;

/// @brief comparator for resolving clicks
struct ComparatorClickPriority {
bool operator()(const GUIGlObject* const a, const GUIGlObject* const b) const {
if (a->getClickPriority() == b->getClickPriority()) {
// sorty by GUIGlID as second criterion to simplify
// duplicate removal
return a->getGlID() > b->getGlID();
} else {
return a->getClickPriority() > b->getClickPriority();
}
}
};

// ===========================================================================
// class definitions
// ===========================================================================
Expand Down Expand Up @@ -177,6 +190,9 @@ class GUISUMOAbstractView : public FXGLCanvas {
/// @brief hook to react on change in visualization settings
virtual long onVisualizationChange(FXObject*, FXSelector, void*);

/// @brief filter out duplicate and forbidden objects
std::vector<GUIGlObject*> filterContextObjects(const std::vector<GUIGlObject*>& objects);

/// @brief open object dialog at the cursor position
virtual void openObjectDialogAtCursor(const FXEvent* ev);

Expand Down

0 comments on commit 7c9c43a

Please sign in to comment.