updated changelog
[wmaker-crm.git] / WINGs / wtabview.c
blob00e2727f60758ab75d7e0059c7254c7e251cc5d2
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 enabled:1;
33 unsigned tabbed:1;
34 unsigned dontFitAll:1;
35 unsigned bordered:1;
36 unsigned uniformTabs:1;
37 } flags;
38 } TabView;
41 typedef struct W_TabViewItem {
42 WMTabView *tabView;
44 W_View *view;
46 char *label;
48 short tabWidth;
49 int identifier;
51 struct {
52 unsigned visible:1;
53 unsigned enabled:1;
54 } flags;
55 } W_TabViewItem;
62 #define DEFAULT_WIDTH 40
63 #define DEFAULT_HEIGHT 40
65 #define NORMAL_SIDE_OFFSET 8
66 #define BUTTONED_SIDE_OFFSET 15
69 static void destroyTabView(TabView *tPtr);
70 static void paintTabView(TabView *tPtr);
73 static void W_SetTabViewItemParent(WMTabViewItem *item, WMTabView *parent);
75 static void W_DrawLabel(WMTabViewItem *item, Drawable d, WMRect rect,
76 Bool enabled);
78 static void W_UnmapTabViewItem(WMTabViewItem *item);
80 static void W_MapTabViewItem(WMTabViewItem *item);
82 static WMView *W_TabViewItemView(WMTabViewItem *item);
84 static int W_TabViewItemTabWidth(WMTabViewItem *item);
86 static void W_SetTabViewItemTabWidth(WMTabViewItem *item, int width);
89 static void recalcTabWidth(TabView *tPtr);
90 static void rearrange(TabView *tPtr);
92 static void didResize(struct W_ViewDelegate*, WMView*);
94 static W_ViewDelegate delegate = {
95 NULL,
96 NULL,
97 didResize,
98 NULL,
99 NULL
103 static int
104 positionOfTab(WMTabView *tabView, int tab)
106 int i;
107 int offs;
109 if (tab < tabView->firstVisible)
110 return -1;
112 if (tab > tabView->firstVisible + tabView->visibleTabs)
113 return -1;
115 if (tabView->flags.dontFitAll)
116 offs = BUTTONED_SIDE_OFFSET;
117 else
118 offs = NORMAL_SIDE_OFFSET;
120 for (i = tabView->firstVisible; i < tab; i++)
121 offs += W_TabViewItemTabWidth(tabView->items[i]) - 10;
123 return offs;
127 static int
128 countVisibleTabs(TabView *tPtr, int first)
130 int i;
131 int width;
133 if (first < 0) {
134 width = W_VIEW_WIDTH(tPtr->view) - 2 * NORMAL_SIDE_OFFSET;
135 first = 0;
136 } else {
137 width = W_VIEW_WIDTH(tPtr->view) - 2 * BUTTONED_SIDE_OFFSET;
140 for (i = first; i < tPtr->itemCount; i++) {
141 width -= W_TabViewItemTabWidth(tPtr->items[i]) - 10;
142 if (width <= 0) {
143 return i - first;
146 return i - first;
151 static void
152 handleEvents(XEvent *event, void *data)
154 TabView *tPtr = (TabView*)data;
156 CHECK_CLASS(data, WC_TabView);
158 switch (event->type) {
159 case Expose:
160 if (event->xexpose.count!=0)
161 break;
162 paintTabView(tPtr);
163 break;
165 case ButtonPress:
166 if (tPtr->flags.enabled) {
167 WMTabViewItem *item = WMTabViewItemAtPoint(tPtr,
168 event->xbutton.x,
169 event->xbutton.y);
170 /*if (item && !item->flags.enabled)
171 break;*/
173 if (item && item->flags.enabled) {
174 WMSelectTabViewItem(tPtr, item);
175 } else if (tPtr->flags.dontFitAll) {
176 int redraw = 0;
177 int lastVisible = tPtr->firstVisible+tPtr->visibleTabs-1;
179 if (event->xbutton.x < BUTTONED_SIDE_OFFSET) {
180 if (tPtr->firstVisible > 0) {
181 redraw = 1;
182 tPtr->firstVisible--;
184 } else if (event->xbutton.x > positionOfTab(tPtr,lastVisible)){
186 if (lastVisible < tPtr->itemCount-1) {
187 redraw = 1;
188 tPtr->firstVisible++;
191 tPtr->visibleTabs = countVisibleTabs(tPtr, tPtr->firstVisible);
192 if (redraw) {
193 paintTabView(tPtr);
197 break;
199 case DestroyNotify:
200 destroyTabView(tPtr);
201 break;
207 WMTabView*
208 WMCreateTabView(WMWidget *parent)
210 TabView *tPtr;
211 WMScreen *scr = WMWidgetScreen(parent);
213 tPtr = wmalloc(sizeof(TabView));
214 memset(tPtr, 0, sizeof(TabView));
216 tPtr->widgetClass = WC_TabView;
218 tPtr->view = W_CreateView(W_VIEW(parent));
219 if (!tPtr->view) {
220 wfree(tPtr);
221 return NULL;
223 tPtr->view->self = tPtr;
224 tPtr->view->delegate = &delegate;
226 tPtr->lightGray = WMCreateRGBColor(scr, 0xd9d9, 0xd9d9, 0xd9d9, False);
227 tPtr->tabColor = WMCreateRGBColor(scr, 0x8420, 0x8420, 0x8420, False);
229 tPtr->font = WMRetainFont(scr->normalFont);
231 tPtr->flags.type = WTTopTabsBevelBorder;
232 tPtr->flags.bordered = 1;
233 tPtr->flags.uniformTabs = 0;
234 tPtr->flags.enabled = 1;
236 WMCreateEventHandler(tPtr->view, ExposureMask|StructureNotifyMask
237 |ButtonPressMask, handleEvents, tPtr);
239 WMResizeWidget(tPtr, DEFAULT_WIDTH, DEFAULT_HEIGHT);
241 tPtr->tabHeight = WMFontHeight(tPtr->font) + 3;
243 return tPtr;
247 void
248 WMSetTabViewDelegate(WMTabView *tPtr, WMTabViewDelegate *delegate)
250 tPtr->delegate = delegate;
254 WMTabViewItem*
255 WMAddTabViewItemWithView(WMTabView *tPtr, WMView *view, int identifier,
256 char *label)
258 WMTabViewItem *item;
260 item = WMCreateTabViewItemWithIdentifier(identifier);
261 WMSetTabViewItemView(item, view);
262 WMAddItemInTabView(tPtr, item);
263 WMSetTabViewItemLabel(item, label);
265 return item;
269 void
270 WMAddItemInTabView(WMTabView *tPtr, WMTabViewItem *item)
272 WMInsertItemInTabView(tPtr, tPtr->itemCount, item);
276 void
277 WMSetTabViewEnabled(WMTabView *tPtr, Bool flag)
279 tPtr->flags.enabled = ((flag==0) ? 0 : 1);
280 if (W_VIEW_REALIZED(tPtr->view))
281 paintTabView(tPtr);
285 void
286 WMInsertItemInTabView(WMTabView *tPtr, int index, WMTabViewItem *item)
288 wassertr(W_TabViewItemView(item) != NULL);
290 if (tPtr->maxItems == tPtr->itemCount) {
291 WMTabViewItem **items;
293 items = wrealloc(tPtr->items,
294 sizeof(WMTabViewItem*) * (tPtr->maxItems + 10));
295 memset(&items[tPtr->maxItems], 0, sizeof(WMTabViewItem*) * 10);
296 tPtr->items = items;
297 tPtr->maxItems += 10;
300 if (index > tPtr->itemCount)
301 index = tPtr->itemCount;
303 if (index == 0 && tPtr->items[0]) {
304 W_UnmapTabViewItem(tPtr->items[0]);
307 if (index < tPtr->itemCount) {
308 memmove(tPtr->items + index + 1, tPtr->items + index,
309 (tPtr->itemCount - index) * sizeof(WMTabViewItem*));
312 tPtr->items[index] = item;
314 tPtr->itemCount++;
316 recalcTabWidth(tPtr);
318 W_SetTabViewItemParent(item, tPtr);
320 W_UnmapTabViewItem(item);
322 if (tPtr->flags.bordered) {
323 W_ReparentView(W_TabViewItemView(item), tPtr->view, 1,
324 tPtr->tabHeight + 1);
326 W_ResizeView(W_TabViewItemView(item), tPtr->view->size.width - 3,
327 tPtr->view->size.height - tPtr->tabHeight - 3);
328 } else {
329 W_ReparentView(W_TabViewItemView(item), tPtr->view, 0,
330 tPtr->tabHeight);
332 W_ResizeView(W_TabViewItemView(item), tPtr->view->size.width,
333 tPtr->view->size.height - tPtr->tabHeight);
336 if (index == 0) {
337 W_MapTabViewItem(item);
339 if (tPtr->delegate && tPtr->delegate->didChangeNumberOfItems)
340 (*tPtr->delegate->didChangeNumberOfItems)(tPtr->delegate, tPtr);
342 if (W_VIEW_REALIZED(tPtr->view))
343 paintTabView(tPtr);
347 void
348 WMRemoveTabViewItem(WMTabView *tPtr, WMTabViewItem *item)
350 int i;
352 for (i = 0; i < tPtr->itemCount; i++) {
353 if (tPtr->items[i] == item) {
354 if (i < tPtr->itemCount - 1)
355 memmove(&tPtr->items[i], &tPtr->items[i + 1],
356 tPtr->itemCount - i - 1);
357 else
358 tPtr->items[i] = NULL;
360 W_SetTabViewItemParent(item, NULL);
362 tPtr->itemCount--;
363 break;
366 if (tPtr->delegate && tPtr->delegate->didChangeNumberOfItems)
367 (*tPtr->delegate->didChangeNumberOfItems)(tPtr->delegate, tPtr);
372 static Bool
373 isInside(int x, int y, int width, int height, int px, int py)
375 if (py >= y + height - 3 && py <= y + height
376 && px >= x + py - (y + height - 3)
377 && px <= x + width - (py - (y + height - 3))) {
379 return True;
381 if (py >= y + 3 && py < y + height - 3
382 && px >= x + 3 + ((y + 3) - py)*3/7
383 && px <= x + width - 3 - ((y + 3) - py)*3/7) {
385 return True;
387 if (py >= y && py < y + 3
388 && px >= x + 7 + py - y
389 && px <= x + width - 7 - (py - y)) {
391 return True;
393 return False;
397 WMTabViewItem*
398 WMTabViewItemAtPoint(WMTabView *tPtr, int x, int y)
400 int i;
401 int count = tPtr->visibleTabs;
402 int first = tPtr->firstVisible;
404 if (tPtr->flags.dontFitAll) {
405 i = tPtr->selectedItem - tPtr->firstVisible;
406 if (i >= 0 && i < tPtr->visibleTabs
407 && isInside(positionOfTab(tPtr, tPtr->selectedItem), 0,
408 W_TabViewItemTabWidth(tPtr->items[tPtr->selectedItem]),
409 tPtr->tabHeight, x, y)) {
410 return tPtr->items[tPtr->selectedItem];
412 } else {
413 i = tPtr->selectedItem;
414 if (isInside(positionOfTab(tPtr, i), 0,
415 W_TabViewItemTabWidth(tPtr->items[i]),
416 tPtr->tabHeight, x, y)) {
417 return tPtr->items[i];
421 for (i = first; i < first + count; i++) {
422 int pos;
424 pos = positionOfTab(tPtr, i);
425 if (isInside(pos, 0, W_TabViewItemTabWidth(tPtr->items[i]),
426 tPtr->tabHeight, x, y)) {
427 return tPtr->items[i];
430 return NULL;
434 void
435 WMSetTabViewType(WMTabView *tPtr, WMTabViewType type)
437 tPtr->flags.type = type;
439 if (type != WTTopTabsBevelBorder)
440 tPtr->tabHeight = 0;
441 else
442 tPtr->tabHeight = WMFontHeight(tPtr->font) + 3;
444 if (type == WTNoTabsNoBorder)
445 tPtr->flags.bordered = 0;
446 else
447 tPtr->flags.bordered = 1;
449 rearrange(tPtr);
452 void
453 WMSelectFirstTabViewItem(WMTabView *tPtr)
455 WMSelectTabViewItemAtIndex(tPtr, 0);
459 void
460 WMSelectLastTabViewItem(WMTabView *tPtr)
462 WMSelectTabViewItemAtIndex(tPtr, tPtr->itemCount);
466 void
467 WMSelectNextTabViewItem(WMTabView *tPtr)
469 WMSelectTabViewItemAtIndex(tPtr, tPtr->selectedItem + 1);
473 void
474 WMSelectPreviousTabViewItem(WMTabView *tPtr)
476 WMSelectTabViewItemAtIndex(tPtr, tPtr->selectedItem - 1);
480 WMTabViewItem*
481 WMGetSelectedTabViewItem(WMTabView *tPtr)
483 return tPtr->items[tPtr->selectedItem];
487 void
488 WMSelectTabViewItem(WMTabView *tPtr, WMTabViewItem *item)
490 int i;
492 for (i = 0; i < tPtr->itemCount; i++) {
493 if (tPtr->items[i] == item) {
494 WMSelectTabViewItemAtIndex(tPtr, i);
495 break;
501 void
502 WMSelectTabViewItemAtIndex(WMTabView *tPtr, int index)
504 WMTabViewItem *item;
506 if (index == tPtr->selectedItem) {
507 return;
510 if (index < 0)
511 index = 0;
512 else if (index >= tPtr->itemCount)
513 index = tPtr->itemCount - 1;
515 item = tPtr->items[tPtr->selectedItem];
517 if (tPtr->delegate && tPtr->delegate->shouldSelectItem)
518 if (!(*tPtr->delegate->shouldSelectItem)(tPtr->delegate, tPtr,
519 tPtr->items[index]))
520 return;
522 if (tPtr->delegate && tPtr->delegate->willSelectItem)
523 (*tPtr->delegate->willSelectItem)(tPtr->delegate, tPtr,
524 tPtr->items[index]);
526 W_UnmapTabViewItem(item);
529 item = tPtr->items[index];
531 W_MapTabViewItem(item);
533 tPtr->selectedItem = index;
535 if (tPtr->delegate && tPtr->delegate->didSelectItem)
536 (*tPtr->delegate->didSelectItem)(tPtr->delegate, tPtr,
537 tPtr->items[index]);
539 paintTabView(tPtr);
544 static void
545 recalcTabWidth(TabView *tPtr)
547 int i;
548 /*int twidth = W_VIEW(tPtr)->size.width;*/
549 int width;
551 if (tPtr->flags.uniformTabs) {
552 int tabWidth;
554 tabWidth = 0;
556 for (i = 0; i < tPtr->itemCount; i++) {
557 char *str = WMGetTabViewItemLabel(tPtr->items[i]);
559 if (str) {
560 width = WMWidthOfString(tPtr->font, str, strlen(str));
561 if (width > tabWidth)
562 tabWidth = width;
566 tabWidth = tabWidth + 30;
568 for (i = 0; i < tPtr->itemCount; i++)
569 W_SetTabViewItemTabWidth(tPtr->items[i], tabWidth);
571 tPtr->firstVisible = 0;
572 tPtr->visibleTabs = countVisibleTabs(tPtr, -1);
573 if (tPtr->visibleTabs < tPtr->itemCount)
574 tPtr->flags.dontFitAll = 1;
575 else
576 tPtr->flags.dontFitAll = 0;
577 } else {
578 for (i = 0; i < tPtr->itemCount; i++) {
579 char *str = WMGetTabViewItemLabel(tPtr->items[i]);
580 if (!str)
581 continue;
583 width = WMWidthOfString(tPtr->font, str, strlen(str)) + 30;
585 W_SetTabViewItemTabWidth(tPtr->items[i], width);
588 if (countVisibleTabs(tPtr, -1) < tPtr->itemCount) {
589 tPtr->flags.dontFitAll = 1;
590 tPtr->firstVisible = 0;
591 tPtr->visibleTabs = countVisibleTabs(tPtr, tPtr->firstVisible);
592 } else {
593 tPtr->flags.dontFitAll = 0;
594 tPtr->firstVisible = 0;
595 tPtr->visibleTabs = tPtr->itemCount;
601 static void
602 drawRelief(W_Screen *scr, Drawable d, int x, int y, unsigned int width,
603 unsigned int height)
605 Display *dpy = scr->display;
606 GC bgc = WMColorGC(scr->black);
607 GC wgc = WMColorGC(scr->white);
608 GC dgc = WMColorGC(scr->darkGray);
610 XDrawLine(dpy, d, wgc, x, y, x, y+height-1);
612 XDrawLine(dpy, d, bgc, x, y+height-1, x+width-1, y+height-1);
613 XDrawLine(dpy, d, dgc, x+1, y+height-2, x+width-2, y+height-2);
615 XDrawLine(dpy, d, bgc, x+width-1, y, x+width-1, y+height-1);
616 XDrawLine(dpy, d, dgc, x+width-2, y+1, x+width-2, y+height-2);
620 static void
621 drawTab(TabView *tPtr, Drawable d, int x, int y,
622 unsigned width, unsigned height, Bool selected)
624 WMScreen *scr = W_VIEW(tPtr)->screen;
625 Display *dpy = scr->display;
626 GC white = WMColorGC(selected ? scr->white : tPtr->lightGray);
627 GC black = WMColorGC(scr->black);
628 GC dark = WMColorGC(scr->darkGray);
629 GC light = WMColorGC(scr->gray);
630 XPoint trap[8];
632 trap[0].x = x + (selected ? 0 : 1);
633 trap[0].y = y + height - (selected ? 0 : 1);
635 trap[1].x = x + 3;
636 trap[1].y = y + height - 3;
638 trap[2].x = x + 10 - 3;
639 trap[2].y = y + 3;
641 trap[3].x = x + 10;
642 trap[3].y = y;
644 trap[4].x = x + width - 10;
645 trap[4].y = y;
647 trap[5].x = x + width - 10 + 3;
648 trap[5].y = y + 3;
650 trap[6].x = x + width - 3;
651 trap[6].y = y + height - 3;
653 trap[7].x = x + width - (selected ? 0 : 1);
654 trap[7].y = y + height - (selected ? 0 : 1);
656 XFillPolygon(dpy, d, selected ? light : WMColorGC(tPtr->tabColor), trap, 8,
657 Convex, CoordModeOrigin);
659 XDrawLine(dpy, d, white, trap[0].x, trap[0].y, trap[1].x, trap[1].y);
660 XDrawLine(dpy, d, white, trap[1].x, trap[1].y, trap[2].x, trap[2].y);
661 XDrawLine(dpy, d, white, trap[2].x, trap[2].y, trap[3].x, trap[3].y);
662 XDrawLine(dpy, d, white, trap[3].x, trap[3].y, trap[4].x, trap[4].y);
663 XDrawLine(dpy, d, dark, trap[4].x, trap[4].y, trap[5].x, trap[5].y);
664 XDrawLine(dpy, d, black, trap[5].x, trap[5].y, trap[6].x, trap[6].y);
665 XDrawLine(dpy, d, black, trap[6].x, trap[6].y, trap[7].x, trap[7].y);
667 XDrawLine(dpy, d, selected ? light : WMColorGC(scr->white),
668 trap[0].x, trap[0].y, trap[7].x, trap[7].y);
672 static void
673 paintDot(TabView *tPtr, Drawable d, int x, int y)
675 WMScreen *scr = W_VIEW(tPtr)->screen;
676 Display *dpy = scr->display;
677 GC white = WMColorGC(scr->white);
678 GC black = WMColorGC(scr->black);
680 XFillRectangle(dpy, d, black, x, y, 2, 2);
681 XDrawPoint(dpy, d, white, x, y);
686 static void
687 paintTabView(TabView *tPtr)
689 Pixmap buffer;
690 WMScreen *scr = W_VIEW(tPtr)->screen;
691 Display *dpy = scr->display;
692 GC white = WMColorGC(scr->white);
693 int i;
695 if (tPtr->flags.type == WTTopTabsBevelBorder) {
696 int count = tPtr->visibleTabs;
697 int first = tPtr->firstVisible;
698 int moreAtLeft;
699 int moreAtRight;
700 int selectedIsVisible;
701 int ty;
702 int twidth, theight;
704 ty = 2;
705 theight = tPtr->tabHeight;
707 buffer = XCreatePixmap(dpy, W_VIEW(tPtr)->window,
708 W_VIEW(tPtr)->size.width, theight,
709 W_VIEW(tPtr)->screen->depth);
711 XFillRectangle(dpy, buffer, WMColorGC(W_VIEW(tPtr)->backColor),
712 0, 0, W_VIEW(tPtr)->size.width, tPtr->tabHeight);
714 if (tPtr->flags.dontFitAll) {
715 moreAtLeft = first > 0;
716 moreAtRight = (first + count) < tPtr->itemCount;
717 if (tPtr->selectedItem >= first
718 && tPtr->selectedItem < first + count)
719 selectedIsVisible = 1;
720 else
721 selectedIsVisible = 0;
722 } else {
723 moreAtLeft = 0;
724 moreAtRight = 0;
725 selectedIsVisible = 1;
728 if (moreAtRight) {
729 drawTab(tPtr, buffer, positionOfTab(tPtr, first+count), 0,
730 W_VIEW_WIDTH(tPtr->view), theight, False);
732 for (i = first + count-1; i >= first; i--) {
733 if (!selectedIsVisible || i != tPtr->selectedItem) {
734 twidth = W_TabViewItemTabWidth(tPtr->items[i]);
736 drawTab(tPtr, buffer, positionOfTab(tPtr, i), 0,
737 twidth, theight, False);
740 if (moreAtLeft) {
741 drawTab(tPtr, buffer, positionOfTab(tPtr, 0)-2*BUTTONED_SIDE_OFFSET,
742 0, BUTTONED_SIDE_OFFSET*4, theight, False);
745 if (selectedIsVisible) {
746 int idx = tPtr->selectedItem;
748 drawTab(tPtr, buffer, positionOfTab(tPtr, idx),
749 0, W_TabViewItemTabWidth(tPtr->items[idx]),
750 theight, True);
752 XDrawLine(dpy, buffer, white, 0, theight - 1,
753 positionOfTab(tPtr, idx), theight - 1);
755 XDrawLine(dpy, buffer, white,
756 positionOfTab(tPtr, idx) + W_TabViewItemTabWidth(tPtr->items[idx]),
757 tPtr->tabHeight - 1, W_VIEW_WIDTH(tPtr->view) - 1,
758 tPtr->tabHeight - 1);
759 } else {
760 XDrawLine(dpy, buffer, white, 0, theight - 1,
761 W_VIEW_WIDTH(tPtr->view), theight - 1);
764 for (i = 0; i < count; i++) {
765 WMRect rect;
767 rect.pos.x = 15 + positionOfTab(tPtr, first+i);
768 rect.pos.y = ty;
769 rect.size.width = W_TabViewItemTabWidth(tPtr->items[first+i]);
770 rect.size.height = theight;
771 W_DrawLabel(tPtr->items[first+i], buffer, rect,
772 tPtr->flags.enabled &&
773 tPtr->items[first+i]->flags.enabled);
776 if (moreAtLeft) {
777 paintDot(tPtr, buffer, 4, 10);
778 paintDot(tPtr, buffer, 7, 10);
779 paintDot(tPtr, buffer, 10, 10);
781 if (moreAtRight) {
782 int x;
784 x = positionOfTab(tPtr, tPtr->firstVisible + tPtr->visibleTabs);
786 x = x + (W_VIEW_WIDTH(tPtr->view) - x)/2;
787 paintDot(tPtr, buffer, x + 5, 10);
788 paintDot(tPtr, buffer, x + 8, 10);
789 paintDot(tPtr, buffer, x + 11, 10);
792 XCopyArea(dpy, buffer, W_VIEW(tPtr)->window, scr->copyGC, 0, 0,
793 W_VIEW_WIDTH(tPtr->view), theight, 0, 0);
795 XFreePixmap(dpy, buffer);
797 switch (tPtr->flags.type) {
798 case WTTopTabsBevelBorder:
799 drawRelief(scr, W_VIEW(tPtr)->window, 0, tPtr->tabHeight - 1,
800 W_VIEW(tPtr)->size.width,
801 W_VIEW(tPtr)->size.height - tPtr->tabHeight + 1);
802 break;
804 case WTNoTabsBevelBorder:
805 W_DrawRelief(scr, W_VIEW(tPtr)->window, 0, 0, W_VIEW(tPtr)->size.width,
806 W_VIEW(tPtr)->size.height, WRRaised);
807 break;
809 case WTNoTabsLineBorder:
810 W_DrawRelief(scr, W_VIEW(tPtr)->window, 0, 0, W_VIEW(tPtr)->size.width,
811 W_VIEW(tPtr)->size.height, WRSimple);
812 break;
814 case WTNoTabsNoBorder:
815 break;
820 static void
821 rearrange(TabView *tPtr)
823 int i;
824 int width, height;
825 int bordered = tPtr->flags.bordered;
827 recalcTabWidth(tPtr);
829 width = tPtr->view->size.width - (bordered ? 3 : 0);
830 height = tPtr->view->size.height - tPtr->tabHeight - (bordered ? 3 : 0);
832 for (i = 0; i < tPtr->itemCount; i++) {
833 W_MoveView(W_TabViewItemView(tPtr->items[i]),
834 1*bordered, tPtr->tabHeight + 1*bordered);
835 W_ResizeView(W_TabViewItemView(tPtr->items[i]), width, height);
837 if (W_VIEW_MAPPED(tPtr->view) && W_VIEW_REALIZED(tPtr->view))
838 paintTabView(tPtr);
842 static void
843 didResize(struct W_ViewDelegate *deleg, WMView *view)
845 rearrange(view->self);
849 static void
850 destroyTabView(TabView *tPtr)
852 int i;
854 for (i = 0; i < tPtr->itemCount; i++) {
855 WMSetTabViewItemView(tPtr->items[i], NULL);
856 WMDestroyTabViewItem(tPtr->items[i]);
858 wfree(tPtr->items);
860 WMReleaseColor(tPtr->lightGray);
861 WMReleaseColor(tPtr->tabColor);
862 WMReleaseFont(tPtr->font);
864 wfree(tPtr);
867 /******************************************************************/
870 static void
871 W_SetTabViewItemParent(WMTabViewItem *item, WMTabView *parent)
873 item->tabView = parent;
877 static void
878 W_DrawLabel(WMTabViewItem *item, Drawable d, WMRect rect, Bool enabled)
880 WMScreen *scr = W_VIEW(item->tabView)->screen;
882 if (!item->label)
883 return;
885 WMDrawString(scr, d, enabled ? scr->black : scr->darkGray,
886 item->tabView->font, rect.pos.x, rect.pos.y,
887 item->label, strlen(item->label));
891 static void
892 W_UnmapTabViewItem(WMTabViewItem *item)
894 wassertr(item->view);
896 W_UnmapView(item->view);
898 item->flags.visible = 0;
902 static void
903 W_MapTabViewItem(WMTabViewItem *item)
905 wassertr(item->view);
907 W_MapView(item->view);
908 W_RaiseView(item->view);
910 item->flags.visible = 1;
914 static WMView*
915 W_TabViewItemView(WMTabViewItem *item)
917 return item->view;
921 static int
922 W_TabViewItemTabWidth(WMTabViewItem *item)
924 return item->tabWidth;
928 static void
929 W_SetTabViewItemTabWidth(WMTabViewItem *item, int width)
931 item->tabWidth = width;
935 WMTabViewItem*
936 WMCreateTabViewItemWithIdentifier(int identifier)
938 WMTabViewItem *item;
940 item = wmalloc(sizeof(WMTabViewItem));
941 memset(item, 0, sizeof(WMTabViewItem));
943 item->identifier = identifier;
945 item->flags.enabled = 1;
947 return item;
951 WMTabViewItem*
952 WMCreateTabViewItem(int identifier, char *label)
954 WMTabViewItem *item;
956 item = wmalloc(sizeof(WMTabViewItem));
957 memset(item, 0, sizeof(WMTabViewItem));
959 item->identifier = identifier;
961 item->flags.enabled = 1;
963 WMSetTabViewItemLabel(item, label);
965 return item;
969 void
970 WMSetTabViewItemEnabled(WMTabViewItem *tPtr, Bool flag)
972 tPtr->flags.enabled = ((flag==0) ? 0 : 1);
973 if (tPtr->tabView && W_VIEW_REALIZED(tPtr->tabView->view))
974 paintTabView(tPtr->tabView);
979 WMGetTabViewItemIdentifier(WMTabViewItem *item)
981 return item->identifier;
985 void
986 WMSetTabViewFont(WMTabView *tPtr, WMFont *font)
988 if (tPtr->font)
989 WMReleaseFont(tPtr->font);
991 tPtr->font = WMRetainFont(font);
992 tPtr->tabHeight = WMFontHeight(tPtr->font) + 3;
993 recalcTabWidth(tPtr);
997 void
998 WMSetTabViewItemLabel(WMTabViewItem *item, char *label)
1000 if (item->label)
1001 wfree(item->label);
1003 if (label)
1004 item->label = wstrdup(label);
1005 else
1006 item->label = NULL;
1008 if (item->tabView)
1009 recalcTabWidth(item->tabView);
1013 char*
1014 WMGetTabViewItemLabel(WMTabViewItem *item)
1016 return item->label;
1020 void
1021 WMSetTabViewItemView(WMTabViewItem *item, WMView *view)
1023 item->view = view;
1027 WMView*
1028 WMGetTabViewItemView(WMTabViewItem *item)
1030 return item->view;
1034 void
1035 WMDestroyTabViewItem(WMTabViewItem *item)
1037 if (item->label)
1038 wfree(item->label);
1040 if (item->view)
1041 W_DestroyView(item->view);
1043 wfree(item);