Added WMGetPopUpButtonItemEnabled() and WMGetPopUpButtonEnabled() functions.
[wmaker-crm.git] / WINGs / wpopupbutton.c
blob5f407a67b13bc36584008a07dcebab282ad07aa0
5 #include "WINGsP.h"
7 typedef struct ItemList {
8 char *text;
9 struct ItemList *nextPtr;
10 unsigned int disabled:1;
11 } ItemList;
14 typedef struct W_PopUpButton {
15 W_Class widgetClass;
16 WMView *view;
18 void *clientData;
19 WMAction *action;
21 char *caption;
23 ItemList *items;
24 short itemCount;
26 short selectedItemIndex;
28 short highlightedItem;
30 ItemList *selectedItem; /* selected item if it is a menu btn */
32 WMView *menuView; /* override redirect popup menu */
34 WMHandlerID timer; /* for autoscroll */
36 /**/
37 int scrollStartY; /* for autoscroll */
39 struct {
40 unsigned int pullsDown:1;
42 unsigned int configured:1;
44 unsigned int insideMenu:1;
46 unsigned int enabled:1;
48 } flags;
49 } PopUpButton;
52 #define MENU_BLINK_DELAY 60000
53 #define MENU_BLINK_COUNT 2
55 #define SCROLL_DELAY 10
58 W_ViewProcedureTable _PopUpButtonViewProcedures = {
59 NULL,
60 NULL,
61 NULL
65 #define DEFAULT_WIDTH 60
66 #define DEFAULT_HEIGHT 20
67 #define DEFAULT_CAPTION ""
70 static void destroyPopUpButton(PopUpButton *bPtr);
71 static void paintPopUpButton(PopUpButton *bPtr);
73 static void handleEvents(XEvent *event, void *data);
74 static void handleActionEvents(XEvent *event, void *data);
76 static void resizeMenu(PopUpButton *bPtr);
79 WMPopUpButton*
80 WMCreatePopUpButton(WMWidget *parent)
82 PopUpButton *bPtr;
83 W_Screen *scr = W_VIEW(parent)->screen;
86 bPtr = wmalloc(sizeof(PopUpButton));
87 memset(bPtr, 0, sizeof(PopUpButton));
89 bPtr->widgetClass = WC_PopUpButton;
91 bPtr->view = W_CreateView(W_VIEW(parent));
92 if (!bPtr->view) {
93 free(bPtr);
94 return NULL;
96 bPtr->view->self = bPtr;
98 WMCreateEventHandler(bPtr->view, ExposureMask|StructureNotifyMask
99 |ClientMessageMask, handleEvents, bPtr);
102 W_ResizeView(bPtr->view, DEFAULT_WIDTH, DEFAULT_HEIGHT);
103 bPtr->caption = wstrdup(DEFAULT_CAPTION);
105 WMCreateEventHandler(bPtr->view, ButtonPressMask|ButtonReleaseMask,
106 handleActionEvents, bPtr);
108 bPtr->flags.enabled = 1;
110 bPtr->menuView = W_CreateTopView(scr);
111 bPtr->menuView->attribs.override_redirect = True;
112 bPtr->menuView->attribFlags |= CWOverrideRedirect;
114 W_ResizeView(bPtr->menuView, bPtr->view->size.width, 1);
116 WMCreateEventHandler(bPtr->menuView, ButtonPressMask|ButtonReleaseMask
117 |EnterWindowMask|LeaveWindowMask|ButtonMotionMask
118 |ExposureMask, handleActionEvents, bPtr);
120 return bPtr;
124 void
125 WMSetPopUpButtonAction(WMPopUpButton *bPtr, WMAction *action, void *clientData)
127 CHECK_CLASS(bPtr, WC_PopUpButton);
129 bPtr->action = action;
131 bPtr->clientData = clientData;
135 void
136 WMAddPopUpButtonItem(WMPopUpButton *bPtr, char *title)
138 ItemList *itemPtr, *tmp;
140 CHECK_CLASS(bPtr, WC_PopUpButton);
142 itemPtr = wmalloc(sizeof(ItemList));
143 memset(itemPtr, 0, sizeof(ItemList));
144 itemPtr->text = wstrdup(title);
146 /* append item to list */
147 tmp = bPtr->items;
148 if (!tmp)
149 bPtr->items = itemPtr;
150 else {
151 while (tmp->nextPtr!=NULL)
152 tmp = tmp->nextPtr;
153 tmp->nextPtr = itemPtr;
156 bPtr->itemCount++;
158 if (bPtr->menuView && bPtr->menuView->flags.realized)
159 resizeMenu(bPtr);
163 void
164 WMInsertPopUpButtonItem(WMPopUpButton *bPtr, int index, char *title)
166 ItemList *itemPtr;
168 CHECK_CLASS(bPtr, WC_PopUpButton);
170 if (index < 0)
171 index = 0;
172 if (index >= bPtr->itemCount) {
173 WMAddPopUpButtonItem(bPtr, title);
174 return;
177 itemPtr = wmalloc(sizeof(ItemList));
178 memset(itemPtr, 0, sizeof(ItemList));
179 itemPtr->text = wstrdup(title);
181 if (index == 0) {
182 itemPtr->nextPtr = bPtr->items;
183 bPtr->items = itemPtr;
184 } else {
185 ItemList *tmp;
186 int i = index;
188 tmp = bPtr->items;
189 /* insert item in list */
190 while (--i > 0) {
191 tmp = tmp->nextPtr;
193 itemPtr->nextPtr = tmp->nextPtr;
194 tmp->nextPtr = itemPtr;
197 bPtr->itemCount++;
199 /* if there is an selected item, update it's index to match the new
200 * position */
201 if (index < bPtr->selectedItemIndex)
202 bPtr->selectedItemIndex++;
204 if (bPtr->menuView && bPtr->menuView->flags.realized)
205 resizeMenu(bPtr);
209 void
210 WMRemovePopUpButtonItem(WMPopUpButton *bPtr, int index)
212 ItemList *tmp;
214 CHECK_CLASS(bPtr, WC_PopUpButton);
216 if (index < 0 || index >= bPtr->itemCount)
217 return;
220 if (index == 0) {
221 free(bPtr->items->text);
222 tmp = bPtr->items->nextPtr;
223 free(bPtr->items);
224 bPtr->items = tmp;
225 } else {
226 ItemList *next;
227 int i = index;
229 tmp = bPtr->items;
230 while (--i > 0)
231 tmp = tmp->nextPtr;
232 next = tmp->nextPtr->nextPtr;
234 free(tmp->nextPtr->text);
235 free(tmp->nextPtr);
237 tmp->nextPtr = next;
240 bPtr->itemCount--;
242 if (bPtr->selectedItem!=NULL && !bPtr->flags.pullsDown) {
243 if (index < bPtr->selectedItemIndex)
244 bPtr->selectedItemIndex--;
245 else if (index == bPtr->selectedItemIndex) {
246 /* reselect first item if the removed item is the
247 * selected one */
248 bPtr->selectedItem = bPtr->items;
249 bPtr->selectedItemIndex = 0;
250 if (bPtr->view->flags.mapped)
251 paintPopUpButton(bPtr);
255 if (bPtr->menuView && bPtr->menuView->flags.realized)
256 resizeMenu(bPtr);
260 void
261 WMSetPopUpButtonEnabled(WMPopUpButton *bPtr, Bool flag)
263 bPtr->flags.enabled = flag;
264 if (bPtr->view->flags.mapped)
265 paintPopUpButton(bPtr);
269 Bool
270 WMGetPopUpButtonEnabled(WMPopUpButton *bPtr)
272 return bPtr->flags.enabled;
276 void
277 WMSetPopUpButtonSelectedItem(WMPopUpButton *bPtr, int index)
279 ItemList *itemPtr = bPtr->items;
280 int i = index;
282 if (index < 0) {
283 bPtr->selectedItem = NULL;
284 if (bPtr->view->flags.mapped)
285 paintPopUpButton(bPtr);
286 return;
289 while (i-- > 0) {
290 itemPtr = itemPtr->nextPtr;
292 bPtr->selectedItem = itemPtr;
293 bPtr->selectedItemIndex = index;
295 if (bPtr->view->flags.mapped)
296 paintPopUpButton(bPtr);
300 WMGetPopUpButtonSelectedItem(WMPopUpButton *bPtr)
302 if (!bPtr->flags.pullsDown && bPtr->selectedItem==NULL)
303 return -1;
304 else
305 return bPtr->selectedItemIndex;
309 void
310 WMSetPopUpButtonText(WMPopUpButton *bPtr, char *text)
312 if (bPtr->caption)
313 free(bPtr->caption);
314 if (text)
315 bPtr->caption = wstrdup(text);
316 else
317 bPtr->caption = NULL;
318 if (bPtr->view->flags.realized) {
319 if (bPtr->flags.pullsDown || bPtr->selectedItemIndex < 0) {
320 paintPopUpButton(bPtr);
327 void
328 WMSetPopUpButtonItemEnabled(WMPopUpButton *bPtr, int index, Bool flag)
330 int i;
331 ItemList *item = bPtr->items;
333 if (index < 0 || index >= bPtr->itemCount)
334 return;
336 for (i = 0; i<index; i++)
337 item=item->nextPtr;
339 item->disabled = !flag;
343 Bool
344 WMGetPopUpButtonItemEnabled(WMPopUpButton *bPtr, int index)
346 int i;
347 ItemList *item = bPtr->items;
349 if (index < 0 || index >= bPtr->itemCount)
350 return False;
352 for (i = 0; i<index; i++)
353 item=item->nextPtr;
355 return !item->disabled;
359 void
360 WMSetPopUpButtonPullsDown(WMPopUpButton *bPtr, Bool flag)
362 bPtr->flags.pullsDown = flag;
363 if (!flag) {
364 /* This code causes bugs. It should not select any item,
365 * since it was not asked to. -Dan
366 bPtr->selectedItem = bPtr->items;
367 if (bPtr->selectedItem)
368 bPtr->selectedItemIndex = 0;
369 else
370 bPtr->selectedItemIndex = -1;
372 bPtr->selectedItem = NULL;
373 /* the drawing routine, still draws things wrong if we put
374 * the index to -1 (i.e. not selected).
375 * Find out why. -Dan */
376 bPtr->selectedItemIndex = 0;
377 } else
378 bPtr->selectedItemIndex = -1;
380 if (bPtr->view->flags.mapped)
381 paintPopUpButton(bPtr);
386 WMGetPopUpButtonNumberOfItems(WMPopUpButton *bPtr)
388 return bPtr->itemCount;
392 char*
393 WMGetPopUpButtonItem(WMPopUpButton *bPtr, int index)
395 ItemList *itemPtr = bPtr->items;
397 if ((index < 0) || (index >= bPtr->itemCount))
398 return NULL;
400 while (index-->0)
401 itemPtr = itemPtr->nextPtr;
403 return itemPtr->text;
407 static void
408 paintPopUpButton(PopUpButton *bPtr)
410 W_Screen *scr = bPtr->view->screen;
411 char *caption;
412 Pixmap pixmap;
415 if (bPtr->flags.pullsDown) {
416 caption = bPtr->caption;
417 } else {
418 if (bPtr->selectedItem == NULL) {
419 /* if no item selected, show the caption */
420 caption = bPtr->caption;
421 } else {
422 caption = bPtr->selectedItem->text;
426 pixmap = XCreatePixmap(scr->display, bPtr->view->window,
427 bPtr->view->size.width, bPtr->view->size.height,
428 scr->depth);
429 XFillRectangle(scr->display, pixmap, WMColorGC(scr->gray), 0, 0,
430 bPtr->view->size.width, bPtr->view->size.height);
432 W_DrawRelief(scr, pixmap, 0, 0, bPtr->view->size.width,
433 bPtr->view->size.height, WRRaised);
435 if (caption) {
436 W_PaintText(bPtr->view, pixmap, scr->normalFont, 6,
437 (bPtr->view->size.height-WMFontHeight(scr->normalFont))/2,
438 bPtr->view->size.width, WALeft,
439 bPtr->flags.enabled ? WMColorGC(scr->black) : WMColorGC(scr->darkGray),
440 False, caption, strlen(caption));
443 if (bPtr->flags.pullsDown) {
444 XCopyArea(scr->display, scr->pullDownIndicator->pixmap,
445 pixmap, scr->copyGC, 0, 0, scr->pullDownIndicator->width,
446 scr->pullDownIndicator->height,
447 bPtr->view->size.width-scr->pullDownIndicator->width-4,
448 (bPtr->view->size.height-scr->pullDownIndicator->height)/2);
449 } else {
450 int x, y;
452 x = bPtr->view->size.width - scr->popUpIndicator->width - 4;
453 y = (bPtr->view->size.height-scr->popUpIndicator->height)/2;
455 XSetClipOrigin(scr->display, scr->clipGC, x, y);
456 XSetClipMask(scr->display, scr->clipGC, scr->popUpIndicator->mask);
457 XCopyArea(scr->display, scr->popUpIndicator->pixmap, pixmap,
458 scr->clipGC, 0, 0, scr->popUpIndicator->width,
459 scr->popUpIndicator->height, x, y);
462 XCopyArea(scr->display, pixmap, bPtr->view->window, scr->copyGC, 0, 0,
463 bPtr->view->size.width, bPtr->view->size.height, 0, 0);
465 XFreePixmap(scr->display, pixmap);
470 static void
471 handleEvents(XEvent *event, void *data)
473 PopUpButton *bPtr = (PopUpButton*)data;
475 CHECK_CLASS(data, WC_PopUpButton);
478 switch (event->type) {
479 case Expose:
480 if (event->xexpose.count!=0)
481 break;
482 paintPopUpButton(bPtr);
483 break;
485 case DestroyNotify:
486 destroyPopUpButton(bPtr);
487 break;
493 static void
494 paintMenuEntry(PopUpButton *bPtr, int index, int highlight)
496 W_Screen *scr = bPtr->view->screen;
497 int i;
498 int yo;
499 ItemList *itemPtr;
500 int width, height, itemHeight;
502 itemHeight = bPtr->view->size.height;
503 width = bPtr->view->size.width;
504 height = itemHeight * bPtr->itemCount;
505 yo = (itemHeight - WMFontHeight(scr->normalFont))/2;
507 if (!highlight) {
508 XClearArea(scr->display, bPtr->menuView->window, 0, index*itemHeight,
509 width, itemHeight, False);
510 return;
511 } else if (index < 0 && bPtr->flags.pullsDown) {
512 return;
515 XFillRectangle(scr->display, bPtr->menuView->window, WMColorGC(scr->white),
516 1, index*itemHeight+1, width-3, itemHeight-3);
518 itemPtr = bPtr->items;
519 for (i = 0; i < index; i++)
520 itemPtr = itemPtr->nextPtr;
522 W_DrawRelief(scr, bPtr->menuView->window, 0, index*itemHeight,
523 width, itemHeight, WRRaised);
525 W_PaintText(bPtr->menuView, bPtr->menuView->window, scr->normalFont, 6,
526 index*itemHeight + yo, width, WALeft, WMColorGC(scr->black), False,
527 itemPtr->text, strlen(itemPtr->text));
529 if (!bPtr->flags.pullsDown && index == bPtr->selectedItemIndex) {
530 XCopyArea(scr->display, scr->popUpIndicator->pixmap,
531 bPtr->menuView->window, scr->copyGC, 0, 0,
532 scr->popUpIndicator->width, scr->popUpIndicator->height,
533 width-scr->popUpIndicator->width-4,
534 i*itemHeight+(itemHeight-scr->popUpIndicator->height)/2);
539 Pixmap
540 makeMenuPixmap(PopUpButton *bPtr)
542 Pixmap pixmap;
543 W_Screen *scr = bPtr->view->screen;
544 int i;
545 int yo;
546 ItemList *itemPtr;
547 int width, height, itemHeight;
549 itemHeight = bPtr->view->size.height;
550 width = bPtr->view->size.width;
551 height = itemHeight * bPtr->itemCount;
552 yo = (itemHeight - WMFontHeight(scr->normalFont))/2;
554 pixmap = XCreatePixmap(scr->display, bPtr->view->window, width, height,
555 scr->depth);
557 XFillRectangle(scr->display, pixmap, WMColorGC(scr->gray), 0, 0, width, height);
559 itemPtr = bPtr->items;
560 for (i = 0; i < bPtr->itemCount; i++) {
561 GC gc;
563 W_DrawRelief(scr, pixmap, 0, i*itemHeight, width, itemHeight,
564 WRRaised);
566 if (itemPtr->disabled)
567 gc = WMColorGC(scr->darkGray);
568 else
569 gc = WMColorGC(scr->black);
571 W_PaintText(bPtr->menuView, pixmap, scr->normalFont, 6,
572 i*itemHeight + yo, width, WALeft, gc, False,
573 itemPtr->text, strlen(itemPtr->text));
575 if (!bPtr->flags.pullsDown && i == bPtr->selectedItemIndex) {
576 XCopyArea(scr->display, scr->popUpIndicator->pixmap, pixmap,
577 scr->copyGC, 0, 0, scr->popUpIndicator->width,
578 scr->popUpIndicator->height,
579 width-scr->popUpIndicator->width-4,
580 i*itemHeight+(itemHeight-scr->popUpIndicator->height)/2);
582 itemPtr = itemPtr->nextPtr;
585 return pixmap;
589 static void
590 resizeMenu(PopUpButton *bPtr)
592 int height;
594 height = bPtr->itemCount * bPtr->view->size.height;
595 if (height > 0)
596 W_ResizeView(bPtr->menuView, bPtr->view->size.width, height);
600 static void
601 popUpMenu(PopUpButton *bPtr)
603 W_Screen *scr = bPtr->view->screen;
604 Window dummyW;
605 int x, y;
607 if (!bPtr->menuView->flags.realized) {
608 W_RealizeView(bPtr->menuView);
609 resizeMenu(bPtr);
612 if (bPtr->itemCount < 1)
613 return;
615 XTranslateCoordinates(scr->display, bPtr->view->window, scr->rootWin,
616 0, 0, &x, &y, &dummyW);
618 if (bPtr->flags.pullsDown) {
619 y += bPtr->view->size.height;
620 } else {
621 y -= bPtr->view->size.height*bPtr->selectedItemIndex;
623 W_MoveView(bPtr->menuView, x, y);
625 XSetWindowBackgroundPixmap(scr->display, bPtr->menuView->window,
626 makeMenuPixmap(bPtr));
627 XClearWindow(scr->display, bPtr->menuView->window);
629 W_MapView(bPtr->menuView);
631 bPtr->highlightedItem = 0;
632 if (!bPtr->flags.pullsDown && bPtr->selectedItem != NULL)
633 paintMenuEntry(bPtr, bPtr->selectedItemIndex, True);
637 static void
638 popDownMenu(PopUpButton *bPtr)
640 W_UnmapView(bPtr->menuView);
642 /* free the background pixmap used to draw the menu contents */
643 XSetWindowBackgroundPixmap(bPtr->view->screen->display,
644 bPtr->menuView->window, None);
648 static int
649 itemIsEnabled(PopUpButton *bPtr, int index)
651 ItemList *item = bPtr->items;
653 while (index-- > 0 && item)
654 item = item->nextPtr;
656 return item ? !item->disabled : False;
660 static void
661 autoScroll(void *data)
663 PopUpButton *bPtr = (PopUpButton*)data;
664 int scrHeight = WMWidgetScreen(bPtr)->rootView->size.height;
665 int repeat = 0;
666 int dy = 0;
669 if (bPtr->scrollStartY >= scrHeight-1
670 && bPtr->menuView->pos.y+bPtr->menuView->size.height >= scrHeight-1) {
671 repeat = 1;
673 if (bPtr->menuView->pos.y+bPtr->menuView->size.height-5
674 <= scrHeight - 1) {
675 dy = scrHeight - 1
676 - (bPtr->menuView->pos.y+bPtr->menuView->size.height);
677 } else
678 dy = -5;
680 } else if (bPtr->scrollStartY <= 1 && bPtr->menuView->pos.y < 1) {
681 repeat = 1;
683 if (bPtr->menuView->pos.y+5 > 1)
684 dy = 1 - bPtr->menuView->pos.y;
685 else
686 dy = 5;
689 if (repeat) {
690 int oldItem;
692 W_MoveView(bPtr->menuView, bPtr->menuView->pos.x,
693 bPtr->menuView->pos.y + dy);
695 oldItem = bPtr->highlightedItem;
696 bPtr->highlightedItem = (bPtr->scrollStartY - bPtr->menuView->pos.y)
697 / bPtr->view->size.height;
699 if (oldItem!=bPtr->highlightedItem) {
700 paintMenuEntry(bPtr, oldItem, False);
701 paintMenuEntry(bPtr, bPtr->highlightedItem,
702 itemIsEnabled(bPtr, bPtr->highlightedItem));
705 bPtr->timer = WMAddTimerHandler(SCROLL_DELAY, autoScroll, bPtr);
706 } else {
707 bPtr->timer = NULL;
712 static void
713 handleActionEvents(XEvent *event, void *data)
715 PopUpButton *bPtr = (PopUpButton*)data;
716 int oldItem;
717 int scrHeight = WMWidgetScreen(bPtr)->rootView->size.height;
719 CHECK_CLASS(data, WC_PopUpButton);
721 if (bPtr->itemCount < 1)
722 return;
724 switch (event->type) {
725 /* called for menuView */
726 case Expose:
727 paintMenuEntry(bPtr, bPtr->highlightedItem,
728 itemIsEnabled(bPtr, bPtr->highlightedItem));
729 break;
731 case LeaveNotify:
732 bPtr->flags.insideMenu = 0;
733 if (bPtr->menuView->flags.mapped)
734 paintMenuEntry(bPtr, bPtr->highlightedItem, False);
735 bPtr->highlightedItem = -1;
736 break;
738 case EnterNotify:
739 bPtr->flags.insideMenu = 1;
740 break;
742 case MotionNotify:
743 if (bPtr->flags.insideMenu) {
744 oldItem = bPtr->highlightedItem;
745 bPtr->highlightedItem = event->xmotion.y / bPtr->view->size.height;
746 if (oldItem!=bPtr->highlightedItem) {
747 paintMenuEntry(bPtr, oldItem, False);
748 paintMenuEntry(bPtr, bPtr->highlightedItem,
749 itemIsEnabled(bPtr, bPtr->highlightedItem));
752 if (event->xmotion.y_root >= scrHeight-1
753 || event->xmotion.y_root <= 1) {
754 bPtr->scrollStartY = event->xmotion.y_root;
755 if (!bPtr->timer)
756 autoScroll(bPtr);
757 } else if (bPtr->timer) {
758 WMDeleteTimerHandler(bPtr->timer);
759 bPtr->timer = NULL;
762 break;
764 /* called for bPtr->view */
765 case ButtonPress:
766 if (!bPtr->flags.enabled)
767 break;
769 popUpMenu(bPtr);
770 if (!bPtr->flags.pullsDown) {
771 bPtr->highlightedItem = bPtr->selectedItemIndex;
772 bPtr->flags.insideMenu = 1;
773 } else {
774 bPtr->highlightedItem = -1;
775 bPtr->flags.insideMenu = 0;
777 XGrabPointer(bPtr->view->screen->display, bPtr->menuView->window,
778 False, ButtonReleaseMask|ButtonMotionMask|EnterWindowMask
779 |LeaveWindowMask, GrabModeAsync, GrabModeAsync,
780 None, None, CurrentTime);
781 break;
783 case ButtonRelease:
784 XUngrabPointer(bPtr->view->screen->display, event->xbutton.time);
785 if (!bPtr->flags.pullsDown)
786 popDownMenu(bPtr);
788 if (bPtr->timer) {
789 WMDeleteTimerHandler(bPtr->timer);
790 bPtr->timer = NULL;
793 if (bPtr->flags.insideMenu && bPtr->highlightedItem>=0) {
794 if (itemIsEnabled(bPtr, bPtr->highlightedItem)) {
795 int i;
796 WMSetPopUpButtonSelectedItem(bPtr, bPtr->highlightedItem);
798 if (bPtr->flags.pullsDown) {
799 for (i=0; i<MENU_BLINK_COUNT; i++) {
800 paintMenuEntry(bPtr, bPtr->highlightedItem, False);
801 XSync(bPtr->view->screen->display, 0);
802 wusleep(MENU_BLINK_DELAY);
803 paintMenuEntry(bPtr, bPtr->highlightedItem, True);
804 XSync(bPtr->view->screen->display, 0);
805 wusleep(MENU_BLINK_DELAY);
808 paintMenuEntry(bPtr, bPtr->highlightedItem, False);
809 popDownMenu(bPtr);
810 if (bPtr->action)
811 (*bPtr->action)(bPtr, bPtr->clientData);
814 if (bPtr->menuView->flags.mapped)
815 popDownMenu(bPtr);
816 break;
822 static void
823 destroyPopUpButton(PopUpButton *bPtr)
825 ItemList *itemPtr, *tmp;
827 if (bPtr->timer) {
828 WMDeleteTimerHandler(bPtr->timer);
831 itemPtr = bPtr->items;
832 while (itemPtr!=NULL) {
833 free(itemPtr->text);
834 tmp = itemPtr->nextPtr;
835 free(itemPtr);
836 itemPtr = tmp;
839 if (bPtr->caption)
840 free(bPtr->caption);
842 /* have to destroy explicitly because the popup is a toplevel */
843 W_DestroyView(bPtr->menuView);
845 free(bPtr);