Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
GUIDialog_ChooserAbstract.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3// Copyright (C) 2001-2024 German Aerospace Center (DLR) and others.
4// This program and the accompanying materials are made available under the
5// terms of the Eclipse Public License 2.0 which is available at
6// https://www.eclipse.org/legal/epl-2.0/
7// This Source Code may also be made available under the following Secondary
8// Licenses when the conditions for such availability set forth in the Eclipse
9// Public License 2.0 are satisfied: GNU General Public License, version 2
10// or later which is available at
11// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13/****************************************************************************/
20// Class for the window that allows to choose a street, junction or vehicle
21/****************************************************************************/
22#include <config.h>
23
24#include <string>
25#include <vector>
26#include <fxkeys.h>
37
39
40
41// ===========================================================================
42// FOX callback mapping
43// ===========================================================================
61
62FXIMPLEMENT(GUIDialog_ChooserAbstract, FXMainWindow, GUIDialog_ChooserAbstractMap, ARRAYNUMBER(GUIDialog_ChooserAbstractMap))
63
64
65// ===========================================================================
66// method definitions
67// ===========================================================================
69 FXIcon* icon, const FXString& title, const std::vector<GUIGlID>& ids, GUIGlObjectStorage& /*glStorage*/) :
70 FXMainWindow(windowsParent->getApp(), title, icon, nullptr, GUIDesignChooserDialog),
71 GUIPersistentWindowPos(this, "LOCATOR", true, 20, 40, 300, 350),
72 myWindowsParent(windowsParent),
73 myMessageId(messageId),
74 myLocateByName(false),
75 myHaveFilteredSubstring(false) {
76 FXHorizontalFrame* hbox = new FXHorizontalFrame(this, GUIDesignAuxiliarFrame);
77 // build the list
78 FXVerticalFrame* layoutLeft = new FXVerticalFrame(hbox, GUIDesignChooserLayoutLeft);
79 myTextEntry = new FXTextField(layoutLeft, 0, this, MID_CHOOSER_TEXT, TEXTFIELD_ENTER_ONLY | GUIDesignChooserTextField);
80 FXVerticalFrame* layoutList = new FXVerticalFrame(layoutLeft, GUIDesignChooserLayoutList);
81 myList = new FXList(layoutList, this, MID_CHOOSER_LIST, GUIDesignChooserListSingle);
82 // build the buttons
83 FXVerticalFrame* layoutRight = new FXVerticalFrame(hbox, GUIDesignChooserLayoutRight);
86 // only enable Track Button if we're locating vehicles
87 if (title.text() != std::string(TL("Vehicle Chooser"))) {
88 myTrackButton->disable();
89 myTrackButton->hide();
90 }
91 new FXHorizontalSeparator(layoutRight, GUIDesignHorizontalSeparator);
93 GUIDesigns::buildFXButton(layoutRight, TL("By &Name"), TL("Locate item by name"), "", nullptr, this, MID_CHOOSEN_NAME, GUIDesignChooserButtons);
94 GUIDesigns::buildFXButton(layoutRight, TL("&Select/deselect"), "", TL("Select/deselect current object"), GUIIconSubSys::getIcon(GUIIcon::FLAG), this, MID_CHOOSEN_INVERT, GUIDesignChooserButtons);
95 GUIDesigns::buildFXButton(layoutRight, TL("&Filter substring"), "", "", nullptr, this, MID_CHOOSER_FILTER_SUBSTR, GUIDesignChooserButtons);
96 GUIDesigns::buildFXButton(layoutRight, TL("Select &all"), "", TL("Select all items in list"), GUIIconSubSys::getIcon(GUIIcon::FLAG), this, MID_CHOOSEN_SELECT, GUIDesignChooserButtons);
97 GUIDesigns::buildFXButton(layoutRight, TL("&Deselect all"), "", TL("Deselect all items in list"), GUIIconSubSys::getIcon(GUIIcon::FLAG), this, MID_CHOOSEN_CLEAR, GUIDesignChooserButtons);
98 GUIDesigns::buildFXButton(layoutRight, TL("&Update"), "", TL("Reload all ids"), GUIIconSubSys::getIcon(GUIIcon::RELOAD), this, MID_UPDATE, GUIDesignChooserButtons);
99 new FXHorizontalSeparator(layoutRight, GUIDesignHorizontalSeparator);
101 myCountLabel = new FXLabel(layoutRight, "placeholder", nullptr, LAYOUT_BOTTOM | LAYOUT_FILL_X | JUSTIFY_LEFT);
102 myCaseSensitive = new FXCheckButton(layoutRight, TL("case-sensitive search"));
103 myCaseSensitive->setCheck(getApp()->reg().readIntEntry("LOCATOR", "caseSensitive", 0) == 1);
104 myInstantCenter = new FXCheckButton(layoutRight, TL("auto-center"));
105 myInstantCenter->setCheck(getApp()->reg().readIntEntry("LOCATOR", "autoCenter", 0) == 1);
106 refreshList(ids);
107 // add child in windowsParent
108 myWindowsParent->getGUIMainWindowParent()->addChild(this);
109 loadWindowPos();
110 // create and show dialog
111 create();
112 show();
113}
114
115
117 // remove child from windowsParent
119 getApp()->reg().writeIntEntry("LOCATOR", "autoCenter", myInstantCenter->getCheck());
120 getApp()->reg().writeIntEntry("LOCATOR", "caseSensitive", myCaseSensitive->getCheck());
121}
122
123
126 return static_cast<GUIGlObject*>(mySelected);
127}
128
129
130void
132 FXMainWindow::show();
133 myTextEntry->setFocus();
134}
135
136
137long
138GUIDialog_ChooserAbstract::onCmdCenter(FXObject*, FXSelector, void*) {
139 int selected = myList->getCurrentItem();
140 if (selected >= 0) {
142 myWindowsParent->setView(*static_cast<GUIGlID*>(myList->getItemData(selected)));
143 }
144 return 1;
145}
146
147
148long
149GUIDialog_ChooserAbstract::onCmdTrack(FXObject*, FXSelector, void*) {
150 int selected = myList->getCurrentItem();
151 if (selected >= 0) {
152 myWindowsParent->setView(*static_cast<GUIGlID*>(myList->getItemData(selected)));
153 GUIGlID id = *static_cast<GUIGlID*>(myList->getItemData(selected));
155 if (o->getType() == GLO_VEHICLE) {
157 }
159 }
160 return 1;
161}
162
163
164long
165GUIDialog_ChooserAbstract::onCmdClose(FXObject*, FXSelector, void*) {
166 close(true);
167 return 1;
168}
169
170long
171GUIDialog_ChooserAbstract::onChgList(FXObject*, FXSelector, void*) {
172 // mouse-click toggles item selection but changked current item with
173 // keyboard does not affect select
174 // Enabling the line blow toggles the behavior (which must be fixed via onChgListSel)
175 myList->selectItem(myList->getCurrentItem());
176 if (myInstantCenter->getCheck()) {
177 onCmdCenter(nullptr, 0, nullptr);
178 }
179 return 1;
180}
181
182long
183GUIDialog_ChooserAbstract::onChgListSel(FXObject*, FXSelector, void*) {
184 myList->selectItem(myList->getCurrentItem());
185 return 1;
186}
187
188long
189GUIDialog_ChooserAbstract::onChgText(FXObject*, FXSelector, void*) {
190 const bool caseSensitive = myCaseSensitive->getCheck() == TRUE;
191 int id = -1;
193 // findItem does not support substring search
194 const int numItems = myList->getNumItems();
195 FXString t = myTextEntry->getText();
196 if (!caseSensitive) {
197 t = t.lower();
198 }
199 for (int i = 0; i < numItems; i++) {
200 FXString t2 = myList->getItemText(i);
201 if (!caseSensitive) {
202 t2 = t2.lower();
203 }
204 if (t2.find(t) >= 0) {
205 id = i;
206 break;
207 }
208 }
209 } else {
210 const int caseOpt = caseSensitive ? 0 : SEARCH_IGNORECASE;
211 id = myList->findItem(myTextEntry->getText(), -1, SEARCH_PREFIX | caseOpt);
212 }
213 if (id < 0) {
214 if (myList->getNumItems() > 0) {
215 myList->deselectItem(myList->getCurrentItem());
216 }
217 myCenterButton->disable();
218 myTrackButton->disable();
219 return 1;
220 }
221 myList->deselectItem(myList->getCurrentItem());
222 myList->makeItemVisible(id);
223 myList->selectItem(id);
224 myList->setCurrentItem(id, true);
225 myCenterButton->enable();
226 myTrackButton->enable();
227 return 1;
228}
229
230
231long
232GUIDialog_ChooserAbstract::onCmdText(FXObject*, FXSelector, void*) {
233 int current = myList->getCurrentItem();
234 if (current >= 0 && myList->isItemSelected(current)) {
235 myWindowsParent->setView(*static_cast<GUIGlID*>(myList->getItemData(current)));
236 }
237 return 1;
238}
239
240
241
242long
243GUIDialog_ChooserAbstract::onListKeyPress(FXObject*, FXSelector, void* ptr) {
244 FXEvent* event = (FXEvent*)ptr;
245 if (event->code == KEY_Return) {
246 onCmdText(nullptr, 0, nullptr);
247 if ((event->state & CONTROLMASK) != 0) {
248 close(true);
249 }
250 return 1;
251 } else if (event->code == KEY_Left || (event->code == KEY_Up && myList->getCurrentItem() == 0)) {
252 myTextEntry->setFocus();
253 return 1;
254 }
255 // let other elements handle the keypress
256 return 0;
257}
258
259
260long
261GUIDialog_ChooserAbstract::onCmdFilter(FXObject*, FXSelector, void*) {
263 std::vector<GUIGlID> selectedGlIDs;
264 const int numItems = myList->getNumItems();
265 for (int i = 0; i < numItems; i++) {
266 const GUIGlID glID = *static_cast<GUIGlID*>(myList->getItemData(i));
267 if (myList->getItemIcon(i) == flag) {
268 selectedGlIDs.push_back(glID);
269 }
270 }
271 refreshList(selectedGlIDs);
272 return 1;
273}
274
275
276long
277GUIDialog_ChooserAbstract::onCmdFilterSubstr(FXObject*, FXSelector, void*) {
278 const bool caseSensitive = myCaseSensitive->getCheck() == TRUE;
279 std::vector<GUIGlID> selectedGlIDs;
280 const int numItems = myList->getNumItems();
281 FXString t = myTextEntry->getText();
282 if (!caseSensitive) {
283 t = t.lower();
284 }
285 for (int i = 0; i < numItems; i++) {
286 FXString t2 = myList->getItemText(i);
287 if (!caseSensitive) {
288 t2 = t2.lower();
289 }
290 if (t2.find(t) >= 0) {
291 const GUIGlID glID = *static_cast<GUIGlID*>(myList->getItemData(i));
292 selectedGlIDs.push_back(glID);
293 }
294 }
295 refreshList(selectedGlIDs);
296 // filter ACs in netedit
297 filterACs(selectedGlIDs);
299 onChgText(nullptr, 0, nullptr);
300 return 1;
301}
302
303
304std::string
306 if (myLocateByName) {
307 return o->getOptionalName();
308 } else {
309 return o->getMicrosimID();
310 }
311}
312
313void
314GUIDialog_ChooserAbstract::refreshList(const std::vector<GUIGlID>& ids) {
315 myList->clearItems();
316 for (auto i : ids) {
318 if (o == nullptr) {
319 continue;
320 }
321 const std::string& name = getObjectName(o);
322 const bool selected = myWindowsParent->isSelected(o);
323 FXIcon* const ico = selected ? GUIIconSubSys::getIcon(GUIIcon::FLAG) : nullptr;
324 myIDs.insert(o->getGlID());
325 myList->appendItem(name.c_str(), ico, (void*) & (*myIDs.find(o->getGlID())));
327 }
328 myList->update();
329 myCountLabel->setText(TLF("% objects", toString(ids.size())).c_str());
330}
331
332
333long
336 int i = myList->getCurrentItem();
337 if (i >= 0) {
339 if (myList->getItemIcon(i) == flag) {
340 myList->setItemIcon(i, nullptr);
341 } else {
342 myList->setItemIcon(i, flag);
343 }
344 }
345 myList->update();
346 myWindowsParent->getView()->update();
347 return 1;
348}
349
350
351long
354 const int numItems = myList->getNumItems();
355 for (int i = 0; i < numItems; i++) {
356 select(i);
357 myList->setItemIcon(i, flag);
358 }
359 myList->update();
360 myWindowsParent->getView()->update();
361 return 1;
362}
363
364
365long
367 const int numItems = myList->getNumItems();
368 for (int i = 0; i < numItems; i++) {
369 deselect(i);
370 myList->setItemIcon(i, nullptr);
371 }
372 myList->update();
373 myWindowsParent->getView()->update();
374 return 1;
375}
376
377
378long
379GUIDialog_ChooserAbstract::onCmdLocateByName(FXObject*, FXSelector, void*) {
380 std::vector<std::pair<std::string, GUIGlID> > namesAndIDs;
381 myLocateByName = true;
382 const int numItems = myList->getNumItems();
383 for (int i = 0; i < numItems; i++) {
384 GUIGlID glID = *static_cast<GUIGlID*>(myList->getItemData(i));
386 if (o != 0) {
387 const std::string& name = getObjectName(o);
388 if (name != "") {
389 namesAndIDs.push_back(std::make_pair(name, glID));
390 }
391 }
393 }
394 std::sort(namesAndIDs.begin(), namesAndIDs.end());
395 std::vector<GUIGlID> selectedGlIDs;
396 for (const auto& item : namesAndIDs) {
397 selectedGlIDs.push_back(item.second);
398 }
399 refreshList(selectedGlIDs);
400 myTextEntry->setFocus();
401 return 1;
402}
403
404long
405GUIDialog_ChooserAbstract::onCmdUpdate(FXObject*, FXSelector, void*) {
407 return 1;
408}
409
410void
412 GUIGlID* glID = static_cast<GUIGlID*>(myList->getItemData(listIndex));
414}
415
416void
418 GUIGlID* glID = static_cast<GUIGlID*>(myList->getItemData(listIndex));
419 gSelected.select(*glID);
420}
421
422void
424 GUIGlID* glID = static_cast<GUIGlID*>(myList->getItemData(listIndex));
425 gSelected.deselect(*glID);
426}
427
428
429void
430GUIDialog_ChooserAbstract::filterACs(const std::vector<GUIGlID>& /*GLIDs*/) {
431 // overrided in GNEDialogACChooser
432}
433
434/****************************************************************************/
@ MID_CHOOSER_TRACK
Track object.
Definition GUIAppEnum.h:581
@ MID_CANCEL
Cancel-button pressed.
Definition GUIAppEnum.h:308
@ MID_CHOOSER_TEXT
Text entry.
Definition GUIAppEnum.h:583
@ MID_UPDATE
Update-button pressed.
Definition GUIAppEnum.h:310
@ MID_CHOOSEN_INVERT
Deselect selected items.
Definition GUIAppEnum.h:615
@ MID_CHOOSEN_SELECT
select all items
Definition GUIAppEnum.h:611
@ MID_CHOOSER_LIST
Object list.
Definition GUIAppEnum.h:585
@ MID_CHOOSEN_NAME
Deselect selected items.
Definition GUIAppEnum.h:617
@ MID_CHOOSER_FILTER_SUBSTR
Filter list by substring.
Definition GUIAppEnum.h:589
@ MID_CHOOSEN_CLEAR
Clear set.
Definition GUIAppEnum.h:605
@ MID_CHOOSER_FILTER
Filter selected.
Definition GUIAppEnum.h:587
@ MID_CHOOSER_CENTER
Center object.
Definition GUIAppEnum.h:579
#define GUIDesignChooserTextField
design for Chooser TextField
Definition GUIDesigns.h:654
#define GUIDesignChooserListSingle
design for Chooser List
Definition GUIDesigns.h:657
#define GUIDesignChooserButtons
design for Chooser buttons
Definition GUIDesigns.h:651
#define GUIDesignChooserLayoutLeft
design for Chooser Layout left
Definition GUIDesigns.h:666
#define GUIDesignChooserLayoutRight
design for Chooser Layout right
Definition GUIDesigns.h:669
#define GUIDesignHorizontalSeparator
Definition GUIDesigns.h:466
#define GUIDesignChooserLayoutList
design for Chooser Layout list
Definition GUIDesigns.h:672
#define GUIDesignAuxiliarFrame
design for auxiliar (Without borders) frame extended in all directions
Definition GUIDesigns.h:396
#define GUIDesignChooserDialog
Definition GUIDesigns.h:648
FXDEFMAP(GUIDialog_ChooserAbstract) GUIDialog_ChooserAbstractMap[]
unsigned int GUIGlID
Definition GUIGlObject.h:43
@ GLO_VEHICLE
a vehicle
GUISelectedStorage gSelected
A global holder of selected objects.
@ RECENTERVIEW
#define TL(string)
Definition MsgHandler.h:315
#define TLF(string,...)
Definition MsgHandler.h:317
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
Definition ToString.h:46
static FXButton * buildFXButton(FXComposite *p, const std::string &text, const std::string &tip, const std::string &help, FXIcon *ic, FXObject *tgt, FXSelector sel, FXuint opts=BUTTON_NORMAL, FXint x=0, FXint y=0, FXint w=0, FXint h=0, FXint pl=DEFAULT_PAD, FXint pr=DEFAULT_PAD, FXint pt=DEFAULT_PAD, FXint pb=DEFAULT_PAD)
build button
bool myLocateByName
whether to locate by object name instead of id
FXButton * myCenterButton
The button that triggers centering on the select object.
long onCmdText(FXObject *, FXSelector, void *)
Callback: Selects to current item if enter is pressed.
long onCmdClose(FXObject *, FXSelector, void *)
Callback: The dialog shall be closed.
void refreshList(const std::vector< GUIGlID > &ids)
update the list with the given ids
long onCmdCenter(FXObject *, FXSelector, void *)
Callback: The selected item shall be centered within the calling view.
FXCheckButton * myCaseSensitive
Whether search is case sensitive.
int myMessageId
the object type being chosen
virtual ~GUIDialog_ChooserAbstract()
Destructor.
long onCmdFilter(FXObject *, FXSelector, void *)
Callback: Hides unselected items if pressed.
long onCmdFilterSubstr(FXObject *, FXSelector, void *)
Callback: Hides unmatched items if pressed.
virtual void deselect(int listIndex)
unset selection (handled differently in netedit)
virtual void select(int listIndex)
set selection (handled differently in netedit)
void show()
sets the focus after the window is created to work-around bug in libfox
long onCmdTrack(FXObject *, FXSelector, void *)
Callback: The selected vehicle shall be tracked within the calling view.
long onCmdLocateByName(FXObject *, FXSelector, void *)
Callback: Toggle locator by name.
bool myHaveFilteredSubstring
whether the list was filter by substring
FXLabel * myCountLabel
label for declaring list size
long onListKeyPress(FXObject *, FXSelector, void *)
Callback: Selects to current item if enter is pressed.
long onChgText(FXObject *, FXSelector, void *)
Callback: Something has been typed into the field.
GUIGlChildWindow * myWindowsParent
window parent
long onCmdUpdate(FXObject *, FXSelector, void *)
Callback: Update list.
std::set< GUIGlID > myIDs
myList contains (void) pointers to elements of myIDs instead of the more volatile pointers to GUIGlOb...
long onChgListSel(FXObject *, FXSelector, void *)
Callback: Current list item selection has changed.
GUIGlObject * mySelected
The chosen id.
long onCmdClearListSelection(FXObject *, FXSelector, void *)
long onCmdAddListSelection(FXObject *, FXSelector, void *)
virtual void toggleSelection(int listIndex)
fox need this
FXButton * myTrackButton
The button that triggers tracking on the select vehicle.
virtual std::string getObjectName(GUIGlObject *o) const
retrieve name for the given object
virtual void filterACs(const std::vector< GUIGlID > &GLIDs)
filter ACs (needed in netedit)
FXTextField * myTextEntry
The text field.
long onCmdToggleSelection(FXObject *, FXSelector, void *)
Callback: Toggle selection status of current object / list.
FXCheckButton * myInstantCenter
Whether each change in the list should re-center the view.
long onChgList(FXObject *, FXSelector, void *)
Callback: Current list item has changed.
GUIGlObject * getObject() const
Returns the chosen (selected) object.
FXList * myList
The list that holds the ids.
void setView(GUIGlID id)
Centers the view onto the given artifact.
virtual bool isSelected(GUIGlObject *o) const
true if the object is selected (may include extra logic besides calling gSelected)
GUISUMOAbstractView * getView() const
return GUISUMOAbstractView
GUIMainWindow * getGUIMainWindowParent()
Returns the GUIMainWindow parent.
virtual std::vector< GUIGlID > getObjectIDs(int messageId) const
const std::string & getMicrosimID() const
Returns the id of the object as known to microsim.
virtual const std::string getOptionalName() const
Returns the name of the object (default "")
GUIGlObjectType getType() const
Returns the type of the object as coded in GUIGlObjectType.
GUIGlID getGlID() const
Returns the numerical id of the object.
A storage for of displayed objects via their numerical id.
void unblockObject(GUIGlID id)
Marks an object as unblocked.
GUIGlObject * getObjectBlocking(GUIGlID id) const
Returns the object from the container locking it.
static GUIGlObjectStorage gIDStorage
A single static instance of this class.
static FXIcon * getIcon(const GUIIcon which)
returns a icon previously defined in the enum GUIIcon
void removeChild(FXMainWindow *child)
removes the given child window from the list (FXMainWindow)
Persists window position in the registry.
virtual void stopTrack()
stop track
virtual void startTrack(int)
star track
void toggleSelection(GUIGlID id)
Toggles selection of an object.
void select(GUIGlID id, bool update=true)
Adds the object with the given id.
void deselect(GUIGlID id)
Deselects the object with the given id.
Definition json.hpp:4471