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

            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      1735535 : FXIMPLEMENT(MFXListIcon, FXScrollArea, MFXListIconMap, ARRAYNUMBER(MFXListIconMap))
      72              : 
      73              : // ===========================================================================
      74              : // member method definitions
      75              : // ===========================================================================
      76              : 
      77         7106 : MFXListIcon::MFXListIcon(FXComposite* p, FXObject* tgt, FXSelector sel, FXuint opts, FXint x, FXint y, FXint w, FXint h):
      78         7106 :     FXScrollArea(p, opts, x, y, w, h) {
      79         7106 :     flags |= FLAG_ENABLED;
      80         7106 :     target = tgt;
      81         7106 :     message = sel;
      82         7106 :     font = getApp()->getNormalFont();
      83         7106 :     textColor = getApp()->getForeColor();
      84         7106 :     selbackColor = getApp()->getSelbackColor();
      85         7106 :     seltextColor = getApp()->getSelforeColor();
      86         7106 : }
      87              : 
      88              : 
      89        14186 : MFXListIcon::~MFXListIcon() {
      90         7093 :     getApp()->removeTimeout(this, ID_TIPTIMER);
      91         7093 :     getApp()->removeTimeout(this, ID_LOOKUPTIMER);
      92         7093 :     clearItems(FALSE);
      93         7093 :     font = (FXFont*) - 1L;
      94        14186 : }
      95              : 
      96              : 
      97              : void
      98        28424 : MFXListIcon::create() {
      99        28424 :     FXScrollArea::create();
     100       170676 :     for (const auto& item : items) {
     101       142252 :         item->create();
     102              :     }
     103        28424 :     font->create();
     104        28424 : }
     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        41580 : MFXListIcon::getDefaultWidth() {
     139        41580 :     return FXScrollArea::getDefaultWidth();
     140              : }
     141              : 
     142              : 
     143              : FXint
     144        55794 : MFXListIcon::getDefaultHeight() {
     145        55794 :     if (visible > (int)itemFiltered.size()) {
     146        55794 :         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        56868 : MFXListIcon::recalc() {
     155        56868 :     FXScrollArea::recalc();
     156        56868 :     flags |= FLAG_RECALC;
     157        56868 :     cursor = nullptr;
     158        56868 : }
     159              : 
     160              : 
     161              : void
     162         7106 : MFXListIcon::setNumVisible(FXint nvis) {
     163         7106 :     if (nvis < 0) {
     164              :         nvis = 0;
     165              :     }
     166         7106 :     if (visible != nvis) {
     167         7106 :         visible = nvis;
     168         7106 :         recalc();
     169              :     }
     170         7106 : }
     171              : 
     172              : 
     173              : FXint
     174        48686 : MFXListIcon::getContentWidth() {
     175        48686 :     if (flags & FLAG_RECALC) {
     176         7106 :         recompute();
     177              :     }
     178        48686 :     return listWidth;
     179              : }
     180              : 
     181              : 
     182              : FXint
     183         7106 : MFXListIcon::getContentHeight() {
     184         7106 :     if (flags & FLAG_RECALC) {
     185            0 :         recompute();
     186              :     }
     187         7106 :     return listHeight;
     188              : }
     189              : 
     190              : 
     191              : void
     192         7106 : MFXListIcon::layout() {
     193              :     // Calculate contents
     194         7106 :     FXScrollArea::layout();
     195              :     // Determine line size for scroll bars
     196         7106 :     if (0 < (int)itemFiltered.size()) {
     197         7106 :         vertical->setLine(itemFiltered[0]->getHeight(this));
     198         7106 :         horizontal->setLine(itemFiltered[0]->getWidth(this) / 10);
     199              :     }
     200         7106 :     update();
     201              :     // We were supposed to make this item viewable
     202         7106 :     if (viewable) {
     203         7106 :         makeItemVisible(viewable);
     204              :     }
     205              :     // No more dirty
     206         7106 :     flags &= ~(FXuint)FLAG_DIRTY;
     207         7106 : }
     208              : 
     209              : 
     210              : FXbool
     211        35563 : MFXListIcon::isItemCurrent(FXint index) const {
     212        35563 :     for (int i = 0; i < (int)items.size(); i++) {
     213        35563 :         if (items[i] == currentItem) {
     214        35563 :             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        14244 : MFXListIcon::makeItemVisible(MFXListIconItem* item) {
     229              :     FXint y, h;
     230              :     // Remember for later
     231        14244 :     viewable = item;
     232              :     // Was realized
     233        14244 :     if (xid) {
     234              :         // Force layout if dirty
     235         7138 :         if (flags & FLAG_RECALC) {
     236            0 :             layout();
     237              :         }
     238         7138 :         y = pos_y;
     239         7138 :         h = item->getHeight(this);
     240         7138 :         if (viewport_h <= y + item->y + h) {
     241            0 :             y = viewport_h - item->y - h;
     242              :         }
     243         7138 :         if (y + item->y <= 0) {
     244         7106 :             y = -item->y;
     245              :         }
     246              :         // Scroll into view
     247         7138 :         setPosition(pos_x, y);
     248              :         // Done it
     249         7138 :         viewable = nullptr;
     250              :     }
     251        14244 : }
     252              : 
     253              : 
     254              : void
     255         7138 : MFXListIcon::makeItemVisible(FXint index) {
     256         7138 :     makeItemVisible(items[index]);
     257         7138 : }
     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           35 : MFXListIcon::findItem(const FXString& text) const {
     301          211 :     for (int i = 0; i < (int)items.size(); i++) {
     302          208 :         if (items[i]->getText().text() == text) {
     303           32 :             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        14276 : MFXListIcon::updateItem(MFXListIconItem* item) const {
     326        14276 :     update(0, pos_y + item->y, viewport_w, item->getHeight(this));
     327        14276 : }
     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         7045 : MFXListIcon::onPaint(FXObject*, FXSelector, void* ptr) {
     475              :     FXEvent* event = (FXEvent*)ptr;
     476         7045 :     FXDCWindow dc(this,  event);
     477              :     FXint y,  h;
     478              :     // Paint items
     479         7045 :     y = pos_y;
     480        42302 :     for (int i = 0; i < (int)itemFiltered.size(); i++) {
     481        35257 :         h = itemFiltered[i]->getHeight(this);
     482        35257 :         if (event->rect.y <= (y + h) && y < (event->rect.y + event->rect.h)) {
     483        35257 :             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         7045 :     if (y < (event->rect.y + event->rect.h)) {
     489         7045 :         dc.setForeground(backColor);
     490         7045 :         dc.fillRectangle(event->rect.x,  y,  event->rect.w,  event->rect.y + event->rect.h - y);
     491              :     }
     492         7045 :     return 1;
     493         7045 : }
     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              :         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         7138 : MFXListIcon::setCurrentItem(MFXListIconItem* item, FXbool notify) {
     852         7138 :     if (item) {
     853              :         // Deactivate old item
     854         7138 :         if (currentItem) {
     855         7138 :             currentItem->setFocus(FALSE);
     856         7138 :             updateItem(currentItem);
     857              :         }
     858         7138 :         currentItem = item;
     859              :         // Activate new item
     860              :         if (currentItem) {
     861         7138 :             currentItem->setFocus(TRUE);
     862         7138 :             updateItem(currentItem);
     863              :         }
     864              :         // Notify item change
     865         7138 :         if (notify && target) {
     866            0 :             target->tryHandle(this, FXSEL(SEL_CHANGED, message), (void*)currentItem);
     867              :         }
     868              :     }
     869         7138 : }
     870              : 
     871              : 
     872              : FXint
     873        35563 : MFXListIcon::getCurrentItemIndex() const {
     874        42669 :     for (int i = 0; i < (int)items.size(); i++) {
     875        35563 :         if (items[i] == currentItem) {
     876        28457 :             return i;
     877              :         }
     878              :     }
     879              :     return -1;
     880              : }
     881              : 
     882              : 
     883              : FXint
     884        35563 : MFXListIcon::getViewableItem() const {
     885              :     // continue depending if we're filtering
     886        35563 :     if (filter.empty()) {
     887        42669 :         for (int i = 0; i < (int)items.size(); i++) {
     888        35563 :             if (items[i] == viewable) {
     889        28457 :                 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         7138 : MFXListIcon::getItem(FXint index) const {
     939         7138 :     if (index < 0 || (int)items.size() <= index) {
     940            0 :         fxerror("%s::getItem: index out of range.\n", getClassName());
     941              :     }
     942         7138 :     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        35563 : MFXListIcon::insertItem(FXint index, MFXListIconItem* item, FXbool notify) {
     980        35563 :     MFXListIconItem* old = currentItem;
     981              :     // Must have item
     982        35563 :     if (!item) {
     983            0 :         fxerror("%s::insertItem: item is NULL.\n", getClassName());
     984              :     }
     985              :     // Must be in range
     986        35563 :     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        35563 :     items.insert(items.begin() + index, item);
     991              :     // Adjust indices
     992        35563 :     if (anchor >= index) {
     993            0 :         anchor++;
     994              :     }
     995        35563 :     if (extent >= index) {
     996            0 :         extent++;
     997              :     }
     998        35563 :     if (getCurrentItemIndex() >= index) {
     999            0 :         currentItem = items[index];
    1000              :     }
    1001        35563 :     if (getViewableItem() >= index) {
    1002            0 :         viewable = items[index];
    1003              :     }
    1004        35563 :     if ((currentItem == nullptr) && ((int)items.size() == 1)) {
    1005         7106 :         currentItem = items[0];
    1006              :     }
    1007              :     // Notify item has been inserted
    1008        35563 :     if (notify && target) {
    1009            0 :         target->tryHandle(this, FXSEL(SEL_INSERTED, message), (void*)(FXival)index);
    1010              :     }
    1011              :     // Current item may have changed
    1012        35563 :     if (old != currentItem) {
    1013         7106 :         if (notify && target) {
    1014            0 :             target->tryHandle(this, FXSEL(SEL_CHANGED, message), (void*)currentItem);
    1015              :         }
    1016              :     }
    1017              :     // Was new item
    1018        35563 :     if (currentItem && currentItem == items[index]) {
    1019         7106 :         if (hasFocus()) {
    1020            0 :             currentItem->setFocus(TRUE);
    1021              :         }
    1022              :     }
    1023              :     // apply filter
    1024        35563 :     setFilter(filter, nullptr);
    1025        35563 :     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        35563 : MFXListIcon::appendItem(MFXListIconItem* item, FXbool notify) {
    1037        35563 :     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         7093 : MFXListIcon::clearItems(FXbool notify) {
    1101              :     // Delete items
    1102        42590 :     for (FXint index = (int)items.size() - 1; 0 <= index; index--) {
    1103        35497 :         if (notify && target) {
    1104            0 :             target->tryHandle(this, FXSEL(SEL_DELETED, message), (void*)(FXival)index);
    1105              :         }
    1106        35497 :         delete items[index];
    1107              :     }
    1108              :     // Free array
    1109              :     items.clear();
    1110              :     // Adjust indices
    1111         7093 :     anchor = -1;
    1112         7093 :     extent = -1;
    1113              :     // Current item has changed
    1114         7093 :     if (currentItem) {
    1115         7093 :         if (notify && target) {
    1116            0 :             target->tryHandle(this, FXSEL(SEL_CHANGED, message), (void*)(FXival) - 1);
    1117              :         }
    1118         7093 :         currentItem = nullptr;
    1119              :     }
    1120         7093 :     viewable = nullptr;
    1121              :     // apply filter
    1122         7093 :     setFilter(filter, nullptr);
    1123         7093 : }
    1124              : 
    1125              : 
    1126              : void
    1127        42656 : MFXListIcon::setFilter(const FXString& value, FXLabel* label) {
    1128        42656 :     filter = value;
    1129              :     // update item filtered
    1130              :     itemFiltered.clear();
    1131       149445 :     for (int i = 0; i < (int)items.size(); i++) {
    1132       106789 :         items[i]->show = showItem(items[i]->getText());
    1133       106789 :         if (items[i]->show) {
    1134       106789 :             itemFiltered.push_back(items[i]);
    1135              :         }
    1136              :     }
    1137              :     // check if show label
    1138        42656 :     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        42656 :     recompute();
    1147        42656 :     recalc();
    1148        42656 : }
    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        49762 : MFXListIcon::recompute() {
    1184              :     FXint x, y, w, h;
    1185              :     x = 0;
    1186              :     y = 0;
    1187        49762 :     listWidth = 0;
    1188        49762 :     listHeight = 0;
    1189       192114 :     for (auto& item : itemFiltered) {
    1190              :         // set position and size
    1191       142352 :         item->x = x;
    1192       142352 :         item->y = y;
    1193       142352 :         w = item->getWidth(this);
    1194       142352 :         h = item->getHeight(this);
    1195       142352 :         if (w > listWidth) {
    1196        78232 :             listWidth = w;
    1197              :         }
    1198       142352 :         y += h;
    1199              :     }
    1200        49762 :     listHeight = y;
    1201        49762 :     flags &= ~(FXuint)FLAG_RECALC;
    1202        49762 : }
    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       106789 : MFXListIcon::showItem(const FXString& itemName) const {
    1213       106789 :     if (filter.empty()) {
    1214              :         return true;
    1215              :     } else {
    1216            0 :         return tolowerString(itemName).find(tolowerString(filter)) != -1;
    1217              :     }
    1218              : }
        

Generated by: LCOV version 2.0-1