various table widget updates
[wmaker-crm.git] / WINGs / wtabview.c
blobf68d9f6771ee78e88cf2b5d31aea75a1769d8986
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 tabHeight;
27 struct {
28 WMReliefType relief:4;
29 WMTitlePosition titlePosition:4;
30 WMTabViewType type:2;
32 unsigned tabbed:1;
33 unsigned dontFitAll:1;
34 unsigned bordered:1;
35 unsigned uniformTabs:1;
36 } flags;
37 } TabView;
44 #define DEFAULT_WIDTH 40
45 #define DEFAULT_HEIGHT 40
47 #define NORMAL_SIDE_OFFSET 8
48 #define BUTTONED_SIDE_OFFSET 15
51 static void destroyTabView(TabView *tPtr);
52 static void paintTabView(TabView *tPtr);
55 static void W_SetTabViewItemParent(WMTabViewItem *item, WMTabView *parent);
57 static void W_DrawLabel(WMTabViewItem *item, Drawable d, WMRect rect);
59 static void W_UnmapTabViewItem(WMTabViewItem *item);
61 static void W_MapTabViewItem(WMTabViewItem *item);
63 static WMView *W_TabViewItemView(WMTabViewItem *item);
65 static int W_TabViewItemTabWidth(WMTabViewItem *item);
67 static void W_SetTabViewItemTabWidth(WMTabViewItem *item, int width);
70 static void recalcTabWidth(TabView *tPtr);
71 static void rearrange(TabView *tPtr);
73 static void didResize(struct W_ViewDelegate*, WMView*);
75 static W_ViewDelegate delegate = {
76 NULL,
77 NULL,
78 didResize,
79 NULL,
80 NULL
84 static int
85 positionOfTab(WMTabView *tabView, int tab)
87 int i;
88 int offs;
90 if (tab < tabView->firstVisible)
91 return -1;
93 if (tab > tabView->firstVisible + tabView->visibleTabs)
94 return -1;
96 if (tabView->flags.dontFitAll)
97 offs = BUTTONED_SIDE_OFFSET;
98 else
99 offs = NORMAL_SIDE_OFFSET;
101 for (i = tabView->firstVisible; i < tab; i++)
102 offs += W_TabViewItemTabWidth(tabView->items[i]) - 10;
104 return offs;
108 static int
109 countVisibleTabs(TabView *tPtr, int first)
111 int i;
112 int width;
114 if (first < 0) {
115 width = W_VIEW_WIDTH(tPtr->view) - 2 * NORMAL_SIDE_OFFSET;
116 first = 0;
117 } else {
118 width = W_VIEW_WIDTH(tPtr->view) - 2 * BUTTONED_SIDE_OFFSET;
121 for (i = first; i < tPtr->itemCount; i++) {
122 width -= W_TabViewItemTabWidth(tPtr->items[i]) - 10;
123 if (width <= 0) {
124 return i - first;
127 return i - first;
132 static void
133 handleEvents(XEvent *event, void *data)
135 TabView *tPtr = (TabView*)data;
137 CHECK_CLASS(data, WC_TabView);
139 switch (event->type) {
140 case Expose:
141 if (event->xexpose.count!=0)
142 break;
143 paintTabView(tPtr);
144 break;
146 case ButtonPress:
148 WMTabViewItem *item = WMTabViewItemAtPoint(tPtr,
149 event->xbutton.x,
150 event->xbutton.y);
151 if (item) {
152 WMSelectTabViewItem(tPtr, item);
153 } else if (tPtr->flags.dontFitAll) {
154 int redraw;
155 int lastVisible = tPtr->firstVisible+tPtr->visibleTabs-1;
157 if (event->xbutton.x < BUTTONED_SIDE_OFFSET) {
158 if (tPtr->firstVisible > 0) {
159 redraw = 1;
160 tPtr->firstVisible--;
162 } else if (event->xbutton.x > positionOfTab(tPtr,lastVisible)){
164 if (lastVisible < tPtr->itemCount-1) {
165 redraw = 1;
166 tPtr->firstVisible++;
169 tPtr->visibleTabs = countVisibleTabs(tPtr, tPtr->firstVisible);
170 if (redraw) {
171 paintTabView(tPtr);
175 break;
177 case DestroyNotify:
178 destroyTabView(tPtr);
179 break;
185 WMTabView*
186 WMCreateTabView(WMWidget *parent)
188 TabView *tPtr;
189 WMScreen *scr = WMWidgetScreen(parent);
191 tPtr = wmalloc(sizeof(TabView));
192 memset(tPtr, 0, sizeof(TabView));
194 tPtr->widgetClass = WC_TabView;
196 tPtr->view = W_CreateView(W_VIEW(parent));
197 if (!tPtr->view) {
198 wfree(tPtr);
199 return NULL;
201 tPtr->view->self = tPtr;
202 tPtr->view->delegate = &delegate;
204 tPtr->lightGray = WMCreateRGBColor(scr, 0xd9d9, 0xd9d9, 0xd9d9, False);
205 tPtr->tabColor = WMCreateRGBColor(scr, 0x8420, 0x8420, 0x8420, False);
207 tPtr->font = WMRetainFont(scr->normalFont);
209 tPtr->flags.type = WTTopTabsBevelBorder;
210 tPtr->flags.bordered = 1;
211 tPtr->flags.uniformTabs = 0;
213 WMCreateEventHandler(tPtr->view, ExposureMask|StructureNotifyMask
214 |ButtonPressMask, handleEvents, tPtr);
216 WMResizeWidget(tPtr, DEFAULT_WIDTH, DEFAULT_HEIGHT);
218 tPtr->tabHeight = WMFontHeight(tPtr->font) + 3;
220 return tPtr;
224 void
225 WMSetTabViewDelegate(WMTabView *tPtr, WMTabViewDelegate *delegate)
227 tPtr->delegate = delegate;
231 WMTabViewItem*
232 WMAddTabViewItemWithView(WMTabView *tPtr, WMView *view, int identifier,
233 char *label)
235 WMTabViewItem *item;
237 item = WMCreateTabViewItemWithIdentifier(identifier);
238 WMSetTabViewItemView(item, view);
239 WMAddItemInTabView(tPtr, item);
240 WMSetTabViewItemLabel(item, label);
242 return item;
246 void
247 WMAddItemInTabView(WMTabView *tPtr, WMTabViewItem *item)
249 WMInsertItemInTabView(tPtr, tPtr->itemCount, item);
253 void
254 WMInsertItemInTabView(WMTabView *tPtr, int index, WMTabViewItem *item)
256 wassertr(W_TabViewItemView(item) != NULL);
258 if (tPtr->maxItems == tPtr->itemCount) {
259 WMTabViewItem **items;
261 items = wrealloc(tPtr->items,
262 sizeof(WMTabViewItem*) * (tPtr->maxItems + 10));
263 memset(&items[tPtr->maxItems], 0, sizeof(WMTabViewItem*) * 10);
264 tPtr->items = items;
265 tPtr->maxItems += 10;
268 if (index > tPtr->itemCount)
269 index = tPtr->itemCount;
271 if (index == 0 && tPtr->items[0]) {
272 W_UnmapTabViewItem(tPtr->items[0]);
275 if (index < tPtr->itemCount) {
276 memmove(tPtr->items + index + 1, tPtr->items + index,
277 (tPtr->itemCount - index) * sizeof(WMTabViewItem*));
280 tPtr->items[index] = item;
282 tPtr->itemCount++;
284 recalcTabWidth(tPtr);
286 W_SetTabViewItemParent(item, tPtr);
288 W_UnmapTabViewItem(item);
290 if (tPtr->flags.bordered) {
291 W_ReparentView(W_TabViewItemView(item), tPtr->view, 1,
292 tPtr->tabHeight + 1);
294 W_ResizeView(W_TabViewItemView(item), tPtr->view->size.width - 3,
295 tPtr->view->size.height - tPtr->tabHeight - 3);
296 } else {
297 W_ReparentView(W_TabViewItemView(item), tPtr->view, 0,
298 tPtr->tabHeight);
300 W_ResizeView(W_TabViewItemView(item), tPtr->view->size.width,
301 tPtr->view->size.height - tPtr->tabHeight);
304 if (index == 0) {
305 W_MapTabViewItem(item);
307 if (tPtr->delegate && tPtr->delegate->didChangeNumberOfItems)
308 (*tPtr->delegate->didChangeNumberOfItems)(tPtr->delegate, tPtr);
310 if (W_VIEW_REALIZED(tPtr->view))
311 paintTabView(tPtr);
315 void
316 WMRemoveTabViewItem(WMTabView *tPtr, WMTabViewItem *item)
318 int i;
320 for (i = 0; i < tPtr->itemCount; i++) {
321 if (tPtr->items[i] == item) {
322 if (i < tPtr->itemCount - 1)
323 memmove(&tPtr->items[i], &tPtr->items[i + 1],
324 tPtr->itemCount - i - 1);
325 else
326 tPtr->items[i] = NULL;
328 W_SetTabViewItemParent(item, NULL);
330 tPtr->itemCount--;
331 break;
334 if (tPtr->delegate && tPtr->delegate->didChangeNumberOfItems)
335 (*tPtr->delegate->didChangeNumberOfItems)(tPtr->delegate, tPtr);
340 static Bool
341 isInside(int x, int y, int width, int height, int px, int py)
343 if (py >= y + height - 3 && py <= y + height
344 && px >= x + py - (y + height - 3)
345 && px <= x + width - (py - (y + height - 3))) {
347 return True;
349 if (py >= y + 3 && py < y + height - 3
350 && px >= x + 3 + ((y + 3) - py)*3/7
351 && px <= x + width - 3 - ((y + 3) - py)*3/7) {
353 return True;
355 if (py >= y && py < y + 3
356 && px >= x + 7 + py - y
357 && px <= x + width - 7 - (py - y)) {
359 return True;
361 return False;
365 WMTabViewItem*
366 WMTabViewItemAtPoint(WMTabView *tPtr, int x, int y)
368 int i;
369 int offset;
370 int count = tPtr->visibleTabs;
371 int first = tPtr->firstVisible;
373 if (tPtr->flags.dontFitAll) {
374 i = tPtr->selectedItem - tPtr->firstVisible;
375 if (i >= 0 && i < tPtr->visibleTabs
376 && isInside(positionOfTab(tPtr, tPtr->selectedItem), 0,
377 W_TabViewItemTabWidth(tPtr->items[tPtr->selectedItem]),
378 tPtr->tabHeight, x, y)) {
379 return tPtr->items[tPtr->selectedItem];
381 } else {
382 i = tPtr->selectedItem;
383 if (isInside(positionOfTab(tPtr, i), 0,
384 W_TabViewItemTabWidth(tPtr->items[i]),
385 tPtr->tabHeight, x, y)) {
386 return tPtr->items[i];
390 for (i = first; i < first + count; i++) {
391 int pos;
393 pos = positionOfTab(tPtr, i);
394 if (isInside(pos, 0, W_TabViewItemTabWidth(tPtr->items[i]),
395 tPtr->tabHeight, x, y)) {
396 return tPtr->items[i];
399 return NULL;
403 void
404 WMSetTabViewType(WMTabView *tPtr, WMTabViewType type)
406 tPtr->flags.type = type;
408 if (type != WTTopTabsBevelBorder)
409 tPtr->tabHeight = 0;
410 else
411 tPtr->tabHeight = WMFontHeight(tPtr->font) + 3;
413 if (type == WTNoTabsNoBorder)
414 tPtr->flags.bordered = 0;
415 else
416 tPtr->flags.bordered = 1;
418 rearrange(tPtr);
421 void
422 WMSelectFirstTabViewItem(WMTabView *tPtr)
424 WMSelectTabViewItemAtIndex(tPtr, 0);
428 void
429 WMSelectLastTabViewItem(WMTabView *tPtr)
431 WMSelectTabViewItemAtIndex(tPtr, tPtr->itemCount);
435 void
436 WMSelectNextTabViewItem(WMTabView *tPtr)
438 WMSelectTabViewItemAtIndex(tPtr, tPtr->selectedItem + 1);
442 void
443 WMSelectPreviousTabViewItem(WMTabView *tPtr)
445 WMSelectTabViewItemAtIndex(tPtr, tPtr->selectedItem - 1);
449 WMTabViewItem*
450 WMGetSelectedTabViewItem(WMTabView *tPtr)
452 return tPtr->items[tPtr->selectedItem];
456 void
457 WMSelectTabViewItem(WMTabView *tPtr, WMTabViewItem *item)
459 int i;
461 for (i = 0; i < tPtr->itemCount; i++) {
462 if (tPtr->items[i] == item) {
463 WMSelectTabViewItemAtIndex(tPtr, i);
464 break;
470 void
471 WMSelectTabViewItemAtIndex(WMTabView *tPtr, int index)
473 WMTabViewItem *item;
475 if (index == tPtr->selectedItem) {
476 return;
479 if (index < 0)
480 index = 0;
481 else if (index >= tPtr->itemCount)
482 index = tPtr->itemCount - 1;
484 item = tPtr->items[tPtr->selectedItem];
486 if (tPtr->delegate && tPtr->delegate->shouldSelectItem)
487 if (!(*tPtr->delegate->shouldSelectItem)(tPtr->delegate, tPtr,
488 tPtr->items[index]))
489 return;
491 if (tPtr->delegate && tPtr->delegate->willSelectItem)
492 (*tPtr->delegate->willSelectItem)(tPtr->delegate, tPtr,
493 tPtr->items[index]);
495 W_UnmapTabViewItem(item);
498 item = tPtr->items[index];
500 W_MapTabViewItem(item);
502 tPtr->selectedItem = index;
504 if (tPtr->delegate && tPtr->delegate->didSelectItem)
505 (*tPtr->delegate->didSelectItem)(tPtr->delegate, tPtr,
506 tPtr->items[index]);
508 paintTabView(tPtr);
513 static void
514 recalcTabWidth(TabView *tPtr)
516 int i;
517 int twidth = W_VIEW(tPtr)->size.width;
518 int width;
520 if (tPtr->flags.uniformTabs) {
521 int tabWidth;
523 tabWidth = 0;
525 for (i = 0; i < tPtr->itemCount; i++) {
526 char *str = WMGetTabViewItemLabel(tPtr->items[i]);
528 if (str) {
529 width = WMWidthOfString(tPtr->font, str, strlen(str));
530 if (width > tabWidth)
531 tabWidth = width;
535 tabWidth = tabWidth + 30;
537 for (i = 0; i < tPtr->itemCount; i++)
538 W_SetTabViewItemTabWidth(tPtr->items[i], tabWidth);
540 tPtr->firstVisible = 0;
541 tPtr->visibleTabs = countVisibleTabs(tPtr, -1);
542 if (tPtr->visibleTabs < tPtr->itemCount)
543 tPtr->flags.dontFitAll = 1;
544 else
545 tPtr->flags.dontFitAll = 0;
546 } else {
547 for (i = 0; i < tPtr->itemCount; i++) {
548 char *str = WMGetTabViewItemLabel(tPtr->items[i]);
549 if (!str)
550 continue;
552 width = WMWidthOfString(tPtr->font, str, strlen(str)) + 30;
554 W_SetTabViewItemTabWidth(tPtr->items[i], width);
557 if (countVisibleTabs(tPtr, -1) < tPtr->itemCount) {
558 tPtr->flags.dontFitAll = 1;
559 tPtr->firstVisible = 0;
560 tPtr->visibleTabs = countVisibleTabs(tPtr, tPtr->firstVisible);
561 } else {
562 tPtr->flags.dontFitAll = 0;
563 tPtr->firstVisible = 0;
564 tPtr->visibleTabs = tPtr->itemCount;
570 static void
571 drawRelief(W_Screen *scr, Drawable d, int x, int y, unsigned int width,
572 unsigned int height)
574 Display *dpy = scr->display;
575 GC bgc = WMColorGC(scr->black);
576 GC wgc = WMColorGC(scr->white);
577 GC dgc = WMColorGC(scr->darkGray);
579 XDrawLine(dpy, d, wgc, x, y, x, y+height-1);
581 XDrawLine(dpy, d, bgc, x, y+height-1, x+width-1, y+height-1);
582 XDrawLine(dpy, d, dgc, x+1, y+height-2, x+width-2, y+height-2);
584 XDrawLine(dpy, d, bgc, x+width-1, y, x+width-1, y+height-1);
585 XDrawLine(dpy, d, dgc, x+width-2, y+1, x+width-2, y+height-2);
589 static void
590 drawTab(TabView *tPtr, Drawable d, int x, int y,
591 unsigned width, unsigned height, Bool selected)
593 WMScreen *scr = W_VIEW(tPtr)->screen;
594 Display *dpy = scr->display;
595 GC white = WMColorGC(selected ? scr->white : tPtr->lightGray);
596 GC black = WMColorGC(scr->black);
597 GC dark = WMColorGC(scr->darkGray);
598 GC light = WMColorGC(scr->gray);
599 XPoint trap[8];
601 trap[0].x = x + (selected ? 0 : 1);
602 trap[0].y = y + height - (selected ? 0 : 1);
604 trap[1].x = x + 3;
605 trap[1].y = y + height - 3;
607 trap[2].x = x + 10 - 3;
608 trap[2].y = y + 3;
610 trap[3].x = x + 10;
611 trap[3].y = y;
613 trap[4].x = x + width - 10;
614 trap[4].y = y;
616 trap[5].x = x + width - 10 + 3;
617 trap[5].y = y + 3;
619 trap[6].x = x + width - 3;
620 trap[6].y = y + height - 3;
622 trap[7].x = x + width - (selected ? 0 : 1);
623 trap[7].y = y + height - (selected ? 0 : 1);
625 XFillPolygon(dpy, d, selected ? light : WMColorGC(tPtr->tabColor), trap, 8,
626 Convex, CoordModeOrigin);
628 XDrawLine(dpy, d, white, trap[0].x, trap[0].y, trap[1].x, trap[1].y);
629 XDrawLine(dpy, d, white, trap[1].x, trap[1].y, trap[2].x, trap[2].y);
630 XDrawLine(dpy, d, white, trap[2].x, trap[2].y, trap[3].x, trap[3].y);
631 XDrawLine(dpy, d, white, trap[3].x, trap[3].y, trap[4].x, trap[4].y);
632 XDrawLine(dpy, d, dark, trap[4].x, trap[4].y, trap[5].x, trap[5].y);
633 XDrawLine(dpy, d, black, trap[5].x, trap[5].y, trap[6].x, trap[6].y);
634 XDrawLine(dpy, d, black, trap[6].x, trap[6].y, trap[7].x, trap[7].y);
636 XDrawLine(dpy, d, selected ? light : WMColorGC(scr->white),
637 trap[0].x, trap[0].y, trap[7].x, trap[7].y);
641 static void
642 paintDot(TabView *tPtr, Drawable d, int x, int y)
644 WMScreen *scr = W_VIEW(tPtr)->screen;
645 Display *dpy = scr->display;
646 GC white = WMColorGC(scr->white);
647 GC black = WMColorGC(scr->black);
649 XFillRectangle(dpy, d, black, x, y, 2, 2);
650 XDrawPoint(dpy, d, white, x, y);
655 static void
656 paintTabView(TabView *tPtr)
658 Pixmap buffer;
659 WMScreen *scr = W_VIEW(tPtr)->screen;
660 Display *dpy = scr->display;
661 GC white = WMColorGC(scr->white);
662 int i;
664 if (tPtr->flags.type == WTTopTabsBevelBorder) {
665 int count = tPtr->visibleTabs;
666 int first = tPtr->firstVisible;
667 int moreAtLeft;
668 int moreAtRight;
669 int selectedIsVisible;
670 int tx, ty;
671 int twidth, theight;
673 ty = 2;
674 theight = tPtr->tabHeight;
676 buffer = XCreatePixmap(dpy, W_VIEW(tPtr)->window,
677 W_VIEW(tPtr)->size.width, theight,
678 W_VIEW(tPtr)->screen->depth);
680 XFillRectangle(dpy, buffer, WMColorGC(W_VIEW(tPtr)->backColor),
681 0, 0, W_VIEW(tPtr)->size.width, tPtr->tabHeight);
683 if (tPtr->flags.dontFitAll) {
684 moreAtLeft = first > 0;
685 moreAtRight = (first + count) < tPtr->itemCount;
686 if (tPtr->selectedItem >= first
687 && tPtr->selectedItem < first + count)
688 selectedIsVisible = 1;
689 else
690 selectedIsVisible = 0;
691 } else {
692 moreAtLeft = 0;
693 moreAtRight = 0;
694 selectedIsVisible = 1;
697 if (moreAtRight) {
698 drawTab(tPtr, buffer, positionOfTab(tPtr, first+count), 0,
699 W_VIEW_WIDTH(tPtr->view), theight, False);
701 for (i = first + count-1; i >= first; i--) {
702 if (!selectedIsVisible || i != tPtr->selectedItem) {
703 twidth = W_TabViewItemTabWidth(tPtr->items[i]);
705 drawTab(tPtr, buffer, positionOfTab(tPtr, i), 0,
706 twidth, theight, False);
709 if (moreAtLeft) {
710 drawTab(tPtr, buffer, positionOfTab(tPtr, 0)-2*BUTTONED_SIDE_OFFSET,
711 0, BUTTONED_SIDE_OFFSET*4, theight, False);
714 if (selectedIsVisible) {
715 int idx = tPtr->selectedItem;
717 drawTab(tPtr, buffer, positionOfTab(tPtr, idx),
718 0, W_TabViewItemTabWidth(tPtr->items[idx]),
719 theight, True);
721 XDrawLine(dpy, buffer, white, 0, theight - 1,
722 positionOfTab(tPtr, idx), theight - 1);
724 XDrawLine(dpy, buffer, white,
725 positionOfTab(tPtr, idx) + W_TabViewItemTabWidth(tPtr->items[idx]),
726 tPtr->tabHeight - 1, W_VIEW_WIDTH(tPtr->view) - 1,
727 tPtr->tabHeight - 1);
728 } else {
729 XDrawLine(dpy, buffer, white, 0, theight - 1,
730 W_VIEW_WIDTH(tPtr->view), theight - 1);
733 for (i = 0; i < count; i++) {
734 WMRect rect;
736 rect.pos.x = 15 + positionOfTab(tPtr, first+i);
737 rect.pos.y = ty;
738 rect.size.width = W_TabViewItemTabWidth(tPtr->items[first+i]);
739 rect.size.height = theight;
740 W_DrawLabel(tPtr->items[first+i], buffer, rect);
743 if (moreAtLeft) {
744 paintDot(tPtr, buffer, 4, 10);
745 paintDot(tPtr, buffer, 7, 10);
746 paintDot(tPtr, buffer, 10, 10);
748 if (moreAtRight) {
749 int x;
751 x = positionOfTab(tPtr, tPtr->firstVisible + tPtr->visibleTabs);
753 x = x + (W_VIEW_WIDTH(tPtr->view) - x)/2;
754 paintDot(tPtr, buffer, x + 5, 10);
755 paintDot(tPtr, buffer, x + 8, 10);
756 paintDot(tPtr, buffer, x + 11, 10);
759 XCopyArea(dpy, buffer, W_VIEW(tPtr)->window, scr->copyGC, 0, 0,
760 W_VIEW_WIDTH(tPtr->view), theight, 0, 0);
762 XFreePixmap(dpy, buffer);
764 switch (tPtr->flags.type) {
765 case WTTopTabsBevelBorder:
766 drawRelief(scr, W_VIEW(tPtr)->window, 0, tPtr->tabHeight - 1,
767 W_VIEW(tPtr)->size.width,
768 W_VIEW(tPtr)->size.height - tPtr->tabHeight + 1);
769 break;
771 case WTNoTabsBevelBorder:
772 W_DrawRelief(scr, W_VIEW(tPtr)->window, 0, 0, W_VIEW(tPtr)->size.width,
773 W_VIEW(tPtr)->size.height, WRRaised);
774 break;
776 case WTNoTabsLineBorder:
777 W_DrawRelief(scr, W_VIEW(tPtr)->window, 0, 0, W_VIEW(tPtr)->size.width,
778 W_VIEW(tPtr)->size.height, WRSimple);
779 break;
781 case WTNoTabsNoBorder:
782 break;
787 static void
788 rearrange(TabView *tPtr)
790 int i;
791 int width, height;
792 int bordered = tPtr->flags.bordered;
794 recalcTabWidth(tPtr);
796 width = tPtr->view->size.width - (bordered ? 3 : 0);
797 height = tPtr->view->size.height - tPtr->tabHeight - (bordered ? 3 : 0);
799 for (i = 0; i < tPtr->itemCount; i++) {
800 W_MoveView(W_TabViewItemView(tPtr->items[i]),
801 1*bordered, tPtr->tabHeight + 1*bordered);
802 W_ResizeView(W_TabViewItemView(tPtr->items[i]), width, height);
804 if (W_VIEW_MAPPED(tPtr->view) && W_VIEW_REALIZED(tPtr->view))
805 paintTabView(tPtr);
809 static void
810 didResize(struct W_ViewDelegate *deleg, WMView *view)
812 rearrange(view->self);
816 static void
817 destroyTabView(TabView *tPtr)
819 int i;
821 for (i = 0; i < tPtr->itemCount; i++) {
822 WMSetTabViewItemView(tPtr->items[i], NULL);
823 WMDestroyTabViewItem(tPtr->items[i]);
825 wfree(tPtr->items);
827 WMReleaseColor(tPtr->lightGray);
828 WMReleaseColor(tPtr->tabColor);
829 WMReleaseFont(tPtr->font);
831 wfree(tPtr);
834 /******************************************************************/
837 typedef struct W_TabViewItem {
838 WMTabView *tabView;
840 W_View *view;
842 char *label;
844 short tabWidth;
845 int identifier;
847 struct {
848 unsigned visible:1;
849 } flags;
850 } TabViewItem;
853 static void
854 W_SetTabViewItemParent(WMTabViewItem *item, WMTabView *parent)
856 item->tabView = parent;
860 static void
861 W_DrawLabel(WMTabViewItem *item, Drawable d, WMRect rect)
863 WMScreen *scr = W_VIEW(item->tabView)->screen;
865 if (!item->label)
866 return;
868 WMDrawString(scr, d, WMColorGC(scr->black), item->tabView->font,
869 rect.pos.x, rect.pos.y, item->label, strlen(item->label));
873 static void
874 W_UnmapTabViewItem(WMTabViewItem *item)
876 wassertr(item->view);
878 W_UnmapView(item->view);
880 item->flags.visible = 0;
884 static void
885 W_MapTabViewItem(WMTabViewItem *item)
887 wassertr(item->view);
889 W_MapView(item->view);
890 W_RaiseView(item->view);
892 item->flags.visible = 1;
896 static WMView*
897 W_TabViewItemView(WMTabViewItem *item)
899 return item->view;
903 static int
904 W_TabViewItemTabWidth(WMTabViewItem *item)
906 return item->tabWidth;
910 static void
911 W_SetTabViewItemTabWidth(WMTabViewItem *item, int width)
913 item->tabWidth = width;
917 WMTabViewItem*
918 WMCreateTabViewItemWithIdentifier(int identifier)
920 WMTabViewItem *item;
922 item = wmalloc(sizeof(WMTabViewItem));
923 memset(item, 0, sizeof(WMTabViewItem));
925 item->identifier = identifier;
927 return item;
931 WMTabViewItem*
932 WMCreateTabViewItem(int identifier, char *label)
934 WMTabViewItem *item;
936 item = wmalloc(sizeof(WMTabViewItem));
937 memset(item, 0, sizeof(WMTabViewItem));
939 item->identifier = identifier;
940 WMSetTabViewItemLabel(item, label);
942 return item;
948 WMGetTabViewItemIdentifier(WMTabViewItem *item)
950 return item->identifier;
954 void
955 WMSetTabViewFont(WMTabView *tPtr, WMFont *font)
957 if (tPtr->font)
958 WMReleaseFont(tPtr->font);
960 tPtr->font = WMRetainFont(font);
961 tPtr->tabHeight = WMFontHeight(tPtr->font) + 3;
962 recalcTabWidth(tPtr);
966 void
967 WMSetTabViewItemLabel(WMTabViewItem *item, char *label)
969 if (item->label)
970 wfree(item->label);
972 if (label)
973 item->label = wstrdup(label);
974 else
975 item->label = NULL;
977 if (item->tabView)
978 recalcTabWidth(item->tabView);
982 char*
983 WMGetTabViewItemLabel(WMTabViewItem *item)
985 return item->label;
989 void
990 WMSetTabViewItemView(WMTabViewItem *item, WMView *view)
992 item->view = view;
996 WMView*
997 WMGetTabViewItemView(WMTabViewItem *item)
999 return item->view;
1003 void
1004 WMDestroyTabViewItem(WMTabViewItem *item)
1006 if (item->label)
1007 wfree(item->label);
1009 if (item->view)
1010 W_DestroyView(item->view);
1012 wfree(item);