/* This goofed-up box whacked into shape by Elliot Lee <sopwith@cuc.edu>
(from the original listbox by Erik Troan <ewt@redhat.com>)
and contributed to newt for use under the LGPL license.
- Copyright Elliot Lee 1996 */
+ 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"
/* Linked list of items in the listbox */
struct items {
- void *key, *data;
+ char * text;
+ const void *data;
+ unsigned char isSelected;
struct items *next;
};
/* Holds all the relevant information for this listbox */
struct listbox {
- newtComponent sb; /* Scrollbar on right side of listbox */
- int numItems, curWidth;
+ newtComponent sb; /* Scrollbar on right side of listbox */
+ int curWidth; /* size of text w/o scrollbar or border*/
+ int curHeight; /* size of text w/o border */
+ int sbAdjust;
+ int bdxAdjust, bdyAdjust;
+ int numItems, numSelected;
+ int userHasSetWidth;
int currItem, startShowItem; /* startShowItem is the first item displayed
on the screen */
int isActive; /* If we handle key events all the time, it seems
struct items *boxItems;
int grow;
int flags; /* flags for this listbox, right now just
- NEWT_LISTBOX_RETURNEXIT */
+ NEWT_FLAG_RETURNEXIT */
};
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, 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 listboxMapped(newtComponent co, int isMapped) {
+ struct listbox * li = co->data;
+
+ 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) {
newtComponent co, sb;
struct listbox * li;
li->boxItems = NULL;
li->numItems = 0;
li->currItem = 0;
+ li->numSelected = 0;
li->isActive = 0;
+ li->userHasSetWidth = 0;
li->startShowItem = 0;
- li->flags = flags & (NEWT_LISTBOX_RETURNEXIT|NEWT_FLAG_DOBORDER);
+ li->sbAdjust = 0;
+ li->bdxAdjust = 0;
+ li->bdyAdjust = 0;
+ li->flags = flags & (NEWT_FLAG_RETURNEXIT | NEWT_FLAG_BORDER |
+ NEWT_FLAG_MULTIPLE | NEWT_FLAG_SHOWCURSOR);
+
+ 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)
+ if (flags & NEWT_FLAG_SCROLL) {
+ sb = newtVerticalScrollbar(left, top + li->bdyAdjust,
+ li->curHeight,
+ COLORSET_LISTBOX, COLORSET_ACTLISTBOX);
+ li->sbAdjust = 3;
+ } else {
sb = NULL;
- else
- sb = newtVerticalScrollbar(left, top, height, COLORSET_LISTBOX,
- COLORSET_ACTLISTBOX);
+ }
} else {
li->grow = 1;
sb = NULL;
li->sb = sb;
co->data = li;
+ co->isMapped = 0;
co->left = left;
co->top = top;
- co->height = height;
- li->curWidth = 5;
co->ops = &listboxOps;
co->takesFocus = 1;
+ co->callback = NULL;
+ co->destroyCallback = NULL;
+
+ updateWidth(co, li, 5);
return co;
}
-void newtListboxSetCurrent(newtComponent co, int num) {
+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 - 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)
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)
+{
+ struct listbox * li = co->data;
+
if(li->sb)
newtScrollbarSet(li->sb, li->currItem + 1, li->numItems);
listboxDraw(co);
+ if(co->callback) co->callback(co, co->callbackData);
+}
+
+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->left + co->width - li->bdxAdjust - 1;
+ listboxDraw(co);
}
void * newtListboxGetCurrent(newtComponent co) {
i++, item = item->next);
if (item)
- return item->data;
+ return (void *)item->data;
else
return NULL;
}
-void newtListboxSetText(newtComponent co, int num, char * text) {
+void newtListboxSelectItem(newtComponent co, const void * key,
+ enum newtFlagsSense sense)
+{
+ struct listbox * li = co->data;
+ int i;
+ 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);
+}
+
+void newtListboxClearSelection(newtComponent co)
+{
+ struct items *item;
+ struct listbox * li = co->data;
+
+ for(item = li->boxItems; item != NULL;
+ item = item->next)
+ item->isSelected = 0;
+ li->numSelected = 0;
+ listboxDraw(co);
+}
+
+/* Free the returned array after use, but NOT the values in the array */
+void ** newtListboxGetSelection(newtComponent co, int *numitems)
+{
+ struct listbox * li;
+ int i;
+ void **retval;
+ struct items *item;
+
+ if(!co || !numitems) return NULL;
+
+ li = co->data;
+ if(!li || !li->numSelected) return NULL;
+
+ retval = malloc(li->numSelected * sizeof(void *));
+ for(i = 0, item = li->boxItems; item != NULL;
+ item = item->next)
+ if(item->isSelected)
+ retval[i++] = (void *)item->data;
+ *numitems = li->numSelected;
+ return retval;
+}
+
+void newtListboxSetEntry(newtComponent co, int num, const char * text) {
struct listbox * li = co->data;
int i;
struct items *item;
if(!item)
return;
else {
- free(item->key);
- item->key = strdup(text);
+ free(item->text);
+ item->text = strdup(text);
}
- if (strlen(text) > li->curWidth) {
- co->width = li->curWidth = strlen(text);
- if (li->sb)
- li->sb->left = co->left + co->width + 2;
+ 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, char * text) {
- newtListboxSetText(co, num, text);
-}
-
void newtListboxSetData(newtComponent co, int num, void * data) {
struct listbox * li = co->data;
int i;
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, char * text, void * data) {
+int newtListboxAppendEntry(newtComponent co, const char * text,
+ const void * data) {
struct listbox * li = co->data;
struct items *item;
item = li->boxItems = malloc(sizeof(struct items));
}
- if (text && (strlen(text) > li->curWidth))
- li->curWidth = strlen(text) ;
-
- item->key = strdup(text); item->data = data; item->next = NULL;
+ if (!li->userHasSetWidth && text && (wstrlen(text,-1) > li->curWidth))
+ updateWidth(co, li, wstrlen(text,-1));
- if (li->sb)
- li->sb->left = co->left + li->curWidth + 2;
+ item->text = strdup(text); item->data = data; item->next = NULL;
+ item->isSelected = 0;
if (li->grow)
- co->height++;
-
- co->width = li->curWidth;
+ co->height++, li->curHeight++;
li->numItems++;
- return li->numItems;
+ return 0;
}
-
-int newtListboxInsertEntry(newtComponent co, char * text, void * data,
- int num) {
+int newtListboxInsertEntry(newtComponent co, const char * text,
+ 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 > 1) {
- 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;
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 (text && (strlen(text) > li->curWidth))
- li->curWidth = 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 + li->curWidth + 2;
-
- co->width = li->curWidth;
+ 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;
- struct items *item, *item2;
+ int widest = 0, t;
+ struct items *item, *item2 = NULL;
+ int num;
- if(num > li->numItems)
- num = li->numItems;
+ if (li->boxItems == NULL || li->numItems <= 0)
+ return 0;
- if (!li->boxItems)
- return -1;
+ num = 0;
- if (num <= 1) {
- item = li->boxItems;
- li->boxItems = item->next;
-
- /* Fix things up for the width-finding loop near the bottom */
- item2 = li->boxItems;
- widest = strlen(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->next; item != NULL; item = item->next)
- if((t = strlen(item->key)) > widest) widest = t;
- /* Adjust the listbox width */
- co->width = li->curWidth = widest;
- if (li->sb)
- li->sb->left = co->left + widest + 2;
+ if (!li->userHasSetWidth) {
+ updateWidth(co, li, widest);
+ }
listboxDraw(co);
+ return 0;
+}
+
+void newtListboxClear(newtComponent co)
+{
+ struct listbox * li;
+ struct items *anitem, *nextitem;
+ if(co == NULL || (li = co->data) == NULL)
+ return;
+ for(anitem = li->boxItems; anitem != NULL; anitem = nextitem) {
+ nextitem = anitem->next;
+ free(anitem->text);
+ free(anitem);
+ }
+ li->numItems = li->numSelected = li->currItem = li->startShowItem = 0;
+ li->boxItems = NULL;
+ if (!li->userHasSetWidth)
+ updateWidth(co, li, 5);
+}
+
+int newtListboxItemCount(newtComponent co)
+{
+ struct listbox *li = co->data;
return li->numItems;
}
}
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 = item->data;
+ *data = (void *)item->data;
}
}
struct items *item;
int i, j;
- if(li->sb)
- li->sb->ops->draw(li->sb);
+ if (!co->isMapped) return ;
- if(li->flags & NEWT_FLAG_DOBORDER) {
+ newtTrashScreen();
+
+ if(li->flags & NEWT_FLAG_BORDER) {
if(li->isActive)
SLsmg_set_color(NEWT_COLORSET_ACTLISTBOX);
else
SLsmg_set_color(NEWT_COLORSET_LISTBOX);
- newtDrawBox(co->left-1, co->top-1, co->width+5, co->height+2, 0);
+ 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 < co->height; i++, item = item->next) {
- if (!item->key) continue;
-
- newtGotorc(co->top + i, co->left + 1);
- if(j + i == li->currItem)
- SLsmg_set_color(NEWT_COLORSET_ACTLISTBOX);
+ for (i = 0; item != NULL && i < li->curHeight; i++, item = item->next) {
+ if (!item->text) continue;
+
+ newtGotorc(co->top + i + li->bdyAdjust, co->left + li->bdxAdjust);
+ if(j + i == li->currItem) {
+ if(li->isActive)
+ SLsmg_set_color(NEWT_COLORSET_ACTSELLISTBOX);
+ else
+ SLsmg_set_color(NEWT_COLORSET_ACTLISTBOX);
+ } else if(item->isSelected)
+ 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(j + i == li->currItem)
- SLsmg_set_color(NEWT_COLORSET_LISTBOX);
+ 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;
switch(ev.u.key) {
+ case ' ':
+ if(!(li->flags & NEWT_FLAG_MULTIPLE)) break;
+ 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 */
+
+ case NEWT_KEY_DOWN:
+ 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;
+
case NEWT_KEY_ENTER:
- if(li-> flags & NEWT_LISTBOX_RETURNEXIT)
+ if(li->numItems <= 0) break;
+ if(li->flags & NEWT_FLAG_RETURNEXIT)
er.result = ER_EXITFORM;
break;
case NEWT_KEY_UP:
+ if(li->numItems <= 0) break;
if(li->currItem > 0) {
li->currItem--;
if(li->currItem < li->startShowItem)
newtScrollbarSet(li->sb, li->currItem + 1, li->numItems);
listboxDraw(co);
}
- er.result = ER_SWALLOWED;
- break;
-
- case NEWT_KEY_DOWN:
- if(li->currItem < li->numItems - 1) {
- li->currItem++;
- 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;
- }
- 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;
case NEWT_KEY_PGUP:
- newtListboxSetCurrent(co, li->currItem - co->height + 1);
+ if(li->numItems <= 0) break;
+ li->startShowItem -= li->curHeight - 1;
+ if(li->startShowItem < 0)
+ li->startShowItem = 0;
+ li->currItem -= li->curHeight - 1;
+ if(li->currItem < 0)
+ li->currItem = 0;
+ newtListboxRealSetCurrent(co);
er.result = ER_SWALLOWED;
break;
case NEWT_KEY_PGDN:
- newtListboxSetCurrent(co, li->currItem + co->height - 1);
+ if(li->numItems <= 0) break;
+ li->startShowItem += li->curHeight;
+ if(li->startShowItem > (li->numItems - li->curHeight)) {
+ li->startShowItem = li->numItems - li->curHeight;
+ }
+ li->currItem += li->curHeight;
+ if(li->currItem >= li->numItems) {
+ li->currItem = li->numItems - 1;
+ }
+ newtListboxRealSetCurrent(co);
er.result = ER_SWALLOWED;
break;
+
case NEWT_KEY_HOME:
+ if(li->numItems <= 0) break;
newtListboxSetCurrent(co, 0);
er.result = ER_SWALLOWED;
break;
+
case NEWT_KEY_END:
- newtListboxSetCurrent(co, li->numItems - 1);
+ if(li->numItems <= 0) break;
+ li->startShowItem = li->numItems - li->curHeight;
+ if(li->startShowItem < 0)
+ li->startShowItem = 0;
+ 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;
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);
}
-