]>
Commit | Line | Data |
---|---|---|
0b38669d | 1 | /* This goofed-up box whacked into shape by Elliot Lee <sopwith@cuc.edu> |
2 | (from the original listbox by Erik Troan <ewt@redhat.com>) | |
3 | and contributed to newt for use under the LGPL license. | |
ad792351 | 4 | Copyright (C) 1996, 1997 Elliot Lee */ |
a61e44cc | 5 | |
139f06bc | 6 | #include <slang.h> |
4a93351d | 7 | #include <stdio.h> |
962b92a5 | 8 | #include <stdlib.h> |
9 | #include <string.h> | |
10 | ||
11 | #include "newt.h" | |
12 | #include "newt_pr.h" | |
13 | ||
a61e44cc | 14 | |
15 | /* Linked list of items in the listbox */ | |
16 | struct items { | |
a507b3ec | 17 | char * text; |
d4109c37 | 18 | const void *data; |
2dbc072e | 19 | unsigned char isSelected; |
a61e44cc | 20 | struct items *next; |
21 | }; | |
22 | ||
23 | /* Holds all the relevant information for this listbox */ | |
962b92a5 | 24 | struct listbox { |
e948278c | 25 | newtComponent sb; /* Scrollbar on right side of listbox */ |
913d0524 | 26 | int curWidth; /* size of text w/o scrollbar or border*/ |
27 | int curHeight; /* size of text w/o border */ | |
e948278c | 28 | int sbAdjust; |
913d0524 | 29 | int bdxAdjust, bdyAdjust; |
e948278c | 30 | int numItems, numSelected; |
babcb349 | 31 | int userHasSetWidth; |
a61e44cc | 32 | int currItem, startShowItem; /* startShowItem is the first item displayed |
33 | on the screen */ | |
34 | int isActive; /* If we handle key events all the time, it seems | |
35 | to do things even when they are supposed to be for | |
36 | another button/whatever */ | |
37 | struct items *boxItems; | |
0bf47501 | 38 | int grow; |
a61e44cc | 39 | int flags; /* flags for this listbox, right now just |
4a93351d | 40 | NEWT_FLAG_RETURNEXIT */ |
962b92a5 | 41 | }; |
42 | ||
43 | static void listboxDraw(newtComponent co); | |
44 | static void listboxDestroy(newtComponent co); | |
45 | static struct eventResult listboxEvent(newtComponent co, struct event ev); | |
4e9c4bb9 | 46 | static void newtListboxRealSetCurrent(newtComponent co); |
8f52cd47 | 47 | static void listboxPlace(newtComponent co, int newLeft, int newTop); |
913d0524 | 48 | static inline void updateWidth(newtComponent co, struct listbox * li, |
49 | int maxField); | |
8f52cd47 | 50 | static void listboxMapped(newtComponent co, int isMapped); |
962b92a5 | 51 | |
52 | static struct componentOps listboxOps = { | |
53 | listboxDraw, | |
54 | listboxEvent, | |
55 | listboxDestroy, | |
e948278c | 56 | listboxPlace, |
8f52cd47 | 57 | listboxMapped, |
a61e44cc | 58 | }; |
962b92a5 | 59 | |
8f52cd47 | 60 | static void listboxMapped(newtComponent co, int isMapped) { |
e948278c | 61 | struct listbox * li = co->data; |
62 | ||
8f52cd47 | 63 | co->isMapped = isMapped; |
64 | if (li->sb) | |
65 | li->sb->ops->mapped(li->sb, isMapped); | |
66 | } | |
67 | ||
68 | static void listboxPlace(newtComponent co, int newLeft, int newTop) { | |
69 | struct listbox * li = co->data; | |
70 | ||
71 | co->top = newTop; | |
72 | co->left = newLeft; | |
73 | ||
74 | if (li->sb) | |
aa564c1d | 75 | li->sb->ops->place(li->sb, co->left + co->width - li->bdxAdjust - 1, |
76 | co->top); | |
e948278c | 77 | } |
78 | ||
962b92a5 | 79 | newtComponent newtListbox(int left, int top, int height, int flags) { |
b9523497 | 80 | newtComponent co, sb; |
962b92a5 | 81 | struct listbox * li; |
82 | ||
a61e44cc | 83 | if (!(co = malloc(sizeof(*co)))) |
84 | return NULL; | |
962b92a5 | 85 | |
a61e44cc | 86 | if (!(li = malloc(sizeof(struct listbox)))) { |
87 | free(co); | |
88 | return NULL; | |
89 | } | |
90 | ||
91 | li->boxItems = NULL; | |
92 | li->numItems = 0; | |
93 | li->currItem = 0; | |
2dbc072e | 94 | li->numSelected = 0; |
a61e44cc | 95 | li->isActive = 0; |
babcb349 | 96 | li->userHasSetWidth = 0; |
a61e44cc | 97 | li->startShowItem = 0; |
dc3ac6cf | 98 | li->sbAdjust = 0; |
913d0524 | 99 | li->bdxAdjust = 0; |
100 | li->bdyAdjust = 0; | |
dd2f0e88 | 101 | li->flags = flags & (NEWT_FLAG_RETURNEXIT | NEWT_FLAG_BORDER | |
913d0524 | 102 | NEWT_FLAG_MULTIPLE); |
103 | ||
dd2f0e88 | 104 | if (li->flags & NEWT_FLAG_BORDER) { |
913d0524 | 105 | li->bdxAdjust = 2; |
106 | li->bdyAdjust = 1; | |
107 | } | |
962b92a5 | 108 | |
aa564c1d | 109 | co->height = height; |
110 | li->curHeight = co->height - (2 * li->bdyAdjust); | |
111 | ||
0bf47501 | 112 | if (height) { |
113 | li->grow = 0; | |
dd2f0e88 | 114 | if (flags & NEWT_FLAG_SCROLL) { |
aa564c1d | 115 | sb = newtVerticalScrollbar(left, top + li->bdyAdjust, |
116 | li->curHeight, | |
117 | COLORSET_LISTBOX, COLORSET_ACTLISTBOX); | |
e948278c | 118 | li->sbAdjust = 3; |
dd2f0e88 | 119 | } else { |
120 | sb = NULL; | |
e948278c | 121 | } |
0bf47501 | 122 | } else { |
123 | li->grow = 1; | |
b9523497 | 124 | sb = NULL; |
0bf47501 | 125 | } |
962b92a5 | 126 | |
a61e44cc | 127 | li->sb = sb; |
962b92a5 | 128 | co->data = li; |
913d0524 | 129 | co->isMapped = 0; |
962b92a5 | 130 | co->left = left; |
131 | co->top = top; | |
962b92a5 | 132 | co->ops = &listboxOps; |
133 | co->takesFocus = 1; | |
f37450e9 | 134 | co->callback = NULL; |
962b92a5 | 135 | |
913d0524 | 136 | updateWidth(co, li, 5); |
913d0524 | 137 | |
962b92a5 | 138 | return co; |
139 | } | |
140 | ||
913d0524 | 141 | static inline void updateWidth(newtComponent co, struct listbox * li, |
142 | int maxField) { | |
143 | li->curWidth = maxField; | |
144 | co->width = li->curWidth + li->sbAdjust + 2 * li->bdxAdjust; | |
145 | ||
146 | if (li->sb) | |
aa564c1d | 147 | li->sb->left = co->left + co->width - li->bdxAdjust - 1; |
913d0524 | 148 | } |
149 | ||
d5878365 | 150 | void newtListboxSetCurrentByKey(newtComponent co, void * key) { |
151 | struct listbox * li = co->data; | |
152 | struct items * item; | |
153 | int i; | |
154 | ||
155 | item = li->boxItems, i = 0; | |
156 | while (item && item->data != key) | |
157 | item = item->next, i++; | |
158 | ||
159 | if (item) | |
160 | newtListboxSetCurrent(co, i); | |
161 | } | |
162 | ||
4e9c4bb9 | 163 | void newtListboxSetCurrent(newtComponent co, int num) |
164 | { | |
7ea3dccd | 165 | struct listbox * li = co->data; |
d5878365 | 166 | |
a61e44cc | 167 | if (num >= li->numItems) |
168 | li->currItem = li->numItems - 1; | |
169 | else if (num < 0) | |
170 | li->currItem = 0; | |
171 | else | |
172 | li->currItem = num; | |
173 | ||
174 | if (li->currItem < li->startShowItem) | |
175 | li->startShowItem = li->currItem; | |
176 | else if (li->currItem - li->startShowItem > co->height - 1) | |
177 | li->startShowItem = li->currItem - co->height + 1; | |
178 | if (li->startShowItem + co->height > li->numItems) | |
179 | li->startShowItem = li->numItems - co->height; | |
3a779f2f | 180 | if(li->startShowItem < 0) |
181 | li->startShowItem = 0; | |
d5878365 | 182 | |
4e9c4bb9 | 183 | newtListboxRealSetCurrent(co); |
184 | } | |
185 | ||
d5878365 | 186 | static void newtListboxRealSetCurrent(newtComponent co) |
4e9c4bb9 | 187 | { |
188 | struct listbox * li = co->data; | |
d5878365 | 189 | |
0bf47501 | 190 | if(li->sb) |
191 | newtScrollbarSet(li->sb, li->currItem + 1, li->numItems); | |
913d0524 | 192 | listboxDraw(co); |
f37450e9 | 193 | if(co->callback) co->callback(co, co->callbackData); |
7ea3dccd | 194 | } |
195 | ||
913d0524 | 196 | void newtListboxSetWidth(newtComponent co, int width) { |
babcb349 | 197 | struct listbox * li = co->data; |
198 | ||
e948278c | 199 | co->width = width; |
913d0524 | 200 | li->curWidth = co->width - li->sbAdjust - 2 * li->bdxAdjust; |
babcb349 | 201 | li->userHasSetWidth = 1; |
6e25d997 | 202 | if (li->sb) li->sb->left = co->width + co->left - 1; |
913d0524 | 203 | listboxDraw(co); |
babcb349 | 204 | } |
205 | ||
2287215a | 206 | void * newtListboxGetCurrent(newtComponent co) { |
207 | struct listbox * li = co->data; | |
2287215a | 208 | int i; |
a61e44cc | 209 | struct items *item; |
2287215a | 210 | |
a61e44cc | 211 | for(i = 0, item = li->boxItems; item != NULL && i < li->currItem; |
212 | i++, item = item->next); | |
2287215a | 213 | |
a61e44cc | 214 | if (item) |
d4109c37 | 215 | return (void *)item->data; |
2287215a | 216 | else |
217 | return NULL; | |
218 | } | |
219 | ||
dd2f0e88 | 220 | void newtListboxSelectItem(newtComponent co, const void * key, |
69bf2308 | 221 | enum newtFlagsSense sense) |
46263d9e | 222 | { |
223 | struct listbox * li = co->data; | |
224 | int i; | |
dd2f0e88 | 225 | struct items * item; |
46263d9e | 226 | |
dd2f0e88 | 227 | item = li->boxItems, i = 0; |
228 | while (item && item->data != key) | |
229 | item = item->next, i++; | |
230 | ||
231 | if (!item) return; | |
232 | ||
233 | if (item->isSelected) | |
234 | li->numSelected--; | |
235 | ||
236 | switch(sense) { | |
237 | case NEWT_FLAGS_RESET: | |
238 | item->isSelected = 0; break; | |
239 | case NEWT_FLAGS_SET: | |
240 | item->isSelected = 1; break; | |
241 | case NEWT_FLAGS_TOGGLE: | |
242 | item->isSelected = !item->isSelected; | |
46263d9e | 243 | } |
dd2f0e88 | 244 | |
245 | if (item->isSelected) | |
246 | li->numSelected++; | |
247 | ||
913d0524 | 248 | listboxDraw(co); |
46263d9e | 249 | } |
250 | ||
251 | void newtListboxClearSelection(newtComponent co) | |
252 | { | |
253 | struct items *item; | |
254 | struct listbox * li = co->data; | |
255 | ||
256 | for(item = li->boxItems; item != NULL; | |
257 | item = item->next) | |
258 | item->isSelected = 0; | |
69bf2308 | 259 | li->numSelected = 0; |
913d0524 | 260 | listboxDraw(co); |
46263d9e | 261 | } |
262 | ||
2dbc072e | 263 | /* Free the returned array after use, but NOT the values in the array */ |
cb586ef6 | 264 | void ** newtListboxGetSelection(newtComponent co, int *numitems) |
2dbc072e | 265 | { |
266 | struct listbox * li; | |
267 | int i; | |
268 | void **retval; | |
269 | struct items *item; | |
270 | ||
cb586ef6 | 271 | if(!co || !numitems) return NULL; |
2dbc072e | 272 | |
273 | li = co->data; | |
274 | if(!li || !li->numSelected) return NULL; | |
275 | ||
cb586ef6 | 276 | retval = malloc(li->numSelected * sizeof(void *)); |
2dbc072e | 277 | for(i = 0, item = li->boxItems; item != NULL; |
278 | item = item->next) | |
279 | if(item->isSelected) | |
d4109c37 | 280 | retval[i++] = (void *)item->data; |
cb586ef6 | 281 | *numitems = li->numSelected; |
2dbc072e | 282 | return retval; |
283 | } | |
284 | ||
dd2f0e88 | 285 | void newtListboxSetEntry(newtComponent co, int num, const char * text) { |
a61e44cc | 286 | struct listbox * li = co->data; |
287 | int i; | |
288 | struct items *item; | |
289 | ||
290 | for(i = 0, item = li->boxItems; item != NULL && i < num; | |
291 | i++, item = item->next); | |
292 | ||
293 | if(!item) | |
294 | return; | |
3a779f2f | 295 | else { |
a507b3ec | 296 | free(item->text); |
297 | item->text = strdup(text); | |
3a779f2f | 298 | } |
913d0524 | 299 | if (li->userHasSetWidth == 0 && strlen(text) > li->curWidth) { |
300 | updateWidth(co, li, strlen(text)); | |
a61e44cc | 301 | } |
302 | ||
303 | if (num >= li->startShowItem && num <= li->startShowItem + co->height) | |
913d0524 | 304 | listboxDraw(co); |
a61e44cc | 305 | } |
306 | ||
a61e44cc | 307 | void newtListboxSetData(newtComponent co, int num, void * data) { |
2287215a | 308 | struct listbox * li = co->data; |
a61e44cc | 309 | int i; |
310 | struct items *item; | |
2287215a | 311 | |
a61e44cc | 312 | for(i = 0, item = li->boxItems; item != NULL && i < num; |
313 | i++, item = item->next); | |
2287215a | 314 | |
a61e44cc | 315 | item->data = data; |
2287215a | 316 | } |
317 | ||
dd2f0e88 | 318 | int newtListboxAppendEntry(newtComponent co, const char * text, |
a507b3ec | 319 | const void * data) { |
962b92a5 | 320 | struct listbox * li = co->data; |
a61e44cc | 321 | struct items *item; |
322 | ||
323 | if(li->boxItems) { | |
324 | for (item = li->boxItems; item->next != NULL; item = item->next); | |
962b92a5 | 325 | |
a61e44cc | 326 | item = item->next = malloc(sizeof(struct items)); |
327 | } else { | |
328 | item = li->boxItems = malloc(sizeof(struct items)); | |
962b92a5 | 329 | } |
330 | ||
913d0524 | 331 | if (!li->userHasSetWidth && text && (strlen(text) > li->curWidth)) |
332 | updateWidth(co, li, strlen(text)); | |
a61e44cc | 333 | |
a507b3ec | 334 | item->text = strdup(text); item->data = data; item->next = NULL; |
46263d9e | 335 | item->isSelected = 0; |
336 | ||
0bf47501 | 337 | if (li->grow) |
9b1b15f5 | 338 | co->height++, li->curHeight++; |
962b92a5 | 339 | li->numItems++; |
a61e44cc | 340 | |
a507b3ec | 341 | return 0; |
a61e44cc | 342 | } |
343 | ||
d4109c37 | 344 | int newtListboxInsertEntry(newtComponent co, const char * text, |
a507b3ec | 345 | const void * data, void * key) { |
a61e44cc | 346 | struct listbox * li = co->data; |
347 | struct items *item, *t; | |
962b92a5 | 348 | |
a61e44cc | 349 | if (li->boxItems) { |
a507b3ec | 350 | if (key) { |
351 | item = li->boxItems; | |
352 | while (item && item->data != key) item = item->next; | |
353 | ||
354 | if (!item) return 1; | |
355 | ||
aed35dda | 356 | t = item->next; |
357 | item = item->next = malloc(sizeof(struct items)); | |
358 | item->next = t; | |
359 | } else { | |
360 | t = li->boxItems; | |
361 | item = li->boxItems = malloc(sizeof(struct items)); | |
362 | item->next = t; | |
363 | } | |
a507b3ec | 364 | } else if (key) { |
365 | return 1; | |
a61e44cc | 366 | } else { |
367 | item = li->boxItems = malloc(sizeof(struct items)); | |
368 | item->next = NULL; | |
369 | } | |
370 | ||
913d0524 | 371 | if (!li->userHasSetWidth && text && (strlen(text) > li->curWidth)) |
372 | updateWidth(co, li, strlen(text)); | |
a61e44cc | 373 | |
a507b3ec | 374 | item->text = strdup(text?text:"(null)"); item->data = data; |
46263d9e | 375 | item->isSelected = 0; |
376 | ||
b9523497 | 377 | if (li->sb) |
aa564c1d | 378 | li->sb->left = co->left + co->width - li->bdxAdjust - 1; |
a61e44cc | 379 | li->numItems++; |
46263d9e | 380 | |
913d0524 | 381 | listboxDraw(co); |
a61e44cc | 382 | |
a507b3ec | 383 | return 0; |
962b92a5 | 384 | } |
385 | ||
a507b3ec | 386 | int newtListboxDeleteEntry(newtComponent co, void * key) { |
962b92a5 | 387 | struct listbox * li = co->data; |
a507b3ec | 388 | int widest = 0, t; |
a880525e | 389 | struct items *item, *item2 = NULL; |
a507b3ec | 390 | int num; |
aed35dda | 391 | |
4a93351d | 392 | if (li->boxItems == NULL || li->numItems <= 0) |
393 | return 0; | |
a61e44cc | 394 | |
a507b3ec | 395 | num = 0; |
a61e44cc | 396 | |
a507b3ec | 397 | item2 = NULL, item = li->boxItems; |
398 | while (item && item->data != key) { | |
399 | item2 = item; | |
400 | item = item->next; | |
401 | num++; | |
402 | } | |
a61e44cc | 403 | |
a507b3ec | 404 | if (!item) |
405 | return -1; | |
a61e44cc | 406 | |
a507b3ec | 407 | if (item2) |
a61e44cc | 408 | item2->next = item->next; |
a507b3ec | 409 | else |
410 | li->boxItems = item->next; | |
411 | ||
412 | free(item->text); | |
a61e44cc | 413 | free(item); |
414 | li->numItems--; | |
a507b3ec | 415 | |
416 | if (!li->userHasSetWidth) { | |
417 | widest = 0; | |
418 | for (item = li->boxItems; item != NULL; item = item->next) | |
419 | if ((t = strlen(item->text)) > widest) widest = t; | |
420 | } | |
421 | ||
422 | if (li->currItem >= num) | |
aed35dda | 423 | li->currItem--; |
a61e44cc | 424 | |
913d0524 | 425 | if (!li->userHasSetWidth) { |
426 | updateWidth(co, li, widest); | |
babcb349 | 427 | } |
a61e44cc | 428 | |
913d0524 | 429 | listboxDraw(co); |
962b92a5 | 430 | |
a507b3ec | 431 | return 0; |
962b92a5 | 432 | } |
433 | ||
49a541f2 | 434 | void newtListboxClear(newtComponent co) |
435 | { | |
436 | struct listbox * li; | |
437 | struct items *anitem, *nextitem; | |
438 | if(co == NULL || (li = co->data) == NULL) | |
439 | return; | |
440 | for(anitem = li->boxItems; anitem != NULL; anitem = nextitem) { | |
441 | nextitem = anitem->next; | |
a507b3ec | 442 | free(anitem->text); |
49a541f2 | 443 | free(anitem); |
444 | } | |
445 | li->numItems = li->numSelected = li->currItem = li->startShowItem = 0; | |
446 | li->boxItems = NULL; | |
913d0524 | 447 | if (!li->userHasSetWidth) |
448 | updateWidth(co, li, 5); | |
49a541f2 | 449 | } |
450 | ||
a61e44cc | 451 | /* If you don't want to get back the text, pass in NULL for the ptr-ptr. Same |
452 | goes for the data. */ | |
453 | void newtListboxGetEntry(newtComponent co, int num, char **text, void **data) { | |
962b92a5 | 454 | struct listbox * li = co->data; |
a61e44cc | 455 | int i; |
456 | struct items *item; | |
457 | ||
458 | if (!li->boxItems || num >= li->numItems) { | |
459 | if(text) | |
460 | *text = NULL; | |
461 | if(data) | |
462 | *data = NULL; | |
463 | return; | |
464 | } | |
465 | ||
466 | i = 0; | |
467 | item = li->boxItems; | |
468 | while (item && i < num) { | |
469 | i++, item = item->next; | |
470 | } | |
471 | ||
472 | if (item) { | |
473 | if (text) | |
a507b3ec | 474 | *text = item->text; |
a61e44cc | 475 | if (data) |
d4109c37 | 476 | *data = (void *)item->data; |
a61e44cc | 477 | } |
478 | } | |
479 | ||
480 | static void listboxDraw(newtComponent co) | |
481 | { | |
482 | struct listbox * li = co->data; | |
483 | struct items *item; | |
484 | int i, j; | |
485 | ||
913d0524 | 486 | if (!co->isMapped) return ; |
c6e478c2 | 487 | |
dd2f0e88 | 488 | if(li->flags & NEWT_FLAG_BORDER) { |
69f73704 | 489 | if(li->isActive) |
490 | SLsmg_set_color(NEWT_COLORSET_ACTLISTBOX); | |
491 | else | |
492 | SLsmg_set_color(NEWT_COLORSET_LISTBOX); | |
493 | ||
913d0524 | 494 | newtDrawBox(co->left, co->top, co->width, co->height, 0); |
69f73704 | 495 | } |
0b38669d | 496 | |
aa564c1d | 497 | if(li->sb) |
498 | li->sb->ops->draw(li->sb); | |
499 | ||
69f73704 | 500 | SLsmg_set_color(NEWT_COLORSET_LISTBOX); |
501 | ||
a61e44cc | 502 | for(i = 0, item = li->boxItems; item != NULL && i < li->startShowItem; |
503 | i++, item = item->next); | |
504 | ||
505 | j = i; | |
a61e44cc | 506 | |
913d0524 | 507 | for (i = 0; item != NULL && i < li->curHeight; i++, item = item->next) { |
a507b3ec | 508 | if (!item->text) continue; |
a61e44cc | 509 | |
913d0524 | 510 | newtGotorc(co->top + i + li->bdyAdjust, co->left + li->bdxAdjust); |
46263d9e | 511 | if(j + i == li->currItem) { |
512 | if(item->isSelected) | |
513 | SLsmg_set_color(NEWT_COLORSET_ACTSELLISTBOX); | |
514 | else | |
515 | SLsmg_set_color(NEWT_COLORSET_ACTLISTBOX); | |
516 | } else if(item->isSelected) | |
517 | SLsmg_set_color(NEWT_COLORSET_SELLISTBOX); | |
518 | else | |
519 | SLsmg_set_color(NEWT_COLORSET_LISTBOX); | |
520 | ||
a507b3ec | 521 | SLsmg_write_nstring(item->text, li->curWidth); |
a61e44cc | 522 | |
a61e44cc | 523 | } |
0b38669d | 524 | newtGotorc(co->top + (li->currItem - li->startShowItem), co->left); |
a61e44cc | 525 | } |
526 | ||
527 | static struct eventResult listboxEvent(newtComponent co, struct event ev) { | |
2287215a | 528 | struct eventResult er; |
a61e44cc | 529 | struct listbox * li = co->data; |
2287215a | 530 | |
a61e44cc | 531 | er.result = ER_IGNORED; |
532 | ||
0b38669d | 533 | if(ev.when == EV_EARLY || ev.when == EV_LATE) { |
534 | return er; | |
535 | } | |
536 | ||
a61e44cc | 537 | switch(ev.event) { |
538 | case EV_KEYPRESS: | |
539 | if (!li->isActive) break; | |
540 | ||
541 | switch(ev.u.key) { | |
46263d9e | 542 | case ' ': |
543 | if(!(li->flags & NEWT_FLAG_MULTIPLE)) break; | |
dd2f0e88 | 544 | newtListboxSelectItem(co, li->boxItems[li->currItem].data, |
545 | NEWT_FLAGS_TOGGLE); | |
69bf2308 | 546 | er.result = ER_SWALLOWED; |
547 | /* We don't break here, because it is cool to be able to | |
548 | hold space to select a bunch of items in a list at once */ | |
549 | ||
550 | case NEWT_KEY_DOWN: | |
551 | if(li->numItems <= 0) break; | |
552 | if(li->currItem < li->numItems - 1) { | |
553 | li->currItem++; | |
913d0524 | 554 | if(li->currItem > (li->startShowItem + li->curHeight - 1)) { |
555 | li->startShowItem = li->currItem - li->curHeight + 1; | |
556 | if(li->startShowItem + li->curHeight > li->numItems) | |
557 | li->startShowItem = li->numItems - li->curHeight; | |
69bf2308 | 558 | } |
559 | if(li->sb) | |
560 | newtScrollbarSet(li->sb, li->currItem + 1, li->numItems); | |
561 | listboxDraw(co); | |
562 | } | |
563 | if(co->callback) co->callback(co, co->callbackData); | |
46263d9e | 564 | er.result = ER_SWALLOWED; |
565 | break; | |
566 | ||
a61e44cc | 567 | case NEWT_KEY_ENTER: |
4e9c4bb9 | 568 | if(li->numItems <= 0) break; |
569 | if(li->flags & NEWT_FLAG_RETURNEXIT) | |
a61e44cc | 570 | er.result = ER_EXITFORM; |
571 | break; | |
572 | ||
573 | case NEWT_KEY_UP: | |
4e9c4bb9 | 574 | if(li->numItems <= 0) break; |
a61e44cc | 575 | if(li->currItem > 0) { |
576 | li->currItem--; | |
577 | if(li->currItem < li->startShowItem) | |
578 | li->startShowItem = li->currItem; | |
0bf47501 | 579 | if(li->sb) |
580 | newtScrollbarSet(li->sb, li->currItem + 1, li->numItems); | |
a61e44cc | 581 | listboxDraw(co); |
582 | } | |
f37450e9 | 583 | if(co->callback) co->callback(co, co->callbackData); |
a61e44cc | 584 | er.result = ER_SWALLOWED; |
585 | break; | |
586 | ||
a61e44cc | 587 | case NEWT_KEY_PGUP: |
4e9c4bb9 | 588 | if(li->numItems <= 0) break; |
913d0524 | 589 | li->startShowItem -= li->curHeight - 1; |
4e9c4bb9 | 590 | if(li->startShowItem < 0) |
591 | li->startShowItem = 0; | |
913d0524 | 592 | li->currItem -= li->curHeight - 1; |
4e9c4bb9 | 593 | if(li->currItem < 0) |
594 | li->currItem = 0; | |
595 | newtListboxRealSetCurrent(co); | |
a61e44cc | 596 | er.result = ER_SWALLOWED; |
597 | break; | |
598 | ||
599 | case NEWT_KEY_PGDN: | |
4e9c4bb9 | 600 | if(li->numItems <= 0) break; |
913d0524 | 601 | li->startShowItem += li->curHeight; |
602 | if(li->startShowItem > (li->numItems - li->curHeight)) { | |
603 | li->startShowItem = li->numItems - li->curHeight; | |
4e9c4bb9 | 604 | } |
913d0524 | 605 | li->currItem += li->curHeight; |
4e9c4bb9 | 606 | if(li->currItem > li->numItems) { |
607 | li->currItem = li->numItems - 1; | |
608 | } | |
609 | newtListboxRealSetCurrent(co); | |
a61e44cc | 610 | er.result = ER_SWALLOWED; |
611 | break; | |
f37450e9 | 612 | |
3a779f2f | 613 | case NEWT_KEY_HOME: |
4e9c4bb9 | 614 | if(li->numItems <= 0) break; |
3a779f2f | 615 | newtListboxSetCurrent(co, 0); |
616 | er.result = ER_SWALLOWED; | |
617 | break; | |
f37450e9 | 618 | |
3a779f2f | 619 | case NEWT_KEY_END: |
4e9c4bb9 | 620 | if(li->numItems <= 0) break; |
ae5aa3ac | 621 | li->startShowItem = li->numItems - li->curHeight; |
50c7eaa1 | 622 | if(li->startShowItem < 0) |
623 | li->startShowItem = 0; | |
ae5aa3ac | 624 | li->currItem = li->numItems - 1; |
625 | newtListboxRealSetCurrent(co); | |
3a779f2f | 626 | er.result = ER_SWALLOWED; |
627 | break; | |
a61e44cc | 628 | default: |
629 | /* keeps gcc quiet */ | |
630 | } | |
631 | break; | |
632 | ||
633 | case EV_FOCUS: | |
a61e44cc | 634 | li->isActive = 1; |
0b38669d | 635 | listboxDraw(co); |
a61e44cc | 636 | er.result = ER_SWALLOWED; |
637 | break; | |
638 | ||
639 | case EV_UNFOCUS: | |
640 | li->isActive = 0; | |
3a779f2f | 641 | listboxDraw(co); |
a61e44cc | 642 | er.result = ER_SWALLOWED; |
643 | break; | |
2287215a | 644 | } |
962b92a5 | 645 | |
a61e44cc | 646 | return er; |
962b92a5 | 647 | } |
648 | ||
649 | static void listboxDestroy(newtComponent co) { | |
650 | struct listbox * li = co->data; | |
a61e44cc | 651 | struct items * item, * nextitem; |
652 | ||
653 | nextitem = item = li->boxItems; | |
654 | ||
655 | while (item != NULL) { | |
656 | nextitem = item->next; | |
a507b3ec | 657 | free(item->text); |
a61e44cc | 658 | free(item); |
659 | item = nextitem; | |
660 | } | |
962b92a5 | 661 | |
962b92a5 | 662 | free(li); |
663 | free(co); | |
664 | } | |
a61e44cc | 665 |