LCOV - code coverage report
Current view: top level - src/utils/foxtools - MFXListIcon.cpp (source / functions) Hit Total Coverage
Test: lcov.info Lines: 174 558 31.2 %
Date: 2024-04-28 15:39:05 Functions: 28 76 36.8 %

          Line data    Source code
       1             : /****************************************************************************/
       2             : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3             : // Copyright (C) 2006-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             : /****************************************************************************/
      14             : /// @file    MFXListIcon.cpp
      15             : /// @author  Pablo Alvarez Lopez
      16             : /// @date    Feb 2023
      17             : ///
      18             : //
      19             : /****************************************************************************/
      20             : 
      21             : // ===========================================================================
      22             : // included modules
      23             : // ===========================================================================
      24             : 
      25             : #include <utils/common/UtilExceptions.h>
      26             : #include <fxkeys.h>
      27             : 
      28             : #include "MFXListIcon.h"
      29             : 
      30             : // ===========================================================================
      31             : // Macross
      32             : // ===========================================================================
      33             : 
      34             : #define LINE_SPACING    4   // Line spacing between items
      35             : #define ICON_SIZE       16
      36             : 
      37             : #define LIST_MASK   (SELECT_MASK | LIST_AUTOSELECT)
      38             : 
      39             : // ===========================================================================
      40             : // FOX callback mapping
      41             : // ===========================================================================
      42             : 
      43             : // Map
      44             : FXDEFMAP(MFXListIcon) MFXListIconMap[] = {
      45             :     FXMAPFUNC(SEL_PAINT,                0,                              MFXListIcon::onPaint),
      46             :     FXMAPFUNC(SEL_ENTER,                0,                              MFXListIcon::onEnter),
      47             :     FXMAPFUNC(SEL_LEAVE,                0,                              MFXListIcon::onLeave),
      48             :     FXMAPFUNC(SEL_MOTION,               0,                              MFXListIcon::onMotion),
      49             :     FXMAPFUNC(SEL_TIMEOUT,              FXWindow::ID_AUTOSCROLL,        MFXListIcon::onAutoScroll),
      50             :     FXMAPFUNC(SEL_TIMEOUT,              MFXListIcon::ID_TIPTIMER,       MFXListIcon::onTipTimer),
      51             :     FXMAPFUNC(SEL_TIMEOUT,              MFXListIcon::ID_LOOKUPTIMER,    MFXListIcon::onLookupTimer),
      52             :     FXMAPFUNC(SEL_UNGRABBED,            0,                              MFXListIcon::onUngrabbed),
      53             :     FXMAPFUNC(SEL_LEFTBUTTONPRESS,      0,                              MFXListIcon::onLeftBtnPress),
      54             :     FXMAPFUNC(SEL_LEFTBUTTONRELEASE,    0,                              MFXListIcon::onLeftBtnRelease),
      55             :     FXMAPFUNC(SEL_RIGHTBUTTONPRESS,     0,                              MFXListIcon::onRightBtnPress),
      56             :     FXMAPFUNC(SEL_RIGHTBUTTONRELEASE,   0,                              MFXListIcon::onRightBtnRelease),
      57             :     FXMAPFUNC(SEL_KEYPRESS,             0,                              MFXListIcon::onKeyPress),
      58             :     FXMAPFUNC(SEL_KEYRELEASE,           0,                              MFXListIcon::onKeyRelease),
      59             :     FXMAPFUNC(SEL_FOCUSIN,              0,                              MFXListIcon::onFocusIn),
      60             :     FXMAPFUNC(SEL_FOCUSOUT,             0,                              MFXListIcon::onFocusOut),
      61             :     FXMAPFUNC(SEL_CLICKED,              0,                              MFXListIcon::onClicked),
      62             :     FXMAPFUNC(SEL_DOUBLECLICKED,        0,                              MFXListIcon::onDoubleClicked),
      63             :     FXMAPFUNC(SEL_TRIPLECLICKED,        0,                              MFXListIcon::onTripleClicked),
      64             :     FXMAPFUNC(SEL_COMMAND,              0,                              MFXListIcon::onCommand),
      65             :     FXMAPFUNC(SEL_QUERY_TIP,            0,                              MFXListIcon::onQueryTip),
      66             :     FXMAPFUNC(SEL_QUERY_HELP,           0,                              MFXListIcon::onQueryHelp),
      67             : };
      68             : 
      69             : 
      70             : // Object implementation
      71     1861755 : FXIMPLEMENT(MFXListIcon, FXScrollArea, MFXListIconMap, ARRAYNUMBER(MFXListIconMap))
      72             : 
      73             : // ===========================================================================
      74             : // member method definitions
      75             : // ===========================================================================
      76             : 
      77        6815 : MFXListIcon::MFXListIcon(FXComposite* p, FXObject* tgt, FXSelector sel, FXuint opts, FXint x, FXint y, FXint w, FXint h):
      78        6815 :     FXScrollArea(p, opts, x, y, w, h) {
      79        6815 :     flags |= FLAG_ENABLED;
      80        6815 :     target = tgt;
      81        6815 :     message = sel;
      82        6815 :     font = getApp()->getNormalFont();
      83        6815 :     textColor = getApp()->getForeColor();
      84        6815 :     selbackColor = getApp()->getSelbackColor();
      85        6815 :     seltextColor = getApp()->getSelforeColor();
      86        6815 : }
      87             : 
      88             : 
      89       13606 : MFXListIcon::~MFXListIcon() {
      90        6803 :     getApp()->removeTimeout(this, ID_TIPTIMER);
      91        6803 :     getApp()->removeTimeout(this, ID_LOOKUPTIMER);
      92        6803 :     clearItems(FALSE);
      93        6803 :     font = (FXFont*) - 1L;
      94       20409 : }
      95             : 
      96             : 
      97             : void
      98       27260 : MFXListIcon::create() {
      99       27260 :     FXScrollArea::create();
     100      163688 :     for (const auto& item : items) {
     101      136428 :         item->create();
     102             :     }
     103       27260 :     font->create();
     104       27260 : }
     105             : 
     106             : 
     107             : void
     108           0 : MFXListIcon::detach() {
     109           0 :     FXScrollArea::detach();
     110           0 :     for (const auto& item : items) {
     111           0 :         item->detach();
     112             :     }
     113           0 :     font->detach();
     114           0 : }
     115             : 
     116             : 
     117             : bool
     118           0 : MFXListIcon::canFocus() const {
     119           0 :     return true;
     120             : }
     121             : 
     122             : 
     123             : void
     124           0 : MFXListIcon::setFocus() {
     125           0 :     FXScrollArea::setFocus();
     126           0 :     setDefault(TRUE);
     127           0 : }
     128             : 
     129             : 
     130             : void
     131           0 : MFXListIcon::killFocus() {
     132           0 :     FXScrollArea::killFocus();
     133           0 :     setDefault(MAYBE);
     134           0 : }
     135             : 
     136             : 
     137             : FXint
     138       39538 : MFXListIcon::getDefaultWidth() {
     139       39538 :     return FXScrollArea::getDefaultWidth();
     140             : }
     141             : 
     142             : 
     143             : FXint
     144       53146 : MFXListIcon::getDefaultHeight() {
     145       53146 :     if (visible > (int)itemFiltered.size()) {
     146       53146 :         return (int)itemFiltered.size() * (LINE_SPACING + FXMAX(font->getFontHeight(),  ICON_SIZE));
     147             :     } else {
     148           0 :         return visible * (LINE_SPACING + FXMAX(font->getFontHeight(),  ICON_SIZE));
     149             :     }
     150             : }
     151             : 
     152             : 
     153             : void
     154       54540 : MFXListIcon::recalc() {
     155       54540 :     FXScrollArea::recalc();
     156       54540 :     flags |= FLAG_RECALC;
     157       54540 :     cursor = nullptr;
     158       54540 : }
     159             : 
     160             : 
     161             : void
     162        6815 : MFXListIcon::setNumVisible(FXint nvis) {
     163             :     if (nvis < 0) {
     164             :         nvis = 0;
     165             :     }
     166        6815 :     if (visible != nvis) {
     167        6815 :         visible = nvis;
     168        6815 :         recalc();
     169             :     }
     170        6815 : }
     171             : 
     172             : 
     173             : FXint
     174       46353 : MFXListIcon::getContentWidth() {
     175       46353 :     if (flags & FLAG_RECALC) {
     176        6815 :         recompute();
     177             :     }
     178       46353 :     return listWidth;
     179             : }
     180             : 
     181             : 
     182             : FXint
     183        6815 : MFXListIcon::getContentHeight() {
     184        6815 :     if (flags & FLAG_RECALC) {
     185           0 :         recompute();
     186             :     }
     187        6815 :     return listHeight;
     188             : }
     189             : 
     190             : 
     191             : void
     192        6815 : MFXListIcon::layout() {
     193             :     // Calculate contents
     194        6815 :     FXScrollArea::layout();
     195             :     // Determine line size for scroll bars
     196        6815 :     if (0 < (int)itemFiltered.size()) {
     197        6815 :         vertical->setLine(itemFiltered[0]->getHeight(this));
     198        6815 :         horizontal->setLine(itemFiltered[0]->getWidth(this) / 10);
     199             :     }
     200        6815 :     update();
     201             :     // We were supposed to make this item viewable
     202        6815 :     if (viewable) {
     203        6815 :         makeItemVisible(viewable);
     204             :     }
     205             :     // No more dirty
     206        6815 :     flags &= ~FLAG_DIRTY;
     207        6815 : }
     208             : 
     209             : 
     210             : FXbool
     211       34107 : MFXListIcon::isItemCurrent(FXint index) const {
     212       34107 :     for (int i = 0; i < (int)items.size(); i++) {
     213       34107 :         if (items[i] == currentItem) {
     214       34107 :             return i == index;
     215             :         }
     216             :     }
     217             :     return false;
     218             : }
     219             : 
     220             : 
     221             : FXbool
     222           0 : MFXListIcon::isItemVisible(MFXListIconItem* item) const {
     223           0 :     return (0 < (pos_y + item->y + item->getHeight(this))) && ((pos_y + item->y) < viewport_h);
     224             : }
     225             : 
     226             : 
     227             : void
     228       13665 : MFXListIcon::makeItemVisible(MFXListIconItem* item) {
     229             :     FXint y, h;
     230             :     // Remember for later
     231       13665 :     viewable = item;
     232             :     // Was realized
     233       13665 :     if (xid) {
     234             :         // Force layout if dirty
     235        6850 :         if (flags & FLAG_RECALC) {
     236           0 :             layout();
     237             :         }
     238        6850 :         y = pos_y;
     239        6850 :         h = item->getHeight(this);
     240        6850 :         if (viewport_h <= y + item->y + h) {
     241           0 :             y = viewport_h - item->y - h;
     242             :         }
     243        6850 :         if (y + item->y <= 0) {
     244        6815 :             y = -item->y;
     245             :         }
     246             :         // Scroll into view
     247        6850 :         setPosition(pos_x, y);
     248             :         // Done it
     249        6850 :         viewable = nullptr;
     250             :     }
     251       13665 : }
     252             : 
     253             : 
     254             : void
     255        6850 : MFXListIcon::makeItemVisible(FXint index) {
     256        6850 :     makeItemVisible(items[index]);
     257        6850 : }
     258             : 
     259             : 
     260             : FXint
     261           0 : MFXListIcon::getItemWidth(FXint index) const {
     262           0 :     if ((index < 0) || ((int)itemFiltered.size() <= index)) {
     263           0 :         fxerror("%s::isItemSelected: index out of range.\n", getClassName());
     264             :     }
     265           0 :     return itemFiltered[index]->getWidth(this);
     266             : }
     267             : 
     268             : 
     269             : FXint
     270           0 : MFXListIcon::getItemHeight(FXint index) const {
     271           0 :     if ((index < 0) || ((int)itemFiltered.size() <= index)) {
     272           0 :         fxerror("%s::isItemSelected: index out of range.\n", getClassName());
     273             :     }
     274           0 :     return itemFiltered[index]->getHeight(this);
     275             : }
     276             : 
     277             : 
     278             : MFXListIconItem*
     279           0 : MFXListIcon::getItemAt(FXint y) const {
     280           0 :     y -= pos_y;
     281             :     // continue depending if we're filtering
     282           0 :     if (filter.empty()) {
     283           0 :         for (int i = 0; i < (int)items.size(); i++) {
     284           0 :             if (items[i]->y <= y && y < items[i]->y + items[i]->getHeight(this)) {
     285           0 :                 return items[i];
     286             :             }
     287             :         }
     288             :     } else {
     289           0 :         for (int i = 0; i < (int)itemFiltered.size(); i++) {
     290           0 :             if ((itemFiltered[i]->y <= y) && (y < itemFiltered[i]->y + itemFiltered[i]->getHeight(this))) {
     291           0 :                 return itemFiltered[i];
     292             :             }
     293             :         }
     294             :     }
     295             :     return nullptr;
     296             : }
     297             : 
     298             : 
     299             : int
     300          41 : MFXListIcon::findItem(const FXString& text) const {
     301         235 :     for (int i = 0; i < (int)items.size(); i++) {
     302         229 :         if (items[i]->getText().text() == text) {
     303          35 :             return i;
     304             :         }
     305             :     }
     306             :     return -1;
     307             : }
     308             : 
     309             : 
     310             : FXint
     311           0 : MFXListIcon::hitItem(MFXListIconItem* item, FXint x, FXint y) const {
     312             :     FXint ix, iy, hit = 0;
     313           0 :     if (item) {
     314           0 :         x -= pos_x;
     315           0 :         y -= pos_y;
     316           0 :         ix = item->x;
     317           0 :         iy = item->y;
     318           0 :         hit = item->hitItem(this, x - ix, y - iy);
     319             :     }
     320           0 :     return hit;
     321             : }
     322             : 
     323             : 
     324             : void
     325       13700 : MFXListIcon::updateItem(MFXListIconItem* item) const {
     326       13700 :     update(0, pos_y + item->y, viewport_w, item->getHeight(this));
     327       13700 : }
     328             : 
     329             : 
     330             : FXbool
     331           0 : MFXListIcon::selectItem(MFXListIconItem* item, FXbool notify) {
     332           0 :     if (!item->isSelected()) {
     333           0 :         killSelection(notify);
     334           0 :         item->setSelected(TRUE);
     335           0 :         updateItem(item);
     336           0 :         if (notify && target) {
     337           0 :             target->tryHandle(this, FXSEL(SEL_SELECTED, message), nullptr);
     338             :         }
     339           0 :         return TRUE;
     340             :     } else {
     341             :         return FALSE;
     342             :     }
     343             : }
     344             : 
     345             : 
     346             : FXbool
     347           0 : MFXListIcon::deselectItem(MFXListIconItem* item, FXbool notify) {
     348           0 :     if (item->isSelected()) {
     349           0 :         item->setSelected(FALSE);
     350           0 :         updateItem(item);
     351           0 :         if (notify && target) {
     352           0 :             target->tryHandle(this, FXSEL(SEL_DESELECTED, message), nullptr);
     353             :         }
     354           0 :         return TRUE;
     355             :     } else {
     356             :         return FALSE;
     357             :     }
     358             : }
     359             : 
     360             : 
     361             : FXbool
     362           0 : MFXListIcon::toggleItem(MFXListIconItem* item, FXbool notify) {
     363           0 :     if (!item->isSelected()) {
     364           0 :         killSelection(notify);
     365           0 :         item->setSelected(TRUE);
     366           0 :         updateItem(item);
     367           0 :         if (notify && target) {
     368           0 :             target->tryHandle(this, FXSEL(SEL_SELECTED, message), nullptr);
     369             :         }
     370             :     } else {
     371           0 :         item->setSelected(FALSE);
     372           0 :         updateItem(item);
     373           0 :         if (notify && target) {
     374           0 :             target->tryHandle(this, FXSEL(SEL_DESELECTED, message), nullptr);
     375             :         }
     376             :     }
     377           0 :     return TRUE;
     378             : }
     379             : 
     380             : 
     381             : FXbool
     382           0 : MFXListIcon::killSelection(FXbool notify) {
     383             :     FXbool changes = FALSE;
     384             :     FXint i;
     385           0 :     for (i = 0; i < (int)items.size(); i++) {
     386           0 :         if (items[i]->isSelected()) {
     387           0 :             items[i]->setSelected(FALSE);
     388           0 :             updateItem(items[i]);
     389             :             changes = TRUE;
     390           0 :             if (notify && target) {
     391           0 :                 target->tryHandle(this, FXSEL(SEL_DESELECTED, message), (void*)(FXival)i);
     392             :             }
     393             :         }
     394             :     }
     395           0 :     return changes;
     396             : }
     397             : 
     398             : 
     399             : long
     400           0 : MFXListIcon::onEnter(FXObject* sender, FXSelector sel, void* ptr) {
     401           0 :     FXScrollArea::onEnter(sender, sel, ptr);
     402           0 :     getApp()->addTimeout(this, ID_TIPTIMER, getApp()->getMenuPause());
     403           0 :     cursor = nullptr;
     404           0 :     return 1;
     405             : }
     406             : 
     407             : 
     408             : long
     409           0 : MFXListIcon::onLeave(FXObject* sender, FXSelector sel, void* ptr) {
     410           0 :     FXScrollArea::onLeave(sender, sel, ptr);
     411           0 :     getApp()->removeTimeout(this, ID_TIPTIMER);
     412           0 :     cursor = nullptr;
     413           0 :     return 1;
     414             : }
     415             : 
     416             : 
     417             : long
     418           0 : MFXListIcon::onFocusIn(FXObject* sender, FXSelector sel, void* ptr) {
     419           0 :     FXScrollArea::onFocusIn(sender, sel, ptr);
     420           0 :     if (currentItem) {
     421           0 :         currentItem->setFocus(TRUE);
     422           0 :         updateItem(currentItem);
     423             :     }
     424           0 :     return 1;
     425             : }
     426             : 
     427             : 
     428             : long
     429           0 : MFXListIcon::onTipTimer(FXObject*, FXSelector, void*) {
     430           0 :     flags |= FLAG_TIP;
     431           0 :     return 1;
     432             : }
     433             : 
     434             : 
     435             : long
     436           0 : MFXListIcon::onQueryTip(FXObject* sender, FXSelector sel, void* ptr) {
     437           0 :     if (FXWindow::onQueryTip(sender, sel, ptr)) {
     438             :         return 1;
     439             :     }
     440           0 :     if (cursor && (flags & FLAG_TIP) && !(options & LIST_AUTOSELECT)) {    // No tip when autoselect!
     441           0 :         FXString string = cursor->getText();
     442           0 :         sender->handle(this, FXSEL(SEL_COMMAND, ID_SETSTRINGVALUE), (void*) & string);
     443             :         return 1;
     444           0 :     }
     445             :     return 0;
     446             : }
     447             : 
     448             : 
     449             : long
     450           0 : MFXListIcon::onQueryHelp(FXObject* sender, FXSelector sel, void* ptr) {
     451           0 :     if (FXWindow::onQueryHelp(sender, sel, ptr)) {
     452             :         return 1;
     453             :     }
     454           0 :     if ((flags & FLAG_HELP) && !help.empty()) {
     455           0 :         sender->handle(this, FXSEL(SEL_COMMAND, ID_SETSTRINGVALUE), (void*) & help);
     456           0 :         return 1;
     457             :     }
     458             :     return 0;
     459             : }
     460             : 
     461             : 
     462             : long
     463           0 : MFXListIcon::onFocusOut(FXObject* sender, FXSelector sel, void* ptr) {
     464           0 :     FXScrollArea::onFocusOut(sender, sel, ptr);
     465           0 :     if (currentItem) {
     466           0 :         currentItem->setFocus(FALSE);
     467           0 :         updateItem(currentItem);
     468             :     }
     469           0 :     return 1;
     470             : }
     471             : 
     472             : 
     473             : long
     474        6765 : MFXListIcon::onPaint(FXObject*, FXSelector, void* ptr) {
     475             :     FXEvent* event = (FXEvent*)ptr;
     476        6765 :     FXDCWindow dc(this,  event);
     477             :     FXint y,  h;
     478             :     // Paint items
     479        6765 :     y = pos_y;
     480       40619 :     for (int i = 0; i < (int)itemFiltered.size(); i++) {
     481       33854 :         h = itemFiltered[i]->getHeight(this);
     482       33854 :         if (event->rect.y <= (y + h) && y < (event->rect.y + event->rect.h)) {
     483       33854 :             itemFiltered[i]->draw(this,  dc,  pos_x,  y,  FXMAX(listWidth,  viewport_w),  h);
     484             :         }
     485             :         y += h;
     486             :     }
     487             :     // Paint blank area below items
     488        6765 :     if (y < (event->rect.y + event->rect.h)) {
     489        6765 :         dc.setForeground(backColor);
     490        6765 :         dc.fillRectangle(event->rect.x,  y,  event->rect.w,  event->rect.y + event->rect.h - y);
     491             :     }
     492        6765 :     return 1;
     493        6765 : }
     494             : 
     495             : 
     496             : long
     497           0 : MFXListIcon::onLookupTimer(FXObject*, FXSelector, void*) {
     498           0 :     lookup = FXString::null;
     499           0 :     return 1;
     500             : }
     501             : 
     502             : 
     503             : long
     504           0 : MFXListIcon::onKeyPress(FXObject*, FXSelector, void* ptr) {
     505             :     FXEvent* event = (FXEvent*)ptr;
     506           0 :     FXint index = getCurrentItemIndex();
     507           0 :     flags &= ~FLAG_TIP;
     508           0 :     if (!isEnabled()) {
     509             :         return 0;
     510             :     }
     511           0 :     if (target && target->tryHandle(this, FXSEL(SEL_KEYPRESS, message), ptr)) {
     512             :         return 1;
     513             :     }
     514           0 :     switch (event->code) {
     515           0 :         case KEY_Control_L:
     516             :         case KEY_Control_R:
     517             :         case KEY_Shift_L:
     518             :         case KEY_Shift_R:
     519             :         case KEY_Alt_L:
     520             :         case KEY_Alt_R:
     521           0 :             if (flags & FLAG_DODRAG) {
     522           0 :                 handle(this, FXSEL(SEL_DRAGGED, 0), ptr);
     523             :             }
     524             :             return 1;
     525           0 :         case KEY_Page_Up:
     526             :         case KEY_KP_Page_Up:
     527           0 :             lookup = FXString::null;
     528           0 :             setPosition(pos_x, pos_y + verticalScrollBar()->getPage());
     529           0 :             return 1;
     530           0 :         case KEY_Page_Down:
     531             :         case KEY_KP_Page_Down:
     532           0 :             lookup = FXString::null;
     533           0 :             setPosition(pos_x, pos_y - verticalScrollBar()->getPage());
     534           0 :             return 1;
     535           0 :         case KEY_Up:
     536             :         case KEY_KP_Up:
     537           0 :             index -= 1;
     538           0 :             goto hop;
     539           0 :         case KEY_Down:
     540             :         case KEY_KP_Down:
     541           0 :             index += 1;
     542           0 :             goto hop;
     543           0 :         case KEY_Home:
     544             :         case KEY_KP_Home:
     545             :             index = 0;
     546           0 :             goto hop;
     547           0 :         case KEY_End:
     548             :         case KEY_KP_End:
     549           0 :             index = (int)itemFiltered.size() - 1;
     550           0 : hop:
     551           0 :             lookup = FXString::null;
     552             :             // continue depending of filter
     553           0 :             if (filter.empty()) {
     554           0 :                 if (0 <= index && index < (int)items.size()) {
     555           0 :                     setCurrentItem(items[index], TRUE);
     556           0 :                     makeItemVisible(items[index]);
     557             :                 }
     558             :             } else {
     559           0 :                 if ((0 <= index) && (index < (int)itemFiltered.size())) {
     560           0 :                     setCurrentItem(itemFiltered[index], TRUE);
     561           0 :                     makeItemVisible(itemFiltered[index]);
     562             :                 }
     563             :             }
     564           0 :             handle(this, FXSEL(SEL_CLICKED, 0), (void*)currentItem);
     565           0 :             if (currentItem && currentItem->isEnabled()) {
     566           0 :                 handle(this, FXSEL(SEL_COMMAND, 0), (void*)currentItem);
     567             :             }
     568             :             return 1;
     569           0 :         case KEY_space:
     570             :         case KEY_KP_Space:
     571           0 :             lookup = FXString::null;
     572           0 :             if (currentItem && currentItem->isEnabled()) {
     573           0 :                 toggleItem(currentItem, TRUE);
     574           0 :                 setAnchorItem(currentItem);
     575             :             }
     576           0 :             handle(this, FXSEL(SEL_CLICKED, 0), (void*)currentItem);
     577           0 :             if (currentItem && currentItem->isEnabled()) {
     578           0 :                 handle(this, FXSEL(SEL_COMMAND, 0), (void*)currentItem);
     579             :             }
     580             :             return 1;
     581           0 :         case KEY_Return:
     582             :         case KEY_KP_Enter:
     583           0 :             lookup = FXString::null;
     584           0 :             handle(this, FXSEL(SEL_DOUBLECLICKED, 0), (void*)currentItem);
     585           0 :             if (currentItem && currentItem->isEnabled()) {
     586           0 :                 handle(this, FXSEL(SEL_COMMAND, 0), (void*)currentItem);
     587             :             }
     588             :             return 1;
     589             :         default:
     590             :             return 1;
     591             :     }
     592             : }
     593             : 
     594             : 
     595             : long
     596           0 : MFXListIcon::onKeyRelease(FXObject*, FXSelector, void* ptr) {
     597             :     FXEvent* event = (FXEvent*)ptr;
     598           0 :     if (!isEnabled()) {
     599             :         return 0;
     600             :     }
     601           0 :     if (target && target->tryHandle(this, FXSEL(SEL_KEYRELEASE, message), ptr)) {
     602             :         return 1;
     603             :     }
     604           0 :     switch (event->code) {
     605           0 :         case KEY_Shift_L:
     606             :         case KEY_Shift_R:
     607             :         case KEY_Control_L:
     608             :         case KEY_Control_R:
     609             :         case KEY_Alt_L:
     610             :         case KEY_Alt_R:
     611           0 :             if (flags & FLAG_DODRAG) {
     612           0 :                 handle(this, FXSEL(SEL_DRAGGED, 0), ptr);
     613             :             }
     614             :             return 1;
     615             :     }
     616             :     return 0;
     617             : }
     618             : 
     619             : 
     620             : long
     621           0 : MFXListIcon::onAutoScroll(FXObject*,  FXSelector,  void*) {
     622           0 :     return 1;
     623             : }
     624             : 
     625             : 
     626             : long
     627           0 : MFXListIcon::onMotion(FXObject*, FXSelector, void* ptr) {
     628             :     FXEvent* event = (FXEvent*)ptr;
     629           0 :     MFXListIconItem* oldcursor = cursor;
     630           0 :     FXuint flg = flags;
     631             : 
     632             :     // Kill the tip
     633           0 :     flags &= ~FLAG_TIP;
     634             : 
     635             :     // Kill the tip timer
     636           0 :     getApp()->removeTimeout(this, ID_TIPTIMER);
     637             : 
     638             :     // Right mouse scrolling
     639           0 :     if (flags & FLAG_SCROLLING) {
     640           0 :         setPosition(event->win_x - grabx, event->win_y - graby);
     641           0 :         return 1;
     642             :     }
     643             : 
     644             :     // Drag and drop mode
     645           0 :     if (flags & FLAG_DODRAG) {
     646           0 :         if (startAutoScroll(event, TRUE)) {
     647             :             return 1;
     648             :         }
     649           0 :         handle(this, FXSEL(SEL_DRAGGED, 0), ptr);
     650           0 :         return 1;
     651             :     }
     652             : 
     653             :     // Tentative drag and drop
     654           0 :     if ((flags & FLAG_TRYDRAG) && event->moved) {
     655           0 :         flags &= ~FLAG_TRYDRAG;
     656           0 :         if (handle(this, FXSEL(SEL_BEGINDRAG, 0), ptr)) {
     657           0 :             flags |= FLAG_DODRAG;
     658             :         }
     659           0 :         return 1;
     660             :     }
     661             : 
     662             :     // Normal operation
     663           0 :     if ((flags & FLAG_PRESSED) || (options & LIST_AUTOSELECT)) {
     664             :         // Start auto scrolling?
     665           0 :         if (startAutoScroll(event, FALSE)) {
     666             :             return 1;
     667             :         }
     668             :         // Find item
     669           0 :         auto element = getItemAt(event->win_y);
     670             :         // Got an item different from before
     671           0 :         if (element) {
     672             :             // Make it the current item
     673           0 :             setCurrentItem(element, TRUE);
     674           0 :             return 1;
     675             :         }
     676             :     }
     677             : 
     678             :     // Reset tip timer if nothing's going on
     679           0 :     getApp()->addTimeout(this, ID_TIPTIMER, getApp()->getMenuPause());
     680             : 
     681             :     // Get item we're over
     682           0 :     cursor = getItemAt(event->win_y);
     683             : 
     684             :     // Force GUI update only when needed
     685           0 :     return (cursor != oldcursor) || (flg & FLAG_TIP);
     686             : }
     687             : 
     688             : 
     689             : long
     690           0 : MFXListIcon::onLeftBtnPress(FXObject*, FXSelector, void* ptr) {
     691             :     FXEvent* event = (FXEvent*)ptr;
     692             :     FXint code;
     693           0 :     flags &= ~FLAG_TIP;
     694           0 :     handle(this, FXSEL(SEL_FOCUS_SELF, 0), ptr);
     695           0 :     if (isEnabled()) {
     696           0 :         grab();
     697           0 :         flags &= ~FLAG_UPDATE;
     698             :         // First change callback
     699           0 :         if (target && target->tryHandle(this, FXSEL(SEL_LEFTBUTTONPRESS, message), ptr)) {
     700             :             return 1;
     701             :         }
     702             :         // Autoselect mode
     703           0 :         if (options & LIST_AUTOSELECT) {
     704             :             return 1;
     705             :         }
     706             :         // Locate item
     707           0 :         auto item = getItemAt(event->win_y);
     708             :         // No item
     709           0 :         if (item == nullptr) {
     710             :             return 1;
     711             :         }
     712             :         // Find out where hit
     713           0 :         code = hitItem(item, event->win_x, event->win_y);
     714             :         // Change current item
     715           0 :         setCurrentItem(item, TRUE);
     716             :         // Change item selection
     717           0 :         state = item->isSelected();
     718           0 :         if (item->isEnabled() && !state) {
     719           0 :             selectItem(item, TRUE);
     720             :         }
     721             :         // Start drag if actually pressed text or icon only
     722           0 :         if (code && item->isSelected() && item->isDraggable()) {
     723           0 :             flags |= FLAG_TRYDRAG;
     724             :         }
     725           0 :         flags |= FLAG_PRESSED;
     726           0 :         return 1;
     727             :     }
     728             :     return 0;
     729             : }
     730             : 
     731             : 
     732             : long
     733           0 : MFXListIcon::onLeftBtnRelease(FXObject*, FXSelector, void* ptr) {
     734             :     FXEvent* event = (FXEvent*)ptr;
     735           0 :     FXuint flg = flags;
     736           0 :     if (isEnabled()) {
     737           0 :         ungrab();
     738           0 :         stopAutoScroll();
     739           0 :         flags |= FLAG_UPDATE;
     740           0 :         flags &= ~(FLAG_PRESSED | FLAG_TRYDRAG | FLAG_DODRAG);
     741             :         // First chance callback
     742           0 :         if (target && target->tryHandle(this, FXSEL(SEL_LEFTBUTTONRELEASE, message), ptr)) {
     743             :             return 1;
     744             :         }
     745             :         // No activity
     746           0 :         if (!(flg & FLAG_PRESSED) && !(options & LIST_AUTOSELECT)) {
     747             :             return 1;
     748             :         }
     749             :         // Was dragging
     750           0 :         if (flg & FLAG_DODRAG) {
     751           0 :             handle(this, FXSEL(SEL_ENDDRAG, 0), ptr);
     752           0 :             return 1;
     753             :         }
     754           0 :         if (currentItem && currentItem->isEnabled()) {
     755           0 :             if (state) {
     756           0 :                 deselectItem(currentItem, TRUE);
     757             :             }
     758             :         }
     759             :         // Scroll to make item visibke
     760           0 :         makeItemVisible(currentItem);
     761             :         // Update anchor
     762           0 :         setAnchorItem(currentItem);
     763             :         // Generate clicked callbacks
     764           0 :         if (event->click_count == 1) {
     765           0 :             handle(this, FXSEL(SEL_CLICKED, 0), (void*)currentItem);
     766           0 :         } else if (event->click_count == 2) {
     767           0 :             handle(this, FXSEL(SEL_DOUBLECLICKED, 0), (void*)currentItem);
     768           0 :         } else if (event->click_count == 3) {
     769           0 :             handle(this, FXSEL(SEL_TRIPLECLICKED, 0), (void*)currentItem);
     770             :         }
     771             :         // Command callback only when clicked on item
     772           0 :         if (currentItem && currentItem->isEnabled()) {
     773           0 :             handle(this, FXSEL(SEL_COMMAND, 0), (void*)currentItem);
     774             :         }
     775           0 :         return 1;
     776             :     }
     777             :     return 0;
     778             : }
     779             : 
     780             : 
     781             : long
     782           0 : MFXListIcon::onRightBtnPress(FXObject*, FXSelector, void* ptr) {
     783             :     FXEvent* event = (FXEvent*)ptr;
     784           0 :     flags &= ~FLAG_TIP;
     785           0 :     handle(this, FXSEL(SEL_FOCUS_SELF, 0), ptr);
     786           0 :     if (isEnabled()) {
     787           0 :         grab();
     788           0 :         flags &= ~FLAG_UPDATE;
     789           0 :         if (target && target->tryHandle(this, FXSEL(SEL_RIGHTBUTTONPRESS, message), ptr)) {
     790             :             return 1;
     791             :         }
     792           0 :         flags |= FLAG_SCROLLING;
     793           0 :         grabx = event->win_x - pos_x;
     794           0 :         graby = event->win_y - pos_y;
     795           0 :         return 1;
     796             :     }
     797             :     return 0;
     798             : }
     799             : 
     800             : 
     801             : long
     802           0 : MFXListIcon::onRightBtnRelease(FXObject*, FXSelector, void* ptr) {
     803           0 :     if (isEnabled()) {
     804           0 :         ungrab();
     805           0 :         flags &= ~FLAG_SCROLLING;
     806           0 :         flags |= FLAG_UPDATE;
     807           0 :         if (target && target->tryHandle(this, FXSEL(SEL_RIGHTBUTTONRELEASE, message), ptr)) {
     808             :             return 1;
     809             :         }
     810           0 :         return 1;
     811             :     }
     812             :     return 0;
     813             : }
     814             : 
     815             : 
     816             : long
     817           0 : MFXListIcon::onUngrabbed(FXObject* sender, FXSelector sel, void* ptr) {
     818           0 :     FXScrollArea::onUngrabbed(sender, sel, ptr);
     819           0 :     flags &= ~(FLAG_DODRAG | FLAG_TRYDRAG | FLAG_PRESSED | FLAG_CHANGED | FLAG_SCROLLING);
     820           0 :     flags |= FLAG_UPDATE;
     821           0 :     stopAutoScroll();
     822           0 :     return 1;
     823             : }
     824             : 
     825             : 
     826             : long
     827           0 : MFXListIcon::onCommand(FXObject*, FXSelector, void* ptr) {
     828           0 :     return target ? target->tryHandle(this, FXSEL(SEL_COMMAND, message), ptr) : 0;
     829             : }
     830             : 
     831             : 
     832             : long
     833           0 : MFXListIcon::onClicked(FXObject*, FXSelector, void* ptr) {
     834           0 :     return target ? target->tryHandle(this, FXSEL(SEL_CLICKED, message), ptr) : 0;
     835             : }
     836             : 
     837             : 
     838             : long
     839           0 : MFXListIcon::onDoubleClicked(FXObject*, FXSelector, void* ptr) {
     840           0 :     return target ? target->tryHandle(this, FXSEL(SEL_DOUBLECLICKED, message), ptr) : 0;
     841             : }
     842             : 
     843             : 
     844             : long
     845           0 : MFXListIcon::onTripleClicked(FXObject*, FXSelector, void* ptr) {
     846           0 :     return target ? target->tryHandle(this, FXSEL(SEL_TRIPLECLICKED, message), ptr) : 0;
     847             : }
     848             : 
     849             : 
     850             : void
     851        6850 : MFXListIcon::setCurrentItem(MFXListIconItem* item, FXbool notify) {
     852        6850 :     if (item) {
     853             :         // Deactivate old item
     854        6850 :         if (currentItem) {
     855        6850 :             currentItem->setFocus(FALSE);
     856        6850 :             updateItem(currentItem);
     857             :         }
     858        6850 :         currentItem = item;
     859             :         // Activate new item
     860             :         if (currentItem) {
     861        6850 :             currentItem->setFocus(TRUE);
     862        6850 :             updateItem(currentItem);
     863             :         }
     864             :         // Notify item change
     865        6850 :         if (notify && target) {
     866           0 :             target->tryHandle(this, FXSEL(SEL_CHANGED, message), (void*)currentItem);
     867             :         }
     868             :     }
     869        6850 : }
     870             : 
     871             : 
     872             : FXint
     873       34107 : MFXListIcon::getCurrentItemIndex() const {
     874       40922 :     for (int i = 0; i < (int)items.size(); i++) {
     875       34107 :         if (items[i] == currentItem) {
     876       27292 :             return i;
     877             :         }
     878             :     }
     879             :     return -1;
     880             : }
     881             : 
     882             : 
     883             : FXint
     884       34107 : MFXListIcon::getViewableItem() const {
     885             :     // continue depending if we're filtering
     886       34107 :     if (filter.empty()) {
     887       40922 :         for (int i = 0; i < (int)items.size(); i++) {
     888       34107 :             if (items[i] == viewable) {
     889       27292 :                 return i;
     890             :             }
     891             :         }
     892             :     } else {
     893           0 :         for (int i = 0; i < (int)itemFiltered.size(); i++) {
     894           0 :             if (itemFiltered[i] == viewable) {
     895           0 :                 return i;
     896             :             }
     897             :         }
     898             :     }
     899             :     return -1;
     900             : }
     901             : 
     902             : 
     903             : void
     904           0 : MFXListIcon::setAnchorItem(MFXListIconItem* item) {
     905             :     int index = 0;
     906             :     // continue depending if we're filtering
     907           0 :     if (filter.empty()) {
     908           0 :         for (int i = 0; i < (int)items.size(); i++) {
     909           0 :             if (items[i] == item) {
     910             :                 index = i;
     911             :             }
     912             :         }
     913             :     } else {
     914           0 :         for (int i = 0; i < (int)itemFiltered.size(); i++) {
     915           0 :             if (itemFiltered[i] == item) {
     916             :                 index = i;
     917             :             }
     918             :         }
     919             :     }
     920           0 :     anchor = index;
     921           0 :     extent = index;
     922           0 : }
     923             : 
     924             : 
     925             : FXint
     926           0 : MFXListIcon::getAnchorItem() const {
     927           0 :     return anchor;
     928             : }
     929             : 
     930             : 
     931             : MFXListIconItem*
     932           0 : MFXListIcon::getCursorItem() const {
     933           0 :     return cursor;
     934             : }
     935             : 
     936             : 
     937             : MFXListIconItem*
     938        6850 : MFXListIcon::getItem(FXint index) const {
     939        6850 :     if (index < 0 || (int)items.size() <= index) {
     940           0 :         fxerror("%s::getItem: index out of range.\n", getClassName());
     941             :     }
     942        6850 :     return items[index];
     943             : }
     944             : 
     945             : 
     946             : FXint
     947           0 : MFXListIcon::setItem(FXint index, MFXListIconItem* item, FXbool notify) {
     948             :     // Must have item
     949           0 :     if (!item) {
     950           0 :         fxerror("%s::setItem: item is NULL.\n", getClassName());
     951             :     }
     952             :     // Must be in range
     953           0 :     if (index < 0 || (int)items.size() <= index) {
     954           0 :         fxerror("%s::setItem: index out of range.\n", getClassName());
     955             :     }
     956             :     // Notify item will be replaced
     957           0 :     if (notify && target) {
     958           0 :         target->tryHandle(this, FXSEL(SEL_REPLACED, message), (void*)(FXival)index);
     959             :     }
     960             :     // Copy the state over
     961           0 :     item->state = items[index]->state;
     962             :     // Delete old
     963           0 :     delete items[index];
     964             :     // Add new
     965           0 :     items[index] = item;
     966             :     // apply filter
     967           0 :     setFilter(filter, nullptr);
     968           0 :     return index;
     969             : }
     970             : 
     971             : 
     972             : FXint
     973           0 : MFXListIcon::editItem(FXint index, const FXString& text, FXIcon* icon, void* ptr, FXbool notify) {
     974           0 :     return setItem(index, createItem(text, icon, ptr), notify);
     975             : }
     976             : 
     977             : 
     978             : FXint
     979       34107 : MFXListIcon::insertItem(FXint index, MFXListIconItem* item, FXbool notify) {
     980       34107 :     MFXListIconItem* old = currentItem;
     981             :     // Must have item
     982       34107 :     if (!item) {
     983           0 :         fxerror("%s::insertItem: item is NULL.\n", getClassName());
     984             :     }
     985             :     // Must be in range
     986       34107 :     if (index < 0 || (int)items.size() < index) {
     987           0 :         fxerror("%s::insertItem: index out of range.\n", getClassName());
     988             :     }
     989             :     // Add item to list
     990       34107 :     items.insert(items.begin() + index, item);
     991             :     // Adjust indices
     992       34107 :     if (anchor >= index) {
     993           0 :         anchor++;
     994             :     }
     995       34107 :     if (extent >= index) {
     996           0 :         extent++;
     997             :     }
     998       34107 :     if (getCurrentItemIndex() >= index) {
     999           0 :         currentItem = items[index];
    1000             :     }
    1001       34107 :     if (getViewableItem() >= index) {
    1002           0 :         viewable = items[index];
    1003             :     }
    1004       34107 :     if ((currentItem == nullptr) && ((int)items.size() == 1)) {
    1005        6815 :         currentItem = items[0];
    1006             :     }
    1007             :     // Notify item has been inserted
    1008       34107 :     if (notify && target) {
    1009           0 :         target->tryHandle(this, FXSEL(SEL_INSERTED, message), (void*)(FXival)index);
    1010             :     }
    1011             :     // Current item may have changed
    1012       34107 :     if (old != currentItem) {
    1013        6815 :         if (notify && target) {
    1014           0 :             target->tryHandle(this, FXSEL(SEL_CHANGED, message), (void*)currentItem);
    1015             :         }
    1016             :     }
    1017             :     // Was new item
    1018       34107 :     if (currentItem && currentItem == items[index]) {
    1019        6815 :         if (hasFocus()) {
    1020           0 :             currentItem->setFocus(TRUE);
    1021             :         }
    1022             :     }
    1023             :     // apply filter
    1024       34107 :     setFilter(filter, nullptr);
    1025       34107 :     return index;
    1026             : }
    1027             : 
    1028             : 
    1029             : FXint
    1030           0 : MFXListIcon::insertItem(FXint index, const FXString& text, FXIcon* icon, void* ptr, FXbool notify) {
    1031           0 :     return insertItem(index, createItem(text, icon, ptr), notify);
    1032             : }
    1033             : 
    1034             : 
    1035             : FXint
    1036       34107 : MFXListIcon::appendItem(MFXListIconItem* item, FXbool notify) {
    1037       34107 :     return insertItem((int)items.size(), item, notify);
    1038             : }
    1039             : 
    1040             : 
    1041             : FXint
    1042           0 : MFXListIcon::appendItem(const FXString& text, FXIcon* icon, void* ptr, FXbool notify) {
    1043           0 :     return insertItem((int)items.size(), createItem(text, icon, ptr), notify);
    1044             : }
    1045             : 
    1046             : 
    1047             : void
    1048           0 : MFXListIcon::removeItem(FXint index, FXbool notify) {
    1049           0 :     MFXListIconItem* old = currentItem;
    1050             :     // Must be in range
    1051           0 :     if ((index < 0) || ((int)items.size() <= index)) {
    1052           0 :         fxerror("%s::removeItem: index out of range.\n", getClassName());
    1053             :     }
    1054             :     // Notify item will be deleted
    1055           0 :     if (notify && target) {
    1056           0 :         target->tryHandle(this, FXSEL(SEL_DELETED, message), (void*)(FXival)index);
    1057             :     }
    1058             :     // Delete item
    1059           0 :     delete items[index];
    1060             :     // Remove item from list
    1061           0 :     items.erase(items.begin() + index);
    1062             :     // Adjust indices
    1063           0 :     if (anchor >= index) {
    1064           0 :         anchor++;
    1065             :     }
    1066           0 :     if (extent >= index) {
    1067           0 :         extent++;
    1068             :     }
    1069           0 :     if (getCurrentItemIndex() >= index) {
    1070           0 :         currentItem = items[index];
    1071             :     }
    1072           0 :     if (getViewableItem() >= index) {
    1073           0 :         viewable = items[index];
    1074             :     }
    1075           0 :     if ((currentItem == nullptr) && ((int)items.size() == 1)) {
    1076           0 :         currentItem = items[0];
    1077             :     }
    1078             :     // Notify item has been inserted
    1079           0 :     if (notify && target) {
    1080           0 :         target->tryHandle(this, FXSEL(SEL_INSERTED, message), (void*)(FXival)index);
    1081             :     }
    1082             :     // Current item may have changed
    1083           0 :     if (old != currentItem) {
    1084           0 :         if (notify && target) {
    1085           0 :             target->tryHandle(this, FXSEL(SEL_CHANGED, message), (void*)currentItem);
    1086             :         }
    1087             :     }
    1088             :     // Was new item
    1089           0 :     if (currentItem && currentItem == items[index]) {
    1090           0 :         if (hasFocus()) {
    1091           0 :             currentItem->setFocus(TRUE);
    1092             :         }
    1093             :     }
    1094             :     // apply filter
    1095           0 :     setFilter(filter, nullptr);
    1096           0 : }
    1097             : 
    1098             : 
    1099             : void
    1100        6803 : MFXListIcon::clearItems(FXbool notify) {
    1101             :     // Delete items
    1102       40849 :     for (FXint index = (int)items.size() - 1; 0 <= index; index--) {
    1103       34046 :         if (notify && target) {
    1104           0 :             target->tryHandle(this, FXSEL(SEL_DELETED, message), (void*)(FXival)index);
    1105             :         }
    1106       34046 :         delete items[index];
    1107             :     }
    1108             :     // Free array
    1109             :     items.clear();
    1110             :     // Adjust indices
    1111        6803 :     anchor = -1;
    1112        6803 :     extent = -1;
    1113             :     // Current item has changed
    1114        6803 :     if (currentItem) {
    1115        6803 :         if (notify && target) {
    1116           0 :             target->tryHandle(this, FXSEL(SEL_CHANGED, message), (void*)(FXival) - 1);
    1117             :         }
    1118        6803 :         currentItem = nullptr;
    1119             :     }
    1120        6803 :     viewable = nullptr;
    1121             :     // apply filter
    1122        6803 :     setFilter(filter, nullptr);
    1123        6803 : }
    1124             : 
    1125             : 
    1126             : void
    1127       40910 : MFXListIcon::setFilter(const FXString& value, FXLabel* label) {
    1128       40910 :     filter = value;
    1129             :     // update item filtered
    1130       40910 :     itemFiltered.clear();
    1131      143328 :     for (int i = 0; i < (int)items.size(); i++) {
    1132      102418 :         items[i]->show = showItem(items[i]->getText());
    1133      102418 :         if (items[i]->show) {
    1134      102418 :             itemFiltered.push_back(items[i]);
    1135             :         }
    1136             :     }
    1137             :     // check if show label
    1138       40910 :     if (label) {
    1139           0 :         if (!value.empty() && ((int)itemFiltered.size() == 0)) {
    1140           0 :             label->show();
    1141             :         } else {
    1142           0 :             label->hide();
    1143             :         }
    1144             :     }
    1145             :     // recompute and recalc
    1146       40910 :     recompute();
    1147       40910 :     recalc();
    1148       40910 : }
    1149             : 
    1150             : 
    1151             : void
    1152           0 : MFXListIcon::setTextColor(FXColor clr) {
    1153           0 :     if (textColor != clr) {
    1154           0 :         textColor = clr;
    1155           0 :         update();
    1156             :     }
    1157           0 : }
    1158             : 
    1159             : 
    1160             : void
    1161           0 : MFXListIcon::setHelpText(const FXString& text) {
    1162           0 :     help = text;
    1163           0 : }
    1164             : 
    1165             : 
    1166             : FXString
    1167           0 : MFXListIcon::tolowerString(const FXString& str) const {
    1168           0 :     FXString result;
    1169           0 :     for (int i = 0; i < str.count(); i++) {
    1170           0 :         result.append((char)::tolower(str[i]));
    1171             :     }
    1172           0 :     return result;
    1173           0 : }
    1174             : 
    1175             : 
    1176           0 : MFXListIcon::MFXListIcon() {
    1177           0 :     flags |= FLAG_ENABLED;
    1178           0 :     font = (FXFont*) - 1L;
    1179           0 : }
    1180             : 
    1181             : 
    1182             : void
    1183       47725 : MFXListIcon::recompute() {
    1184             :     FXint x, y, w, h;
    1185             :     x = 0;
    1186             :     y = 0;
    1187       47725 :     listWidth = 0;
    1188       47725 :     listHeight = 0;
    1189      184250 :     for (auto& item : itemFiltered) {
    1190             :         // set position and size
    1191      136525 :         item->x = x;
    1192      136525 :         item->y = y;
    1193      136525 :         w = item->getWidth(this);
    1194      136525 :         h = item->getHeight(this);
    1195      136525 :         if (w > listWidth) {
    1196       75029 :             listWidth = w;
    1197             :         }
    1198      136525 :         y += h;
    1199             :     }
    1200       47725 :     listHeight = y;
    1201       47725 :     flags &= ~FLAG_RECALC;
    1202       47725 : }
    1203             : 
    1204             : 
    1205             : MFXListIconItem*
    1206           0 : MFXListIcon::createItem(const FXString& text, FXIcon* icon, void* ptr) {
    1207           0 :     return new MFXListIconItem(text, icon, 0, ptr);
    1208             : }
    1209             : 
    1210             : 
    1211             : bool
    1212      102418 : MFXListIcon::showItem(const FXString& itemName) const {
    1213      102418 :     if (filter.empty()) {
    1214             :         return true;
    1215             :     } else {
    1216           0 :         return tolowerString(itemName).find(tolowerString(filter)) != -1;
    1217             :     }
    1218             : }

Generated by: LCOV version 1.14