File Browser fixes:

* The code to draw only visible items was not working, giving slow
  performance with many files (bug #19469).
* Fix detailed list display on non-windows, would give overlapping text.
* Fix folders with many files not displaying all items, changed short to
  int in various places, was overflowing.
* Recreate layout on area resizes, file view gets out of sync otherwise.
* Workaround for v2d height not being correct with image display due to
  scrollers.
* Fix view2d code to compute minimum scroller size, this would make the
  scroller go outside of its bounds.
This commit is contained in:
Brecht Van Lommel 2009-09-28 12:10:23 +00:00
parent 996c767071
commit 0356b92d46
6 changed files with 91 additions and 77 deletions

@ -51,21 +51,21 @@ typedef enum FileListColumns {
typedef struct FileLayout typedef struct FileLayout
{ {
/* view settings - XXX - move into own struct */ /* view settings - XXX - move into own struct */
short prv_w; int prv_w;
short prv_h; int prv_h;
short tile_w; int tile_w;
short tile_h; int tile_h;
short tile_border_x; int tile_border_x;
short tile_border_y; int tile_border_y;
short prv_border_x; int prv_border_x;
short prv_border_y; int prv_border_y;
short rows; int rows;
short columns; int columns;
short width; int width;
short height; int height;
short flag; int flag;
short dirty; int dirty;
short textheight; int textheight;
float column_widths[MAX_FILE_COLUMN]; float column_widths[MAX_FILE_COLUMN];
} FileLayout; } FileLayout;
@ -84,7 +84,7 @@ FileLayout* ED_fileselect_get_layout(struct SpaceFile *sfile, struct ARegion *ar
int ED_fileselect_layout_numfiles(FileLayout* layout, struct ARegion *ar); int ED_fileselect_layout_numfiles(FileLayout* layout, struct ARegion *ar);
int ED_fileselect_layout_offset(FileLayout* layout, int x, int y); int ED_fileselect_layout_offset(FileLayout* layout, int x, int y);
void ED_fileselect_layout_tilepos(FileLayout* layout, int tile, short *x, short *y); void ED_fileselect_layout_tilepos(FileLayout* layout, int tile, int *x, int *y);
#endif /* ED_FILES_H */ #endif /* ED_FILES_H */

@ -831,6 +831,7 @@ void UI_view2d_totRect_set_resize (View2D *v2d, int width, int height, int resiz
height= abs(height); height= abs(height);
/* hrumf! */ /* hrumf! */
/* XXX: there are work arounds for this in the panel and file browse code. */
if(scroll & V2D_SCROLL_HORIZONTAL) if(scroll & V2D_SCROLL_HORIZONTAL)
width -= V2D_SCROLL_WIDTH; width -= V2D_SCROLL_WIDTH;
if(scroll & V2D_SCROLL_VERTICAL) if(scroll & V2D_SCROLL_VERTICAL)
@ -1397,8 +1398,14 @@ View2DScrollers *UI_view2d_scrollers_calc(const bContext *C, View2D *v2d, short
if (scrollers->hor_min > scrollers->hor_max) if (scrollers->hor_min > scrollers->hor_max)
scrollers->hor_min= scrollers->hor_max; scrollers->hor_min= scrollers->hor_max;
/* prevent sliders from being too small, and disappearing */ /* prevent sliders from being too small, and disappearing */
if ((scrollers->hor_max - scrollers->hor_min) < V2D_SCROLLER_HANDLE_SIZE) if ((scrollers->hor_max - scrollers->hor_min) < V2D_SCROLLER_HANDLE_SIZE) {
scrollers->hor_max+= V2D_SCROLLER_HANDLE_SIZE; scrollers->hor_max= scrollers->hor_min + V2D_SCROLLER_HANDLE_SIZE;
if(scrollers->hor_max > hor.xmax) {
scrollers->hor_max= hor.xmax;
scrollers->hor_min= MAX2(scrollers->hor_max - V2D_SCROLLER_HANDLE_SIZE, hor.xmin);
}
}
/* check whether sliders can disappear */ /* check whether sliders can disappear */
if(v2d->keeptot) { if(v2d->keeptot) {
@ -1429,8 +1436,14 @@ View2DScrollers *UI_view2d_scrollers_calc(const bContext *C, View2D *v2d, short
if (scrollers->vert_min > scrollers->vert_max) if (scrollers->vert_min > scrollers->vert_max)
scrollers->vert_min= scrollers->vert_max; scrollers->vert_min= scrollers->vert_max;
/* prevent sliders from being too small, and disappearing */ /* prevent sliders from being too small, and disappearing */
if ((scrollers->vert_max - scrollers->vert_min) < V2D_SCROLLER_HANDLE_SIZE) if ((scrollers->vert_max - scrollers->vert_min) < V2D_SCROLLER_HANDLE_SIZE) {
scrollers->vert_max+= V2D_SCROLLER_HANDLE_SIZE; scrollers->vert_max= scrollers->vert_min + V2D_SCROLLER_HANDLE_SIZE;
if(scrollers->vert_max > vert.ymax) {
scrollers->vert_max= vert.ymax;
scrollers->vert_min= MAX2(scrollers->vert_max - V2D_SCROLLER_HANDLE_SIZE, vert.ymin);
}
}
/* check whether sliders can disappear */ /* check whether sliders can disappear */
if(v2d->keeptot) { if(v2d->keeptot) {

@ -133,24 +133,24 @@ static void do_file_buttons(bContext *C, void *arg, int event)
void file_draw_buttons(const bContext *C, ARegion *ar) void file_draw_buttons(const bContext *C, ARegion *ar)
{ {
/* Button layout. */ /* Button layout. */
const short min_x = 10; const int min_x = 10;
const short max_x = ar->winx - 10; const int max_x = ar->winx - 10;
const short line1_y = IMASEL_BUTTONS_HEIGHT/2 + IMASEL_BUTTONS_MARGIN*2; const int line1_y = IMASEL_BUTTONS_HEIGHT/2 + IMASEL_BUTTONS_MARGIN*2;
const short line2_y = IMASEL_BUTTONS_MARGIN; const int line2_y = IMASEL_BUTTONS_MARGIN;
const short input_minw = 20; const int input_minw = 20;
const short btn_h = UI_UNIT_Y; const int btn_h = UI_UNIT_Y;
const short btn_fn_w = UI_UNIT_X; const int btn_fn_w = UI_UNIT_X;
const short btn_minw = 80; const int btn_minw = 80;
const short btn_margin = 20; const int btn_margin = 20;
const short separator = 4; const int separator = 4;
/* Additional locals. */ /* Additional locals. */
char name[20]; char name[20];
short loadbutton; int loadbutton;
short fnumbuttons; int fnumbuttons;
short available_w = max_x - min_x; int available_w = max_x - min_x;
short line1_w = available_w; int line1_w = available_w;
short line2_w = available_w; int line2_w = available_w;
uiBut* but; uiBut* but;
uiBlock* block; uiBlock* block;
@ -230,7 +230,7 @@ void file_draw_buttons(const bContext *C, ARegion *ar)
} }
static void draw_tile(short sx, short sy, short width, short height, int colorid, int shade) static void draw_tile(int sx, int sy, int width, int height, int colorid, int shade)
{ {
UI_ThemeColorShade(colorid, shade); UI_ThemeColorShade(colorid, shade);
uiSetRoundBox(15); uiSetRoundBox(15);
@ -310,7 +310,7 @@ static int get_file_icon(struct direntry *file)
return ICON_FILE_BLANK; return ICON_FILE_BLANK;
} }
static void file_draw_icon(short sx, short sy, int icon, short width, short height) static void file_draw_icon(int sx, int sy, int icon, int width, int height)
{ {
float x,y; float x,y;
int blend=0; int blend=0;
@ -326,9 +326,9 @@ static void file_draw_icon(short sx, short sy, int icon, short width, short heig
} }
static void file_draw_string(short sx, short sy, const char* string, float width, short height, int flag) static void file_draw_string(int sx, int sy, const char* string, float width, int height, int flag)
{ {
short soffs; int soffs;
char fname[FILE_MAXFILE]; char fname[FILE_MAXFILE];
float sw; float sw;
float x,y; float x,y;
@ -350,18 +350,19 @@ void file_calc_previews(const bContext *C, ARegion *ar)
View2D *v2d= &ar->v2d; View2D *v2d= &ar->v2d;
ED_fileselect_init_layout(sfile, ar); ED_fileselect_init_layout(sfile, ar);
UI_view2d_totRect_set(v2d, sfile->layout->width, sfile->layout->height); /* +SCROLL_HEIGHT is bad hack to work around issue in UI_view2d_totRect_set */
UI_view2d_totRect_set(v2d, sfile->layout->width, sfile->layout->height+V2D_SCROLL_HEIGHT);
} }
static void file_draw_preview(short sx, short sy, ImBuf *imb, FileLayout *layout, short dropshadow) static void file_draw_preview(int sx, int sy, ImBuf *imb, FileLayout *layout, short dropshadow)
{ {
if (imb) { if (imb) {
float fx, fy; float fx, fy;
float dx, dy; float dx, dy;
short xco, yco; int xco, yco;
float scaledx, scaledy; float scaledx, scaledy;
float scale; float scale;
short ex, ey; int ex, ey;
if ( (imb->x > layout->prv_w) || (imb->y > layout->prv_h) ) { if ( (imb->x > layout->prv_w) || (imb->y > layout->prv_h) ) {
if (imb->x > imb->y) { if (imb->x > imb->y) {
@ -379,8 +380,8 @@ static void file_draw_preview(short sx, short sy, ImBuf *imb, FileLayout *layout
scaledy = (float)imb->y; scaledy = (float)imb->y;
scale = 1.0; scale = 1.0;
} }
ex = (short)scaledx; ex = (int)scaledx;
ey = (short)scaledy; ey = (int)scaledy;
fx = ((float)layout->prv_w - (float)ex)/2.0f; fx = ((float)layout->prv_w - (float)ex)/2.0f;
fy = ((float)layout->prv_h - (float)ey)/2.0f; fy = ((float)layout->prv_h - (float)ey)/2.0f;
dx = (fx + 0.5f + layout->prv_border_x); dx = (fx + 0.5f + layout->prv_border_x);
@ -442,7 +443,7 @@ static void renamebutton_cb(bContext *C, void *arg1, char *oldname)
static void draw_background(FileLayout *layout, View2D *v2d) static void draw_background(FileLayout *layout, View2D *v2d)
{ {
int i; int i;
short sy; int sy;
/* alternating flat shade background */ /* alternating flat shade background */
for (i=0; (i <= layout->rows); i+=2) for (i=0; (i <= layout->rows); i+=2)
@ -457,7 +458,7 @@ static void draw_background(FileLayout *layout, View2D *v2d)
static void draw_dividers(FileLayout *layout, View2D *v2d) static void draw_dividers(FileLayout *layout, View2D *v2d)
{ {
short sx; int sx;
/* vertical column dividers */ /* vertical column dividers */
sx = v2d->tot.xmin; sx = v2d->tot.xmin;
@ -483,7 +484,7 @@ void file_draw_list(const bContext *C, ARegion *ar)
int numfiles; int numfiles;
int numfiles_layout; int numfiles_layout;
int colorid = 0; int colorid = 0;
short sx, sy; int sx, sy;
int offset; int offset;
int i; int i;
float sw, spos; float sw, spos;
@ -491,12 +492,6 @@ void file_draw_list(const bContext *C, ARegion *ar)
numfiles = filelist_numfiles(files); numfiles = filelist_numfiles(files);
sx = ar->v2d.tot.xmin + layout->tile_border_x/2;
sy = ar->v2d.cur.ymax - layout->tile_border_y;
offset = ED_fileselect_layout_offset(layout, 0, 0);
if (offset<0) offset=0;
if (params->display != FILE_IMGDISPLAY) { if (params->display != FILE_IMGDISPLAY) {
draw_background(layout, v2d); draw_background(layout, v2d);
@ -504,9 +499,9 @@ void file_draw_list(const bContext *C, ARegion *ar)
draw_dividers(layout, v2d); draw_dividers(layout, v2d);
} }
sx = ar->v2d.cur.xmin + layout->tile_border_x; offset = ED_fileselect_layout_offset(layout, ar->v2d.cur.xmin, -ar->v2d.cur.ymax);
sy = ar->v2d.cur.ymax - layout->tile_border_y; if (offset<0) offset=0;
numfiles_layout = ED_fileselect_layout_numfiles(layout, ar); numfiles_layout = ED_fileselect_layout_numfiles(layout, ar);
for (i=offset; (i < numfiles) && (i<offset+numfiles_layout); ++i) for (i=offset; (i < numfiles) && (i<offset+numfiles_layout); ++i)
@ -552,7 +547,7 @@ void file_draw_list(const bContext *C, ARegion *ar)
sw = file_string_width(file->relname); sw = file_string_width(file->relname);
if (file->flags & EDITING) { if (file->flags & EDITING) {
short but_width = (FILE_IMGDISPLAY == params->display) ? layout->tile_w : layout->column_widths[COLUMN_NAME]; int but_width = (FILE_IMGDISPLAY == params->display) ? layout->tile_w : layout->column_widths[COLUMN_NAME];
uiBlock *block = uiBeginBlock(C, ar, "FileName", UI_EMBOSS); uiBlock *block = uiBeginBlock(C, ar, "FileName", UI_EMBOSS);
uiBut *but = uiDefBut(block, TEX, 1, "", spos, sy-layout->tile_h-3, uiBut *but = uiDefBut(block, TEX, 1, "", spos, sy-layout->tile_h-3,
but_width, layout->textheight*2, file->relname, 1.0f, (float)FILE_MAX,0,0,""); but_width, layout->textheight*2, file->relname, 1.0f, (float)FILE_MAX,0,0,"");
@ -573,15 +568,14 @@ void file_draw_list(const bContext *C, ARegion *ar)
spos += layout->column_widths[COLUMN_NAME] + 12; spos += layout->column_widths[COLUMN_NAME] + 12;
if (!(file->type & S_IFDIR)) { if (!(file->type & S_IFDIR)) {
sw = file_string_width(file->size); sw = file_string_width(file->size);
spos += layout->column_widths[COLUMN_SIZE] + 12 - sw;
file_draw_string(spos, sy, file->size, sw+1, layout->tile_h, FILE_SHORTEN_END); file_draw_string(spos, sy, file->size, sw+1, layout->tile_h, FILE_SHORTEN_END);
spos += layout->column_widths[COLUMN_SIZE] + 12;
} }
} else if (params->display == FILE_LONGDISPLAY) { } else if (params->display == FILE_LONGDISPLAY) {
spos += layout->column_widths[COLUMN_NAME] + 12; spos += layout->column_widths[COLUMN_NAME] + 12;
#ifndef WIN32 #ifndef WIN32
/* rwx rwx rwx */ /* rwx rwx rwx */
spos += 20;
sw = file_string_width(file->mode1); sw = file_string_width(file->mode1);
file_draw_string(spos, sy, file->mode1, sw, layout->tile_h, FILE_SHORTEN_END); file_draw_string(spos, sy, file->mode1, sw, layout->tile_h, FILE_SHORTEN_END);
spos += layout->column_widths[COLUMN_MODE1] + 12; spos += layout->column_widths[COLUMN_MODE1] + 12;
@ -609,8 +603,8 @@ void file_draw_list(const bContext *C, ARegion *ar)
if (!(file->type & S_IFDIR)) { if (!(file->type & S_IFDIR)) {
sw = file_string_width(file->size); sw = file_string_width(file->size);
spos += layout->column_widths[COLUMN_SIZE] + 12 - sw;
file_draw_string(spos, sy, file->size, sw, layout->tile_h, FILE_SHORTEN_END); file_draw_string(spos, sy, file->size, sw, layout->tile_h, FILE_SHORTEN_END);
spos += layout->column_widths[COLUMN_SIZE] + 12;
} }
} }
} }

@ -68,7 +68,7 @@
/* ---------- FILE SELECTION ------------ */ /* ---------- FILE SELECTION ------------ */
static int find_file_mouse(SpaceFile *sfile, struct ARegion* ar, short x, short y) static int find_file_mouse(SpaceFile *sfile, struct ARegion* ar, int x, int y)
{ {
float fx,fy; float fx,fy;
int active_file = -1; int active_file = -1;

@ -189,14 +189,14 @@ int ED_fileselect_layout_numfiles(FileLayout* layout, struct ARegion *ar)
int numfiles; int numfiles;
if (layout->flag & FILE_LAYOUT_HOR) { if (layout->flag & FILE_LAYOUT_HOR) {
short width = ar->v2d.cur.xmax - ar->v2d.cur.xmin - 2*layout->tile_border_x; int width = ar->v2d.cur.xmax - ar->v2d.cur.xmin - 2*layout->tile_border_x;
numfiles = width/layout->tile_w + 1; numfiles = width/layout->tile_w + 1;
return numfiles*layout->rows;
} else { } else {
short height = ar->v2d.cur.ymax - ar->v2d.cur.ymin - 2*layout->tile_border_y; int height = ar->v2d.cur.ymax - ar->v2d.cur.ymin - 2*layout->tile_border_y;
numfiles = height/layout->tile_h + 1; numfiles = height/layout->tile_h + 1;
return numfiles*layout->columns;
} }
return layout->columns*layout->rows;
} }
int ED_fileselect_layout_offset(FileLayout* layout, int x, int y) int ED_fileselect_layout_offset(FileLayout* layout, int x, int y)
@ -220,7 +220,7 @@ int ED_fileselect_layout_offset(FileLayout* layout, int x, int y)
return active_file; return active_file;
} }
void ED_fileselect_layout_tilepos(FileLayout* layout, int tile, short *x, short *y) void ED_fileselect_layout_tilepos(FileLayout* layout, int tile, int *x, int *y)
{ {
if (layout->flag == FILE_LAYOUT_HOR) { if (layout->flag == FILE_LAYOUT_HOR) {
*x = layout->tile_border_x + (tile/layout->rows)*(layout->tile_w+2*layout->tile_border_x); *x = layout->tile_border_x + (tile/layout->rows)*(layout->tile_w+2*layout->tile_border_x);
@ -263,7 +263,7 @@ static void column_widths(struct FileList* files, struct FileLayout* layout)
if (file) { if (file) {
int len; int len;
len = file_string_width(file->relname); len = file_string_width(file->relname);
if (len > layout->column_widths[COLUMN_NAME]) layout->column_widths[COLUMN_NAME] = len; if (len > layout->column_widths[COLUMN_NAME]) layout->column_widths[COLUMN_NAME] = len + 20;
len = file_string_width(file->date); len = file_string_width(file->date);
if (len > layout->column_widths[COLUMN_DATE]) layout->column_widths[COLUMN_DATE] = len; if (len > layout->column_widths[COLUMN_DATE]) layout->column_widths[COLUMN_DATE] = len;
len = file_string_width(file->time); len = file_string_width(file->time);
@ -335,18 +335,23 @@ void ED_fileselect_init_layout(struct SpaceFile *sfile, struct ARegion *ar)
column_widths(sfile->files, layout); column_widths(sfile->files, layout);
if (params->display == FILE_SHORTDISPLAY) { if (params->display == FILE_SHORTDISPLAY) {
maxlen = layout->column_widths[COLUMN_NAME] + maxlen = layout->column_widths[COLUMN_NAME] + 12 +
layout->column_widths[COLUMN_SIZE]; layout->column_widths[COLUMN_SIZE];
maxlen += 20+2*10; // for icon and space between columns maxlen += 20; // for icon
} else { } else {
maxlen = layout->column_widths[COLUMN_NAME] + maxlen = layout->column_widths[COLUMN_NAME] + 12 +
layout->column_widths[COLUMN_DATE] + #ifndef WIN32
layout->column_widths[COLUMN_TIME] + layout->column_widths[COLUMN_MODE1] + 12 +
layout->column_widths[COLUMN_MODE2] + 12 +
layout->column_widths[COLUMN_MODE3] + 12 +
layout->column_widths[COLUMN_OWNER] + 12 +
#endif
layout->column_widths[COLUMN_DATE] + 12 +
layout->column_widths[COLUMN_TIME] + 12 +
layout->column_widths[COLUMN_SIZE]; layout->column_widths[COLUMN_SIZE];
/* XXX add mode1, mode2, mode3, owner columns for non-windows platforms */ maxlen += 20; // for icon
maxlen += 20+4*10; // for icon and space between columns
} }
layout->tile_w = maxlen + 40; layout->tile_w = maxlen;
if(layout->rows > 0) if(layout->rows > 0)
layout->columns = numfiles/layout->rows + 1; // XXX dirty, modulo is zero layout->columns = numfiles/layout->rows + 1; // XXX dirty, modulo is zero
else { else {

@ -155,8 +155,10 @@ static void file_free(SpaceLink *sl)
/* spacetype; init callback, area size changes, screen set, etc */ /* spacetype; init callback, area size changes, screen set, etc */
static void file_init(struct wmWindowManager *wm, ScrArea *sa) static void file_init(struct wmWindowManager *wm, ScrArea *sa)
{ {
//SpaceFile *sfile= (SpaceFile*)sa->spacedata.first; SpaceFile *sfile= (SpaceFile*)sa->spacedata.first;
printf("file_init\n"); printf("file_init\n");
if(sfile->layout) sfile->layout->dirty= 1;
} }