2.5
[blender-staging.git] / source / blender / editors / space_file / file_draw.c
1 /**
2  * $Id:
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. 
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2008 Blender Foundation.
21  * All rights reserved.
22  *
23  * 
24  * Contributor(s): Blender Foundation
25  *
26  * ***** END GPL LICENSE BLOCK *****
27  */
28
29 #include <string.h>
30
31 #include "BLI_blenlib.h"
32 #include "BLI_storage_types.h"
33 #ifdef WIN32
34 #include "BLI_winstuff.h"
35 #endif
36
37 #include "BIF_gl.h"
38 #include "BIF_glutil.h"
39
40 #include "BKE_colortools.h"
41 #include "BKE_context.h"
42 #include "BKE_screen.h"
43 #include "BKE_global.h"
44 #include "BKE_utildefines.h"
45
46 #include "DNA_space_types.h"
47 #include "DNA_scene_types.h"
48 #include "DNA_screen_types.h"
49 #include "DNA_userdef_types.h"
50 #include "DNA_windowmanager_types.h"
51
52 #include "IMB_imbuf_types.h"
53 #include "IMB_imbuf.h"
54  
55 #include "MEM_guardedalloc.h"
56
57 #include "PIL_time.h"
58
59 #include "RNA_access.h"
60
61 #include "ED_fileselect.h"
62 #include "ED_screen.h"
63
64 #include "UI_interface.h"
65 #include "UI_interface_icons.h"
66 #include "UI_resources.h"
67 #include "UI_text.h"
68 #include "UI_view2d.h"
69
70 #include "WM_api.h"
71 #include "WM_types.h"
72
73 #include "fsmenu.h"
74 #include "filelist.h"
75
76 #include "file_intern.h"        // own include
77
78 /* ui geometry */
79 #define IMASEL_BUTTONS_HEIGHT 60
80 #define TILE_BORDER_X 8
81 #define TILE_BORDER_Y 8
82
83 /* button events */
84 enum {
85         B_REDR  = 0,
86         B_FS_LOAD,
87         B_FS_CANCEL,
88 } eFile_ButEvents;
89
90 static void do_file_buttons(bContext *C, void *arg, int event)
91 {
92         SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C);
93         switch(event) {
94                 case B_FS_LOAD:
95                         {
96                                 char name[FILE_MAX];
97
98                                 ED_screen_full_prevspace(C);
99                                 if(sfile->op) {
100                                         wmOperator *op= sfile->op;
101                                         
102                                         /* if load .blend, all UI pointers after exec are invalid! */
103                                         /* but, operator can be freed still */
104                                         
105                                         sfile->op = NULL;
106                                         BLI_strncpy(name, sfile->params->dir, sizeof(name));
107                                         strcat(name, sfile->params->file);
108                                         RNA_string_set(op->ptr, "filename", name);
109                                 
110                                         op->type->exec(C, op);
111                                 
112                                         WM_operator_free(op);
113                                 }
114
115                         }
116                         break;
117                 case B_FS_CANCEL:
118                         if(sfile->op) {
119                                 WM_operator_free(sfile->op);
120                                 sfile->op = NULL;
121                         }
122                         ED_screen_full_prevspace(C);
123                         
124                         break;
125         }
126 }
127
128 void file_draw_buttons(const bContext *C, ARegion *ar)
129 {
130         SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C);
131         FileSelectParams* params = sfile->params;
132         uiBlock *block;
133         int loadbutton;
134         char name[20];
135         char *menu;
136         float slen;
137         float parentbut_width = 20;
138         float bookmarkbut_width = 0.0f;
139         float file_start_width = 0.0f;
140
141         int filebuty1, filebuty2;
142
143         float xmin = ar->v2d.mask.xmin + 10;
144         float xmax = ar->v2d.mask.xmax - 10;
145
146         filebuty1= ar->v2d.mask.ymax - IMASEL_BUTTONS_HEIGHT;
147         filebuty2= filebuty1+IMASEL_BUTTONS_HEIGHT/2 -6;
148
149         /* HEADER */
150         sprintf(name, "win %d", 1); // XXX sa-win???
151         block = uiBeginBlock(C, ar, name, UI_EMBOSS, UI_HELV);
152         uiBlockSetHandleFunc(block, do_file_buttons, NULL);
153
154         /* XXXX
155         uiSetButLock( filelist_gettype(simasel->files)==FILE_MAIN && simasel->returnfunc, NULL); 
156         */
157
158         /* space available for load/save buttons? */
159         slen = UI_GetStringWidth(G.font, sfile->params->title, 0);
160         loadbutton= slen > 60 ? slen + 20 : MAX2(80, 20+UI_GetStringWidth(G.font, params->title, 0));
161         if(ar->v2d.mask.xmax-ar->v2d.mask.xmin > loadbutton+20) {
162                 /* XXX
163                 if(simasel->title[0]==0) {
164                         loadbutton= 0;
165                 }
166                 */
167         }
168         else {
169                 loadbutton= 0;
170         }
171
172         /* XXX to channel region */
173         menu= fsmenu_build_menu();
174
175         if (menu[0]&& (params->type != FILE_MAIN)) {
176                 bookmarkbut_width = parentbut_width;
177                 file_start_width = parentbut_width;
178         }
179
180         uiDefBut(block, TEX, 0 /* XXX B_FS_FILENAME */,"",      xmin+file_start_width+bookmarkbut_width+2, filebuty1, xmax-xmin-loadbutton-file_start_width-bookmarkbut_width, 21, params->file, 0.0, (float)FILE_MAXFILE-1, 0, 0, "");
181         uiDefBut(block, TEX, 0 /* XXX B_FS_DIRNAME */,"",       xmin+parentbut_width, filebuty2, xmax-xmin-loadbutton-parentbut_width, 21, params->dir, 0.0, (float)FILE_MAXFILE-1, 0, 0, "");
182
183         if(loadbutton) {
184                 uiSetCurFont(block, UI_HELV);
185                 uiDefBut(block, BUT, B_FS_LOAD, params->title,  xmax-loadbutton, filebuty2, loadbutton, 21, params->dir, 0.0, (float)FILE_MAXFILE-1, 0, 0, "");
186                 uiDefBut(block, BUT, B_FS_CANCEL, "Cancel",             xmax-loadbutton, filebuty1, loadbutton, 21, params->file, 0.0, (float)FILE_MAXFILE-1, 0, 0, "");
187         }
188
189         /* menu[0] = NULL happens when no .Bfs is there, and first time browse
190            disallow external directory browsing for databrowse */
191
192         if(menu[0] && (params->type != FILE_MAIN))      { 
193                 uiDefButS(block, MENU, 0 /* B_FS_DIR_MENU */, menu, xmin, filebuty1, parentbut_width, 21, &params->menu, 0, 0, 0, 0, "");
194                 uiDefBut(block, BUT, 0 /* B_FS_BOOKMARK */, "B", xmin+22, filebuty1, bookmarkbut_width, 21, 0, 0, 0, 0, 0, "Bookmark current directory");
195         }
196
197         MEM_freeN(menu);
198
199         uiDefBut(block, BUT, 0 /* XXX B_FS_PARDIR */, "P", xmin, filebuty2, parentbut_width, 21, 0, 0, 0, 0, 0, "Move to the parent directory (PKEY)"); 
200         uiEndBlock(C, block);
201         uiDrawBlock(C, block);
202 }
203
204
205 static void draw_tile(short sx, short sy, short width, short height, int colorid)
206 {
207         /* TODO: BIF_ThemeColor seems to need this to show the color, not sure why? - elubie */
208         glEnable(GL_BLEND);
209         glColor4ub(0, 0, 0, 100);
210         glDisable(GL_BLEND);
211         
212         UI_ThemeColor4(colorid);
213         uiSetRoundBox(15);      
214         glRecti(sx, sy - height, sx + width, sy);
215
216         // uiRoundBox(sx+TILE_BORDER_X, sy - sfile->prv_h - TILE_BORDER_Y*3 - U.fontsize, sx + sfile->prv_w + TILE_BORDER_X*3, sy, 6);
217 }
218
219 static float shorten_string(char* string, float w)
220 {       
221         short shortened = 0;
222         float sw = 0;
223         
224         sw = UI_GetStringWidth(G.font, string,0);
225         while (sw>w) {
226                 int slen = strlen(string);
227                 string[slen-1] = '\0';
228                 sw = UI_GetStringWidth(G.font, string,0);
229                 shortened = 1;
230         }
231         if (shortened) {
232                 int slen = strlen(string);
233                 if (slen > 3) {
234                         BLI_strncpy(string+slen-3, "...", 4);                           
235                 }
236         }
237         return sw;
238 }
239
240 static void file_draw_string(short sx, short sy, char* string, short width, short height)
241 {
242         short soffs;
243         char fname[FILE_MAXFILE];
244         float sw;
245         float x,y;
246
247         BLI_strncpy(fname,string, FILE_MAXFILE);
248         sw = shorten_string(fname, width );
249         soffs = (width - sw) / 2;
250         x = (float)(sx);
251         y = (float)(sy-height);
252
253         // XXX was using ui_rasterpos_safe
254         glRasterPos2f(x, y);
255         UI_RasterPos(x, y);
256
257         /* XXX TODO: handling of international fonts.
258             TODO: proper support for utf8 in languages different from ja_JP abd zh_CH
259             needs update of iconv in lib/windows to support getting the system language string
260         */
261         UI_DrawString(G.font, fname, 0);
262
263 }
264
265 /* returns max number of rows in view */
266 static int file_view_rows(SpaceFile* sfile, View2D *v2d)
267 {
268         int height= (v2d->cur.ymax - v2d->cur.ymin - 2*sfile->tile_border_y);
269         return height / (sfile->tile_h + sfile->tile_border_y);
270 }
271
272 /* returns max number of columns in view */
273 static int file_view_columns(SpaceFile* sfile, View2D *v2d)
274 {
275         int width= (v2d->cur.xmax - v2d->cur.xmin - 2*sfile->tile_border_x);
276         return width / (sfile->tile_w + sfile->tile_border_x);
277 }
278
279 void file_calc_previews(const bContext *C, ARegion *ar)
280 {
281         SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C);
282         FileSelectParams* params = sfile->params;
283         View2D *v2d= &ar->v2d;
284         int width=0, height=0;
285         int rows, columns;
286
287         if (params->display) {
288                 sfile->prv_w = 96;
289                 sfile->prv_h = 96;
290                 sfile->tile_border_x = 8;
291                 sfile->tile_border_y = 8;
292                 sfile->prv_border_x = 4;
293                 sfile->prv_border_y = 4;
294                 sfile->tile_w = sfile->prv_w + 2*sfile->prv_border_x;
295                 sfile->tile_h = sfile->prv_h + 2*sfile->prv_border_y + U.fontsize*3/2;
296                 width= (v2d->cur.xmax - v2d->cur.xmin - 2*sfile->tile_border_x);
297                 columns= file_view_columns(sfile, v2d);
298                 rows= filelist_numfiles(params->files)/columns + 1; // XXX dirty, modulo is zero
299                 height= rows*(sfile->tile_h+sfile->tile_border_y) + sfile->tile_border_y*2;
300         } else {
301                 sfile->prv_w = 0;
302                 sfile->prv_h = 0;
303                 sfile->tile_border_x = 8;
304                 sfile->tile_border_y = 2;
305                 sfile->prv_border_x = 0;
306                 sfile->prv_border_y = 0;
307                 sfile->tile_w = 240;
308                 sfile->tile_h = U.fontsize*3/2;
309                 height= v2d->cur.ymax - v2d->cur.ymin;
310                 rows = file_view_rows(sfile, v2d);
311                 columns = filelist_numfiles(params->files)/rows + 1; // XXX dirty, modulo is zero
312                 width = columns * (sfile->tile_w + sfile->tile_border_x) + sfile->tile_border_x*2;
313         }
314
315         UI_view2d_totRect_set(v2d, width, height);
316 }
317
318 void file_draw_previews(const bContext *C, ARegion *ar)
319 {
320         SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C);
321         FileSelectParams* params=sfile->params;
322         View2D *v2d= &ar->v2d;
323         static double lasttime= 0;
324         struct FileList* files = params->files;
325         int numfiles;
326         struct direntry *file;
327
328         short sx, sy;
329         int do_load = 1;
330         
331         ImBuf* imb=0;
332         int i;
333         short type;
334         int colorid = 0;
335         int todo;
336         int offset;
337         int columns;
338         
339         if (!files) return;
340         /* Reload directory */
341         BLI_strncpy(params->dir, filelist_dir(files), FILE_MAX);        
342         
343         type = filelist_gettype(files); 
344
345         filelist_imgsize(files,sfile->prv_w,sfile->prv_h);
346
347         numfiles = filelist_numfiles(files);
348         
349         todo = 0;
350         if (lasttime < 0.001) lasttime = PIL_check_seconds_timer();
351
352         sx = v2d->cur.xmin + sfile->tile_border_x;
353         sy = v2d->cur.ymax - sfile->tile_border_y;
354         columns = file_view_columns(sfile, v2d);
355         offset = columns*(-v2d->cur.ymax+sfile->tile_border_y)/sfile->tile_h;
356         offset = (offset/columns-1)*columns;
357         if (offset<0) offset=0;
358         for (i=offset; (i < numfiles); ++i)
359         {
360                 sx = v2d->tot.xmin + sfile->tile_border_x + ((i)%columns)*(sfile->tile_w+sfile->tile_border_x);
361                 sy = v2d->tot.ymax - sfile->tile_border_y - ((i)/columns)*(sfile->tile_h+sfile->tile_border_y);
362                 file = filelist_file(files, i);                         
363
364                 if (params->active_file == i) {
365                         colorid = TH_ACTIVE;
366                         draw_tile(sx, sy, sfile->tile_w, sfile->tile_h, colorid);
367                 } else if (file->flags & ACTIVE) {
368                         colorid = TH_HILITE;
369                         draw_tile(sx, sy+sfile->tile_border_y, sfile->tile_w, sfile->tile_h-sfile->tile_border_y, colorid);
370                 } else {
371                         /*
372                         colorid = TH_PANEL;
373                         draw_tile(simasel, sx, sy, tilewidth, tileheight, colorid);
374                         */
375                 }
376
377 #if 0
378                 if ( type == FILE_MAIN) {
379                         ID *id;
380                         int icon_id = 0;
381                         int idcode;
382                         idcode= groupname_to_code(sfile->dir);
383                         if (idcode == ID_MA || idcode == ID_TE || idcode == ID_LA || idcode == ID_WO || idcode == ID_IM) {
384                                 id = (ID *)file->poin;
385                                 icon_id = BKE_icon_getid(id);
386                         }               
387                         if (icon_id) {
388                                 glEnable(GL_BLEND);
389                                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
390                                 if (do_load) {
391                                         UI_icon_draw_preview(sx+2*TILE_BORDER_X, sy-simasel->prv_w-TILE_BORDER_X, icon_id, 0);                  
392                                 } else {
393                                         UI_icon_draw_preview(sx+2*TILE_BORDER_X, sy-simasel->prv_w-TILE_BORDER_X, icon_id, 1);
394                                         todo++;
395                                 }
396                                 
397                                 glDisable(GL_BLEND);
398                         }               
399                 }
400                 else {
401 #endif
402                         if ( (file->flags & IMAGEFILE) /* || (file->flags & MOVIEFILE) */)
403                         {
404                                 if (do_load) {                                  
405                                         filelist_loadimage(files, i);                           
406                                 } else {
407                                         todo++;
408                                 }
409                                 imb = filelist_getimage(files, i);
410                         } else {
411                                 imb = filelist_getimage(files, i);
412                         }
413
414                         if (imb) {              
415                                 float fx = ((float)sfile->prv_w - (float)imb->x)/2.0f;
416                                 float fy = ((float)sfile->prv_h - (float)imb->y)/2.0f;
417                                 short dx = (short)(fx + 0.5f + sfile->prv_border_x);
418                                 short dy = (short)(fy + 0.5f + sfile->prv_border_y);
419                                 
420                                 glEnable(GL_BLEND);
421                                 glBlendFunc(GL_SRC_ALPHA,  GL_ONE_MINUS_SRC_ALPHA);                                                                                                     
422                                 // glaDrawPixelsSafe((float)sx+8 + dx, (float)sy - imgwidth + dy - 8, imb->x, imb->y, imb->x, GL_RGBA, GL_UNSIGNED_BYTE, imb->rect);
423                                 glColor4f(1.0, 1.0, 1.0, 1.0);
424                                 glaDrawPixelsTex((float)sx + dx, (float)sy - sfile->prv_h + dy, imb->x, imb->y,GL_UNSIGNED_BYTE, imb->rect);
425                                 // glDisable(GL_BLEND);
426                                 imb = 0;
427                         }
428 #if 0
429                 }               
430 #endif
431                 if (type == FILE_MAIN) {
432                         glColor3f(1.0f, 1.0f, 1.0f);                    
433                 }
434                 else {
435                         if (S_ISDIR(file->type)) {
436                                 glColor3f(1.0f, 1.0f, 0.9f);
437                         }
438                         else if (file->flags & IMAGEFILE) {
439                                 UI_ThemeColor(TH_SEQ_IMAGE);
440                         }
441                         else if (file->flags & MOVIEFILE) {
442                                 UI_ThemeColor(TH_SEQ_MOVIE);
443                         }
444                         else if (file->flags & BLENDERFILE) {
445                                 UI_ThemeColor(TH_SEQ_SCENE);
446                         }
447                         else {
448                                 if (params->active_file == i) {
449                                         UI_ThemeColor(TH_GRID); /* grid used for active text */
450                                 } else if (file->flags & ACTIVE) {
451                                         UI_ThemeColor(TH_TEXT_HI);                      
452                                 } else {
453                                         UI_ThemeColor(TH_TEXT);
454                                 }
455                         }
456                 }
457                         
458                 file_draw_string(sx + sfile->prv_border_x, sy, file->relname, sfile->tile_w, sfile->tile_h);
459 #if 0
460                 if(do_load && (PIL_check_seconds_timer() - lasttime > 0.3)) {
461                         lasttime= PIL_check_seconds_timer();
462                         do_load = 0;
463                 }
464 #endif
465         }
466 #if 0 // XXX solve with threads or add notifier ??
467         if (!do_load && todo > 0) /* we broke off loading */
468                 addafterqueue(sa->win, RENDERPREVIEW, 1);
469 #endif
470 }
471
472
473 void file_draw_list(const bContext *C, ARegion *ar)
474 {
475         SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C);
476         FileSelectParams* params = sfile->params;
477         struct FileList* files = params->files;
478         struct direntry *file;
479         int numfiles;
480         int colorid = 0;
481         short sx, sy;
482         int offset;
483         short type;
484         int i;
485         int rows;
486
487         numfiles = filelist_numfiles(files);
488         type = filelist_gettype(files); 
489
490         sx = ar->v2d.tot.xmin + sfile->tile_border_x/2;
491         sy = ar->v2d.cur.ymax - sfile->tile_border_y;
492
493         rows = (ar->v2d.cur.ymax - ar->v2d.cur.ymin - 2*sfile->tile_border_y) / (sfile->tile_h+sfile->tile_border_y);
494         offset = rows*(sx - sfile->tile_border_x)/(sfile->tile_w+sfile->tile_border_x);
495         offset = (offset/rows-1)*rows;
496
497         while (sx < ar->v2d.cur.xmax) {
498                 sx += (sfile->tile_w+sfile->tile_border_x);
499                 glColor4ub(0xB0,0xB0,0xB0, 0xFF);
500                 sdrawline(sx+1,  ar->v2d.cur.ymax - sfile->tile_border_y ,  sx+1,  ar->v2d.cur.ymin + sfile->tile_border_y); 
501                 glColor4ub(0x30,0x30,0x30, 0xFF);
502                 sdrawline(sx,  ar->v2d.cur.ymax - sfile->tile_border_y ,  sx,  ar->v2d.cur.ymin + sfile->tile_border_y); 
503         }
504
505         sx = ar->v2d.cur.xmin + sfile->tile_border_x;
506         sy = ar->v2d.cur.ymax - sfile->tile_border_y;
507         if (offset<0) offset=0;
508         for (i=offset; (i < numfiles); ++i)
509         {
510                 sy = ar->v2d.tot.ymax-sfile->tile_border_y - (i%rows)*(sfile->tile_h+sfile->tile_border_y);
511                 sx = ar->v2d.tot.xmin +sfile->tile_border_x + (i/rows)*(sfile->tile_w+sfile->tile_border_x);
512
513                 file = filelist_file(files, i); 
514
515                 if (params->active_file == i) {
516                         colorid = TH_ACTIVE;
517                         draw_tile(sx, sy, sfile->tile_w, sfile->tile_h, colorid);
518                 } else if (file->flags & ACTIVE) {
519                         colorid = TH_HILITE;
520                         draw_tile(sx, sy, sfile->tile_w, sfile->tile_h, colorid);
521                 } else {
522                         /*
523                         colorid = TH_PANEL;
524                         draw_tile(sx, sy, sfile->tile_w, sfile->tile_h, colorid);
525                         */
526                 }
527                 if (type == FILE_MAIN) {
528                         glColor3f(1.0f, 1.0f, 1.0f);                    
529                 }
530                 else {
531                         if (S_ISDIR(file->type)) {
532                                 glColor3f(1.0f, 1.0f, 0.9f);
533                         }
534                         else if (file->flags & IMAGEFILE) {
535                                 UI_ThemeColor(TH_SEQ_IMAGE);
536                         }
537                         else if (file->flags & MOVIEFILE) {
538                                 UI_ThemeColor(TH_SEQ_MOVIE);
539                         }
540                         else if (file->flags & BLENDERFILE) {
541                                 UI_ThemeColor(TH_SEQ_SCENE);
542                         }
543                         else {
544                                 if (params->active_file == i) {
545                                         UI_ThemeColor(TH_GRID); /* grid used for active text */
546                                 } else if (file->flags & ACTIVE) {
547                                         UI_ThemeColor(TH_TEXT_HI);                      
548                                 } else {
549                                         UI_ThemeColor(TH_TEXT);
550                                 }
551                         }
552                 }
553
554                 file_draw_string(sx, sy, file->relname, sfile->tile_w, sfile->tile_h);
555                 file_draw_string(sx + sfile->tile_w - UI_GetStringWidth(G.font, file->size, 0), sy,
556                         file->size, sfile->tile_w - UI_GetStringWidth(G.font, file->size, 0), sfile->tile_h);
557         }
558 }
559
560 void file_draw_fsmenu(const bContext *C, ARegion *ar)
561 {
562         SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C);
563         FileSelectParams* params = sfile->params;
564         char bookmark[FILE_MAX];
565         int nentries = fsmenu_get_nentries();
566         int linestep = U.fontsize*3/2;
567         int i;
568         short sx, sy;
569         int bmwidth = ar->v2d.cur.xmax - ar->v2d.cur.xmin - 2*TILE_BORDER_X;
570         int fontsize = U.fontsize;
571
572         sx = ar->v2d.cur.xmin + TILE_BORDER_X;
573         sy = -2*TILE_BORDER_Y;
574         for (i=0; i< nentries && (sy > ar->v2d.cur.ymin) ;++i) {
575                 char *fname = fsmenu_get_entry(i);
576
577                 if (fname) {
578                         int sl;
579                         BLI_strncpy(bookmark, fname, FILE_MAX);
580                 
581                         sl = strlen(bookmark)-1;
582                         while (bookmark[sl] == '\\' || bookmark[sl] == '/') {
583                                 bookmark[sl] = '\0';
584                                 sl--;
585                         }
586                         if (params->active_bookmark == i ) {
587                                 glColor4ub(0, 0, 0, 100);
588                                 UI_ThemeColor(TH_HILITE);
589                                 // uiSetRoundBox(15);   
590                                 // uiRoundBox(simasel->bookmarkrect.xmin + TILE_BORDER_X - 1, sy - linestep*0.25, simasel->bookmarkrect.xmax - TILE_BORDER_X + 1, sy + linestep*0.75, 6);
591                                 glRecti(sx, sy - linestep, sx + bmwidth, sy);
592                                 UI_ThemeColor(TH_TEXT_HI);
593                         } else {
594                                 UI_ThemeColor(TH_TEXT);
595                         }
596
597                         file_draw_string(sx, sy, bookmark, bmwidth, fontsize);
598                         sy -= linestep;
599                 } else {
600                         glColor4ub(0xB0,0xB0,0xB0, 0xFF);
601                         sdrawline(sx,  sy-1-fontsize/2 ,  sx + bmwidth,  sy-1-fontsize/2); 
602                         glColor4ub(0x30,0x30,0x30, 0xFF);
603                         sdrawline(sx,  sy-fontsize/2 ,  sx + bmwidth,  sy - fontsize/2);
604                         sy -= linestep;
605                 }
606         }
607 }