diff options
author | Andrea Weikert <elubie@gmx.net> | 2011-03-14 22:56:13 +0300 |
---|---|---|
committer | Andrea Weikert <elubie@gmx.net> | 2011-03-14 22:56:13 +0300 |
commit | 41c27cd6efa70f9a7a8135a0dcbf483c766db18c (patch) | |
tree | f646f073692d2a632689ad1118a0ed69cc995754 /source/blender/editors | |
parent | d789484dc707ca46ab84af0fe1c14eb9e4ce5933 (diff) |
== filebrowser ==
Cleanup of selection code.
Also fixed bug where selection outside the tiles was clamped and file in last column was selected.
Diffstat (limited to 'source/blender/editors')
-rw-r--r-- | source/blender/editors/include/ED_fileselect.h | 10 | ||||
-rw-r--r-- | source/blender/editors/space_file/file_draw.c | 2 | ||||
-rw-r--r-- | source/blender/editors/space_file/file_ops.c | 185 | ||||
-rw-r--r-- | source/blender/editors/space_file/filelist.c | 17 | ||||
-rw-r--r-- | source/blender/editors/space_file/filelist.h | 3 | ||||
-rw-r--r-- | source/blender/editors/space_file/filesel.c | 60 |
6 files changed, 179 insertions, 98 deletions
diff --git a/source/blender/editors/include/ED_fileselect.h b/source/blender/editors/include/ED_fileselect.h index 6b91779b832..1eedd7ec782 100644 --- a/source/blender/editors/include/ED_fileselect.h +++ b/source/blender/editors/include/ED_fileselect.h @@ -75,6 +75,13 @@ typedef struct FileLayout float column_widths[MAX_FILE_COLUMN]; } FileLayout; +typedef struct FileSelection { + int first; + int last; +} FileSelection; + +struct rcti; + struct FileSelectParams* ED_fileselect_get_params(struct SpaceFile *sfile); short ED_fileselect_set_params(struct SpaceFile *sfile); @@ -88,7 +95,8 @@ void ED_fileselect_init_layout(struct SpaceFile *sfile, struct ARegion *ar); 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 clamp_bounds, int x, int y); +int ED_fileselect_layout_offset(FileLayout* layout, int x, int y); +FileSelection ED_fileselect_layout_offset_rect(FileLayout* layout, const struct rcti* rect); void ED_fileselect_layout_tilepos(FileLayout* layout, int tile, int *x, int *y); diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c index 98bd6c0e70b..9d68acc4d5e 100644 --- a/source/blender/editors/space_file/file_draw.c +++ b/source/blender/editors/space_file/file_draw.c @@ -487,7 +487,7 @@ void file_draw_list(const bContext *C, ARegion *ar) draw_dividers(layout, v2d); } - offset = ED_fileselect_layout_offset(layout, 0, ar->v2d.cur.xmin, -ar->v2d.cur.ymax); + 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); diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index 28f5423f3a6..37f4569d55a 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -71,85 +71,84 @@ #define INACTIVATE 2 /* ---------- FILE SELECTION ------------ */ - -static int find_file_mouse(SpaceFile *sfile, struct ARegion* ar, int clamp_bounds, int x, int y) +static FileSelection find_file_mouse_rect(SpaceFile *sfile, struct ARegion* ar, const rcti* rect) { - float fx,fy; - int active_file = -1; + FileSelection sel; + float fxmin,fymin,fxmax, fymax; + View2D* v2d = &ar->v2d; + rcti rect_view; - UI_view2d_region_to_view(v2d, x, y, &fx, &fy); + UI_view2d_region_to_view(v2d, rect->xmin, rect->ymin, &fxmin, &fymin); + UI_view2d_region_to_view(v2d, rect->xmax, rect->ymax, &fxmax, &fymax); - active_file = ED_fileselect_layout_offset(sfile->layout, clamp_bounds, v2d->tot.xmin + fx, v2d->tot.ymax - fy); + BLI_init_rcti(&rect_view, v2d->tot.xmin + fxmin, v2d->tot.xmin + fxmax, v2d->tot.ymax - fymin, v2d->tot.ymax - fymax); + + sel = ED_fileselect_layout_offset_rect(sfile->layout, &rect_view); - return active_file; + return sel; } - -static void file_deselect_all(SpaceFile* sfile) +static void file_deselect_all(SpaceFile* sfile, unsigned int flag) { int numfiles = filelist_numfiles(sfile->files); int i; for ( i=0; i < numfiles; ++i) { struct direntry* file = filelist_file(sfile->files, i); - if (file && (file->flags & ACTIVEFILE)) { - file->flags &= ~ACTIVEFILE; + if (file && (file->flags & flag)) { + file->flags &= ~flag; } } } -typedef enum FileSelect { FILE_SELECT_DIR = 1, - FILE_SELECT_FILE = 2 } FileSelect; - +typedef enum FileSelect { + FILE_SELECT_NOTHING = 0, + FILE_SELECT_DIR = 1, + FILE_SELECT_FILE = 2 +} FileSelect; -static void clamp_to_filelist(int numfiles, int *first_file, int *last_file) +static void clamp_to_filelist(int numfiles, FileSelection* sel) { /* border select before the first file */ - if ( (*first_file < 0) && (*last_file >=0 ) ) { - *first_file = 0; + if ( (sel->first < 0) && (sel->last >=0 ) ) { + sel->first = 0; } /* don't select if everything is outside filelist */ - if ( (*first_file >= numfiles) && ((*last_file < 0) || (*last_file >= numfiles)) ) { - *first_file = -1; - *last_file = -1; + if ( (sel->first >= numfiles) && ((sel->last < 0) || (sel->last >= numfiles)) ) { + sel->first = -1; + sel->last = -1; } /* fix if last file invalid */ - if ( (*first_file > 0) && (*last_file < 0) ) - *last_file = numfiles-1; + if ( (sel->first > 0) && (sel->last < 0) ) + sel->last = numfiles-1; /* clamp */ - if ( (*first_file >= numfiles) ) { - *first_file = numfiles-1; + if ( (sel->first >= numfiles) ) { + sel->first = numfiles-1; } - if ( (*last_file >= numfiles) ) { - *last_file = numfiles-1; + if ( (sel->last >= numfiles) ) { + sel->last = numfiles-1; } } -static FileSelect file_select(bContext* C, const rcti* rect, short selecting, short toggle_one, short fill) +static FileSelection file_selection_get(bContext* C, const rcti* rect, short fill) { ARegion *ar= CTX_wm_region(C); SpaceFile *sfile= CTX_wm_space_file(C); - int first_file = -1; - int last_file = -1; - int act_file; - FileSelect retval = FILE_SELECT_FILE; + int numfiles = filelist_numfiles(sfile->files); + FileSelection sel; - FileSelectParams *params = ED_fileselect_get_params(sfile); - // FileLayout *layout = ED_fileselect_get_layout(sfile, ar); + sel = find_file_mouse_rect(sfile, ar, rect); + if ( !((sel.first == -1) && (sel.last == -1)) ) { + clamp_to_filelist(numfiles, &sel); + } - int numfiles = filelist_numfiles(sfile->files); - - params->selstate = NOTACTIVEFILE; - first_file = find_file_mouse(sfile, ar, 1, rect->xmin, rect->ymax); - last_file = find_file_mouse(sfile, ar, 1, rect->xmax, rect->ymin); - - clamp_to_filelist(numfiles, &first_file, &last_file); - if (fill && (last_file >= 0) && (last_file < numfiles) ) { - int f= last_file; + /* if desired, fill the selection up from the last selected file to the current one */ + if (fill && (sel.last >= 0) && (sel.last < numfiles) ) { + int f= sel.last; while (f >= 0) { struct direntry* file = filelist_file(sfile->files, f); if (file->flags & ACTIVEFILE) @@ -157,35 +156,23 @@ static FileSelect file_select(bContext* C, const rcti* rect, short selecting, sh f--; } if (f >= 0) { - first_file = f+1; - } - } - - /* select all valid files between first and last indicated */ - if ( (first_file >= 0) && (first_file < numfiles) && (last_file >= 0) && (last_file < numfiles) ) { - for (act_file = first_file; act_file <= last_file; act_file++) { - struct direntry* file = filelist_file(sfile->files, act_file); - - if (toggle_one) { - if (file->flags & ACTIVEFILE) { - file->flags &= ~ACTIVEFILE; - selecting=0; - } else - file->flags |= ACTIVEFILE; - } else if (selecting) - file->flags |= ACTIVEFILE; - else - file->flags &= ~ACTIVEFILE; + sel.first = f+1; } } + return sel; +} - /* Don't act on multiple selected files */ - if (first_file != last_file) selecting= 0; +static FileSelect file_select_do(bContext* C, short select, int selected_idx) +{ + FileSelect retval = FILE_SELECT_NOTHING; + SpaceFile *sfile= CTX_wm_space_file(C); + FileSelectParams *params = ED_fileselect_get_params(sfile); + int numfiles = filelist_numfiles(sfile->files); - /* make the last file active */ - if (selecting && (last_file >= 0 && last_file < numfiles)) { - struct direntry* file = filelist_file(sfile->files, last_file); - params->active_file = last_file; + /* make the selected file active */ + if (select && (selected_idx >= 0) && (selected_idx < numfiles)) { + struct direntry* file = filelist_file(sfile->files, selected_idx); + params->active_file = selected_idx; if(file && S_ISDIR(file->type)) { /* the path is too long and we are not going up! */ @@ -211,9 +198,26 @@ static FileSelect file_select(bContext* C, const rcti* rect, short selecting, sh if (file->relname) { BLI_strncpy(params->file, file->relname, FILE_MAXFILE); } - - } + retval = FILE_SELECT_FILE; + } } + return retval; +} + + +static FileSelect file_select(bContext* C, const rcti* rect, short select, short fill) +{ + SpaceFile *sfile= CTX_wm_space_file(C); + FileSelect retval = FILE_SELECT_NOTHING; + FileSelection sel= file_selection_get(C, rect, fill); /* get the selection */ + + /* flag the files as selected in the filelist */ + filelist_select(sfile->files, &sel, select, ACTIVEFILE); + + /* Don't act on multiple selected files */ + if (sel.first != sel.last) select = 0; + + retval = file_select_do(C, select, sel.last); /* update operator for name change event */ file_draw_check_cb(C, NULL, NULL); @@ -222,24 +226,24 @@ static FileSelect file_select(bContext* C, const rcti* rect, short selecting, sh } - static int file_border_select_exec(bContext *C, wmOperator *op) { ARegion *ar= CTX_wm_region(C); - short selecting; rcti rect; - - selecting= (RNA_int_get(op->ptr, "gesture_mode")==GESTURE_MODAL_SELECT); + FileSelect ret; + + short select= (RNA_int_get(op->ptr, "gesture_mode")==GESTURE_MODAL_SELECT); rect.xmin= RNA_int_get(op->ptr, "xmin"); rect.ymin= RNA_int_get(op->ptr, "ymin"); rect.xmax= RNA_int_get(op->ptr, "xmax"); rect.ymax= RNA_int_get(op->ptr, "ymax"); BLI_isect_rcti(&(ar->v2d.mask), &rect, &rect); - - if (FILE_SELECT_DIR == file_select(C, &rect, selecting, 0, 0)) { + + ret = file_select(C, &rect, select, 0); + if (FILE_SELECT_DIR == ret) { WM_event_add_notifier(C, NC_SPACE|ND_SPACE_FILE_LIST, NULL); - } else { + } else if (FILE_SELECT_FILE == ret) { WM_event_add_notifier(C, NC_SPACE|ND_SPACE_FILE_PARAMS, NULL); } return OPERATOR_FINISHED; @@ -280,9 +284,9 @@ static int file_select_invoke(bContext *C, wmOperator *op, wmEvent *event) return OPERATOR_CANCELLED; /* single select, deselect all selected first */ - if (!extend) file_deselect_all(sfile); + if (!extend) file_deselect_all(sfile, ACTIVEFILE); - if (FILE_SELECT_DIR == file_select(C, &rect, 1, extend, fill )) + if (FILE_SELECT_DIR == file_select(C, &rect, 1, fill)) WM_event_add_notifier(C, NC_SPACE|ND_SPACE_FILE_LIST, NULL); else WM_event_add_notifier(C, NC_SPACE|ND_SPACE_FILE_PARAMS, NULL); @@ -348,10 +352,11 @@ void FILE_OT_select_all_toggle(wmOperatorType *ot) /* api callbacks */ ot->exec= file_select_all_exec; + ot->poll= ED_operator_file_active; /* rna */ - ot->poll= ED_operator_file_active; + } /* ---------- BOOKMARKS ----------- */ @@ -457,9 +462,10 @@ void FILE_OT_delete_bookmark(wmOperatorType *ot) int file_hilight_set(SpaceFile *sfile, ARegion *ar, int mx, int my) { + View2D* v2d = &ar->v2d; FileSelectParams* params; - int numfiles, actfile, origfile; - + int numfiles, origfile; + if(sfile==NULL || sfile->files==NULL) return 0; numfiles = filelist_numfiles(sfile->files); @@ -471,10 +477,15 @@ int file_hilight_set(SpaceFile *sfile, ARegion *ar, int mx, int my) my -= ar->winrct.ymin; if(BLI_in_rcti(&ar->v2d.mask, mx, my)) { - actfile = find_file_mouse(sfile, ar, 0, mx , my); + float fx, fy; + int active_file; + + UI_view2d_region_to_view(v2d, mx, my, &fx, &fy); + + active_file = ED_fileselect_layout_offset(sfile->layout, v2d->tot.xmin + fx, v2d->tot.ymax - fy); - if((actfile >= 0) && (actfile < numfiles)) - params->active_file=actfile; + if((active_file >= 0) && (active_file < numfiles)) + params->active_file=active_file; else params->active_file= -1; } @@ -822,9 +833,9 @@ static int file_smoothscroll_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent ScrArea *sa = CTX_wm_area(C); SpaceFile *sfile= CTX_wm_space_file(C); ARegion *ar, *oldar= CTX_wm_region(C); - int numfiles, offset; + int offset; + int numfiles, numfiles_layout; int edit_idx = 0; - int numfiles_layout; int i; /* escape if not our timer */ @@ -858,7 +869,7 @@ static int file_smoothscroll_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent return OPERATOR_PASS_THROUGH; } - offset = ED_fileselect_layout_offset(sfile->layout, 0, ar->v2d.cur.xmin, -ar->v2d.cur.ymax); + offset = ED_fileselect_layout_offset(sfile->layout, ar->v2d.cur.xmin, -ar->v2d.cur.ymax); if (offset<0) offset=0; /* scroll offset is the first file in the row/column we are editing in */ diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c index 42efa5d4a3b..5fb64b2f2bc 100644 --- a/source/blender/editors/space_file/filelist.c +++ b/source/blender/editors/space_file/filelist.c @@ -926,6 +926,23 @@ void filelist_swapselect(struct FileList* filelist) } } +void filelist_select(struct FileList* filelist, FileSelection* sel, short select, unsigned int flag) +{ + /* select all valid files between first and last indicated */ + if ( (sel->first >= 0) && (sel->first < filelist->numfiltered) && (sel->last >= 0) && (sel->last < filelist->numfiltered) ) { + int current_file; + for (current_file = sel->first; current_file <= sel->last; current_file++) { + struct direntry* file = filelist_file(filelist, current_file); + + if (select) + file->flags |= flag; + else + file->flags &= ~flag; + } + } +} + + void filelist_sort(struct FileList* filelist, short sort) { switch(sort) { diff --git a/source/blender/editors/space_file/filelist.h b/source/blender/editors/space_file/filelist.h index 9af63ee1c1f..399a8ff7943 100644 --- a/source/blender/editors/space_file/filelist.h +++ b/source/blender/editors/space_file/filelist.h @@ -50,6 +50,8 @@ struct Scene; struct Main; struct rcti; struct ReportList; +struct FileSelection; + struct FileList * filelist_new(short type); void filelist_init_icons(void); @@ -61,6 +63,7 @@ int filelist_numfiles(struct FileList* filelist); const char * filelist_dir(struct FileList* filelist); void filelist_setdir(struct FileList* filelist, const char *dir); struct direntry * filelist_file(struct FileList* filelist, int index); +void filelist_select(struct FileList* filelist, FileSelection* sel, short select, unsigned int flag); void filelist_hidedot(struct FileList* filelist, short hide); void filelist_setfilter(struct FileList* filelist, unsigned int filter); void filelist_setfilter_types(struct FileList* filelist, const char *filter_glob); diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c index 87ffc2075c9..dce39ad8a1a 100644 --- a/source/blender/editors/space_file/filesel.c +++ b/source/blender/editors/space_file/filesel.c @@ -257,24 +257,66 @@ int ED_fileselect_layout_numfiles(FileLayout* layout, struct ARegion *ar) } } -int ED_fileselect_layout_offset(FileLayout* layout, int clamp_bounds, int x, int y) +static int is_inside(x,y, cols,rows) +{ + return ( (x >= 0) && (x<cols) && (y>=0) && (y<rows) ); +} + +FileSelection ED_fileselect_layout_offset_rect(FileLayout* layout, const rcti* rect) +{ + int colmin, colmax, rowmin, rowmax; + FileSelection sel; + sel.first = sel.last = -1; + + if (layout == NULL) + return sel; + + colmin = (rect->xmin)/(layout->tile_w + 2*layout->tile_border_x); + rowmin = (rect->ymin)/(layout->tile_h + 2*layout->tile_border_y); + colmax = (rect->xmax)/(layout->tile_w + 2*layout->tile_border_x); + rowmax = (rect->ymax)/(layout->tile_h + 2*layout->tile_border_y); + + if ( is_inside(colmin, rowmin, layout->columns, layout->rows) || + is_inside(colmax, rowmax, layout->columns, layout->rows) ) { + CLAMP(colmin, 0, layout->columns-1); + CLAMP(rowmin, 0, layout->rows-1); + CLAMP(colmax, 0, layout->columns-1); + CLAMP(rowmax, 0, layout->rows-1); + } + + if ( (colmin > layout->columns-1) || (rowmin > layout->rows-1) ) { + sel.first = -1; + } else { + if (layout->flag & FILE_LAYOUT_HOR) + sel.first = layout->rows*colmin + rowmin; + else + sel.first = colmin + layout->columns*rowmin; + } + if ( (colmax > layout->columns-1) || (rowmax > layout->rows-1) ) { + sel.last = -1; + } else { + if (layout->flag & FILE_LAYOUT_HOR) + sel.last = layout->rows*colmax + rowmax; + else + sel.last = colmax + layout->columns*rowmax; + } + + return sel; +} + +int ED_fileselect_layout_offset(FileLayout* layout, int x, int y) { int offsetx, offsety; int active_file; if (layout == NULL) - return 0; + return -1; offsetx = (x)/(layout->tile_w + 2*layout->tile_border_x); offsety = (y)/(layout->tile_h + 2*layout->tile_border_y); - if (clamp_bounds) { - CLAMP(offsetx, 0, layout->columns-1); - CLAMP(offsety, 0, layout->rows-1); - } else { - if (offsetx > layout->columns-1) return -1 ; - if (offsety > layout->rows-1) return -1 ; - } + if (offsetx > layout->columns-1) return -1 ; + if (offsety > layout->rows-1) return -1 ; if (layout->flag & FILE_LAYOUT_HOR) active_file = layout->rows*offsetx + offsety; |