File Browser fixes:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Mon, 28 Sep 2009 12:10:23 +0000 (12:10 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Mon, 28 Sep 2009 12:10:23 +0000 (12:10 +0000)
* 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.

source/blender/editors/include/ED_fileselect.h
source/blender/editors/interface/view2d.c
source/blender/editors/space_file/file_draw.c
source/blender/editors/space_file/file_ops.c
source/blender/editors/space_file/filesel.c
source/blender/editors/space_file/space_file.c

index 57ab6a5f8f61bebbeeee373d7144a014b5694d3b..221b377dd25d701107a305ff358840e3c082ae3e 100644 (file)
@@ -51,21 +51,21 @@ typedef enum FileListColumns {
 typedef struct FileLayout
 {
        /* view settings - XXX - move into own struct */
-       short prv_w;
-       short prv_h;
-       short tile_w;
-       short tile_h;
-       short tile_border_x;
-       short tile_border_y;
-       short prv_border_x;
-       short prv_border_y;
-       short rows;
-       short columns;
-       short width;
-       short height;
-       short flag;
-       short dirty;
-       short textheight;
+       int prv_w;
+       int prv_h;
+       int tile_w;
+       int tile_h;
+       int tile_border_x;
+       int tile_border_y;
+       int prv_border_x;
+       int prv_border_y;
+       int rows;
+       int columns;
+       int width;
+       int height;
+       int flag;
+       int dirty;
+       int textheight;
        float column_widths[MAX_FILE_COLUMN];
 } 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_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 */
index 2da491e488db68138c2d105468567d67f0f9f979..f7546e94f8637420ac4d78fbccc71a7bfd585b4e 100644 (file)
@@ -831,6 +831,7 @@ void UI_view2d_totRect_set_resize (View2D *v2d, int width, int height, int resiz
        height= abs(height);
        
        /* hrumf! */
+       /* XXX: there are work arounds for this in the panel and file browse code. */
        if(scroll & V2D_SCROLL_HORIZONTAL) 
                width -= V2D_SCROLL_WIDTH;
        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) 
                        scrollers->hor_min= scrollers->hor_max;
                /* prevent sliders from being too small, and disappearing */
-               if ((scrollers->hor_max - scrollers->hor_min) < V2D_SCROLLER_HANDLE_SIZE)
-                       scrollers->hor_max+= V2D_SCROLLER_HANDLE_SIZE;
+               if ((scrollers->hor_max - scrollers->hor_min) < 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 */
                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) 
                        scrollers->vert_min= scrollers->vert_max;
                /* prevent sliders from being too small, and disappearing */
-               if ((scrollers->vert_max - scrollers->vert_min) < V2D_SCROLLER_HANDLE_SIZE)
-                       scrollers->vert_max+= V2D_SCROLLER_HANDLE_SIZE;
+               if ((scrollers->vert_max - scrollers->vert_min) < 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 */
                if(v2d->keeptot) {
index 46ed6987752e4d58331c6754eea8f2913761f56b..5d02e096228b7e73a6245a5f58333657c62acd8d 100644 (file)
@@ -133,24 +133,24 @@ static void do_file_buttons(bContext *C, void *arg, int event)
 void file_draw_buttons(const bContext *C, ARegion *ar)
 {
        /* Button layout. */
-       const short min_x      = 10;
-       const short max_x      = ar->winx - 10;
-       const short line1_y    = IMASEL_BUTTONS_HEIGHT/2 + IMASEL_BUTTONS_MARGIN*2;
-       const short line2_y    = IMASEL_BUTTONS_MARGIN;
-       const short input_minw = 20;
-       const short btn_h      = UI_UNIT_Y;
-       const short btn_fn_w   = UI_UNIT_X;
-       const short btn_minw   = 80;
-       const short btn_margin = 20;
-       const short separator  = 4;
+       const int min_x      = 10;
+       const int max_x      = ar->winx - 10;
+       const int line1_y    = IMASEL_BUTTONS_HEIGHT/2 + IMASEL_BUTTONS_MARGIN*2;
+       const int line2_y    = IMASEL_BUTTONS_MARGIN;
+       const int input_minw = 20;
+       const int btn_h      = UI_UNIT_Y;
+       const int btn_fn_w   = UI_UNIT_X;
+       const int btn_minw   = 80;
+       const int btn_margin = 20;
+       const int separator  = 4;
 
        /* Additional locals. */
        char  name[20];
-       short loadbutton;
-       short fnumbuttons;
-       short available_w = max_x - min_x;
-       short line1_w     = available_w;
-       short line2_w     = available_w;
+       int loadbutton;
+       int fnumbuttons;
+       int available_w = max_x - min_x;
+       int line1_w     = available_w;
+       int line2_w     = available_w;
        
        uiBut*            but;
        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);
        uiSetRoundBox(15);      
@@ -310,7 +310,7 @@ static int get_file_icon(struct direntry *file)
                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;
        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];
        float sw;
        float x,y;
@@ -350,18 +350,19 @@ void file_calc_previews(const bContext *C, ARegion *ar)
        View2D *v2d= &ar->v2d;
        
        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) {
                        float fx, fy;
                        float dx, dy;
-                       short xco, yco;
+                       int xco, yco;
                        float scaledx, scaledy;
                        float scale;
-                       short ex, ey;
+                       int ex, ey;
 
                        if ( (imb->x > layout->prv_w) || (imb->y > layout->prv_h) ) {
                                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;
                                scale = 1.0;
                        }
-                       ex = (short)scaledx;
-                       ey = (short)scaledy;
+                       ex = (int)scaledx;
+                       ey = (int)scaledy;
                        fx = ((float)layout->prv_w - (float)ex)/2.0f;
                        fy = ((float)layout->prv_h - (float)ey)/2.0f;
                        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)
 {
        int i;
-       short sy;
+       int sy;
 
        /* alternating flat shade background */
        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)
 {
-       short sx;
+       int sx;
 
        /* vertical column dividers */
        sx = v2d->tot.xmin;
@@ -483,7 +484,7 @@ void file_draw_list(const bContext *C, ARegion *ar)
        int numfiles;
        int numfiles_layout;
        int colorid = 0;
-       short sx, sy;
+       int sx, sy;
        int offset;
        int i;
        float sw, spos;
@@ -491,12 +492,6 @@ void file_draw_list(const bContext *C, ARegion *ar)
 
        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) {
 
                draw_background(layout, v2d);
@@ -504,9 +499,9 @@ void file_draw_list(const bContext *C, ARegion *ar)
                draw_dividers(layout, v2d);
        }
 
-       sx = ar->v2d.cur.xmin + layout->tile_border_x;
-       sy = ar->v2d.cur.ymax - layout->tile_border_y;
-       
+       offset = ED_fileselect_layout_offset(layout, ar->v2d.cur.xmin, -ar->v2d.cur.ymax);
+       if (offset<0) offset=0;
+
        numfiles_layout = ED_fileselect_layout_numfiles(layout, ar);
 
        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);
                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);
                        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,"");
@@ -573,15 +568,14 @@ void file_draw_list(const bContext *C, ARegion *ar)
                        spos += layout->column_widths[COLUMN_NAME] + 12;
                        if (!(file->type & S_IFDIR)) {
                                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); 
+                               spos += layout->column_widths[COLUMN_SIZE] + 12;
                        }
                } else if (params->display == FILE_LONGDISPLAY) {
                        spos += layout->column_widths[COLUMN_NAME] + 12;
 
 #ifndef WIN32
                        /* rwx rwx rwx */
-                       spos += 20;
                        sw = file_string_width(file->mode1);
                        file_draw_string(spos, sy, file->mode1, sw, layout->tile_h, FILE_SHORTEN_END); 
                        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)) {
                                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);
+                               spos += layout->column_widths[COLUMN_SIZE] + 12;
                        }
                }
        }
index c717623696a735c636cc9eef9cce609b09351f4b..75230813a41e1670511add02051c87cfdbcf451e 100644 (file)
@@ -68,7 +68,7 @@
 
 /* ---------- 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;
        int active_file = -1;
index dd16a4268992df01c6f5cf437fa2f84304b11e9b..1f461f1bbd59227a8da00e292a36eb4430e15648 100644 (file)
@@ -189,14 +189,14 @@ int ED_fileselect_layout_numfiles(FileLayout* layout, struct ARegion *ar)
        int numfiles;
 
        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;
+               return numfiles*layout->rows;
        } 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;
+               return numfiles*layout->columns;
        }
-
-       return layout->columns*layout->rows;
 }
 
 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;
 }
 
-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) {
                *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) {
                        int len;
                        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);
                        if (len > layout->column_widths[COLUMN_DATE]) layout->column_widths[COLUMN_DATE] = len;
                        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);
 
                if (params->display == FILE_SHORTDISPLAY) {
-                       maxlen = layout->column_widths[COLUMN_NAME] +
+                       maxlen = layout->column_widths[COLUMN_NAME] + 12 +
                                         layout->column_widths[COLUMN_SIZE];
-                       maxlen += 20+2*10; // for icon and space between columns
+                       maxlen += 20; // for icon
                } else {
-                       maxlen = layout->column_widths[COLUMN_NAME] +
-                                        layout->column_widths[COLUMN_DATE] +
-                                        layout->column_widths[COLUMN_TIME] +
+                       maxlen = layout->column_widths[COLUMN_NAME] + 12 +
+#ifndef WIN32
+                                        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];
-                                       /* XXX add mode1, mode2, mode3, owner columns for non-windows platforms */
-                       maxlen += 20+4*10; // for icon and space between columns
+                       maxlen += 20; // for icon
                }
-               layout->tile_w = maxlen + 40;
+               layout->tile_w = maxlen;
                if(layout->rows > 0)
                        layout->columns = numfiles/layout->rows + 1; // XXX dirty, modulo is zero
                else {
index ca2c145c52b82a5aaceb869d3d531afbd15b5506..ed0d998ef40139c35d110992b90d3acba0c13c0d 100644 (file)
@@ -155,8 +155,10 @@ static void file_free(SpaceLink *sl)
 /* spacetype; init callback, area size changes, screen set, etc */
 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");
+
+       if(sfile->layout) sfile->layout->dirty= 1;
 }