|
Blender
V2.59
|
00001 /* 00002 * $Id: file_draw.c 37552 2011-06-16 15:01:22Z campbellbarton $ 00003 * 00004 * ***** BEGIN GPL LICENSE BLOCK ***** 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU General Public License 00008 * as published by the Free Software Foundation; either version 2 00009 * of the License, or (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software Foundation, 00018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00019 * 00020 * The Original Code is Copyright (C) 2008 Blender Foundation. 00021 * All rights reserved. 00022 * 00023 * 00024 * Contributor(s): Blender Foundation 00025 * 00026 * ***** END GPL LICENSE BLOCK ***** 00027 */ 00028 00034 #include <math.h> 00035 #include <string.h> 00036 00037 #include "BLI_blenlib.h" 00038 #include "BLI_utildefines.h" 00039 #include "BLI_dynstr.h" 00040 #include "BLI_storage_types.h" 00041 #ifdef WIN32 00042 #include "BLI_winstuff.h" 00043 #endif 00044 00045 #include "BIF_gl.h" 00046 #include "BIF_glutil.h" 00047 00048 #include "BKE_context.h" 00049 #include "BKE_global.h" 00050 #include "BKE_main.h" 00051 00052 #include "BLF_api.h" 00053 00054 #include "IMB_imbuf_types.h" 00055 00056 #include "MEM_guardedalloc.h" 00057 00058 #include "DNA_userdef_types.h" 00059 00060 #include "RNA_access.h" 00061 00062 #include "ED_fileselect.h" 00063 #include "ED_screen.h" 00064 00065 #include "UI_interface.h" 00066 #include "UI_interface_icons.h" 00067 #include "UI_resources.h" 00068 #include "UI_view2d.h" 00069 00070 #include "WM_types.h" 00071 00072 #include "fsmenu.h" 00073 #include "filelist.h" 00074 00075 #include "file_intern.h" // own include 00076 00077 /* button events */ 00078 enum { 00079 B_FS_DIRNAME, 00080 B_FS_FILENAME 00081 } /*eFile_ButEvents*/; 00082 00083 00084 static void do_file_buttons(bContext *C, void *UNUSED(arg), int event) 00085 { 00086 switch(event) { 00087 case B_FS_FILENAME: 00088 file_filename_exec(C, NULL); 00089 break; 00090 case B_FS_DIRNAME: 00091 file_directory_exec(C, NULL); 00092 break; 00093 } 00094 } 00095 00096 /* Note: This function uses pixelspace (0, 0, winx, winy), not view2d. 00097 * The controls are laid out as follows: 00098 * 00099 * ------------------------------------------- 00100 * | Directory input | execute | 00101 * ------------------------------------------- 00102 * | Filename input | + | - | cancel | 00103 * ------------------------------------------- 00104 * 00105 * The input widgets will stretch to fill any excess space. 00106 * When there isn't enough space for all controls to be shown, they are 00107 * hidden in this order: x/-, execute/cancel, input widgets. 00108 */ 00109 void file_draw_buttons(const bContext *C, ARegion *ar) 00110 { 00111 /* Button layout. */ 00112 const int max_x = ar->winx - 10; 00113 const int line1_y = IMASEL_BUTTONS_HEIGHT/2 + IMASEL_BUTTONS_MARGIN*2; 00114 const int line2_y = IMASEL_BUTTONS_MARGIN; 00115 const int input_minw = 20; 00116 const int btn_h = UI_UNIT_Y; 00117 const int btn_fn_w = UI_UNIT_X; 00118 const int btn_minw = 80; 00119 const int btn_margin = 20; 00120 const int separator = 4; 00121 00122 /* Additional locals. */ 00123 char name[32]; 00124 int loadbutton; 00125 int fnumbuttons; 00126 int min_x = 10; 00127 int chan_offs = 0; 00128 int available_w = max_x - min_x; 00129 int line1_w = available_w; 00130 int line2_w = available_w; 00131 00132 uiBut* but; 00133 uiBlock* block; 00134 SpaceFile* sfile = CTX_wm_space_file(C); 00135 FileSelectParams* params = ED_fileselect_get_params(sfile); 00136 ARegion* artmp; 00137 00138 /* Initialize UI block. */ 00139 sprintf(name, "win %p", (void *)ar); 00140 block = uiBeginBlock(C, ar, name, UI_EMBOSS); 00141 uiBlockSetHandleFunc(block, do_file_buttons, NULL); 00142 00143 /* exception to make space for collapsed region icon */ 00144 for (artmp=CTX_wm_area(C)->regionbase.first; artmp; artmp=artmp->next) { 00145 if (artmp->regiontype == RGN_TYPE_CHANNELS && artmp->flag & RGN_FLAG_HIDDEN) { 00146 chan_offs = 16; 00147 min_x += chan_offs; 00148 available_w -= chan_offs; 00149 } 00150 } 00151 00152 /* Is there enough space for the execute / cancel buttons? */ 00153 loadbutton = UI_GetStringWidth(sfile->params->title) + btn_margin; 00154 if (loadbutton < btn_minw) { 00155 loadbutton = MAX2(btn_minw, 00156 btn_margin + UI_GetStringWidth(params->title)); 00157 } 00158 00159 if (available_w <= loadbutton + separator + input_minw 00160 || params->title[0] == 0) { 00161 loadbutton = 0; 00162 } else { 00163 line1_w -= (loadbutton + separator); 00164 line2_w = line1_w; 00165 } 00166 00167 /* Is there enough space for file number increment/decrement buttons? */ 00168 fnumbuttons = 2 * btn_fn_w; 00169 if (!loadbutton || line2_w <= fnumbuttons + separator + input_minw) { 00170 fnumbuttons = 0; 00171 } else { 00172 line2_w -= (fnumbuttons + separator); 00173 } 00174 00175 /* Text input fields for directory and file. */ 00176 if (available_w > 0) { 00177 int overwrite_alert= file_draw_check_exists(sfile); 00178 /* callbacks for operator check functions */ 00179 uiBlockSetFunc(block, file_draw_check_cb, NULL, NULL); 00180 00181 but = uiDefButTextO(block, TEX, "FILE_OT_directory", 0, "", 00182 min_x, line1_y, line1_w-chan_offs, btn_h, 00183 params->dir, 0.0, (float)FILE_MAX-1, 0, 0, 00184 "File path."); 00185 uiButSetCompleteFunc(but, autocomplete_directory, NULL); 00186 uiButSetFlag(but, UI_BUT_NO_UTF8); 00187 00188 if((params->flag & FILE_DIRSEL_ONLY) == 0) { 00189 but = uiDefBut(block, TEX, B_FS_FILENAME, "", 00190 min_x, line2_y, line2_w-chan_offs, btn_h, 00191 params->file, 0.0, (float)FILE_MAXFILE-1, 0, 0, 00192 overwrite_alert ?"File name, overwrite existing." : "File name."); 00193 uiButSetCompleteFunc(but, autocomplete_file, NULL); 00194 uiButSetFlag(but, UI_BUT_NO_UTF8); 00195 00196 /* check if this overrides a file and if the operator option is used */ 00197 if(overwrite_alert) { 00198 uiButSetFlag(but, UI_BUT_REDALERT); 00199 } 00200 } 00201 00202 /* clear func */ 00203 uiBlockSetFunc(block, NULL, NULL, NULL); 00204 } 00205 00206 /* Filename number increment / decrement buttons. */ 00207 if (fnumbuttons && (params->flag & FILE_DIRSEL_ONLY) == 0) { 00208 uiBlockBeginAlign(block); 00209 but = uiDefIconButO(block, BUT, "FILE_OT_filenum", 0, ICON_ZOOMOUT, 00210 min_x + line2_w + separator - chan_offs, line2_y, 00211 btn_fn_w, btn_h, 00212 "Decrement the filename number"); 00213 RNA_int_set(uiButGetOperatorPtrRNA(but), "increment", -1); 00214 00215 but = uiDefIconButO(block, BUT, "FILE_OT_filenum", 0, ICON_ZOOMIN, 00216 min_x + line2_w + separator + btn_fn_w - chan_offs, line2_y, 00217 btn_fn_w, btn_h, 00218 "Increment the filename number"); 00219 RNA_int_set(uiButGetOperatorPtrRNA(but), "increment", 1); 00220 uiBlockEndAlign(block); 00221 } 00222 00223 /* Execute / cancel buttons. */ 00224 if(loadbutton) { 00225 00226 uiDefButO(block, BUT, "FILE_OT_execute", WM_OP_EXEC_REGION_WIN, params->title, 00227 max_x - loadbutton, line1_y, loadbutton, btn_h, 00228 params->title); 00229 uiDefButO(block, BUT, "FILE_OT_cancel", WM_OP_EXEC_REGION_WIN, "Cancel", 00230 max_x - loadbutton, line2_y, loadbutton, btn_h, 00231 "Cancel"); 00232 } 00233 00234 uiEndBlock(C, block); 00235 uiDrawBlock(C, block); 00236 } 00237 00238 00239 static void draw_tile(int sx, int sy, int width, int height, int colorid, int shade) 00240 { 00241 UI_ThemeColorShade(colorid, shade); 00242 uiSetRoundBox(15); 00243 uiRoundBox((float)sx, (float)(sy - height), (float)(sx + width), (float)sy, 5.0f); 00244 } 00245 00246 00247 static int get_file_icon(struct direntry *file) 00248 { 00249 if (file->type & S_IFDIR) { 00250 if ( strcmp(file->relname, "..") == 0) { 00251 return ICON_FILE_PARENT; 00252 } 00253 if(file->flags & BLENDERFILE) { 00254 return ICON_FILE_BLEND; 00255 } 00256 return ICON_FILE_FOLDER; 00257 } 00258 else if (file->flags & BLENDERFILE) 00259 return ICON_FILE_BLEND; 00260 else if (file->flags & BLENDERFILE_BACKUP) 00261 return ICON_FILE_BLEND; 00262 else if (file->flags & IMAGEFILE) 00263 return ICON_FILE_IMAGE; 00264 else if (file->flags & MOVIEFILE) 00265 return ICON_FILE_MOVIE; 00266 else if (file->flags & PYSCRIPTFILE) 00267 return ICON_FILE_SCRIPT; 00268 else if (file->flags & SOUNDFILE) 00269 return ICON_FILE_SOUND; 00270 else if (file->flags & FTFONTFILE) 00271 return ICON_FILE_FONT; 00272 else if (file->flags & BTXFILE) 00273 return ICON_FILE_BLANK; 00274 else if (file->flags & COLLADAFILE) 00275 return ICON_FILE_BLANK; 00276 else 00277 return ICON_FILE_BLANK; 00278 } 00279 00280 static void file_draw_icon(uiBlock *block, char *path, int sx, int sy, int icon, int width, int height) 00281 { 00282 uiBut *but; 00283 int x,y; 00284 /*float alpha=1.0f;*/ 00285 00286 x = sx; 00287 y = sy-height; 00288 00289 /*if (icon == ICON_FILE_BLANK) alpha = 0.375f;*/ 00290 00291 but= uiDefIconBut(block, LABEL, 0, icon, x, y, width, height, NULL, 0.0f, 0.0f, 0.0f, 0.0f, ""); 00292 uiButSetDragPath(but, path); 00293 } 00294 00295 00296 static void file_draw_string(int sx, int sy, const char* string, float width, int height, short align) 00297 { 00298 uiStyle *style= U.uistyles.first; 00299 uiFontStyle fs = style->widgetlabel; 00300 rcti rect; 00301 char fname[FILE_MAXFILE]; 00302 00303 fs.align = align; 00304 00305 BLI_strncpy(fname,string, FILE_MAXFILE); 00306 file_shorten_string(fname, width + 1.0f, 0); 00307 00308 /* no text clipping needed, uiStyleFontDraw does it but is a bit too strict (for buttons it works) */ 00309 rect.xmin = sx; 00310 rect.xmax = (int)(sx + ceil(width+4.0f)); 00311 rect.ymin = sy - height; 00312 rect.ymax = sy; 00313 00314 uiStyleFontDraw(&fs, &rect, fname); 00315 } 00316 00317 void file_calc_previews(const bContext *C, ARegion *ar) 00318 { 00319 SpaceFile *sfile= CTX_wm_space_file(C); 00320 View2D *v2d= &ar->v2d; 00321 00322 ED_fileselect_init_layout(sfile, ar); 00323 /* +SCROLL_HEIGHT is bad hack to work around issue in UI_view2d_totRect_set */ 00324 UI_view2d_totRect_set(v2d, sfile->layout->width, sfile->layout->height+V2D_SCROLL_HEIGHT); 00325 } 00326 00327 static void file_draw_preview(uiBlock *block, struct direntry *file, int sx, int sy, ImBuf *imb, FileLayout *layout, short dropshadow) 00328 { 00329 if (imb) { 00330 uiBut *but; 00331 float fx, fy; 00332 float dx, dy; 00333 int xco, yco; 00334 float scaledx, scaledy; 00335 float scale; 00336 int ex, ey; 00337 00338 if ( (imb->x > layout->prv_w) || (imb->y > layout->prv_h) ) { 00339 if (imb->x > imb->y) { 00340 scaledx = (float)layout->prv_w; 00341 scaledy = ( (float)imb->y/(float)imb->x )*layout->prv_w; 00342 scale = scaledx/imb->x; 00343 } 00344 else { 00345 scaledy = (float)layout->prv_h; 00346 scaledx = ( (float)imb->x/(float)imb->y )*layout->prv_h; 00347 scale = scaledy/imb->y; 00348 } 00349 } else { 00350 scaledx = (float)imb->x; 00351 scaledy = (float)imb->y; 00352 scale = 1.0; 00353 } 00354 ex = (int)scaledx; 00355 ey = (int)scaledy; 00356 fx = ((float)layout->prv_w - (float)ex)/2.0f; 00357 fy = ((float)layout->prv_h - (float)ey)/2.0f; 00358 dx = (fx + 0.5f + layout->prv_border_x); 00359 dy = (fy + 0.5f - layout->prv_border_y); 00360 xco = sx + (int)dx; 00361 yco = sy - layout->prv_h + (int)dy; 00362 00363 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 00364 00365 /* shadow */ 00366 if (dropshadow) 00367 uiDrawBoxShadow(220, (float)xco, (float)yco, (float)(xco + ex), (float)(yco + ey)); 00368 00369 glEnable(GL_BLEND); 00370 00371 /* the image */ 00372 glColor4f(1.0, 1.0, 1.0, 1.0); 00373 glaDrawPixelsTexScaled((float)xco, (float)yco, imb->x, imb->y, GL_UNSIGNED_BYTE, imb->rect, scale, scale); 00374 00375 /* border */ 00376 if (dropshadow) { 00377 glColor4f(0.0f, 0.0f, 0.0f, 0.4f); 00378 fdrawbox((float)xco, (float)yco, (float)(xco + ex), (float)(yco + ey)); 00379 } 00380 00381 /* dragregion */ 00382 but= uiDefBut(block, LABEL, 0, "", xco, yco, ex, ey, NULL, 0.0, 0.0, 0, 0, ""); 00383 uiButSetDragImage(but, file->path, get_file_icon(file), imb, scale); 00384 00385 glDisable(GL_BLEND); 00386 imb = NULL; 00387 } 00388 } 00389 00390 static void renamebutton_cb(bContext *C, void *UNUSED(arg1), char *oldname) 00391 { 00392 char newname[FILE_MAX+12]; 00393 char orgname[FILE_MAX+12]; 00394 char filename[FILE_MAX+12]; 00395 SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C); 00396 ARegion* ar = CTX_wm_region(C); 00397 00398 BLI_make_file_string(G.main->name, orgname, sfile->params->dir, oldname); 00399 BLI_strncpy(filename, sfile->params->renameedit, sizeof(filename)); 00400 BLI_make_file_string(G.main->name, newname, sfile->params->dir, filename); 00401 00402 if( strcmp(orgname, newname) != 0 ) { 00403 if (!BLI_exists(newname)) { 00404 BLI_rename(orgname, newname); 00405 /* to make sure we show what is on disk */ 00406 ED_fileselect_clear(C, sfile); 00407 } 00408 00409 ED_region_tag_redraw(ar); 00410 } 00411 } 00412 00413 00414 static void draw_background(FileLayout *layout, View2D *v2d) 00415 { 00416 int i; 00417 int sy; 00418 00419 /* alternating flat shade background */ 00420 for (i=0; (i <= layout->rows); i+=2) 00421 { 00422 sy = (int)v2d->cur.ymax - i*(layout->tile_h+2*layout->tile_border_y) - layout->tile_border_y; 00423 00424 UI_ThemeColorShade(TH_BACK, -7); 00425 glRectf(v2d->cur.xmin, (float)sy, v2d->cur.xmax, (float)(sy+layout->tile_h+2*layout->tile_border_y)); 00426 00427 } 00428 } 00429 00430 static void draw_dividers(FileLayout *layout, View2D *v2d) 00431 { 00432 int sx; 00433 00434 /* vertical column dividers */ 00435 sx = (int)v2d->tot.xmin; 00436 while (sx < v2d->cur.xmax) { 00437 sx += (layout->tile_w+2*layout->tile_border_x); 00438 00439 UI_ThemeColorShade(TH_BACK, 30); 00440 sdrawline(sx+1, (short)(v2d->cur.ymax - layout->tile_border_y), sx+1, (short)v2d->cur.ymin); 00441 UI_ThemeColorShade(TH_BACK, -30); 00442 sdrawline(sx, (short)(v2d->cur.ymax - layout->tile_border_y), sx, (short)v2d->cur.ymin); 00443 } 00444 } 00445 00446 void file_draw_list(const bContext *C, ARegion *ar) 00447 { 00448 SpaceFile *sfile= CTX_wm_space_file(C); 00449 FileSelectParams* params = ED_fileselect_get_params(sfile); 00450 FileLayout* layout= ED_fileselect_get_layout(sfile, ar); 00451 View2D *v2d= &ar->v2d; 00452 struct FileList* files = sfile->files; 00453 struct direntry *file; 00454 ImBuf *imb; 00455 uiBlock *block = uiBeginBlock(C, ar, "FileNames", UI_EMBOSS); 00456 int numfiles; 00457 int numfiles_layout; 00458 int sx, sy; 00459 int offset; 00460 int textwidth, textheight; 00461 int i; 00462 short is_icon; 00463 short align; 00464 00465 00466 numfiles = filelist_numfiles(files); 00467 00468 if (params->display != FILE_IMGDISPLAY) { 00469 00470 draw_background(layout, v2d); 00471 00472 draw_dividers(layout, v2d); 00473 } 00474 00475 offset = ED_fileselect_layout_offset(layout, (int)ar->v2d.cur.xmin, (int)-ar->v2d.cur.ymax); 00476 if (offset<0) offset=0; 00477 00478 numfiles_layout = ED_fileselect_layout_numfiles(layout, ar); 00479 00480 /* adjust, so the next row is already drawn when scrolling */ 00481 if (layout->flag & FILE_LAYOUT_HOR) { 00482 numfiles_layout += layout->rows; 00483 } else { 00484 numfiles_layout += layout->columns; 00485 } 00486 00487 textwidth =( FILE_IMGDISPLAY == params->display) ? layout->tile_w : (int)layout->column_widths[COLUMN_NAME]; 00488 textheight = (int)(layout->textheight*3.0/2.0 + 0.5); 00489 00490 align = ( FILE_IMGDISPLAY == params->display) ? UI_STYLE_TEXT_CENTER : UI_STYLE_TEXT_LEFT; 00491 00492 for (i=offset; (i < numfiles) && (i<offset+numfiles_layout); ++i) 00493 { 00494 ED_fileselect_layout_tilepos(layout, i, &sx, &sy); 00495 sx += (int)(v2d->tot.xmin+2.0f); 00496 sy = (int)(v2d->tot.ymax - sy); 00497 00498 file = filelist_file(files, i); 00499 00500 UI_ThemeColor4(TH_TEXT); 00501 00502 00503 if (!(file->selflag & EDITING_FILE)) { 00504 if ((params->active_file == i) || (file->selflag & HILITED_FILE) || (file->selflag & SELECTED_FILE) ) { 00505 int colorid = (file->selflag & SELECTED_FILE) ? TH_HILITE : TH_BACK; 00506 int shade = (params->active_file == i) || (file->selflag & HILITED_FILE) ? 20 : 0; 00507 draw_tile(sx, sy-1, layout->tile_w+4, sfile->layout->tile_h+layout->tile_border_y, colorid, shade); 00508 } 00509 } 00510 uiSetRoundBox(0); 00511 00512 if ( FILE_IMGDISPLAY == params->display ) { 00513 is_icon = 0; 00514 imb = filelist_getimage(files, i); 00515 if (!imb) { 00516 imb = filelist_geticon(files,i); 00517 is_icon = 1; 00518 } 00519 00520 file_draw_preview(block, file, sx, sy, imb, layout, !is_icon && (file->flags & IMAGEFILE)); 00521 } else { 00522 file_draw_icon(block, file->path, sx, sy-(UI_UNIT_Y / 6), get_file_icon(file), ICON_DEFAULT_WIDTH_SCALE, ICON_DEFAULT_WIDTH_SCALE); 00523 sx += ICON_DEFAULT_WIDTH_SCALE + 4; 00524 } 00525 00526 UI_ThemeColor4(TH_TEXT); 00527 00528 if (file->selflag & EDITING_FILE) { 00529 uiBut *but = uiDefBut(block, TEX, 1, "", sx , sy-layout->tile_h-3, 00530 textwidth, textheight, sfile->params->renameedit, 1.0f, (float)sizeof(sfile->params->renameedit),0,0,""); 00531 uiButSetRenameFunc(but, renamebutton_cb, file); 00532 uiButSetFlag(but, UI_BUT_NO_UTF8); /* allow non utf8 names */ 00533 if ( 0 == uiButActiveOnly(C, block, but)) { 00534 file->selflag &= ~EDITING_FILE; 00535 } 00536 } 00537 00538 if (!(file->selflag & EDITING_FILE)) { 00539 int tpos = (FILE_IMGDISPLAY == params->display) ? sy - layout->tile_h + layout->textheight : sy; 00540 file_draw_string(sx+1, tpos, file->relname, (float)textwidth, textheight, align); 00541 } 00542 00543 if (params->display == FILE_SHORTDISPLAY) { 00544 sx += (int)layout->column_widths[COLUMN_NAME] + 12; 00545 if (!(file->type & S_IFDIR)) { 00546 file_draw_string(sx, sy, file->size, layout->column_widths[COLUMN_SIZE], layout->tile_h, align); 00547 sx += (int)layout->column_widths[COLUMN_SIZE] + 12; 00548 } 00549 } else if (params->display == FILE_LONGDISPLAY) { 00550 sx += (int)layout->column_widths[COLUMN_NAME] + 12; 00551 00552 #ifndef WIN32 00553 /* rwx rwx rwx */ 00554 file_draw_string(sx, sy, file->mode1, layout->column_widths[COLUMN_MODE1], layout->tile_h, align); 00555 sx += layout->column_widths[COLUMN_MODE1] + 12; 00556 00557 file_draw_string(sx, sy, file->mode2, layout->column_widths[COLUMN_MODE2], layout->tile_h, align); 00558 sx += layout->column_widths[COLUMN_MODE2] + 12; 00559 00560 file_draw_string(sx, sy, file->mode3, layout->column_widths[COLUMN_MODE3], layout->tile_h, align); 00561 sx += layout->column_widths[COLUMN_MODE3] + 12; 00562 00563 file_draw_string(sx, sy, file->owner, layout->column_widths[COLUMN_OWNER] , layout->tile_h, align); 00564 sx += layout->column_widths[COLUMN_OWNER] + 12; 00565 #endif 00566 00567 file_draw_string(sx, sy, file->date, layout->column_widths[COLUMN_DATE], layout->tile_h, align); 00568 sx += (int)layout->column_widths[COLUMN_DATE] + 12; 00569 00570 file_draw_string(sx, sy, file->time, layout->column_widths[COLUMN_TIME] , layout->tile_h, align); 00571 sx += (int)layout->column_widths[COLUMN_TIME] + 12; 00572 00573 if (!(file->type & S_IFDIR)) { 00574 file_draw_string(sx, sy, file->size, layout->column_widths[COLUMN_SIZE], layout->tile_h, align); 00575 sx += (int)layout->column_widths[COLUMN_SIZE] + 12; 00576 } 00577 } 00578 } 00579 00580 uiEndBlock(C, block); 00581 uiDrawBlock(C, block); 00582 00583 }