Initial revision
[wmaker-crm.git] / WINGs / wbrowser.c
blob44a3ba27528393f90bad88acfdec8719cd701885
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 W_PaintText(view, d, scr->normalFont, x+4, y, width,
440 WALeft, W_GC(scr->black), False, text, strlen(text));
442 if (state & WLDSIsBranch) {
443 XDrawLine(scr->display, d, W_GC(scr->darkGray), x+width-11, y+3,
444 x+width-6, y+height/2);
445 if (state & WLDSSelected)
446 XDrawLine(scr->display, d,W_GC(scr->gray), x+width-11, y+height-5,
447 x+width-6, y+height/2);
448 else
449 XDrawLine(scr->display, d,W_GC(scr->white), x+width-11, y+height-5,
450 x+width-6, y+height/2);
451 XDrawLine(scr->display, d, W_GC(scr->black), x+width-12, y+3,
452 x+width-12, y+height-5);
457 static void
458 scrollCallback(WMWidget *scroller, void *self)
460 WMBrowser *bPtr = (WMBrowser*)self;
461 WMScroller *sPtr = (WMScroller*)scroller;
462 int newFirst;
463 #define LAST_VISIBLE_COLUMN bPtr->firstVisibleColumn+bPtr->maxVisibleColumns
465 switch (WMGetScrollerHitPart(sPtr)) {
466 case WSDecrementLine:
467 if (bPtr->firstVisibleColumn > 0) {
468 scrollToColumn(bPtr, bPtr->firstVisibleColumn-1);
470 break;
472 case WSDecrementPage:
473 if (bPtr->firstVisibleColumn > 0) {
474 newFirst = bPtr->firstVisibleColumn - bPtr->maxVisibleColumns;
476 scrollToColumn(bPtr, newFirst);
478 break;
481 case WSIncrementLine:
482 if (LAST_VISIBLE_COLUMN < bPtr->columnCount) {
483 scrollToColumn(bPtr, bPtr->firstVisibleColumn+1);
485 break;
487 case WSIncrementPage:
488 if (LAST_VISIBLE_COLUMN < bPtr->columnCount) {
489 newFirst = bPtr->firstVisibleColumn + bPtr->maxVisibleColumns;
491 if (newFirst+bPtr->maxVisibleColumns >= bPtr->columnCount)
492 newFirst = bPtr->columnCount - bPtr->maxVisibleColumns;
494 scrollToColumn(bPtr, newFirst);
496 break;
498 case WSKnob:
500 float floatValue;
501 float value = bPtr->columnCount - bPtr->maxVisibleColumns;
503 floatValue = WMGetScrollerValue(bPtr->scroller);
505 floatValue = (floatValue*value)/value;
507 newFirst = floatValue*(float)(bPtr->columnCount - bPtr->maxVisibleColumns);
509 if (bPtr->firstVisibleColumn != newFirst)
510 scrollToColumn(bPtr, newFirst);
511 else
512 WMSetScrollerParameters(bPtr->scroller, floatValue,
513 bPtr->maxVisibleColumns/(float)bPtr->columnCount);
516 break;
518 case WSKnobSlot:
519 case WSNoPart:
520 /* do nothing */
521 break;
523 #undef LAST_VISIBLE_COLUMN
527 static void
528 setupScroller(WMBrowser *bPtr)
530 WMScroller *sPtr;
531 int y;
533 y = bPtr->view->size.height - SCROLLER_WIDTH - 1;
535 sPtr = WMCreateScroller(bPtr);
536 WMSetScrollerAction(sPtr, scrollCallback, bPtr);
537 WMMoveWidget(sPtr, 1, y);
538 WMResizeWidget(sPtr, bPtr->view->size.width-2, SCROLLER_WIDTH);
540 bPtr->scroller = sPtr;
542 WMMapWidget(sPtr);
546 void
547 WMSetBrowserAction(WMBrowser *bPtr, WMAction *action, void *clientData)
549 bPtr->action = action;
550 bPtr->clientData = clientData;
554 void
555 WMSetBrowserHasScroller(WMBrowser *bPtr, int hasScroller)
557 bPtr->flags.hasScroller = hasScroller;
562 Bool
563 WMSetBrowserPath(WMBrowser *bPtr, char *path)
565 int i;
566 char *str = wstrdup(path);
567 char *tmp;
568 int item;
569 Bool ok = True;
570 WMListItem *listItem;
572 removeColumn(bPtr, 1);
574 i = 0;
575 tmp = strtok(str, bPtr->pathSeparator);
576 while (tmp) {
577 /* select it in the column */
578 item = WMFindRowOfListItemWithTitle(bPtr->columns[i], tmp);
579 if (item<0) {
580 ok = False;
581 break;
583 WMSelectListItem(bPtr->columns[i], item);
584 WMSetListPosition(bPtr->columns[i], item);
586 listItem = WMGetListItem(bPtr->columns[i], item);
587 if (!listItem || !listItem->isBranch) {
588 break;
591 /* load next column */
592 WMAddBrowserColumn(bPtr);
594 loadColumn(bPtr, i+1);
596 tmp = strtok(NULL, bPtr->pathSeparator);
598 i++;
600 free(str);
602 bPtr->selectedColumn = bPtr->usedColumnCount - 1;
604 scrollToColumn(bPtr, bPtr->columnCount-bPtr->maxVisibleColumns);
606 return ok;
610 char*
611 WMGetBrowserPath(WMBrowser *bPtr)
613 return WMGetBrowserPathToColumn(bPtr, bPtr->columnCount);
617 char*
618 WMGetBrowserPathToColumn(WMBrowser *bPtr, int column)
620 int i, size;
621 char *path;
622 WMListItem *item;
624 if (column >= bPtr->usedColumnCount)
625 column = bPtr->usedColumnCount-1;
627 /* calculate size of buffer */
628 size = 0;
629 for (i = 0; i <= column; i++) {
630 item = WMGetListSelectedItem(bPtr->columns[i]);
631 if (!item)
632 break;
633 size += strlen(item->text);
636 /* get the path */
637 path = wmalloc(size+(column+1)*strlen(bPtr->pathSeparator)+1);
638 /* ignore first / */
639 *path = 0;
640 for (i = 0; i <= column; i++) {
641 strcat(path, bPtr->pathSeparator);
642 item = WMGetListSelectedItem(bPtr->columns[i]);
643 if (!item)
644 break;
645 strcat(path, item->text);
648 return path;
652 static void
653 loadColumn(WMBrowser *bPtr, int column)
655 assert(bPtr->fillColumn);
657 bPtr->flags.loadingColumn = 1;
658 (*bPtr->fillColumn)(bPtr, column);
659 bPtr->flags.loadingColumn = 0;
663 static void
664 paintBrowser(WMBrowser *bPtr)
666 int i;
668 if (!bPtr->view->flags.mapped)
669 return;
671 W_DrawRelief(bPtr->view->screen, bPtr->view->window, 0,
672 bPtr->view->size.height-SCROLLER_WIDTH-2,
673 bPtr->view->size.width, 22, WRSunken);
675 if (bPtr->flags.isTitled) {
676 for (i=0; i<bPtr->maxVisibleColumns; i++) {
677 drawTitleOfColumn(bPtr, i+bPtr->firstVisibleColumn);
683 static void
684 handleEvents(XEvent *event, void *data)
686 WMBrowser *bPtr = (WMBrowser*)data;
688 CHECK_CLASS(data, WC_Browser);
691 switch (event->type) {
692 case Expose:
693 paintBrowser(bPtr);
694 break;
696 case DestroyNotify:
697 destroyBrowser(bPtr);
698 break;
705 static void
706 scrollToColumn(WMBrowser *bPtr, int column)
708 int i;
709 int x;
710 int notify = 0;
713 if (column != bPtr->firstVisibleColumn)
714 notify = 1;
716 if (column < 0)
717 column = 0;
719 x = 0;
720 bPtr->firstVisibleColumn = column;
721 for (i = 0; i < bPtr->usedColumnCount; i++) {
722 if (COLUMN_IS_VISIBLE(bPtr, i)) {
723 WMMoveWidget(bPtr->columns[i], x,
724 WMWidgetView(bPtr->columns[i])->pos.y);
725 if (!WMWidgetView(bPtr->columns[i])->flags.realized)
726 WMRealizeWidget(bPtr->columns[i]);
727 WMMapWidget(bPtr->columns[i]);
728 x += bPtr->columnSize.width+COLUMN_SPACING;
729 } else {
730 WMUnmapWidget(bPtr->columns[i]);
734 /* update the scroller */
735 if (bPtr->columnCount > bPtr->maxVisibleColumns) {
736 float value, proportion;
738 value = bPtr->firstVisibleColumn
739 /(float)(bPtr->columnCount-bPtr->maxVisibleColumns);
740 proportion = bPtr->maxVisibleColumns/(float)bPtr->columnCount;
741 WMSetScrollerParameters(bPtr->scroller, value, proportion);
742 } else {
743 WMSetScrollerParameters(bPtr->scroller, 0, 1);
746 if (bPtr->view->flags.mapped)
747 paintBrowser(bPtr);
749 if (notify)
750 WMPostNotificationName(WMBrowserDidScrollNotification, bPtr, NULL);
754 static void
755 listCallback(void *self, void *clientData)
757 WMBrowser *bPtr = (WMBrowser*)clientData;
758 WMList *lPtr = (WMList*)self;
759 WMListItem *item;
760 int i;
762 item = WMGetListSelectedItem(lPtr);
763 if (!item)
764 return;
766 for (i=0; i<bPtr->columnCount; i++) {
767 if (lPtr == bPtr->columns[i])
768 break;
770 assert(i<bPtr->columnCount);
772 bPtr->selectedColumn = i;
774 /* columns at right must be cleared */
775 removeColumn(bPtr, i+1);
776 /* open directory */
777 if (item->isBranch) {
778 WMAddBrowserColumn(bPtr);
779 loadColumn(bPtr, bPtr->usedColumnCount-1);
781 if (bPtr->usedColumnCount < bPtr->maxVisibleColumns)
782 i = 0;
783 else
784 i = bPtr->usedColumnCount-bPtr->maxVisibleColumns;
785 scrollToColumn(bPtr, i);
787 /* call callback for click */
788 if (bPtr->action)
789 (*bPtr->action)(bPtr, bPtr->clientData);
793 void
794 WMLoadBrowserColumnZero(WMBrowser *bPtr)
796 if (!bPtr->flags.loaded) {
797 /* create column 0 */
798 WMAddBrowserColumn(bPtr);
800 loadColumn(bPtr, 0);
802 /* make column 0 visible */
803 scrollToColumn(bPtr, 0);
805 bPtr->flags.loaded = 1;
810 void
811 WMRemoveBrowserItem(WMBrowser *bPtr, int column, int row)
813 WMList *list;
815 if (column < 0 || column >= bPtr->usedColumnCount)
816 return;
818 list = WMGetBrowserListInColumn(bPtr, column);
820 if (row < 0 || row >= WMGetListNumberOfRows(list))
821 return;
823 removeColumn(bPtr, column+1);
824 if (bPtr->usedColumnCount < bPtr->maxVisibleColumns)
825 scrollToColumn(bPtr, 0);
826 else
827 scrollToColumn(bPtr, bPtr->usedColumnCount-bPtr->maxVisibleColumns);
829 WMRemoveListItem(list, row);
834 WMAddBrowserColumn(WMBrowser *bPtr)
836 WMList *list;
837 WMList **clist;
838 char **tlist;
839 int colY;
840 int index;
843 if (bPtr->usedColumnCount < bPtr->columnCount) {
844 return bPtr->usedColumnCount++;
847 bPtr->usedColumnCount++;
849 if (bPtr->flags.isTitled) {
850 colY = TITLE_SPACING + bPtr->titleHeight;
851 } else {
852 colY = 0;
855 index = bPtr->columnCount;
856 bPtr->columnCount++;
857 clist = wmalloc(sizeof(WMList*)*bPtr->columnCount);
858 tlist = wmalloc(sizeof(char*)*bPtr->columnCount);
859 memcpy(clist, bPtr->columns, sizeof(WMList*)*(bPtr->columnCount-1));
860 memcpy(tlist, bPtr->titles, sizeof(char*)*(bPtr->columnCount-1));
861 if (bPtr->columns)
862 free(bPtr->columns);
863 if (bPtr->titles)
864 free(bPtr->titles);
865 bPtr->columns = clist;
866 bPtr->titles = tlist;
868 bPtr->titles[index] = NULL;
870 list = WMCreateList(bPtr);
871 WMSetListAction(list, listCallback, bPtr);
872 WMSetListUserDrawProc(list, paintItem);
873 bPtr->columns[index] = list;
875 WMResizeWidget(list, bPtr->columnSize.width, bPtr->columnSize.height);
876 WMMoveWidget(list, (bPtr->columnSize.width+COLUMN_SPACING)*index, colY);
877 if (COLUMN_IS_VISIBLE(bPtr, index))
878 WMMapWidget(list);
880 /* update the scroller */
881 if (bPtr->columnCount > bPtr->maxVisibleColumns) {
882 float value, proportion;
884 value = bPtr->firstVisibleColumn
885 /(float)(bPtr->columnCount-bPtr->maxVisibleColumns);
886 proportion = bPtr->maxVisibleColumns/(float)bPtr->columnCount;
887 WMSetScrollerParameters(bPtr->scroller, value, proportion);
890 return index;
895 static void
896 destroyBrowser(WMBrowser *bPtr)
898 int i;
900 for (i=0; i<bPtr->columnCount; i++) {
901 if (bPtr->titles[i])
902 free(bPtr->titles[i]);
904 free(bPtr->titles);
906 free(bPtr->pathSeparator);
908 free(bPtr);