Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
MFXComboBoxIcon.cpp
Go to the documentation of this file.
1/****************************************************************************/
2// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3// Copyright (C) 2006-2025 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/****************************************************************************/
19//
20/****************************************************************************/
21
26
27#include "MFXComboBoxIcon.h"
28#include "MFXListIcon.h"
29#include "MFXListIconItem.h"
30#include "MFXTextFieldSearch.h"
31
32// ===========================================================================
33// FOX callback mapping
34// ===========================================================================
35
36FXDEFMAP(MFXComboBoxIcon) MFXComboBoxIconMap[] = {
37 FXMAPFUNC(SEL_FOCUS_UP, 0, MFXComboBoxIcon::onFocusUp),
38 FXMAPFUNC(SEL_FOCUS_DOWN, 0, MFXComboBoxIcon::onFocusDown),
39 FXMAPFUNC(SEL_FOCUS_SELF, 0, MFXComboBoxIcon::onFocusSelf),
43 FXMAPFUNC(SEL_LEFTBUTTONPRESS, MFXComboBoxIcon::ID_TEXT, MFXComboBoxIcon::onTextButton),
47 FXMAPFUNC(SEL_COMMAND, FXWindow::ID_SETVALUE, MFXComboBoxIcon::onFwdToText),
48 FXMAPFUNC(SEL_COMMAND, FXWindow::ID_SETINTVALUE, MFXComboBoxIcon::onFwdToText),
49 FXMAPFUNC(SEL_COMMAND, FXWindow::ID_SETREALVALUE, MFXComboBoxIcon::onFwdToText),
50 FXMAPFUNC(SEL_COMMAND, FXWindow::ID_SETSTRINGVALUE, MFXComboBoxIcon::onFwdToText),
51 FXMAPFUNC(SEL_COMMAND, FXWindow::ID_GETINTVALUE, MFXComboBoxIcon::onFwdToText),
52 FXMAPFUNC(SEL_COMMAND, FXWindow::ID_GETREALVALUE, MFXComboBoxIcon::onFwdToText),
53 FXMAPFUNC(SEL_COMMAND, FXWindow::ID_GETSTRINGVALUE, MFXComboBoxIcon::onFwdToText),
55};
56
57// Object implementation
58FXIMPLEMENT(MFXComboBoxIcon, FXPacker, MFXComboBoxIconMap, ARRAYNUMBER(MFXComboBoxIconMap))
59
60// ===========================================================================
61// member method definitions
62// ===========================================================================
63
64MFXComboBoxIcon::MFXComboBoxIcon(FXComposite* p, MFXStaticToolTip* staticToolTip, const bool canSearch, const int visibleItems,
65 FXObject* tgt, FXSelector sel, FXuint opts, FXint x, FXint y, FXint w, FXint h, FXint pl, FXint pr, FXint pt, FXint pb):
66 FXPacker(p, opts, x, y, w, h, 0, 0, 0, 0, 0, 0) {
67 flags |= FLAG_ENABLED;
68 target = tgt;
69 message = sel;
70 // create text field
71 myTextFieldIcon = new MFXTextFieldIcon(this, staticToolTip, GUIIcon::EMPTY, this, MFXComboBoxIcon::ID_TEXT, 0, 0, 0, 0, 0, pl, pr, pt, pb);
72 if (options & COMBOBOX_STATIC) {
73 myTextFieldIcon->setEditable(FALSE);
74 }
75 // create pane for list
76 myPane = new FXPopup(this, FRAME_LINE);
77 // check if create search button
78 if (canSearch) {
79 myTextFieldSearch = new MFXTextFieldSearch(myPane, staticToolTip, this, ID_SEARCH, FRAME_THICK | LAYOUT_FIX_WIDTH | LAYOUT_FIX_HEIGHT, 0, 0, 0, 0, 2, 2, 2, 2);
80 // create label for empty icon
81 myNoItemsLabel = new FXLabel(myPane, TL("No matches found"), nullptr, FRAME_THICK | LAYOUT_FIX_WIDTH | LAYOUT_FIX_HEIGHT, 0, 0, 0, 0, 2, 2, 2, 2);
83 myNoItemsLabel->hide();
84 }
85 // create list icon
86 myList = new MFXListIcon(myPane, this, MFXComboBoxIcon::ID_LIST, LIST_BROWSESELECT | LIST_AUTOSELECT | LAYOUT_FILL_X | LAYOUT_FILL_Y | SCROLLERS_TRACK | HSCROLLER_NEVER);
87 if (options & COMBOBOX_STATIC) {
88 myList->setScrollStyle(SCROLLERS_TRACK | HSCROLLING_OFF);
89 }
90 myList->setNumVisible(visibleItems);
91 // create button
92 myButton = new FXMenuButton(this, FXString::null, NULL, myPane, FRAME_RAISED | FRAME_THICK | MENUBUTTON_DOWN | MENUBUTTON_ATTACH_RIGHT, 0, 0, 0, 0, 0, 0, 0, 0);
93 myButton->setXOffset(border);
94 myButton->setYOffset(border);
95 flags &= ~(FXuint)FLAG_UPDATE; // Never GUI update
96
97}
98
99
101 delete myPane;
102 myPane = (FXPopup*) - 1L;
104 myButton = (FXMenuButton*) - 1L;
105 if (myTextFieldSearch) {
107 myNoItemsLabel = (FXLabel*) - 1L;
108 }
109 myList = (MFXListIcon*) - 1L;
110}
111
112
113void
115 FXPacker::create();
116 myPane->create();
117}
118
119
120void
122 FXPacker::detach();
123 myPane->detach();
124}
125
126
127void
129 myPane->destroy();
130 FXPacker::destroy();
131}
132
133
134void
136 if (!isEnabled()) {
137 FXPacker::enable();
138 myTextFieldIcon->enable();
139 myButton->enable();
140 }
141}
142
143
144void
146 if (isEnabled()) {
147 FXPacker::disable();
148 myTextFieldIcon->disable();
149 myButton->disable();
150 }
151}
152
153
154FXint
156 FXint ww = myTextFieldIcon->getDefaultWidth() + myButton->getDefaultWidth() + (border << 1);
157 FXint pw = myPane->getDefaultWidth();
158 return FXMAX(ww, pw);
159}
160
161
162FXint
164 FXint th, bh;
165 th = myTextFieldIcon->getDefaultHeight();
166 bh = myButton->getDefaultHeight();
167 return FXMAX(th, bh) + (border << 1);
168}
169
170
171void
173 const FXint itemHeight = height - (border << 1);
174 const FXint buttonWidth = myButton->getDefaultWidth();
175 const FXint textWidth = width - buttonWidth - (border << 1);
176 myTextFieldIcon->position(border, border, textWidth, itemHeight);
177 myButton->position(border + textWidth, border, buttonWidth, itemHeight);
178 if (myTextFieldSearch) {
179 myTextFieldSearch->resize(width, height);
180 myNoItemsLabel->resize(width, height);
181 }
182 myPane->resize(width, myPane->getDefaultHeight());
183 flags &= ~(FXuint)FLAG_DIRTY;
184}
185
186
187FXString
189 return myTextFieldIcon->getText();
190}
191
192
193FXint
195 return myList->getNumItems();
196}
197
198
199void
201 myList->setNumVisible(nvis);
202}
203
204
205void
206MFXComboBoxIcon::setText(const FXString& text, FXbool notify) {
207 myTextFieldIcon->setText(text, notify);
208}
209
210
211FXbool
213 return myList->isItemCurrent(index);
214}
215
216
217long
218MFXComboBoxIcon::setCurrentItem(const FXint index, FXbool notify) {
219 if (index >= 0 && index <= myList->getNumItems()) {
220 // get item
221 MFXListIconItem* item = myList->getItem(index);
222 // set it as current item and make it visible
223 myList->setCurrentItem(item);
224 myList->makeItemVisible(index);
225 // update both text fields
226 myTextFieldIcon->setText(item->getText());
227 myTextFieldIcon->setIcon(item->getIcon());
228 myTextFieldIcon->setBackColor(item->getBackGroundColor());
229 // check if notify
230 if (notify && target) {
231 return target->tryHandle(this, FXSEL(SEL_COMMAND, message), (void*)item);
232 }
233 } else {
234 fxerror("%s::setItem: index out of range.\n", getClassName());
235 }
236 return 0;
237}
238
239
240long
241MFXComboBoxIcon::setCurrentItem(const FXString& text, FXbool notify) {
242 // check if item exist
243 for (int i = 0; i < myList->getNumItems(); i++) {
244 const auto itemText = myList->tolowerString(myList->getItem(i)->getText());
245 if (myList->tolowerString(text) == itemText) {
246 // use "set curent item" function
247 return setCurrentItem(i, notify);
248 }
249 }
250 return 0;
251}
252
253
254FXint
256 return myList->getCurrentItemIndex();
257}
258
259
260FXint
261MFXComboBoxIcon::updateIconItem(FXint index, const FXString& text, FXIcon* icon, FXColor bgColor, void* ptr) {
262 if (index < 0 || myList->getNumItems() <= index) {
263 fxerror("%s::setItem: index out of range.\n", getClassName());
264 }
265 myList->editItem(index, text, NULL, ptr);
266 if (isItemCurrent(index)) {
267 myTextFieldIcon->setText(text);
268 myTextFieldIcon->setBackColor(bgColor);
269 myTextFieldIcon->setIcon(icon);
270 }
271 recalc();
272 return index;
273}
274
275
276FXint
277MFXComboBoxIcon::insertIconItem(FXint index, const FXString& text, FXIcon* icon, FXColor bgColor, void* ptr) {
278 index = myList->insertItem(index, new MFXListIconItem(text, icon, bgColor, ptr));
279 if (isItemCurrent(index)) {
280 myTextFieldIcon->setText(text);
281 myTextFieldIcon->setBackColor(bgColor);
282 myTextFieldIcon->setIcon(icon);
283 }
284 recalc();
285 return index;
286}
287
288
289FXint
290MFXComboBoxIcon::appendIconItem(const FXString& text, FXIcon* icon, FXColor bgColor, void* ptr) {
291 FXint index = myList->appendItem(new MFXListIconItem(text, icon, bgColor, ptr));
292 if (isItemCurrent(getNumItems() - 1)) {
293 myTextFieldIcon->setText(text);
294 myTextFieldIcon->setBackColor(bgColor);
295 myTextFieldIcon->setIcon(icon);
296 }
297 recalc();
298 return index;
299}
300
301
302void
304 const auto isCurrent = myList->isItemCurrent(index);
305 if (isCurrent == TRUE) {
306 if ((index > 0) && (index < (int)myList->getNumItems())) {
307 setCurrentItem(index - 1);
308 } else if (myList->getNumItems() > 0) {
310 }
311 }
312 myList->removeItem(index);
313 recalc();
314}
315
316
317void
319 myTextFieldIcon->setText("");
320 myList->clearItems();
321 recalc();
322}
323
324
325FXint
326MFXComboBoxIcon::findItem(const FXString& text) const {
327 return myList->findItem(text);
328}
329
330
331std::string
333 return myList->getItem(index)->getText().text();
334}
335
336
337void
339 myTextFieldIcon->setBackColor(clr);
340 myList->setBackColor(clr);
341}
342
343
344void
346 myTextFieldIcon->setTextColor(clr);
347 myList->setTextColor(clr);
348}
349
350
351FXColor
353 return myTextFieldIcon->getTextColor();
354}
355
356
357void
358MFXComboBoxIcon::setTipText(const FXString& txt) {
359 myTextFieldIcon->setTipText(txt);
360}
361
362
363const FXString&
365 return myTextFieldIcon->getTipText();
366}
367
368
369long
370MFXComboBoxIcon::onUpdFmText(FXObject*, FXSelector, void*) {
371 return (target && !myPane->shown()) ? target->tryHandle(this, FXSEL(SEL_UPDATE, message), NULL) : 0;
372}
373
374
375long
376MFXComboBoxIcon::onCmdFilter(FXObject*, FXSelector, void* ptr) {
377 myList->setFilter(myTextFieldSearch->getText(), myNoItemsLabel);
378 myPane->resize(width, myPane->getDefaultHeight());
379 myPane->recalc();
380 myPane->onPaint(0, 0, ptr);
381 return 1;
382}
383
384
385long
386MFXComboBoxIcon::onFwdToText(FXObject* sender, FXSelector sel, void* ptr) {
387 return myTextFieldIcon->handle(sender, sel, ptr);
388}
389
390
391long
392MFXComboBoxIcon::onListClicked(FXObject*, FXSelector sel, void* ptr) {
393 // hide pane
394 myButton->handle(this, FXSEL(SEL_COMMAND, ID_UNPOST), NULL);
395 if (FXSELTYPE(sel) == SEL_COMMAND) {
396 // cast MFXListIconItem
397 const MFXListIconItem* item = (MFXListIconItem*)ptr;
398 // set icon and background color
399 myTextFieldIcon->setText(item->getText());
400 myTextFieldIcon->setIcon(item->getIcon());
401 myTextFieldIcon->setBackColor(item->getBackGroundColor());
402 // Select if editable
403 if (!(options & COMBOBOX_STATIC)) {
404 myTextFieldIcon->selectAll();
405 }
406 if (target) {
407 target->tryHandle(this, FXSEL(SEL_COMMAND, message), (void*)getText().text());
408 }
409 }
410 return 1;
411}
412
413
414long
415MFXComboBoxIcon::onTextButton(FXObject*, FXSelector, void*) {
416 if (options & COMBOBOX_STATIC) {
417 // Post the myList
418 myButton->handle(this, FXSEL(SEL_COMMAND, ID_POST), NULL);
419 return 1;
420 }
421 return 0;
422}
423
424
425long
426MFXComboBoxIcon::onTextChanged(FXObject*, FXSelector, void* ptr) {
427 return target ? target->tryHandle(this, FXSEL(SEL_CHANGED, message), ptr) : 0;
428}
429
430
431long
432MFXComboBoxIcon::onTextCommand(FXObject*, FXSelector, void* ptr) {
433 // reset background colors
435 // check if item exist
436 for (int i = 0; i < myList->getNumItems(); i++) {
437 const auto itemText = myList->tolowerString(myList->getItem(i)->getText());
438 if (myList->tolowerString(myTextFieldIcon->getText()) == itemText) {
439 // use "set curent item" function
440 return setCurrentItem(i, TRUE);
441 }
442 }
443 // no item found, then reset icon label
445 return target ? target->tryHandle(this, FXSEL(SEL_COMMAND, message), ptr) : 0;
446}
447
448
449long
450MFXComboBoxIcon::onFocusSelf(FXObject* sender, FXSelector, void* ptr) {
451 return myTextFieldIcon->handle(sender, FXSEL(SEL_FOCUS_SELF, 0), ptr);
452}
453
454
455long
456MFXComboBoxIcon::onFocusUp(FXObject*, FXSelector, void*) {
457 if (isEnabled()) {
458 FXint index = getCurrentItem();
459 if (index < 0) {
460 index = getNumItems() - 1;
461 } else if (0 < index) {
462 index--;
463 }
464 if (0 <= index && index < getNumItems()) {
465 setCurrentItem(index, TRUE);
466 }
467 return 1;
468 }
469 return 0;
470}
471
472
473long
474MFXComboBoxIcon::onFocusDown(FXObject*, FXSelector, void*) {
475 if (isEnabled()) {
476 FXint index = getCurrentItem();
477 if (index < 0) {
478 index = 0;
479 } else if (index < getNumItems() - 1) {
480 index++;
481 }
482 if (0 <= index && index < getNumItems()) {
483 setCurrentItem(index, TRUE);
484 }
485 return 1;
486 }
487 return 0;
488}
489
490
491long MFXComboBoxIcon::onMouseWheel(FXObject*, FXSelector, void* ptr) {
492 FXEvent* event = (FXEvent*)ptr;
493 if (isEnabled()) {
494 FXint index = getCurrentItem();
495 if (event->code < 0) {
496 if (index < 0) {
497 index = 0;
498 } else if (index < getNumItems() - 1) {
499 index++;
500 }
501 } else if (event->code > 0) {
502 if (index < 0) {
503 index = getNumItems() - 1;
504 } else if (0 < index) {
505 index--;
506 }
507 }
508 if (0 <= index && index < getNumItems()) {
509 setCurrentItem(index, TRUE);
510 }
511 return 1;
512 }
513 return 0;
514}
515
516
@ MID_MTEXTFIELDSEARCH_UPDATED
callback for MFXTextFieldSearch
#define GUIDesignTextColorRed
red color (for invalid text)
Definition GUIDesigns.h:44
#define GUIDesignBackgroundColorWhite
white background color (for valid text)
Definition GUIDesigns.h:47
@ EMPTY
Definition GUIIcons.h:59
FXDEFMAP(MFXComboBoxIcon) MFXComboBoxIconMap[]
#define TL(string)
Definition MsgHandler.h:304
static FXIcon * getIcon(const GUIIcon which)
returns a icon previously defined in the enum GUIIcon
FXbool isItemCurrent(FXint index) const
Return true if current item.
FXint insertIconItem(FXint index, const FXString &text, FXIcon *icon=nullptr, FXColor bgColor=FXRGB(255, 255, 255), void *ptr=nullptr)
insert icon item in the given position
long setCurrentItem(const FXint index, FXbool notify=FALSE)
Set the current item (index is zero-based).
void layout()
Perform layout.
FXint getCurrentItem() const
Get the current item's index.
void destroy()
Destroy server-side resources.
FXint findItem(const FXString &text) const
find item
long onTextChanged(FXObject *, FXSelector, void *)
void removeItem(FXint index)
Remove this item from the list.
long onFwdToText(FXObject *, FXSelector, void *)
FXint getNumItems() const
Return the number of items in the list.
FXLabel * myNoItemsLabel
no items label
const FXString & getTipText() const
Get the tool tip message for this combobox.
long onMouseWheel(FXObject *, FXSelector, void *)
FXint getDefaultWidth()
Return default width.
MFXTextFieldSearch * myTextFieldSearch
text field search
void setBackColor(FXColor clr)
Set window background color.
long onListClicked(FXObject *, FXSelector, void *)
FXMenuButton * myButton
myButton
MFXListIcon * myList
list with all items
FXString getText() const
Get the text.
long onCmdFilter(FXObject *, FXSelector, void *)
void setTextColor(FXColor clr)
Change text color.
FXPopup * myPane
popup in which place search label and list
void setNumVisible(FXint nvis)
Set the number of visible items in the drop down list.
~MFXComboBoxIcon()
Destructor.
virtual void clearItems()
Remove all items from the list.
FXint updateIconItem(FXint index, const FXString &text, FXIcon *icon=nullptr, FXColor bgColor=FXRGB(255, 255, 255), void *ptr=nullptr)
Replace the item at index.
FXint getDefaultHeight()
Return default height.
long onTextButton(FXObject *, FXSelector, void *)
void setTipText(const FXString &txt)
Set the tool tip message for this combobox.
MFXComboBoxIcon(FXComposite *p, MFXStaticToolTip *staticToolTip, const bool canSearch, const int visibleItems, FXObject *tgt, FXSelector sel, FXuint opts, 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)
Construct a Combo Box widget with room to display cols columns of text.
std::string getItemText(FXint index) const
Get text for specified item.
void disable()
Disable combo box.
MFXComboBoxIcon()
FOX need this.
FXColor getTextColor() const
Return text color.
long onUpdFmText(FXObject *, FXSelector, void *)
FXint appendIconItem(const FXString &text, FXIcon *icon=nullptr, FXColor bgColor=FXRGB(255, 255, 255), void *ptr=nullptr)
append icon item in the last position
void enable()
Enable combo box.
MFXTextFieldIcon * myTextFieldIcon
textField icon
long onTextCommand(FXObject *, FXSelector, void *)
void detach()
Detach server-side resources.
void create()
Create server-side resources.
long onFocusDown(FXObject *, FXSelector, void *)
long onFocusSelf(FXObject *, FXSelector, void *)
void setText(const FXString &text, FXbool notify=FALSE)
Set the text in the textField.
long onFocusUp(FXObject *, FXSelector, void *)
Commands.
A list item which allows for custom coloring.
Definition MFXListIcon.h:38
const FXString & getText() const
Return item's text label.
FXIcon * getIcon() const
Return item's icon.
const FXColor & getBackGroundColor() const
get background color
MFXStaticToolTip (based on FXToolTip).
FXTextFieldIcon (based on FXTextFieldIcon).