Updating to version 0.20.2
[wmaker-crm.git] / WINGs / wbrowser.c
blobcc966dd4572db658522a53651f48597f5e523db5
5 #include "WINGsP.h"
8 char *WMBrowserDidScrollNotification = "WMBrowserDidScrollNotification";
11 typedef struct W_Browser {
12 W_Class widgetClass;
13 W_View *view;
15 char **titles;
16 WMList **columns;
18 short columnCount;
19 short usedColumnCount; /* columns actually being used */
20 short minColumnWidth;
22 short maxVisibleColumns;
23 short firstVisibleColumn;
25 short titleHeight;
27 short selectedColumn;
29 WMSize columnSize;
32 void *clientData;
33 WMAction *action;
34 void *doubleClientData;
35 WMAction *doubleAction;
37 WMBrowserFillColumnProc *fillColumn;
39 WMScroller *scroller;
41 char *pathSeparator;
43 struct {
44 unsigned int isTitled:1;
45 unsigned int allowMultipleSelection:1;
46 unsigned int hasScroller:1;
48 /* */
49 unsigned int loaded:1;
50 unsigned int loadingColumn:1;
51 } flags;
52 } Browser;
55 #define COLUMN_SPACING 4
56 #define TITLE_SPACING 2
58 #define DEFAULT_WIDTH 305
59 #define DEFAULT_HEIGHT 200
60 #define DEFAULT_HAS_SCROLLER True
62 #define DEFAULT_SEPARATOR "/"
64 #define COLUMN_IS_VISIBLE(b, c) ((c) >= (b)->firstVisibleColumn \
65 && (c) < (b)->firstVisibleColumn + (b)->maxVisibleColumns)
68 static void handleEvents(XEvent *event, void *data);
69 static void destroyBrowser(WMBrowser *bPtr);
71 static void setupScroller(WMBrowser *bPtr);
73 static void scrollToColumn(WMBrowser *bPtr, int column);
75 static void paintItem(WMList *lPtr, Drawable d, char *text, int state,
76 WMRect *rect);
78 static void loadColumn(WMBrowser *bPtr, int column);
81 static void resizeBrowser(WMWidget*, unsigned int, unsigned int);
83 W_ViewProcedureTable _BrowserViewProcedures = {
84 NULL,
85 resizeBrowser,
86 NULL
91 WMBrowser*
92 WMCreateBrowser(WMWidget *parent)
94 WMBrowser *bPtr;
95 int i;
97 bPtr = wmalloc(sizeof(WMBrowser));
98 memset(bPtr, 0, sizeof(WMBrowser));
100 bPtr->widgetClass = WC_Browser;
102 bPtr->view = W_CreateView(W_VIEW(parent));
103 if (!bPtr->view) {
104 free(bPtr);
105 return NULL;
107 bPtr->view->self = bPtr;
109 WMCreateEventHandler(bPtr->view, ExposureMask|StructureNotifyMask
110 |ClientMessageMask, handleEvents, bPtr);
112 /* default configuration */
113 bPtr->flags.hasScroller = DEFAULT_HAS_SCROLLER;
115 bPtr->titleHeight = 20;
116 bPtr->flags.isTitled = 1;
117 bPtr->maxVisibleColumns = 2;
119 resizeBrowser(bPtr, DEFAULT_WIDTH, DEFAULT_HEIGHT);
121 bPtr->pathSeparator = wstrdup(DEFAULT_SEPARATOR);
123 if (bPtr->flags.hasScroller)
124 setupScroller(bPtr);
126 for (i=0; i<bPtr->maxVisibleColumns; i++) {
127 WMAddBrowserColumn(bPtr);
129 bPtr->usedColumnCount = 0;
131 bPtr->selectedColumn = -1;
133 return bPtr;
137 int
138 WMGetBrowserNumberOfColumns(WMBrowser *bPtr)
140 return bPtr->usedColumnCount;
143 void
144 WMSetBrowserPathSeparator(WMBrowser *bPtr, char *separator)
146 if (bPtr->pathSeparator)
147 free(bPtr->pathSeparator);
148 bPtr->pathSeparator = wstrdup(separator);
153 static void
154 drawTitleOfColumn(WMBrowser *bPtr, int column)
156 WMScreen *scr = bPtr->view->screen;
157 int x;
159 x=(column-bPtr->firstVisibleColumn)*(bPtr->columnSize.width+COLUMN_SPACING);
161 XFillRectangle(scr->display, bPtr->view->window, W_GC(scr->darkGray), x, 0,
162 bPtr->columnSize.width, bPtr->titleHeight);
163 W_DrawRelief(scr, bPtr->view->window, x, 0,
164 bPtr->columnSize.width, bPtr->titleHeight, WRSunken);
166 if (column < bPtr->usedColumnCount && bPtr->titles[column])
167 W_PaintText(bPtr->view, bPtr->view->window, scr->boldFont, x,
168 (bPtr->titleHeight-scr->boldFont->height)/2,
169 bPtr->columnSize.width, WACenter, W_GC(scr->white),
170 False, bPtr->titles[column], strlen(bPtr->titles[column]));
174 void
175 WMSetBrowserColumnTitle(WMBrowser *bPtr, int column, char *title)
177 assert(column >= 0);
178 assert(column < bPtr->usedColumnCount);
180 if (bPtr->titles[column])
181 free(bPtr->titles[column]);
183 bPtr->titles[column] = wstrdup(title);
185 if (COLUMN_IS_VISIBLE(bPtr, column) && bPtr->flags.isTitled) {
186 drawTitleOfColumn(bPtr, column);
191 WMList*
192 WMGetBrowserListInColumn(WMBrowser *bPtr, int column)
194 if (column < 0 || column >= bPtr->usedColumnCount)
195 return NULL;
197 return bPtr->columns[column];
201 void
202 WMSetBrowserFillColumnProc(WMBrowser *bPtr, WMBrowserFillColumnProc *proc)
204 bPtr->fillColumn = proc;
208 int
209 WMGetBrowserFirstVisibleColumn(WMBrowser *bPtr)
211 return bPtr->firstVisibleColumn;
215 static void
216 removeColumn(WMBrowser *bPtr, int column)
218 int i;
219 WMList **clist;
220 char **tlist;
222 if (column >= bPtr->usedColumnCount)
223 return;
225 if (column < bPtr->maxVisibleColumns) {
226 int tmp;
227 for (i=column; i < bPtr->maxVisibleColumns; i++) {
228 if (bPtr->titles[i])
229 free(bPtr->titles[i]);
230 bPtr->titles[i] = NULL;
232 WMClearList(bPtr->columns[i]);
233 bPtr->usedColumnCount--;
235 tmp = bPtr->columnCount;
236 for (i=bPtr->maxVisibleColumns; i < tmp; i++) {
237 if (bPtr->titles[i])
238 free(bPtr->titles[i]);
239 bPtr->titles[i] = NULL;
241 WMDestroyWidget(bPtr->columns[i]);
242 bPtr->columns[i] = NULL;
243 bPtr->columnCount--;
244 bPtr->usedColumnCount--;
246 } else {
247 int tmp = bPtr->columnCount;
248 for (i=column; i < tmp; i++) {
249 if (bPtr->titles[i])
250 free(bPtr->titles[i]);
251 bPtr->titles[i] = NULL;
253 WMDestroyWidget(bPtr->columns[i]);
254 bPtr->columns[i] = NULL;
255 bPtr->columnCount--;
256 bPtr->usedColumnCount--;
259 clist = wmalloc(sizeof(WMList*)*bPtr->columnCount);
260 tlist = wmalloc(sizeof(char*)*bPtr->columnCount);
261 memcpy(clist, bPtr->columns, sizeof(WMList*)*bPtr->columnCount);
262 memcpy(tlist, bPtr->titles, sizeof(char*)*bPtr->columnCount);
263 free(bPtr->titles);
264 free(bPtr->columns);
265 bPtr->titles = tlist;
266 bPtr->columns = clist;
271 WMListItem*
272 WMGetBrowserSelectedItemInColumn(WMBrowser *bPtr, int column)
274 if ((column < 0) || (column > bPtr->columnCount))
275 return NULL;
277 return WMGetListSelectedItem(bPtr->columns[column]);
283 WMGetBrowserSelectedColumn(WMBrowser *bPtr)
285 return bPtr->selectedColumn;
290 WMGetBrowserSelectedRowInColumn(WMBrowser *bPtr, int column)
292 if (column >= 0 && column < bPtr->columnCount) {
293 return WMGetListSelectedItemRow(bPtr->columns[column]);
294 } else {
295 return -1;
300 void
301 WMSetBrowserTitled(WMBrowser *bPtr, Bool flag)
303 int i;
304 int columnX, columnY;
306 if (bPtr->flags.isTitled == flag)
307 return;
309 columnX = 0;
311 if (!bPtr->flags.isTitled) {
312 columnY = TITLE_SPACING + bPtr->titleHeight;
314 bPtr->columnSize.height -= columnY;
316 for (i=0; i<bPtr->columnCount; i++) {
317 WMResizeWidget(bPtr->columns[i], bPtr->columnSize.width,
318 bPtr->columnSize.height);
320 columnX = WMWidgetView(bPtr->columns[i])->pos.x;
322 WMMoveWidget(bPtr->columns[i], columnX, columnY);
324 } else {
325 bPtr->columnSize.height += TITLE_SPACING + bPtr->titleHeight;
327 for (i=0; i<bPtr->columnCount; i++) {
328 WMResizeWidget(bPtr->columns[i], bPtr->columnSize.width,
329 bPtr->columnSize.height);
331 columnX = WMWidgetView(bPtr->columns[i])->pos.x;
333 WMMoveWidget(bPtr->columns[i], columnX, 0);
337 bPtr->flags.isTitled = flag;
341 WMListItem*
342 WMAddSortedBrowserItem(WMBrowser *bPtr, int column, char *text, Bool isBranch)
344 WMListItem *item;
346 if (column < 0 || column >= bPtr->columnCount)
347 return NULL;
349 item = WMAddSortedListItem(bPtr->columns[column], text);
350 item->isBranch = isBranch;
352 return item;
357 WMListItem*
358 WMInsertBrowserItem(WMBrowser *bPtr, int column, int row, char *text,
359 Bool isBranch)
361 WMListItem *item;
363 if (column < 0 || column >= bPtr->columnCount)
364 return NULL;
366 item = WMInsertListItem(bPtr->columns[column], row, text);
367 item->isBranch = isBranch;
369 return item;
375 static void
376 resizeBrowser(WMWidget *w, unsigned int width, unsigned int height)
378 WMBrowser *bPtr = (WMBrowser*)w;
379 int cols = bPtr->maxVisibleColumns;
380 int colX, colY;
381 int i;
383 assert(width > 0);
384 assert(height > 0);
386 bPtr->columnSize.width = (width-(cols-1)*COLUMN_SPACING) / cols;
387 bPtr->columnSize.height = height;
389 if (bPtr->flags.isTitled) {
390 bPtr->columnSize.height -= TITLE_SPACING + bPtr->titleHeight;
391 colY = TITLE_SPACING + bPtr->titleHeight;
392 } else {
393 colY = 0;
396 if (bPtr->flags.hasScroller) {
397 bPtr->columnSize.height -= SCROLLER_WIDTH + 4;
399 if (bPtr->scroller) {
400 WMResizeWidget(bPtr->scroller, width-2, 1);
401 WMMoveWidget(bPtr->scroller, 1, height-SCROLLER_WIDTH-1);
405 colX = 0;
406 for (i = 0; i < bPtr->columnCount; i++) {
407 WMResizeWidget(bPtr->columns[i], bPtr->columnSize.width,
408 bPtr->columnSize.height);
410 WMMoveWidget(bPtr->columns[i], colX, colY);
412 if (COLUMN_IS_VISIBLE(bPtr, i)) {
413 colX += bPtr->columnSize.width+COLUMN_SPACING;
417 W_ResizeView(bPtr->view, width, height);
421 static void
422 paintItem(WMList *lPtr, Drawable d, char *text, int state, WMRect *rect)
424 WMView *view = W_VIEW(lPtr);
425 W_Screen *scr = view->screen;
426 int width, height, x, y;
428 width = rect->size.width;
429 height = rect->size.height;
430 x = rect->pos.x;
431 y = rect->pos.y;
433 if (state & WLDSSelected)
434 XFillRectangle(scr->display, d, W_GC(scr->white), x, y,
435 width, height);
436 else
437 XClearArea(scr->display, d, x, y, width, height, False);
439 if (text)
440 W_PaintText(view, d, scr->normalFont, x+4, y, width,
441 WALeft, W_GC(scr->black), False, text, strlen(text));
443 if (state & WLDSIsBranch) {
444 XDrawLine(scr->display, d, W_GC(scr->darkGray), x+width-11, y+3,
445 x+width-6, y+height/2);
446 if (state & WLDSSelected)
447 XDrawLine(scr->display, d,W_GC(scr->gray), x+width-11, y+height-5,
448 x+width-6, y+height/2);
449 else
450 XDrawLine(scr->display, d,W_GC(scr->white), x+width-11, y+height-5,
451 x+width-6, y+height/2);
452 XDrawLine(scr->display, d, W_GC(scr->black), x+width-12, y+3,
453 x+width-12, y+height-5);
458 static void
459 scrollCallback(WMWidget *scroller, void *self)
461 WMBrowser *bPtr = (WMBrowser*)self;
462 WMScroller *sPtr = (WMScroller*)scroller;
463 int newFirst;
464 #define LAST_VISIBLE_COLUMN bPtr->firstVisibleColumn+bPtr->maxVisibleColumns
466 switch (WMGetScrollerHitPart(sPtr)) {
467 case WSDecrementLine:
468 if (bPtr->firstVisibleColumn > 0) {
469 scrollToColumn(bPtr, bPtr->firstVisibleColumn-1);
471 break;
473 case WSDecrementPage:
474 if (bPtr->firstVisibleColumn > 0) {
475 newFirst = bPtr->firstVisibleColumn - bPtr->maxVisibleColumns;
477 scrollToColumn(bPtr, newFirst);
479 break;
482 case WSIncrementLine:
483 if (LAST_VISIBLE_COLUMN < bPtr->columnCount) {
484 scrollToColumn(bPtr, bPtr->firstVisibleColumn+1);
486 break;
488 case WSIncrementPage:
489 if (LAST_VISIBLE_COLUMN < bPtr->columnCount) {
490 newFirst = bPtr->firstVisibleColumn + bPtr->maxVisibleColumns;
492 if (newFirst+bPtr->maxVisibleColumns >= bPtr->columnCount)
493 newFirst = bPtr->columnCount - bPtr->maxVisibleColumns;
495 scrollToColumn(bPtr, newFirst);
497 break;
499 case WSKnob:
501 float floatValue;
502 float value = bPtr->columnCount - bPtr->maxVisibleColumns;
504 floatValue = WMGetScrollerValue(bPtr->scroller);
506 floatValue = (floatValue*value)/value;
508 newFirst = floatValue*(float)(bPtr->columnCount - bPtr->maxVisibleColumns);
510 if (bPtr->firstVisibleColumn != newFirst)
511 scrollToColumn(bPtr, newFirst);
512 else
513 WMSetScrollerParameters(bPtr->scroller, floatValue,
514 bPtr->maxVisibleColumns/(float)bPtr->columnCount);
517 break;
519 case WSKnobSlot:
520 case WSNoPart:
521 /* do nothing */
522 break;
524 #undef LAST_VISIBLE_COLUMN
528 static void
529 setupScroller(WMBrowser *bPtr)
531 WMScroller *sPtr;
532 int y;
534 y = bPtr->view->size.height - SCROLLER_WIDTH - 1;
536 sPtr = WMCreateScroller(bPtr);
537 WMSetScrollerAction(sPtr, scrollCallback, bPtr);
538 WMMoveWidget(sPtr, 1, y);
539 WMResizeWidget(sPtr, bPtr->view->size.width-2, SCROLLER_WIDTH);
541 bPtr->scroller = sPtr;
543 WMMapWidget(sPtr);
547 void
548 WMSetBrowserAction(WMBrowser *bPtr, WMAction *action, void *clientData)
550 bPtr->action = action;
551 bPtr->clientData = clientData;
555 void
556 WMSetBrowserHasScroller(WMBrowser *bPtr, int hasScroller)
558 bPtr->flags.hasScroller = hasScroller;
563 Bool
564 WMSetBrowserPath(WMBrowser *bPtr, char *path)
566 int i;
567 char *str = wstrdup(path);
568 char *tmp;
569 int item;
570 Bool ok = True;
571 WMListItem *listItem;
573 removeColumn(bPtr, 1);
575 i = 0;
576 tmp = strtok(str, bPtr->pathSeparator);
577 while (tmp) {
578 /* select it in the column */
579 item = WMFindRowOfListItemWithTitle(bPtr->columns[i], tmp);
580 if (item<0) {
581 ok = False;
582 break;
584 WMSelectListItem(bPtr->columns[i], item);
585 WMSetListPosition(bPtr->columns[i], item);
587 listItem = WMGetListItem(bPtr->columns[i], item);
588 if (!listItem || !listItem->isBranch) {
589 break;
592 /* load next column */
593 WMAddBrowserColumn(bPtr);
595 loadColumn(bPtr, i+1);
597 tmp = strtok(NULL, bPtr->pathSeparator);
599 i++;
601 free(str);
603 bPtr->selectedColumn = bPtr->usedColumnCount - 1;
605 scrollToColumn(bPtr, bPtr->columnCount-bPtr->maxVisibleColumns);
607 return ok;
611 char*
612 WMGetBrowserPath(WMBrowser *bPtr)
614 return WMGetBrowserPathToColumn(bPtr, bPtr->columnCount);
618 char*
619 WMGetBrowserPathToColumn(WMBrowser *bPtr, int column)
621 int i, size;
622 char *path;
623 WMListItem *item;
625 if (column >= bPtr->usedColumnCount)
626 column = bPtr->usedColumnCount-1;
628 /* calculate size of buffer */
629 size = 0;
630 for (i = 0; i <= column; i++) {
631 item = WMGetListSelectedItem(bPtr->columns[i]);
632 if (!item)
633 break;
634 size += strlen(item->text);
637 /* get the path */
638 path = wmalloc(size+(column+1)*strlen(bPtr->pathSeparator)+1);
639 /* ignore first / */
640 *path = 0;
641 for (i = 0; i <= column; i++) {
642 strcat(path, bPtr->pathSeparator);
643 item = WMGetListSelectedItem(bPtr->columns[i]);
644 if (!item)
645 break;
646 strcat(path, item->text);
649 return path;
653 static void
654 loadColumn(WMBrowser *bPtr, int column)
656 assert(bPtr->fillColumn);
658 bPtr->flags.loadingColumn = 1;
659 (*bPtr->fillColumn)(bPtr, column);
660 bPtr->flags.loadingColumn = 0;
664 static void
665 paintBrowser(WMBrowser *bPtr)
667 int i;
669 if (!bPtr->view->flags.mapped)
670 return;
672 W_DrawRelief(bPtr->view->screen, bPtr->view->window, 0,
673 bPtr->view->size.height-SCROLLER_WIDTH-2,
674 bPtr->view->size.width, 22, WRSunken);
676 if (bPtr->flags.isTitled) {
677 for (i=0; i<bPtr->maxVisibleColumns; i++) {
678 drawTitleOfColumn(bPtr, i+bPtr->firstVisibleColumn);
684 static void
685 handleEvents(XEvent *event, void *data)
687 WMBrowser *bPtr = (WMBrowser*)data;
689 CHECK_CLASS(data, WC_Browser);
692 switch (event->type) {
693 case Expose:
694 paintBrowser(bPtr);
695 break;
697 case DestroyNotify:
698 destroyBrowser(bPtr);
699 break;
706 static void
707 scrollToColumn(WMBrowser *bPtr, int column)
709 int i;
710 int x;
711 int notify = 0;
714 if (column != bPtr->firstVisibleColumn)
715 notify = 1;
717 if (column < 0)
718 column = 0;
720 x = 0;
721 bPtr->firstVisibleColumn = column;
722 for (i = 0; i < bPtr->usedColumnCount; i++) {
723 if (COLUMN_IS_VISIBLE(bPtr, i)) {
724 WMMoveWidget(bPtr->columns[i], x,
725 WMWidgetView(bPtr->columns[i])->pos.y);
726 if (!WMWidgetView(bPtr->columns[i])->flags.realized)
727 WMRealizeWidget(bPtr->columns[i]);
728 WMMapWidget(bPtr->columns[i]);
729 x += bPtr->columnSize.width+COLUMN_SPACING;
730 } else {
731 WMUnmapWidget(bPtr->columns[i]);
735 /* update the scroller */
736 if (bPtr->columnCount > bPtr->maxVisibleColumns) {
737 float value, proportion;
739 value = bPtr->firstVisibleColumn
740 /(float)(bPtr->columnCount-bPtr->maxVisibleColumns);
741 proportion = bPtr->maxVisibleColumns/(float)bPtr->columnCount;
742 WMSetScrollerParameters(bPtr->scroller, value, proportion);
743 } else {
744 WMSetScrollerParameters(bPtr->scroller, 0, 1);
747 if (bPtr->view->flags.mapped)
748 paintBrowser(bPtr);
750 if (notify)
751 WMPostNotificationName(WMBrowserDidScrollNotification, bPtr, NULL);
755 static void
756 listCallback(void *self, void *clientData)
758 WMBrowser *bPtr = (WMBrowser*)clientData;
759 WMList *lPtr = (WMList*)self;
760 WMListItem *item;
761 int i;
763 item = WMGetListSelectedItem(lPtr);
764 if (!item)
765 return;
767 for (i=0; i<bPtr->columnCount; i++) {
768 if (lPtr == bPtr->columns[i])
769 break;
771 assert(i<bPtr->columnCount);
773 bPtr->selectedColumn = i;
775 /* columns at right must be cleared */
776 removeColumn(bPtr, i+1);
777 /* open directory */
778 if (item->isBranch) {
779 WMAddBrowserColumn(bPtr);
780 loadColumn(bPtr, bPtr->usedColumnCount-1);
782 if (bPtr->usedColumnCount < bPtr->maxVisibleColumns)
783 i = 0;
784 else
785 i = bPtr->usedColumnCount-bPtr->maxVisibleColumns;
786 scrollToColumn(bPtr, i);
788 /* call callback for click */
789 if (bPtr->action)
790 (*bPtr->action)(bPtr, bPtr->clientData);
794 void
795 WMLoadBrowserColumnZero(WMBrowser *bPtr)
797 if (!bPtr->flags.loaded) {
798 /* create column 0 */
799 WMAddBrowserColumn(bPtr);
801 loadColumn(bPtr, 0);
803 /* make column 0 visible */
804 scrollToColumn(bPtr, 0);
806 bPtr->flags.loaded = 1;
811 void
812 WMRemoveBrowserItem(WMBrowser *bPtr, int column, int row)
814 WMList *list;
816 if (column < 0 || column >= bPtr->usedColumnCount)
817 return;
819 list = WMGetBrowserListInColumn(bPtr, column);
821 if (row < 0 || row >= WMGetListNumberOfRows(list))
822 return;
824 removeColumn(bPtr, column+1);
825 if (bPtr->usedColumnCount < bPtr->maxVisibleColumns)
826 scrollToColumn(bPtr, 0);
827 else
828 scrollToColumn(bPtr, bPtr->usedColumnCount-bPtr->maxVisibleColumns);
830 WMRemoveListItem(list, row);
835 WMAddBrowserColumn(WMBrowser *bPtr)
837 WMList *list;
838 WMList **clist;
839 char **tlist;
840 int colY;
841 int index;
844 if (bPtr->usedColumnCount < bPtr->columnCount) {
845 return bPtr->usedColumnCount++;
848 bPtr->usedColumnCount++;
850 if (bPtr->flags.isTitled) {
851 colY = TITLE_SPACING + bPtr->titleHeight;
852 } else {
853 colY = 0;
856 index = bPtr->columnCount;
857 bPtr->columnCount++;
858 clist = wmalloc(sizeof(WMList*)*bPtr->columnCount);
859 tlist = wmalloc(sizeof(char*)*bPtr->columnCount);
860 memcpy(clist, bPtr->columns, sizeof(WMList*)*(bPtr->columnCount-1));
861 memcpy(tlist, bPtr->titles, sizeof(char*)*(bPtr->columnCount-1));
862 if (bPtr->columns)
863 free(bPtr->columns);
864 if (bPtr->titles)
865 free(bPtr->titles);
866 bPtr->columns = clist;
867 bPtr->titles = tlist;
869 bPtr->titles[index] = NULL;
871 list = WMCreateList(bPtr);
872 WMSetListAction(list, listCallback, bPtr);
873 WMSetListUserDrawProc(list, paintItem);
874 bPtr->columns[index] = list;
876 WMResizeWidget(list, bPtr->columnSize.width, bPtr->columnSize.height);
877 WMMoveWidget(list, (bPtr->columnSize.width+COLUMN_SPACING)*index, colY);
878 if (COLUMN_IS_VISIBLE(bPtr, index))
879 WMMapWidget(list);
881 /* update the scroller */
882 if (bPtr->columnCount > bPtr->maxVisibleColumns) {
883 float value, proportion;
885 value = bPtr->firstVisibleColumn
886 /(float)(bPtr->columnCount-bPtr->maxVisibleColumns);
887 proportion = bPtr->maxVisibleColumns/(float)bPtr->columnCount;
888 WMSetScrollerParameters(bPtr->scroller, value, proportion);
891 return index;
896 static void
897 destroyBrowser(WMBrowser *bPtr)
899 int i;
901 for (i=0; i<bPtr->columnCount; i++) {
902 if (bPtr->titles[i])
903 free(bPtr->titles[i]);
905 free(bPtr->titles);
907 free(bPtr->pathSeparator);
909 free(bPtr);