fixed bugs of resized widgets
[wmaker-crm.git] / WINGs / wtabview.c
blob1204f23da024ed3d87c4d89a1ced3879b7c99372
2 #include "WINGsP.h"
5 typedef struct W_TabView {
6 W_Class widgetClass;
7 W_View *view;
9 struct W_TabViewItem **items;
10 int itemCount;
11 int maxItems; /* size of items array, can be increased */
13 int selectedItem;
14 int firstVisible;
16 int visibleTabs;
18 WMFont *font;
20 WMColor *lightGray;
21 WMColor *tabColor;
23 WMTabViewDelegate *delegate;
25 short tabWidth;
26 short tabHeight;
28 struct {
29 WMReliefType relief:4;
30 WMTitlePosition titlePosition:4;
31 WMTabViewType type:2;
33 unsigned tabbed:1;
34 unsigned dontFitAll:1;
35 } flags;
36 } TabView;
43 #define DEFAULT_WIDTH 40
44 #define DEFAULT_HEIGHT 40
46 #define NORMAL_SIDE_OFFSET 8
47 #define BUTTONED_SIDE_OFFSET 20
50 static void destroyTabView(TabView *tPtr);
51 static void paintTabView(TabView *tPtr);
54 static void W_SetTabViewItemParent(WMTabViewItem *item, WMTabView *parent);
56 static void W_DrawLabel(WMTabViewItem *item, Drawable d, WMRect rect);
58 static void W_UnmapTabViewItem(WMTabViewItem *item);
60 static void W_MapTabViewItem(WMTabViewItem *item);
62 static WMView *W_TabViewItemView(WMTabViewItem *item);
64 static void recalcTabWidth(TabView *tPtr);
67 static void didResize(struct W_ViewDelegate*, WMView*);
69 static W_ViewDelegate delegate = {
70 NULL,
71 NULL,
72 didResize,
73 NULL,
74 NULL
80 static void
81 handleEvents(XEvent *event, void *data)
83 TabView *tPtr = (TabView*)data;
85 CHECK_CLASS(data, WC_TabView);
87 switch (event->type) {
88 case Expose:
89 if (event->xexpose.count!=0)
90 break;
91 paintTabView(tPtr);
92 break;
94 case ButtonPress:
96 WMTabViewItem *item = WMTabViewItemAtPoint(tPtr,
97 event->xbutton.x,
98 event->xbutton.y);
99 if (item) {
100 WMSelectTabViewItem(tPtr, item);
101 } else if (tPtr->flags.dontFitAll) {
102 int redraw;
103 if (event->xbutton.x < BUTTONED_SIDE_OFFSET) {
104 if (tPtr->firstVisible > 0) {
105 redraw = 1;
106 tPtr->firstVisible--;
108 } else if (event->xbutton.x - BUTTONED_SIDE_OFFSET
109 > tPtr->visibleTabs*(tPtr->tabWidth-10)) {
111 if (tPtr->firstVisible + tPtr->visibleTabs
112 < tPtr->itemCount) {
113 redraw = 1;
114 tPtr->firstVisible++;
118 if (redraw) {
119 paintTabView(tPtr);
123 break;
125 case DestroyNotify:
126 destroyTabView(tPtr);
127 break;
133 WMTabView*
134 WMCreateTabView(WMWidget *parent)
136 TabView *tPtr;
137 WMScreen *scr = WMWidgetScreen(parent);
139 tPtr = wmalloc(sizeof(TabView));
140 memset(tPtr, 0, sizeof(TabView));
142 tPtr->widgetClass = WC_TabView;
144 tPtr->view = W_CreateView(W_VIEW(parent));
145 if (!tPtr->view) {
146 wfree(tPtr);
147 return NULL;
149 tPtr->view->self = tPtr;
150 tPtr->view->delegate = &delegate;
152 tPtr->lightGray = WMCreateRGBColor(scr, 0xd9d9, 0xd9d9, 0xd9d9, False);
153 tPtr->tabColor = WMCreateRGBColor(scr, 0x8420, 0x8420, 0x8420, False);
155 tPtr->font = WMRetainFont(scr->normalFont);
157 WMCreateEventHandler(tPtr->view, ExposureMask|StructureNotifyMask
158 |ButtonPressMask, handleEvents, tPtr);
160 WMResizeWidget(tPtr, DEFAULT_WIDTH, DEFAULT_HEIGHT);
162 tPtr->tabHeight = WMFontHeight(tPtr->font) + 3;
164 return tPtr;
168 void
169 WMSetTabViewDelegate(WMTabView *tPtr, WMTabViewDelegate *delegate)
171 tPtr->delegate = delegate;
175 WMTabViewItem*
176 WMAddTabViewItemWithView(WMTabView *tPtr, WMView *view, int identifier,
177 char *label)
179 WMTabViewItem *item;
181 item = WMCreateTabViewItemWithIdentifier(identifier);
182 WMSetTabViewItemView(item, view);
183 WMAddItemInTabView(tPtr, item);
184 WMSetTabViewItemLabel(item, label);
186 return item;
190 void
191 WMAddItemInTabView(WMTabView *tPtr, WMTabViewItem *item)
193 WMInsertItemInTabView(tPtr, tPtr->itemCount, item);
197 void
198 WMInsertItemInTabView(WMTabView *tPtr, int index, WMTabViewItem *item)
200 wassertr(W_TabViewItemView(item) != NULL);
202 if (tPtr->maxItems == tPtr->itemCount) {
203 WMTabViewItem **items;
205 items = wrealloc(tPtr->items,
206 sizeof(WMTabViewItem*) * (tPtr->maxItems + 10));
207 memset(&items[tPtr->maxItems], 0, sizeof(WMTabViewItem*) * 10);
208 tPtr->items = items;
209 tPtr->maxItems += 10;
212 if (index > tPtr->itemCount)
213 index = tPtr->itemCount;
215 if (index == 0 && tPtr->items[0]) {
216 W_UnmapTabViewItem(tPtr->items[0]);
219 if (index < tPtr->itemCount) {
220 memmove(&tPtr->items[index + 1], &tPtr->items[index],
221 tPtr->itemCount - index);
224 tPtr->items[index] = item;
226 tPtr->itemCount++;
228 recalcTabWidth(tPtr);
230 W_SetTabViewItemParent(item, tPtr);
232 W_UnmapTabViewItem(item);
234 W_ReparentView(W_TabViewItemView(item), tPtr->view, 1,
235 tPtr->tabHeight + 1);
237 W_ResizeView(W_TabViewItemView(item), tPtr->view->size.width - 3,
238 tPtr->view->size.height - tPtr->tabHeight - 3);
240 if (index == 0) {
241 W_MapTabViewItem(item);
243 if (tPtr->delegate && tPtr->delegate->didChangeNumberOfItems)
244 (*tPtr->delegate->didChangeNumberOfItems)(tPtr->delegate, tPtr);
248 void
249 WMRemoveTabViewItem(WMTabView *tPtr, WMTabViewItem *item)
251 int i;
253 for (i = 0; i < tPtr->itemCount; i++) {
254 if (tPtr->items[i] == item) {
255 if (i < tPtr->itemCount - 1)
256 memmove(&tPtr->items[i], &tPtr->items[i + 1],
257 tPtr->itemCount - i - 1);
258 else
259 tPtr->items[i] = NULL;
261 W_SetTabViewItemParent(item, NULL);
263 tPtr->itemCount--;
264 break;
267 if (tPtr->delegate && tPtr->delegate->didChangeNumberOfItems)
268 (*tPtr->delegate->didChangeNumberOfItems)(tPtr->delegate, tPtr);
273 static Bool
274 isInside(int x, int y, int width, int height, int px, int py)
276 if (py >= y + height - 3 && py <= y + height
277 && px >= x + py - (y + height - 3)
278 && px <= x + width - (py - (y + height - 3))) {
280 return True;
282 if (py >= y + 3 && py < y + height - 3
283 && px >= x + 3 + ((y + 3) - py)*3/7
284 && px <= x + width - 3 - ((y + 3) - py)*3/7) {
286 return True;
288 if (py >= y && py < y + 3
289 && px >= x + 7 + py - y
290 && px <= x + width - 7 - (py - y)) {
292 return True;
294 return False;
298 WMTabViewItem*
299 WMTabViewItemAtPoint(WMTabView *tPtr, int x, int y)
301 int i;
302 int offset;
303 int count = tPtr->visibleTabs;
304 int first = tPtr->firstVisible;
306 if (tPtr->flags.dontFitAll) {
307 offset = BUTTONED_SIDE_OFFSET;
309 i = tPtr->selectedItem - tPtr->firstVisible;
310 if (i >= 0 && i < tPtr->visibleTabs
311 && isInside(offset + (tPtr->tabWidth-10)*i, 0, tPtr->tabWidth,
312 tPtr->tabHeight, x, y)) {
313 return tPtr->items[tPtr->selectedItem];
315 } else {
316 offset = NORMAL_SIDE_OFFSET;
318 i = tPtr->selectedItem;
319 if (isInside(offset + (tPtr->tabWidth-10)*i, 0, tPtr->tabWidth,
320 tPtr->tabHeight, x, y)) {
321 return tPtr->items[i];
325 for (i = 0; i < count; i++) {
326 if (isInside(offset + (tPtr->tabWidth-10)*i, 0, tPtr->tabWidth,
327 tPtr->tabHeight, x, y)) {
328 return tPtr->items[i+first];
331 return NULL;
335 void
336 WMSelectFirstTabViewItem(WMTabView *tPtr)
338 WMSelectTabViewItemAtIndex(tPtr, 0);
342 void
343 WMSelectLastTabViewItem(WMTabView *tPtr)
345 WMSelectTabViewItemAtIndex(tPtr, tPtr->itemCount);
349 void
350 WMSelectNextTabViewItem(WMTabView *tPtr)
352 WMSelectTabViewItemAtIndex(tPtr, tPtr->selectedItem + 1);
356 void
357 WMSelectPreviousTabViewItem(WMTabView *tPtr)
359 WMSelectTabViewItemAtIndex(tPtr, tPtr->selectedItem - 1);
363 WMTabViewItem*
364 WMGetSelectedTabViewItem(WMTabView *tPtr)
366 return tPtr->items[tPtr->selectedItem];
370 void
371 WMSelectTabViewItem(WMTabView *tPtr, WMTabViewItem *item)
373 int i;
375 for (i = 0; i < tPtr->itemCount; i++) {
376 if (tPtr->items[i] == item) {
377 WMSelectTabViewItemAtIndex(tPtr, i);
378 break;
384 void
385 WMSelectTabViewItemAtIndex(WMTabView *tPtr, int index)
387 WMTabViewItem *item;
389 if (index == tPtr->selectedItem)
390 return;
392 if (index < 0)
393 index = 0;
394 else if (index >= tPtr->itemCount)
395 index = tPtr->itemCount - 1;
397 item = tPtr->items[tPtr->selectedItem];
399 if (tPtr->delegate && tPtr->delegate->shouldSelectItem)
400 if (!(*tPtr->delegate->shouldSelectItem)(tPtr->delegate, tPtr,
401 tPtr->items[index]))
402 return;
404 if (tPtr->delegate && tPtr->delegate->willSelectItem)
405 (*tPtr->delegate->willSelectItem)(tPtr->delegate, tPtr,
406 tPtr->items[index]);
408 W_UnmapTabViewItem(item);
411 item = tPtr->items[index];
413 W_MapTabViewItem(item);
415 tPtr->selectedItem = index;
417 if (tPtr->delegate && tPtr->delegate->didSelectItem)
418 (*tPtr->delegate->didSelectItem)(tPtr->delegate, tPtr,
419 tPtr->items[index]);
423 static void
424 recalcTabWidth(TabView *tPtr)
426 int i;
427 int twidth = W_VIEW(tPtr)->size.width;
428 int width;
430 tPtr->tabWidth = 0;
431 for (i = 0; i < tPtr->itemCount; i++) {
432 char *str = WMGetTabViewItemLabel(tPtr->items[i]);
434 if (str) {
435 width = WMWidthOfString(tPtr->font, str, strlen(str));
436 if (width > tPtr->tabWidth)
437 tPtr->tabWidth = width;
440 tPtr->tabWidth += 30;
441 if ((tPtr->tabWidth + 2) * tPtr->itemCount > twidth - 2*NORMAL_SIDE_OFFSET) {
442 tPtr->flags.dontFitAll = 1;
443 tPtr->firstVisible = 0;
444 tPtr->visibleTabs = (twidth - 2*BUTTONED_SIDE_OFFSET) / (tPtr->tabWidth-10);
445 } else {
446 tPtr->flags.dontFitAll = 0;
447 tPtr->firstVisible = 0;
448 tPtr->visibleTabs = tPtr->itemCount;
453 static void
454 drawRelief(W_Screen *scr, Drawable d, int x, int y, unsigned int width,
455 unsigned int height)
457 Display *dpy = scr->display;
458 GC bgc = WMColorGC(scr->black);
459 GC wgc = WMColorGC(scr->white);
460 GC dgc = WMColorGC(scr->darkGray);
462 XDrawLine(dpy, d, wgc, x, y, x, y+height-1);
464 XDrawLine(dpy, d, bgc, x, y+height-1, x+width-1, y+height-1);
465 XDrawLine(dpy, d, dgc, x+1, y+height-2, x+width-2, y+height-2);
467 XDrawLine(dpy, d, bgc, x+width-1, y, x+width-1, y+height-1);
468 XDrawLine(dpy, d, dgc, x+width-2, y+1, x+width-2, y+height-2);
472 static void
473 drawTab(TabView *tPtr, Drawable d, int x, int y,
474 unsigned width, unsigned height, Bool selected)
476 WMScreen *scr = W_VIEW(tPtr)->screen;
477 Display *dpy = scr->display;
478 GC white = WMColorGC(selected ? scr->white : tPtr->lightGray);
479 GC black = WMColorGC(scr->black);
480 GC dark = WMColorGC(scr->darkGray);
481 GC light = WMColorGC(scr->gray);
482 XPoint trap[8];
484 trap[0].x = x + (selected ? 0 : 1);
485 trap[0].y = y + height - (selected ? 0 : 1);
487 trap[1].x = x + 3;
488 trap[1].y = y + height - 3;
490 trap[2].x = x + 10 - 3;
491 trap[2].y = y + 3;
493 trap[3].x = x + 10;
494 trap[3].y = y;
496 trap[4].x = x + width - 10;
497 trap[4].y = y;
499 trap[5].x = x + width - 10 + 3;
500 trap[5].y = y + 3;
502 trap[6].x = x + width - 3;
503 trap[6].y = y + height - 3;
505 trap[7].x = x + width - (selected ? 0 : 1);
506 trap[7].y = y + height - (selected ? 0 : 1);
508 XFillPolygon(dpy, d, selected ? light : WMColorGC(tPtr->tabColor), trap, 8,
509 Convex, CoordModeOrigin);
511 XDrawLine(dpy, d, white, trap[0].x, trap[0].y, trap[1].x, trap[1].y);
512 XDrawLine(dpy, d, white, trap[1].x, trap[1].y, trap[2].x, trap[2].y);
513 XDrawLine(dpy, d, white, trap[2].x, trap[2].y, trap[3].x, trap[3].y);
514 XDrawLine(dpy, d, white, trap[3].x, trap[3].y, trap[4].x, trap[4].y);
515 XDrawLine(dpy, d, dark, trap[4].x, trap[4].y, trap[5].x, trap[5].y);
516 XDrawLine(dpy, d, black, trap[5].x, trap[5].y, trap[6].x, trap[6].y);
517 XDrawLine(dpy, d, black, trap[6].x, trap[6].y, trap[7].x, trap[7].y);
519 XDrawLine(dpy, d, selected ? light : WMColorGC(scr->white),
520 trap[0].x, trap[0].y, trap[7].x, trap[7].y);
524 static void
525 paintDot(TabView *tPtr, Drawable d, int x, int y)
527 WMScreen *scr = W_VIEW(tPtr)->screen;
528 Display *dpy = scr->display;
529 GC white = WMColorGC(scr->white);
530 GC black = WMColorGC(scr->black);
532 XFillRectangle(dpy, d, black, x, y, 2, 2);
533 XDrawPoint(dpy, d, white, x, y);
538 static void
539 paintTabView(TabView *tPtr)
541 Pixmap buffer;
542 WMScreen *scr = W_VIEW(tPtr)->screen;
543 Display *dpy = scr->display;
544 GC white = WMColorGC(scr->white);
545 int i;
546 WMRect rect;
548 if (tPtr->flags.type == WTTopTabsBevelBorder) {
549 int count = tPtr->visibleTabs;
550 int first = tPtr->firstVisible;
551 int offs;
552 int moreAtLeft;
553 int moreAtRight;
554 int selectedIsVisible;
556 buffer = XCreatePixmap(dpy, W_VIEW(tPtr)->window,
557 W_VIEW(tPtr)->size.width, tPtr->tabHeight,
558 W_VIEW(tPtr)->screen->depth);
560 XFillRectangle(dpy, buffer, WMColorGC(W_VIEW(tPtr)->backColor),
561 0, 0, W_VIEW(tPtr)->size.width, tPtr->tabHeight);
563 rect.pos.y = 2;
564 if (tPtr->flags.dontFitAll) {
565 rect.pos.x = 15 + BUTTONED_SIDE_OFFSET;
566 offs = BUTTONED_SIDE_OFFSET;
567 moreAtLeft = first > 0;
568 moreAtRight = (first + count) < tPtr->itemCount;
569 if (tPtr->selectedItem >= first
570 && tPtr->selectedItem < first + count)
571 selectedIsVisible = 1;
572 else
573 selectedIsVisible = 0;
574 } else {
575 rect.pos.x = 15 + NORMAL_SIDE_OFFSET;
576 offs = NORMAL_SIDE_OFFSET;
577 moreAtLeft = 0;
578 moreAtRight = 0;
579 selectedIsVisible = 1;
581 rect.size.width = tPtr->tabWidth;
582 rect.size.height = tPtr->tabHeight;
584 for (i = count - (moreAtRight ? 0 : 1);
585 i >= (moreAtLeft ? -1 : 0); i--) {
586 if (!selectedIsVisible || i != (tPtr->selectedItem-first)) {
587 drawTab(tPtr, buffer, offs + (rect.size.width-10)*i, 0,
588 rect.size.width, rect.size.height, False);
592 if (selectedIsVisible) {
593 drawTab(tPtr, buffer,
594 offs + (rect.size.width-10) * (tPtr->selectedItem - first),
595 0, rect.size.width, rect.size.height, True);
597 XDrawLine(dpy, buffer, white, 0, tPtr->tabHeight - 1,
598 offs, tPtr->tabHeight - 1);
600 XDrawLine(dpy, buffer, white,
601 offs + 10 + (rect.size.width-10) * count,
602 tPtr->tabHeight - 1, W_VIEW(tPtr)->size.width - 1,
603 tPtr->tabHeight - 1);
604 } else {
605 XDrawLine(dpy, buffer, white, 0, tPtr->tabHeight - 1,
606 W_VIEW(tPtr)->size.width, tPtr->tabHeight - 1);
609 for (i = 0; i < count; i++) {
610 W_DrawLabel(tPtr->items[first+i], buffer, rect);
612 rect.pos.x += rect.size.width - 10;
615 if (moreAtLeft) {
616 paintDot(tPtr, buffer, 4, 10);
617 paintDot(tPtr, buffer, 7, 10);
618 paintDot(tPtr, buffer, 10, 10);
620 if (moreAtRight) {
621 int x;
623 x = BUTTONED_SIDE_OFFSET - 5 + tPtr->visibleTabs * (tPtr->tabWidth - 10);
625 x = x + (W_VIEW(tPtr)->size.width - x)/2;
627 paintDot(tPtr, buffer, x + 5, 10);
628 paintDot(tPtr, buffer, x + 8, 10);
629 paintDot(tPtr, buffer, x + 11, 10);
632 XCopyArea(dpy, buffer, W_VIEW(tPtr)->window, scr->copyGC, 0, 0,
633 W_VIEW(tPtr)->size.width, tPtr->tabHeight, 0, 0);
635 XFreePixmap(dpy, buffer);
637 switch (tPtr->flags.type) {
638 case WTTopTabsBevelBorder:
639 drawRelief(scr, W_VIEW(tPtr)->window, 0, tPtr->tabHeight - 1,
640 W_VIEW(tPtr)->size.width,
641 W_VIEW(tPtr)->size.height - tPtr->tabHeight + 1);
642 break;
644 case WTNoTabsBevelBorder:
645 W_DrawRelief(scr, W_VIEW(tPtr)->window, 0, 0, W_VIEW(tPtr)->size.width,
646 W_VIEW(tPtr)->size.height, WRRaised);
647 break;
649 case WTNoTabsLineBorder:
650 W_DrawRelief(scr, W_VIEW(tPtr)->window, 0, 0, W_VIEW(tPtr)->size.width,
651 W_VIEW(tPtr)->size.height, WRSimple);
652 break;
654 case WTNoTabsNoBorder:
655 break;
660 static void
661 rearrange(TabView *tPtr)
663 int i;
664 int width, height;
666 recalcTabWidth(tPtr);
668 width = tPtr->view->size.width - 3;
669 height = tPtr->view->size.height - tPtr->tabHeight - 3;
671 for (i = 0; i < tPtr->itemCount; i++) {
672 W_ResizeView(W_TabViewItemView(tPtr->items[i]), width, height);
674 if (W_VIEW_MAPPED(tPtr->view) && W_VIEW_REALIZED(tPtr->view))
675 paintTabView(tPtr);
679 static void
680 didResize(struct W_ViewDelegate *deleg, WMView *view)
682 rearrange(view->self);
686 static void
687 destroyTabView(TabView *tPtr)
689 int i;
691 for (i = 0; i < tPtr->itemCount; i++) {
692 WMSetTabViewItemView(tPtr->items[i], NULL);
693 WMDestroyTabViewItem(tPtr->items[i]);
695 wfree(tPtr->items);
697 WMReleaseColor(tPtr->lightGray);
698 WMReleaseColor(tPtr->tabColor);
699 WMReleaseFont(tPtr->font);
701 wfree(tPtr);
704 /******************************************************************/
707 typedef struct W_TabViewItem {
708 WMTabView *tabView;
710 W_View *view;
712 char *label;
714 int identifier;
716 struct {
717 unsigned visible:1;
718 } flags;
719 } TabViewItem;
722 static void
723 W_SetTabViewItemParent(WMTabViewItem *item, WMTabView *parent)
725 item->tabView = parent;
729 static void
730 W_DrawLabel(WMTabViewItem *item, Drawable d, WMRect rect)
732 WMScreen *scr = W_VIEW(item->tabView)->screen;
734 if (!item->label)
735 return;
737 WMDrawString(scr, d, WMColorGC(scr->black), item->tabView->font,
738 rect.pos.x, rect.pos.y, item->label, strlen(item->label));
742 static void
743 W_UnmapTabViewItem(WMTabViewItem *item)
745 wassertr(item->view);
747 W_UnmapView(item->view);
749 item->flags.visible = 0;
753 static void
754 W_MapTabViewItem(WMTabViewItem *item)
756 wassertr(item->view);
758 W_MapView(item->view);
760 item->flags.visible = 1;
764 static WMView*
765 W_TabViewItemView(WMTabViewItem *item)
767 return item->view;
771 WMTabViewItem*
772 WMCreateTabViewItemWithIdentifier(int identifier)
774 WMTabViewItem *item;
776 item = wmalloc(sizeof(WMTabViewItem));
777 memset(item, 0, sizeof(WMTabViewItem));
779 item->identifier = identifier;
781 return item;
785 WMTabViewItem*
786 WMCreateTabViewItem(int identifier, char *label)
788 WMTabViewItem *item;
790 item = wmalloc(sizeof(WMTabViewItem));
791 memset(item, 0, sizeof(WMTabViewItem));
793 item->identifier = identifier;
794 WMSetTabViewItemLabel(item, label);
796 return item;
802 WMGetTabViewItemIdentifier(WMTabViewItem *item)
804 return item->identifier;
808 void
809 WMSetTabViewFont(WMTabView *tPtr, WMFont *font)
811 if (tPtr->font)
812 WMReleaseFont(tPtr->font);
814 tPtr->font = WMRetainFont(font);
815 tPtr->tabHeight = WMFontHeight(tPtr->font) + 3;
816 recalcTabWidth(tPtr);
820 void
821 WMSetTabViewItemLabel(WMTabViewItem *item, char *label)
823 if (item->label)
824 wfree(item->label);
826 item->label = wstrdup(label);
828 if (item->tabView)
829 recalcTabWidth(item->tabView);
833 char*
834 WMGetTabViewItemLabel(WMTabViewItem *item)
836 return item->label;
840 void
841 WMSetTabViewItemView(WMTabViewItem *item, WMView *view)
843 item->view = view;
847 WMView*
848 WMGetTabViewItemView(WMTabViewItem *item)
850 return item->view;
854 void
855 WMDestroyTabViewItem(WMTabViewItem *item)
857 if (item->label)
858 wfree(item->label);
860 if (item->view)
861 W_DestroyView(item->view);
863 wfree(item);