]> git.ipfire.org Git - thirdparty/newt.git/blobdiff - listbox.c
install python modules to purelib and platlib
[thirdparty/newt.git] / listbox.c
index c5753b89cacfe174ece7bc1f26e238068d82f924..aae4f836f7c108b02ca93de826fe3a1800637c85 100644 (file)
--- a/listbox.c
+++ b/listbox.c
@@ -3,10 +3,11 @@
    and contributed to newt for use under the LGPL license.
    Copyright (C) 1996, 1997 Elliot Lee */
 
-#include <slang/slang.h>
+#include <slang.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <ctype.h>
 
 #include "newt.h"
 #include "newt_pr.h"
@@ -14,7 +15,7 @@
 
 /* Linked list of items in the listbox */
 struct items {
-    void *key;
+    char * text;
     const void *data;
     unsigned char isSelected;
     struct items *next;
@@ -27,7 +28,7 @@ struct listbox {
     int curHeight;     /* size of text w/o border */
     int sbAdjust;
     int bdxAdjust, bdyAdjust;
-    int numItems, numSelected; 
+    int numItems, numSelected;
     int userHasSetWidth;
     int currItem, startShowItem; /* startShowItem is the first item displayed
                                   on the screen */
@@ -44,25 +45,36 @@ static void listboxDraw(newtComponent co);
 static void listboxDestroy(newtComponent co);
 static struct eventResult listboxEvent(newtComponent co, struct event ev);
 static void newtListboxRealSetCurrent(newtComponent co);
-static void listboxPlace(newtComponent co);
-static inline void updateWidth(newtComponent co, struct listbox * li, 
+static void listboxPlace(newtComponent co, int newLeft, int newTop);
+static inline void updateWidth(newtComponent co, struct listbox * li,
                                int maxField);
+static void listboxMapped(newtComponent co, int isMapped);
 
 static struct componentOps listboxOps = {
     listboxDraw,
     listboxEvent,
     listboxDestroy,
     listboxPlace,
+    listboxMapped,
 };
 
-static void listboxPlace(newtComponent co) {
+static void listboxMapped(newtComponent co, int isMapped) {
     struct listbox * li = co->data;
 
-    if (li->sb) {
-       li->sb->top = co->top;
-       li->sb->left = co->left + co->width - 1;
-       if (li->sb->ops->place) li->sb->ops->place(li->sb);
-    }
+    co->isMapped = isMapped;
+    if (li->sb)
+       li->sb->ops->mapped(li->sb, isMapped);
+}
+
+static void listboxPlace(newtComponent co, int newLeft, int newTop) {
+    struct listbox * li = co->data;
+
+    co->top = newTop;
+    co->left = newLeft;
+
+    if (li->sb)
+       li->sb->ops->place(li->sb, co->left + co->width - li->bdxAdjust - 1,
+                          co->top + li->bdyAdjust);
 }
 
 newtComponent newtListbox(int left, int top, int height, int flags) {
@@ -87,28 +99,30 @@ newtComponent newtListbox(int left, int top, int height, int flags) {
     li->sbAdjust = 0;
     li->bdxAdjust = 0;
     li->bdyAdjust = 0;
-    li->flags = flags & (NEWT_FLAG_RETURNEXIT | NEWT_FLAG_DOBORDER | 
-                        NEWT_FLAG_MULTIPLE);
+    li->flags = flags & (NEWT_FLAG_RETURNEXIT | NEWT_FLAG_BORDER |
+                        NEWT_FLAG_MULTIPLE | NEWT_FLAG_SHOWCURSOR);
 
-    if (li->flags & NEWT_FLAG_DOBORDER) {
+    if (li->flags & NEWT_FLAG_BORDER) {
        li->bdxAdjust = 2;
        li->bdyAdjust = 1;
     }
 
+    co->height = height;
+    li->curHeight = co->height - (2 * li->bdyAdjust);
+
     if (height) {
        li->grow = 0;
-       if (flags & NEWT_FLAG_NOSCROLL) {
-           sb = NULL;
-       } else {
-           sb = newtVerticalScrollbar(left, top, height, COLORSET_LISTBOX,
-                                      COLORSET_ACTLISTBOX);
+       if (flags & NEWT_FLAG_SCROLL) {
+           sb = newtVerticalScrollbar(left, top + li->bdyAdjust,
+                                       li->curHeight,
+                                       COLORSET_LISTBOX, COLORSET_ACTLISTBOX);
            li->sbAdjust = 3;
+       } else {
+           sb = NULL;
        }
-       co->height = height;
     } else {
        li->grow = 1;
        sb = NULL;
-       co->height = 2 * li->bdyAdjust;
     }
 
     li->sb = sb;
@@ -119,25 +133,39 @@ newtComponent newtListbox(int left, int top, int height, int flags) {
     co->ops = &listboxOps;
     co->takesFocus = 1;
     co->callback = NULL;
+    co->destroyCallback = NULL;
 
     updateWidth(co, li, 5);
-    li->curHeight = co->height - (2 * li->bdyAdjust);
 
     return co;
 }
 
-static inline void updateWidth(newtComponent co, struct listbox * li, 
+static inline void updateWidth(newtComponent co, struct listbox * li,
                                int maxField) {
     li->curWidth = maxField;
     co->width = li->curWidth + li->sbAdjust + 2 * li->bdxAdjust;
 
     if (li->sb)
-       li->sb->left = co->left + co->width - 1;
+       li->sb->left = co->left + co->width - li->bdxAdjust - 1;
+}
+
+void newtListboxSetCurrentByKey(newtComponent co, void * key) {
+    struct listbox * li = co->data;
+    struct items * item;
+    int i;
+
+    item = li->boxItems, i = 0;
+    while (item && item->data != key)
+       item = item->next, i++;
+
+    if (item)
+       newtListboxSetCurrent(co, i);
 }
 
 void newtListboxSetCurrent(newtComponent co, int num)
 {
     struct listbox * li = co->data;
+
     if (num >= li->numItems)
        li->currItem = li->numItems - 1;
     else if (num < 0)
@@ -147,19 +175,20 @@ void newtListboxSetCurrent(newtComponent co, int num)
 
     if (li->currItem < li->startShowItem)
        li->startShowItem = li->currItem;
-    else if (li->currItem - li->startShowItem > co->height - 1)
-       li->startShowItem = li->currItem - co->height + 1;
-    if (li->startShowItem + co->height > li->numItems)
-       li->startShowItem = li->numItems - co->height;
+    else if (li->currItem - li->startShowItem > li->curHeight - 1)
+       li->startShowItem = li->currItem - li->curHeight + 1;
+    if (li->startShowItem + li->curHeight > li->numItems)
+       li->startShowItem = li->numItems - li->curHeight;
     if(li->startShowItem < 0)
        li->startShowItem = 0;
+
     newtListboxRealSetCurrent(co);
 }
 
-static void
-newtListboxRealSetCurrent(newtComponent co)
+static void newtListboxRealSetCurrent(newtComponent co)
 {
     struct listbox * li = co->data;
+
     if(li->sb)
        newtScrollbarSet(li->sb, li->currItem + 1, li->numItems);
     listboxDraw(co);
@@ -168,11 +197,12 @@ newtListboxRealSetCurrent(newtComponent co)
 
 void newtListboxSetWidth(newtComponent co, int width) {
     struct listbox * li = co->data;
-    
+
     co->width = width;
     li->curWidth = co->width - li->sbAdjust - 2 * li->bdxAdjust;
     li->userHasSetWidth = 1;
-    if (li->sb) li->sb->left = co->width + co->left - 1;
+    if (li->sb)
+       li->sb->left = co->left + co->width - li->bdxAdjust - 1;
     listboxDraw(co);
 }
 
@@ -190,30 +220,34 @@ void * newtListboxGetCurrent(newtComponent co) {
        return NULL;
 }
 
-void newtListboxSelectItem(newtComponent co, int item,
+void newtListboxSelectItem(newtComponent co, const void * key,
        enum newtFlagsSense sense)
 {
     struct listbox * li = co->data;
     int i;
-    struct items *iitem;
-    
-    for(i = 0, iitem = li->boxItems; iitem != NULL && i < item;
-       i++, iitem = iitem->next);
-
-    if (iitem) {
-       if(iitem->isSelected && sense != NEWT_FLAGS_SET)
-           li->numSelected--;
-       else if(!iitem->isSelected && sense != NEWT_FLAGS_RESET)
-           li->numSelected++;
-       switch(sense) {
-               case NEWT_FLAGS_RESET:
-                       iitem->isSelected = 0; break;
-               case NEWT_FLAGS_SET:
-                       iitem->isSelected = 1; break;
-               case NEWT_FLAGS_TOGGLE:
-                       iitem->isSelected = !iitem->isSelected;
-       }
+    struct items * item;
+
+    item = li->boxItems, i = 0;
+    while (item && item->data != key)
+       item = item->next, i++;
+
+    if (!item) return;
+
+    if (item->isSelected)
+       li->numSelected--;
+
+    switch(sense) {
+       case NEWT_FLAGS_RESET:
+               item->isSelected = 0; break;
+       case NEWT_FLAGS_SET:
+               item->isSelected = 1; break;
+       case NEWT_FLAGS_TOGGLE:
+               item->isSelected = !item->isSelected;
     }
+
+    if (item->isSelected)
+       li->numSelected++;
+
     listboxDraw(co);
 }
 
@@ -251,7 +285,7 @@ void ** newtListboxGetSelection(newtComponent co, int *numitems)
     return retval;
 }
 
-void newtListboxSetText(newtComponent co, int num, const char * text) {
+void newtListboxSetEntry(newtComponent co, int num, const char * text) {
     struct listbox * li = co->data;
     int i;
     struct items *item;
@@ -262,21 +296,17 @@ void newtListboxSetText(newtComponent co, int num, const char * text) {
     if(!item)
        return;
     else {
-       free(item->key);
-       item->key = strdup(text);
+       free(item->text);
+       item->text = strdup(text);
     }
-    if (li->userHasSetWidth == 0 && strlen(text) > li->curWidth) {
-       updateWidth(co, li, strlen(text));
+    if (li->userHasSetWidth == 0 && wstrlen(text,-1) > li->curWidth) {
+       updateWidth(co, li, wstrlen(text,-1));
     }
 
     if (num >= li->startShowItem && num <= li->startShowItem + co->height)
        listboxDraw(co);
 }
 
-void newtListboxSetEntry(newtComponent co, int num, const char * text) {
-    newtListboxSetText(co, num, text);
-}
-
 void newtListboxSetData(newtComponent co, int num, void * data) {
     struct listbox * li = co->data;
     int i;
@@ -285,11 +315,12 @@ void newtListboxSetData(newtComponent co, int num, void * data) {
     for(i = 0, item = li->boxItems; item != NULL && i < num;
        i++, item = item->next);
 
-    item->data = data;
+    if (item)
+       item->data = data;
 }
 
-int newtListboxAddEntry(newtComponent co, const char * text,
-       const void * data) {
+int newtListboxAppendEntry(newtComponent co, const char * text,
+                       const void * data) {
     struct listbox * li = co->data;
     struct items *item;
 
@@ -301,32 +332,31 @@ int newtListboxAddEntry(newtComponent co, const char * text,
        item = li->boxItems = malloc(sizeof(struct items));
     }
 
-    if (!li->userHasSetWidth && text && (strlen(text) > li->curWidth))
-       updateWidth(co, li, strlen(text));
+    if (!li->userHasSetWidth && text && (wstrlen(text,-1) > li->curWidth))
+       updateWidth(co, li, wstrlen(text,-1));
 
-    item->key = strdup(text); item->data = data; item->next = NULL;
+    item->text = strdup(text); item->data = data; item->next = NULL;
     item->isSelected = 0;
-    
+
     if (li->grow)
        co->height++, li->curHeight++;
     li->numItems++;
 
-    return li->numItems;
+    return 0;
 }
 
-
 int newtListboxInsertEntry(newtComponent co, const char * text,
-       const void * data, int num) {
+                          const void * data, void * key) {
     struct listbox * li = co->data;
     struct items *item, *t;
-    int i;
-    if(num > li->numItems)
-       num = li->numItems;
 
     if (li->boxItems) {
-       if(num > 0) {
-           for(i = 0, item = li->boxItems; item->next != NULL && i < num - 1;
-               item = item->next, i++);
+       if (key) {
+           item = li->boxItems;
+           while (item && item->data != key) item = item->next;
+
+           if (!item) return 1;
+
            t = item->next;
            item = item->next = malloc(sizeof(struct items));
            item->next = t;
@@ -335,72 +365,74 @@ int newtListboxInsertEntry(newtComponent co, const char * text,
            item = li->boxItems = malloc(sizeof(struct items));
            item->next = t;
        }
+    } else if (key) {
+       return 1;
     } else {
        item = li->boxItems = malloc(sizeof(struct items));
        item->next = NULL;
     }
 
-    if (!li->userHasSetWidth && text && (strlen(text) > li->curWidth))
-       updateWidth(co, li, strlen(text));
+    if (!li->userHasSetWidth && text && (wstrlen(text,-1) > li->curWidth))
+       updateWidth(co, li, wstrlen(text,-1));
 
-    item->key = strdup(text?text:"(null)"); item->data = data;
+    item->text = strdup(text?text:"(null)"); item->data = data;
     item->isSelected = 0;
-    
+
     if (li->sb)
-       li->sb->left = co->left + co->width - 1;
+       li->sb->left = co->left + co->width - li->bdxAdjust - 1;
     li->numItems++;
 
     listboxDraw(co);
 
-    return li->numItems;
+    return 0;
 }
 
-int newtListboxDeleteEntry(newtComponent co, int num) {
+int newtListboxDeleteEntry(newtComponent co, void * key) {
     struct listbox * li = co->data;
-    int i, widest = 0, t;
+    int widest = 0, t;
     struct items *item, *item2 = NULL;
-
-    if(num > li->numItems)
-       num = li->numItems;
+    int num;
 
     if (li->boxItems == NULL || li->numItems <= 0)
        return 0;
 
-    if (num <= 1) { 
-       item = li->boxItems;
-       li->boxItems = item->next;
+    num = 0;
 
-       /* Fix things up for the width-finding loop near the bottom */
-       item2 = li->boxItems;
-       widest = strlen(item2?item2->key:"");
-    } else {
-       for(i = 0, item = li->boxItems; item != NULL && i < num - 1;
-           i++, item = item->next) {
-           if((t = strlen(item->key)) > widest) widest = t;
-           item2 = item;
-       }
+    item2 = NULL, item = li->boxItems;
+    while (item && item->data != key) {
+       item2 = item;
+       item = item->next;
+       num++;
+    }
 
-       if (!item)
-           return -1;
+    if (!item)
+       return -1;
 
+    if (item2)
        item2->next = item->next;
-    }
-    free(item->key);
+    else
+       li->boxItems = item->next;
+
+    free(item->text);
     free(item);
     li->numItems--;
-    if(li->currItem >= num)
+
+    if (!li->userHasSetWidth) {
+       widest = 0;
+       for (item = li->boxItems; item != NULL; item = item->next)
+           if ((t = wstrlen(item->text,-1)) > widest) widest = t;
+    }
+
+    if (li->currItem >= num)
        li->currItem--;
-    for (item = item2?item2->next:item2; item != NULL; item = item->next)
-       if((t = strlen(item->key)) > widest) widest = t;
 
-    /* Adjust the listbox width */
     if (!li->userHasSetWidth) {
        updateWidth(co, li, widest);
     }
 
     listboxDraw(co);
 
-    return li->numItems;
+    return 0;
 }
 
 void newtListboxClear(newtComponent co)
@@ -411,15 +443,21 @@ void newtListboxClear(newtComponent co)
        return;
     for(anitem = li->boxItems; anitem != NULL; anitem = nextitem) {
        nextitem = anitem->next;
-       free(anitem->key);
+       free(anitem->text);
        free(anitem);
     }
     li->numItems = li->numSelected = li->currItem = li->startShowItem = 0;
     li->boxItems = NULL;
-    if (!li->userHasSetWidth) 
+    if (!li->userHasSetWidth)
        updateWidth(co, li, 5);
 }
 
+int newtListboxItemCount(newtComponent co)
+{
+    struct listbox *li = co->data;
+    return li->numItems;
+}
+
 /* If you don't want to get back the text, pass in NULL for the ptr-ptr. Same
    goes for the data. */
 void newtListboxGetEntry(newtComponent co, int num, char **text, void **data) {
@@ -436,16 +474,16 @@ void newtListboxGetEntry(newtComponent co, int num, char **text, void **data) {
     }
 
     i = 0;
-    item = li->boxItems; 
+    item = li->boxItems;
     while (item && i < num) {
        i++, item = item->next;
     }
 
     if (item) {
        if (text)
-           *text = item->key;
+           *text = item->text;
        if (data)
-           *data = (void *)item->data; 
+           *data = (void *)item->data;
     }
 }
 
@@ -457,10 +495,9 @@ static void listboxDraw(newtComponent co)
 
     if (!co->isMapped) return ;
 
-    if(li->sb)
-       li->sb->ops->draw(li->sb);
-
-    if(li->flags & NEWT_FLAG_DOBORDER) {
+    newtTrashScreen();
+    
+    if(li->flags & NEWT_FLAG_BORDER) {
       if(li->isActive)
          SLsmg_set_color(NEWT_COLORSET_ACTLISTBOX);
       else
@@ -469,19 +506,22 @@ static void listboxDraw(newtComponent co)
       newtDrawBox(co->left, co->top, co->width, co->height, 0);
     }
 
+    if(li->sb)
+       li->sb->ops->draw(li->sb);
+
     SLsmg_set_color(NEWT_COLORSET_LISTBOX);
-    
+
     for(i = 0, item = li->boxItems; item != NULL && i < li->startShowItem;
        i++, item = item->next);
 
     j = i;
 
     for (i = 0; item != NULL && i < li->curHeight; i++, item = item->next) {
-       if (!item->key) continue;
+       if (!item->text) continue;
 
        newtGotorc(co->top + i + li->bdyAdjust, co->left + li->bdxAdjust);
        if(j + i == li->currItem) {
-           if(item->isSelected)
+           if(li->isActive)
                SLsmg_set_color(NEWT_COLORSET_ACTSELLISTBOX);
            else
                SLsmg_set_color(NEWT_COLORSET_ACTLISTBOX);
@@ -489,23 +529,32 @@ static void listboxDraw(newtComponent co)
            SLsmg_set_color(NEWT_COLORSET_SELLISTBOX);
        else
            SLsmg_set_color(NEWT_COLORSET_LISTBOX);
-           
-       SLsmg_write_nstring(item->key, li->curWidth);
 
+       SLsmg_write_nstring(item->text, li->curWidth);
+
+       if (li->flags & NEWT_FLAG_MULTIPLE) {
+           newtGotorc(co->top + i + li->bdyAdjust, co->left + li->bdxAdjust);
+           SLsmg_set_color(item->isSelected ?
+                   NEWT_COLORSET_SELLISTBOX : NEWT_COLORSET_LISTBOX);
+           SLsmg_write_nstring(item->text, 1);
+       }
     }
-    newtGotorc(co->top + (li->currItem - li->startShowItem), co->left);
+    newtGotorc(co->top + (li->currItem - li->startShowItem) + li->bdyAdjust,
+               co->left + li->bdxAdjust);
 }
 
 static struct eventResult listboxEvent(newtComponent co, struct event ev) {
     struct eventResult er;
     struct listbox * li = co->data;
-
+    struct items *item;
+    int i;
+    
     er.result = ER_IGNORED;
-              
+
     if(ev.when == EV_EARLY || ev.when == EV_LATE) {
        return er;
     }
-                      
+
     switch(ev.event) {
       case EV_KEYPRESS:
        if (!li->isActive) break;
@@ -513,7 +562,8 @@ static struct eventResult listboxEvent(newtComponent co, struct event ev) {
        switch(ev.u.key) {
          case ' ':
            if(!(li->flags & NEWT_FLAG_MULTIPLE)) break;
-           newtListboxSelectItem(co, li->currItem, NEWT_FLAGS_TOGGLE);
+           newtListboxSelectItem(co, newtListboxGetCurrent(co),
+                                 NEWT_FLAGS_TOGGLE);
            er.result = ER_SWALLOWED;
            /* We don't break here, because it is cool to be able to
               hold space to select a bunch of items in a list at once */
@@ -574,7 +624,7 @@ static struct eventResult listboxEvent(newtComponent co, struct event ev) {
                li->startShowItem = li->numItems - li->curHeight;
            }
            li->currItem += li->curHeight;
-           if(li->currItem > li->numItems) {
+           if(li->currItem >= li->numItems) {
                li->currItem = li->numItems - 1;
            }
            newtListboxRealSetCurrent(co);
@@ -589,28 +639,116 @@ static struct eventResult listboxEvent(newtComponent co, struct event ev) {
 
          case NEWT_KEY_END:
            if(li->numItems <= 0) break;
-           li->startShowItem = li->numItems - li->curHeight - 1;
+           li->startShowItem = li->numItems - li->curHeight;
            if(li->startShowItem < 0)
                li->startShowItem = 0;
-           newtListboxRealSetCurrent(co, li->numItems - 1);
+           li->currItem = li->numItems - 1;
+           newtListboxRealSetCurrent(co);
            er.result = ER_SWALLOWED;
            break;
          default:
-           /* keeps gcc quiet */
+             if (li->numItems <= 0) break;
+              if (ev.u.key < NEWT_KEY_EXTRA_BASE && isalpha(ev.u.key)) {
+                 for(i = 0, item = li->boxItems; item != NULL &&
+                         i < li->currItem; i++, item = item->next);
+
+                 if (item && item->text && (toupper(*item->text) == toupper(ev.u.key))) {
+                     item = item->next;
+                     i++;
+                 } else { 
+                     item = li->boxItems;
+                     i = 0;
+                 }
+                 while (item && item->text &&
+                        toupper(*item->text) != toupper(ev.u.key)) {
+                     item = item->next;
+                     i++;
+                 }
+                 if (item) {
+                     li->currItem = i;
+                     if(li->currItem < li->startShowItem ||
+                        li->currItem > li->startShowItem)
+                         li->startShowItem =
+                             li->currItem > li->numItems - li->curHeight ?
+                             li->numItems - li->curHeight :
+                             li->currItem;
+                     if(li->sb)
+                         newtScrollbarSet(li->sb, li->currItem + 1, li->numItems);
+                     newtListboxRealSetCurrent(co);
+                     er.result = ER_SWALLOWED;
+                 }
+             }
        }
        break;
-       
+
       case EV_FOCUS:
        li->isActive = 1;
        listboxDraw(co);
+       if(li->flags & NEWT_FLAG_SHOWCURSOR)
+         newtCursorOn();
        er.result = ER_SWALLOWED;
        break;
 
       case EV_UNFOCUS:
        li->isActive = 0;
        listboxDraw(co);
+       if(li->flags & NEWT_FLAG_SHOWCURSOR)
+         newtCursorOff();
        er.result = ER_SWALLOWED;
        break;
+
+      case EV_MOUSE:
+         /* if this mouse click was within the listbox, make the current
+            item the item clicked on. */
+       /* Up scroll arrow */
+       if (li->sb &&
+           ev.u.mouse.x == co->left + co->width - li->bdxAdjust - 1 &&
+           ev.u.mouse.y == co->top + li->bdyAdjust) {
+           if(li->numItems <= 0) break;
+           if(li->currItem > 0) {
+               li->currItem--;
+               if(li->currItem < li->startShowItem)
+                   li->startShowItem = li->currItem;
+               if(li->sb)
+                   newtScrollbarSet(li->sb, li->currItem + 1, li->numItems);
+               listboxDraw(co);
+           }
+           if(co->callback) co->callback(co, co->callbackData);
+           er.result = ER_SWALLOWED;
+           break;
+       }
+       /* Down scroll arrow */
+       if (li->sb &&
+           ev.u.mouse.x == co->left + co->width - li->bdxAdjust - 1 &&
+           ev.u.mouse.y == co->top + co->height - li->bdyAdjust - 1) {
+           if(li->numItems <= 0) break;
+           if(li->currItem < li->numItems - 1) {
+               li->currItem++;
+               if(li->currItem > (li->startShowItem + li->curHeight - 1)) {
+                   li->startShowItem = li->currItem - li->curHeight + 1;
+                   if(li->startShowItem + li->curHeight > li->numItems)
+                       li->startShowItem = li->numItems - li->curHeight;
+               }
+               if(li->sb)
+                   newtScrollbarSet(li->sb, li->currItem + 1, li->numItems);
+               listboxDraw(co);
+           }
+           if(co->callback) co->callback(co, co->callbackData);
+           er.result = ER_SWALLOWED;
+           break;
+       }
+       if ((ev.u.mouse.y >= co->top + li->bdyAdjust) &&
+           (ev.u.mouse.y <= co->top + co->height - (li->bdyAdjust * 2)) &&
+           (ev.u.mouse.x >= co->left + li->bdxAdjust) &&
+           (ev.u.mouse.x <= co->left + co->width + (li->bdxAdjust * 2))) {
+           li->currItem = li->startShowItem +
+               (ev.u.mouse.y - li->bdyAdjust - co->top);
+           newtListboxRealSetCurrent(co);
+           listboxDraw(co);
+           if(co->callback) co->callback(co, co->callbackData);
+           er.result = ER_SWALLOWED;
+           break;
+       }
     }
 
     return er;
@@ -620,16 +758,17 @@ static void listboxDestroy(newtComponent co) {
     struct listbox * li = co->data;
     struct items * item, * nextitem;
 
-    nextitem = item = li->boxItems;
+    item = li->boxItems;
 
     while (item != NULL) {
        nextitem = item->next;
-       free(item->key);
+       free(item->text);
        free(item);
        item = nextitem;
     }
 
+    if (li->sb) li->sb->ops->destroy(li->sb);
+
     free(li);
     free(co);
 }
-