bugfix [#8263] Video Sequence Editor > Sequence > Reassign Inputs > crash
[blender.git] / source / blender / src / drawimasel.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL 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. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * The Original Code is: all of this file.
27  *
28  * Contributor(s): none yet.
29  *
30  * ***** END GPL/BL DUAL LICENSE BLOCK *****
31  */
32
33 #include <string.h>
34
35 #ifdef HAVE_CONFIG_H
36 #include <config.h>
37 #endif
38
39 #ifdef _WIN32
40 #pragma warning (once : 4761)
41 #endif
42
43 #include "MEM_guardedalloc.h"
44
45 #include "DNA_ID.h"
46 #include "DNA_screen_types.h"
47 #include "DNA_space_types.h"
48 #include "DNA_scene_types.h"
49 #include "DNA_userdef_types.h"
50 #include "DNA_object_types.h"
51 #include "DNA_material_types.h"
52
53 #include "BLI_blenlib.h"
54 #include "BLI_storage_types.h"
55 #ifdef WIN32
56 #include "BLI_winstuff.h"
57 #endif
58
59
60 #include "BKE_global.h"
61 #include "BKE_library.h"
62 #include "BKE_icons.h"
63 #include "BKE_utildefines.h"
64 #include "BIF_filelist.h"
65
66 #include "BIF_gl.h"
67 #include "BIF_glutil.h"
68 #include "BIF_mywindow.h"
69 #include "BIF_screen.h"
70 #include "BIF_resources.h"
71 #include "BIF_language.h"
72
73 #include "BIF_interface.h"
74 #include "BIF_interface_icons.h"
75 #include "BIF_previewrender.h"
76 #include "BIF_fsmenu.h"
77 #include "BIF_space.h"
78 #include "BIF_gl.h"
79 #include "BIF_glutil.h"
80
81 #include "BSE_drawimasel.h"
82 #include "BSE_drawipo.h" /* for v2d functions */ 
83 #include "BSE_view.h"
84
85 #include "BLO_readfile.h"
86
87 #include "IMB_imbuf.h"
88 #include "IMB_imbuf_types.h"
89
90 #include "PIL_time.h"
91
92 #include "blendef.h"
93 #include "mydevice.h"
94
95 #include "interface.h"  /* urm...  for rasterpos_safe, roundbox */
96
97 #define BUTTONWIDTH 20
98 #define BOOKMARKWIDTH_MAX 240
99
100 void calc_imasel_rcts(SpaceImaSel *simasel, int winx, int winy)
101 {       
102         int width = (int)16.0f*simasel->aspect;
103         int numtiles;
104         int numfiles = 0;
105         int tilewidth = simasel->prv_w + TILE_BORDER_X*4;
106         int tileheight = simasel->prv_h + TILE_BORDER_Y*4 + U.fontsize;
107
108         // complete area of the space
109         simasel->v2d.mask.xmin= simasel->v2d.mask.ymin = 0;
110         simasel->v2d.mask.xmax= winx;
111         simasel->v2d.mask.ymax= winy;
112
113         // vertical scroll bar
114         simasel->v2d.vert= simasel->v2d.mask;
115         simasel->v2d.vert.xmax -= TILE_BORDER_X + 2;
116         simasel->v2d.vert.xmin= simasel->v2d.vert.xmax- width - TILE_BORDER_X - 2;
117         simasel->v2d.vert.ymax -= IMASEL_BUTTONS_HEIGHT + TILE_BORDER_Y + 2;
118         simasel->v2d.vert.ymin += TILE_BORDER_Y + 2;
119         // simasel->v2d.mask.xmax= simasel->v2d.vert.xmin;
120         
121         if (simasel->flag & FILE_BOOKMARKS) {
122                 int bmwidth = (simasel->v2d.vert.xmin - simasel->v2d.mask.xmin)/4.0f;
123                 if (bmwidth > BOOKMARKWIDTH_MAX) bmwidth = BOOKMARKWIDTH_MAX;
124
125                 simasel->bookmarkrect.xmin = simasel->v2d.mask.xmin + TILE_BORDER_X;
126                 simasel->bookmarkrect.xmax = simasel->v2d.mask.xmin + bmwidth - TILE_BORDER_X;
127                 simasel->bookmarkrect.ymax = simasel->v2d.mask.ymax - IMASEL_BUTTONS_HEIGHT - TILE_BORDER_Y;    
128                 simasel->bookmarkrect.ymin = simasel->v2d.mask.ymin + TILE_BORDER_Y;
129
130                 simasel->viewrect.xmin = simasel->bookmarkrect.xmax + TILE_BORDER_X;
131                 simasel->viewrect.xmax = simasel->v2d.vert.xmin - TILE_BORDER_X;
132                 simasel->viewrect.ymax = simasel->v2d.mask.ymax - IMASEL_BUTTONS_HEIGHT - TILE_BORDER_Y;        
133                 simasel->viewrect.ymin = simasel->v2d.mask.ymin + TILE_BORDER_Y;        
134         } else {
135                 simasel->viewrect.xmin = simasel->v2d.mask.xmin + TILE_BORDER_X;
136                 simasel->viewrect.xmax = simasel->v2d.vert.xmin - TILE_BORDER_X;
137                 simasel->viewrect.ymax = simasel->v2d.mask.ymax - IMASEL_BUTTONS_HEIGHT - TILE_BORDER_Y;        
138                 simasel->viewrect.ymin = simasel->v2d.mask.ymin + TILE_BORDER_Y;                
139         }
140
141         simasel->numtilesx = (simasel->viewrect.xmax - simasel->viewrect.xmin) / tilewidth;
142         simasel->numtilesy = (simasel->viewrect.ymax - simasel->viewrect.ymin) / tileheight;
143         numtiles = simasel->numtilesx*simasel->numtilesy;
144
145         if (simasel->files) {
146                 numfiles = BIF_filelist_numfiles(simasel->files);
147         }
148         if (numtiles > numfiles) numtiles = numfiles;
149
150         simasel->scrollarea = ((float)simasel->v2d.vert.ymax - (float)simasel->v2d.vert.ymin);
151         if (numtiles < numfiles) {
152                 simasel->scrollheight = ((float)numtiles / (float)numfiles)*simasel->scrollarea;
153                 simasel->scrollarea -= simasel->scrollheight;   
154         } else {
155                 simasel->scrollheight = simasel->scrollarea;
156         }
157         if (simasel->scrollarea < 0) simasel->scrollarea = 0;
158 }
159
160 void draw_imasel_scroll(SpaceImaSel *simasel)
161 {
162         rcti scrollbar;
163         rcti scrollhandle;
164
165         scrollbar.xmin= simasel->v2d.cur.xmin + simasel->v2d.vert.xmin;         
166         scrollbar.ymin = simasel->v2d.cur.ymin + simasel->v2d.vert.ymin;
167         scrollbar.xmax= simasel->v2d.cur.xmin + simasel->v2d.vert.xmax;
168         scrollbar.ymax = simasel->v2d.cur.ymin + simasel->v2d.vert.ymax;
169
170         scrollhandle.xmin= scrollbar.xmin;              
171         scrollhandle.ymin = scrollbar.ymax - simasel->scrollpos -1;
172         scrollhandle.xmax= scrollbar.xmax-1;
173         scrollhandle.ymax = scrollbar.ymax - simasel->scrollpos - simasel->scrollheight;
174
175         BIF_ThemeColor(TH_SHADE1);
176         glRecti(scrollbar.xmin,  scrollbar.ymin, scrollbar.xmax, scrollbar.ymax);
177         uiEmboss(scrollbar.xmin-2,  scrollbar.ymin-2, scrollbar.xmax+2, scrollbar.ymax+2, 1);
178
179         BIF_ThemeColor(TH_SHADE2);
180         glRecti(scrollhandle.xmin,  scrollhandle.ymin,  scrollhandle.xmax,  scrollhandle.ymax);
181         
182         uiEmboss(scrollhandle.xmin, scrollhandle.ymin, scrollhandle.xmax, scrollhandle.ymax, 1); 
183 }
184
185 static void draw_tile(SpaceImaSel *simasel, short sx, short sy, int colorid)
186 {
187         /* TODO: BIF_ThemeColor seems to need this to show the color, not sure why? - elubie */
188         glEnable(GL_BLEND);
189         glColor4ub(0, 0, 0, 100);
190         glDisable(GL_BLEND);
191         
192         BIF_ThemeColor4(colorid);
193         uiSetRoundBox(15);      
194         uiRoundBox(sx+TILE_BORDER_X, sy - simasel->prv_h - TILE_BORDER_Y*3 - U.fontsize, sx + simasel->prv_w + TILE_BORDER_X*3, sy, 6);
195 }
196
197 static float shorten_string(SpaceImaSel *simasel, char* string, float w)
198 {       
199         short shortened = 0;
200         float sw = 0;
201         
202         sw = BIF_GetStringWidth(simasel->curfont, string, 0);
203         while (sw>w) {
204                 int slen = strlen(string);
205                 string[slen-1] = '\0';
206                 sw = BIF_GetStringWidth(simasel->curfont, string, 0);
207                 shortened = 1;
208         }
209         if (shortened) {
210                 int slen = strlen(string);
211                 if (slen > 3) {
212                         BLI_strncpy(string+slen-3, "...", 4);                           
213                 }
214         }
215         return sw;
216 }
217
218 static void draw_file(SpaceImaSel *simasel, short sx, short sy, struct direntry *file)
219 {
220         short soffs;
221         char fname[FILE_MAXFILE];
222         float sw;
223
224         BLI_strncpy(fname,file->relname, FILE_MAXFILE);
225         sw = shorten_string(simasel, fname, simasel->prv_w );
226         soffs = (simasel->prv_w + TILE_BORDER_X*4 - sw) / 2;    
227         
228         ui_rasterpos_safe(sx+soffs, sy - simasel->prv_h - TILE_BORDER_Y*2 - U.fontsize, simasel->aspect);
229 #ifdef WIN32
230         BIF_DrawString(simasel->curfont, fname, ((U.transopts & USER_TR_MENUS) | CONVERT_TO_UTF8));
231 #else
232         BIF_DrawString(simasel->curfont, fname, (U.transopts & USER_TR_MENUS));
233 #endif
234 }
235
236 static void draw_imasel_bookmarks(ScrArea *sa, SpaceImaSel *simasel)
237 {
238         char bookmark[FILE_MAX];
239         float sw;
240
241         if (simasel->flag & FILE_BOOKMARKS) {
242                 int nentries = fsmenu_get_nentries();
243                 int i;
244                 short sx, sy;
245                 int bmwidth;
246                 int linestep = U.fontsize*3/2;
247                 
248                 sx = simasel->bookmarkrect.xmin + TILE_BORDER_X;
249                 sy = simasel->bookmarkrect.ymax - TILE_BORDER_Y - linestep;
250                 bmwidth = simasel->bookmarkrect.xmax - simasel->bookmarkrect.xmin - 2*TILE_BORDER_X;
251                 
252                 if (bmwidth < 0) return;
253
254                 for (i=0; i< nentries && sy > linestep ;++i) {
255                         char *fname = fsmenu_get_entry(i);
256                         char *sname = NULL;
257                         
258                         if (fname) {
259                                 int sl;
260                                 BLI_strncpy(bookmark, fname, FILE_MAX);
261                         
262                                 sl = strlen(bookmark)-1;
263                                 if (bookmark[sl] == '\\' || bookmark[sl] == '/') {
264                                         bookmark[sl] = '\0';
265                                         sl--;
266                                 }
267                                 while (sl) {
268                                         if (bookmark[sl] == '\\' || bookmark[sl] == '/'){
269                                                 sl++;
270                                                 break;
271                                         };
272                                         sl--;
273                                 }
274                                 sname = &bookmark[sl];
275                                 sw = shorten_string(simasel, sname, bmwidth);
276
277                                 
278                                 if (simasel->active_bookmark == i ) {
279                                         glEnable(GL_BLEND);
280                                         glColor4ub(0, 0, 0, 100);
281                                         glDisable(GL_BLEND);
282                                         BIF_ThemeColor(TH_HILITE);
283                                         uiSetRoundBox(15);      
284                                         uiRoundBox(simasel->bookmarkrect.xmin + TILE_BORDER_X - 1, sy - linestep*0.25, simasel->bookmarkrect.xmax - TILE_BORDER_X + 1, sy + linestep*0.75, 6);
285                                         BIF_ThemeColor(TH_TEXT_HI);
286                                 } else {
287                                         BIF_ThemeColor(TH_TEXT);
288                                 }
289                                 ui_rasterpos_safe(sx, sy, simasel->aspect);
290 #ifdef WIN32
291                                 BIF_DrawString(simasel->curfont, sname, ((U.transopts & USER_TR_MENUS) | CONVERT_TO_UTF8));
292 #else
293                                 BIF_DrawString(simasel->curfont, sname, (U.transopts & USER_TR_MENUS));
294 #endif
295                                 sy -= linestep;
296                         } else {
297                                 cpack(0xB0B0B0);
298                                 sdrawline(sx,  sy + U.fontsize/2 ,  sx + bmwidth,  sy + U.fontsize/2); 
299                                 cpack(0x303030);                                
300                                 sdrawline(sx,  sy + 1 + U.fontsize/2 ,  sx + bmwidth,  sy + 1 + U.fontsize/2);
301                                 sy -= linestep;
302                         }
303                 }
304
305                 uiEmboss(simasel->bookmarkrect.xmin, simasel->bookmarkrect.ymin, simasel->bookmarkrect.xmax-1, simasel->bookmarkrect.ymax-1, 1);
306         }
307 }
308
309 static void draw_imasel_previews(ScrArea *sa, SpaceImaSel *simasel)
310 {
311         static double lasttime= 0;
312         struct FileList* files = simasel->files;
313         int numfiles;
314         struct direntry *file;
315         int numtiles;
316         
317         int tilewidth = simasel->prv_w + TILE_BORDER_X*4;
318         int tileheight = simasel->prv_h + TILE_BORDER_Y*4 + U.fontsize;
319         short sx, sy;
320         int do_load = 1;
321         
322         ImBuf* imb=0;
323         int i,j;
324         short type;
325         int colorid = 0;
326         int todo;
327         int fileoffset, rowoffset, columnoffset;
328         float scrollofs;
329         
330
331         rcti viewrect = simasel->viewrect;
332
333         if (!files) return;
334         /* Reload directory */
335         BLI_strncpy(simasel->dir, BIF_filelist_dir(files), FILE_MAXDIR);        
336         
337         type = BIF_filelist_gettype(simasel->files);    
338         
339         if (BIF_filelist_empty(files))
340         {
341                 unsigned int filter = 0;
342                 BIF_filelist_hidedot(simasel->files, simasel->flag & FILE_HIDE_DOT);
343                 if (simasel->flag & FILE_FILTER) {
344                         filter = simasel->filter ;
345                 } else {
346                         filter = 0;
347                 }
348
349                 BIF_filelist_setfilter(simasel->files, filter);
350                 BIF_filelist_readdir(files);
351                 
352                 if(simasel->sort!=FILE_SORTALPHA) BIF_filelist_sort(simasel->files, simasel->sort);             
353         }
354
355         BIF_filelist_imgsize(simasel->files,simasel->prv_w,simasel->prv_h);
356
357         numfiles = BIF_filelist_numfiles(files);
358         numtiles = simasel->numtilesx*simasel->numtilesy;
359
360         if (numtiles > numfiles) numtiles = numfiles;
361         
362         todo = 0;
363         if (lasttime < 0.001) lasttime = PIL_check_seconds_timer();
364
365         
366         if (simasel->numtilesx > 0) {
367                 /* calculate the offset to start drawing */
368                 if ((numtiles < numfiles) && (simasel->scrollarea > 0)) {
369                         fileoffset = numfiles*( (simasel->scrollpos) / simasel->scrollarea) + 0.5;              
370                 } else {
371                         fileoffset = 0;
372                 }
373                 rowoffset = (fileoffset / simasel->numtilesx)*simasel->numtilesx;
374                 columnoffset = fileoffset % simasel->numtilesx;
375                 scrollofs = (float)tileheight*(float)columnoffset/(float)simasel->numtilesx;
376         } else {
377                 rowoffset = 0;
378                 scrollofs = 0;
379         }
380         /* add partially visible row */
381         numtiles += simasel->numtilesx;
382         for (i=rowoffset, j=0 ; (i < numfiles) && (j < numtiles); ++i, ++j)
383         {
384                 sx = simasel->v2d.cur.xmin + viewrect.xmin + (j % simasel->numtilesx)*tilewidth;
385                 sy = simasel->v2d.cur.ymin + viewrect.ymax + (short)scrollofs - (viewrect.ymin + (j / simasel->numtilesx)*tileheight);
386
387                 file = BIF_filelist_file(files, i);                             
388
389                 if (simasel->active_file == i) {
390                         colorid = TH_ACTIVE;
391                         draw_tile(simasel, sx, sy, colorid);
392                 } else if (file->flags & ACTIVE) {
393                         colorid = TH_HILITE;
394                         draw_tile(simasel, sx, sy, colorid);
395                 } else {
396                         /*
397                         colorid = TH_PANEL;
398                         draw_tile(simasel, sx, sy, colorid);
399                         */
400                 }
401
402                 if ( type == FILE_MAIN) {
403                         ID *id;
404                         int icon_id = 0;
405                         int idcode;
406                         idcode= BIF_groupname_to_code(simasel->dir);
407                         if (idcode == ID_MA || idcode == ID_TE || idcode == ID_LA || idcode == ID_WO || idcode == ID_IM) {
408                                 id = (ID *)file->poin;
409                                 icon_id = BKE_icon_getid(id);
410                         }               
411                         if (icon_id) {
412                                 glEnable(GL_BLEND);
413                                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
414                                 if (do_load) {
415                                         BIF_icon_draw_preview(sx+2*TILE_BORDER_X, sy-simasel->prv_w-TILE_BORDER_X, icon_id, 0);                 
416                                 } else {
417                                         BIF_icon_draw_preview(sx+2*TILE_BORDER_X, sy-simasel->prv_w-TILE_BORDER_X, icon_id, 1);
418                                         todo++;
419                                 }
420                                 
421                                 glDisable(GL_BLEND);
422                         }               
423                 }
424                 else {
425                         if ( (file->flags & IMAGEFILE) || (file->flags & MOVIEFILE))
426                         {
427                                 if (do_load) {                                  
428                                         BIF_filelist_loadimage(simasel->files, i);                              
429                                 } else {
430                                         todo++;
431                                 }
432                                 imb = BIF_filelist_getimage(simasel->files, i);
433                         } else {
434                                 imb = BIF_filelist_getimage(simasel->files, i);
435                         }
436
437                         if (imb) {              
438                                         float fx = ((float)simasel->prv_w - (float)imb->x)/2.0f;
439                                         float fy = ((float)simasel->prv_h - (float)imb->y)/2.0f;
440                                         short dx = (short)(fx + 0.5f);
441                                         short dy = (short)(fy + 0.5f);
442                                         
443                                         glEnable(GL_BLEND);
444                                         glBlendFunc(GL_SRC_ALPHA,  GL_ONE_MINUS_SRC_ALPHA);                                                                                                     
445                                         // glaDrawPixelsSafe((float)sx+8 + dx, (float)sy - imgwidth + dy - 8, imb->x, imb->y, imb->x, GL_RGBA, GL_UNSIGNED_BYTE, imb->rect);
446                                         glColor4f(1.0, 1.0, 1.0, 1.0);
447                                         glaDrawPixelsTex((float)sx+2*TILE_BORDER_X + dx, (float)sy - simasel->prv_h + dy - 2*TILE_BORDER_Y, imb->x, imb->y,GL_UNSIGNED_BYTE, imb->rect);
448                                         // glDisable(GL_BLEND);
449                                         imb = 0;
450                         }                       
451                 }               
452
453                 if (type == FILE_MAIN) {
454                         glColor3f(1.0f, 1.0f, 1.0f);                    
455                 }
456                 else {
457                         if (S_ISDIR(file->type)) {
458                                 glColor3f(1.0f, 1.0f, 0.9f);
459                         }
460                         else if (file->flags & IMAGEFILE) {
461                                 BIF_ThemeColor(TH_SEQ_IMAGE);
462                         }
463                         else if (file->flags & MOVIEFILE) {
464                                 BIF_ThemeColor(TH_SEQ_MOVIE);
465                         }
466                         else if (file->flags & BLENDERFILE) {
467                                 BIF_ThemeColor(TH_SEQ_SCENE);
468                         }
469                         else {
470                                 if (simasel->active_file == i) {
471                                         BIF_ThemeColor(TH_GRID); /* grid used for active text */
472                                 } else if (file->flags & ACTIVE) {
473                                         BIF_ThemeColor(TH_TEXT_HI);                     
474                                 } else {
475                                         BIF_ThemeColor(TH_TEXT);
476                                 }
477                         }
478                 }
479                         
480                 draw_file(simasel, sx, sy, file);
481                 
482                 if(do_load && (PIL_check_seconds_timer() - lasttime > 0.3)) {
483                         lasttime= PIL_check_seconds_timer();
484                         do_load = 0;
485                 }
486         }
487
488         if (!do_load && todo > 0) /* we broke off loading */
489                 addafterqueue(sa->win, RENDERPREVIEW, 1);
490 }
491
492
493 /* in panel space! */
494 static void imasel_imgdraw(ScrArea *sa, uiBlock *block)
495 {
496         SpaceImaSel *simasel= sa->spacedata.first;
497         rctf dispf;
498         rcti winrect;
499         struct direntry *file;
500         char path[FILE_MAX];
501         float tsize;
502         short ofsx=0;
503         short ofsy=0;
504         short ex, ey;
505         float scaledx, scaledy;
506         int index;      
507
508         BLI_init_rctf(&dispf, 0.0f, (block->maxx - block->minx)-0.0f, 0.0f, (block->maxy - block->miny)-0.0f);
509         ui_graphics_to_window_rct(sa->win, &dispf, &winrect);
510
511         if (!simasel->img) {
512                 BLI_join_dirfile(path, simasel->dir, simasel->file);
513                 if (!BLI_exists(path))
514                         return;
515         
516                 index = BIF_filelist_find(simasel->files, simasel->file);
517                 if (index >= 0) {
518                         file = BIF_filelist_file(simasel->files,index);
519                         if (file->flags & IMAGEFILE || file->flags & MOVIEFILE) {
520                                 simasel->img = IMB_loadiffname(path, IB_rect);
521
522                                 if (simasel->img) {
523                                         tsize = MIN2(winrect.xmax - winrect.xmin,winrect.ymax - winrect.ymin);
524                                         
525                                         if (simasel->img->x > simasel->img->y) {
526                                                 scaledx = (float)tsize;
527                                                 scaledy =  ( (float)simasel->img->y/(float)simasel->img->x )*tsize;
528                                                 ofsy = (scaledx - scaledy) / 2.0;
529                                                 ofsx = 0;
530                                         }
531                                         else {
532                                                 scaledy = (float)tsize;
533                                                 scaledx =  ( (float)simasel->img->x/(float)simasel->img->y )*tsize;
534                                                 ofsx = (scaledy - scaledx) / 2.0;
535                                                 ofsy = 0;
536                                         }
537                                         ex = (short)scaledx;
538                                         ey = (short)scaledy;
539
540                                         IMB_scaleImBuf(simasel->img, ex, ey);
541                                 }
542                         }
543                 }
544         }
545         if (simasel->img == NULL) 
546                 return;
547         if(simasel->img->rect==NULL)
548                 return;
549
550         /* correction for gla draw */
551         BLI_translate_rcti(&winrect, -curarea->winrct.xmin, -curarea->winrct.ymin);
552                 
553         glaDefine2DArea(&sa->winrct);
554         glaDrawPixelsSafe(winrect.xmin+ofsx, winrect.ymin+ofsy, simasel->img->x, simasel->img->y, simasel->img->x, GL_RGBA, GL_UNSIGNED_BYTE, simasel->img->rect);      
555 }
556
557 static void imasel_panel_image(ScrArea *sa, short cntrl)
558 {
559         uiBlock *block;
560         SpaceImaSel *simasel= sa->spacedata.first;
561         short w = 300;
562         short h = 300;
563         short offsx, offsy;
564
565         if (simasel->img) {
566                 w = simasel->img->x;
567                 h = simasel->img->y;
568         }
569         
570         offsx = -150 + (simasel->v2d.mask.xmax - simasel->v2d.mask.xmin)/2;
571         offsy = -150 + (simasel->v2d.mask.ymax - simasel->v2d.mask.ymin)/2;
572
573         block= uiNewBlock(&curarea->uiblocks, "imasel_panel_image", UI_EMBOSS, UI_HELV, curarea->win);
574         uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl);
575         uiSetPanelHandler(IMASEL_HANDLER_IMAGE);  // for close and esc
576         if(uiNewPanel(curarea, block, "Image Preview", "Image Browser", offsx, offsy, w, h)==0) 
577                 return;
578         uiBlockSetDrawExtraFunc(block, imasel_imgdraw); 
579 }
580
581 static void imasel_blockhandlers(ScrArea *sa)
582 {
583         SpaceImaSel *simasel= sa->spacedata.first;
584         short a;
585                 
586         for(a=0; a<SPACE_MAXHANDLER; a+=2) {
587                 switch(simasel->blockhandler[a]) {
588
589                 case IMASEL_HANDLER_IMAGE:
590                         imasel_panel_image(sa, simasel->blockhandler[a+1]);
591                         break;
592                 
593                 }
594                 /* clear action value for event */
595                 simasel->blockhandler[a+1]= 0;
596         }
597         uiDrawBlocksPanels(sa, 0);
598 }
599
600
601 static void draw_imasel_buttons(ScrArea *sa, SpaceImaSel* simasel)
602 {
603         uiBlock *block;
604         int loadbutton;
605         char name[20];
606         char *menu;
607         float slen;
608         float parentbut_width = 20;
609         float bookmarkbut_width = 0.0f;
610         int filebuty1, filebuty2;
611
612         float xmin = simasel->v2d.mask.xmin + 10;
613         float xmax = simasel->v2d.mask.xmax - 10;
614
615         filebuty1= simasel->v2d.mask.ymax - IMASEL_BUTTONS_HEIGHT;
616         filebuty2= filebuty1+IMASEL_BUTTONS_HEIGHT/2 -6;
617
618         /* HEADER */
619         sprintf(name, "win %d", sa->win);
620         block = uiNewBlock(&sa->uiblocks, name, UI_EMBOSS, UI_HELV, sa->win);
621         
622         uiSetButLock( BIF_filelist_gettype(simasel->files)==FILE_MAIN && simasel->returnfunc, NULL); 
623
624         /* space available for load/save buttons? */
625         slen = BIF_GetStringWidth(G.font, simasel->title, simasel->aspect);
626         loadbutton= slen > 60 ? slen + 20 : 80; /* MAX2(80, 20+BIF_GetStringWidth(G.font, simasel->title)); */
627         if(simasel->v2d.mask.xmax-simasel->v2d.mask.xmin > loadbutton+20) {
628                 if(simasel->title[0]==0) {
629                         loadbutton= 0;
630                 }
631         }
632         else {
633                 loadbutton= 0;
634         }
635
636         menu= fsmenu_build_menu();
637
638         if (menu[0]) {
639                 bookmarkbut_width = parentbut_width;
640         }
641
642         uiDefBut(block, TEX, B_FS_FILENAME,"",  xmin+parentbut_width+bookmarkbut_width+2, filebuty1, xmax-xmin-loadbutton-parentbut_width-bookmarkbut_width, 21, simasel->file, 0.0, (float)FILE_MAXFILE-1, 0, 0, "");
643         uiDefBut(block, TEX, B_FS_DIRNAME,"",   xmin+parentbut_width, filebuty2, xmax-xmin-loadbutton-parentbut_width, 21, simasel->dir, 0.0, (float)FILE_MAXFILE-1, 0, 0, "");
644
645         if(loadbutton) {
646                 uiSetCurFont(block, UI_HELV);
647                 uiDefBut(block, BUT,B_FS_LOAD, simasel->title,  xmax-loadbutton, filebuty2, loadbutton, 21, simasel->dir, 0.0, (float)FILE_MAXFILE-1, 0, 0, "");
648                 uiDefBut(block, BUT,B_FS_CANCEL, "Cancel",              xmax-loadbutton, filebuty1, loadbutton, 21, simasel->file, 0.0, (float)FILE_MAXFILE-1, 0, 0, "");
649         }
650
651         if(menu[0])     { // happens when no .Bfs is there, and first time browse
652                 uiDefButS(block, MENU,B_FS_DIR_MENU, menu, xmin, filebuty1, parentbut_width, 21, &simasel->menu, 0, 0, 0, 0, "");
653                 uiDefBut(block, BUT, B_FS_BOOKMARK, "B", xmin+22, filebuty1, bookmarkbut_width, 21, 0, 0, 0, 0, 0, "Bookmark current directory");
654         }
655         MEM_freeN(menu);
656
657         uiDefBut(block, BUT, B_FS_PARDIR, "P", xmin, filebuty2, parentbut_width, 21, 0, 0, 0, 0, 0, "Move to the parent directory (PKEY)");     
658
659         uiDrawBlock(block);
660 }
661
662
663
664 /* ************** main drawing function ************** */
665
666 void drawimaselspace(ScrArea *sa, void *spacedata)
667 {
668         float col[3];
669         SpaceImaSel *simasel= curarea->spacedata.first;
670         
671         BIF_GetThemeColor3fv(TH_BACK, col);
672         glClearColor(col[0], col[1], col[2], 0.0);
673         glClear(GL_COLOR_BUFFER_BIT);   
674         
675         /* HACK: somehow when going fullscreen, v2d isn't set correctly */
676         simasel->v2d.cur.xmin= simasel->v2d.cur.ymin= 0.0f;
677         simasel->v2d.cur.xmax= sa->winx;
678         simasel->v2d.cur.ymax= sa->winy;        
679         simasel->v2d.tot= simasel->v2d.cur;
680         test_view2d(G.v2d, sa->winx, sa->winy);
681
682         calc_imasel_rcts(simasel, sa->winx, sa->winy);
683
684         myortho2(simasel->v2d.cur.xmin, simasel->v2d.cur.xmax, simasel->v2d.cur.ymin, simasel->v2d.cur.ymax);
685         bwin_clear_viewmat(sa->win);    /* clear buttons view */
686         glLoadIdentity();
687         
688         /* warning; blocks need to be freed each time, handlers dont remove  */
689         uiFreeBlocksWin(&sa->uiblocks, sa->win); 
690
691         /* aspect+font, set each time */
692         simasel->aspect= (simasel->v2d.cur.xmax - simasel->v2d.cur.xmin)/((float)sa->winx);
693         simasel->curfont= uiSetCurFont_ext(simasel->aspect);    
694         
695         if (!simasel->files) {
696                 simasel->files = BIF_filelist_new();
697                 BIF_filelist_setdir(simasel->files, simasel->dir);
698                 BIF_filelist_settype(simasel->files, simasel->type);
699         }
700
701         /* Buttons */
702         draw_imasel_buttons(sa, simasel);       
703         
704         /* scrollbar */
705         draw_imasel_scroll(simasel);    
706
707         /* bookmarks */
708         draw_imasel_bookmarks(sa, simasel);
709
710         uiEmboss(simasel->viewrect.xmin, simasel->viewrect.ymin, simasel->v2d.mask.xmax-TILE_BORDER_X, simasel->viewrect.ymax, 1);
711
712
713         glScissor(sa->winrct.xmin + simasel->viewrect.xmin , 
714                           sa->winrct.ymin + simasel->viewrect.ymin, 
715                           simasel->viewrect.xmax - simasel->viewrect.xmin , 
716                           simasel->viewrect.ymax - simasel->viewrect.ymin);
717
718         /* previews */  
719         draw_imasel_previews(sa, simasel);
720         
721         /* BIF_ThemeColor(TH_HEADER);*/
722         /* glRecti(simasel->viewrect.xmin,  simasel->viewrect.ymin,  simasel->viewrect.xmax,  simasel->viewrect.ymax);*/
723         
724         /* restore viewport (not needed yet) */
725         mywinset(sa->win);
726
727         /* ortho at pixel level curarea */
728         myortho2(-0.375, curarea->winx-0.375, -0.375, curarea->winy-0.375);
729
730         draw_area_emboss(sa);
731
732         imasel_blockhandlers(sa);
733
734         curarea->win_swap= WIN_BACK_OK;
735 }