diff options
-rw-r--r-- | source/blender/editors/space_file/file_draw.c | 17 | ||||
-rw-r--r-- | source/blender/editors/space_file/file_ops.c | 33 | ||||
-rw-r--r-- | source/blender/editors/space_file/filesel.c | 24 | ||||
-rw-r--r-- | source/blender/editors/space_file/space_file.c | 2 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_space_types.h | 17 |
5 files changed, 72 insertions, 21 deletions
diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c index 17ee7726f45..8156e62a427 100644 --- a/source/blender/editors/space_file/file_draw.c +++ b/source/blender/editors/space_file/file_draw.c @@ -434,7 +434,7 @@ static void renamebutton_cb(bContext *C, void *UNUSED(arg1), char *oldname) const char *blendfile_path = BKE_main_blendfile_path(bmain); BLI_make_file_string(blendfile_path, orgname, sfile->params->dir, oldname); - BLI_strncpy(filename, sfile->params->renameedit, sizeof(filename)); + BLI_strncpy(filename, sfile->params->renamefile, sizeof(filename)); BLI_filename_make_safe(filename); BLI_make_file_string(blendfile_path, newname, sfile->params->dir, filename); @@ -449,6 +449,17 @@ static void renamebutton_cb(bContext *C, void *UNUSED(arg1), char *oldname) errno ? strerror(errno) : "unknown error"); WM_report_banner_show(); } + else { + /* If rename is sucessfull, scroll to newly renamed entry. */ + BLI_strncpy(sfile->params->renamefile, filename, sizeof(sfile->params->renamefile)); + sfile->params->rename_flag = FILE_PARAMS_RENAME_POSTSCROLL_PENDING; + + if (sfile->smoothscroll_timer != NULL) { + WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), sfile->smoothscroll_timer); + } + sfile->smoothscroll_timer = WM_event_add_timer(wm, CTX_wm_window(C), TIMER1, 1.0 / 1000.0); + sfile->scroll_offset = 0; + } /* to make sure we show what is on disk */ ED_fileselect_clear(wm, sa, sfile); @@ -677,8 +688,8 @@ void file_draw_list(const bContext *C, ARegion *ar) } but = uiDefBut(block, UI_BTYPE_TEXT, 1, "", sx, sy - layout->tile_h - 0.15f * UI_UNIT_X, - width, textheight, sfile->params->renameedit, 1.0f, - (float)sizeof(sfile->params->renameedit), 0, 0, ""); + width, textheight, sfile->params->renamefile, 1.0f, + (float)sizeof(sfile->params->renamefile), 0, 0, ""); UI_but_func_rename_set(but, renamebutton_cb, file); UI_but_flag_enable(but, UI_BUT_NO_UTF8); /* allow non utf8 names */ UI_but_flag_disable(but, UI_BUT_UNDO); diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index 450c3177f92..080a8e46c8e 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -21,9 +21,11 @@ * \ingroup spfile */ -#include "BLI_blenlib.h" #include "BLI_utildefines.h" + +#include "BLI_blenlib.h" #include "BLI_linklist.h" +#include "BLI_math.h" #include "BLO_readfile.h" @@ -1593,13 +1595,13 @@ static int file_smoothscroll_invoke(bContext *C, wmOperator *UNUSED(op), const w /* Due to async nature of file listing, we may execute this code before `file_refresh()` * editing entry is available in our listing, so we also have to handle switching to rename mode here. */ FileSelectParams *params = ED_fileselect_get_params(sfile); - if (params->renamefile[0] != '\0') { + if ((params->rename_flag & (FILE_PARAMS_RENAME_PENDING | FILE_PARAMS_RENAME_POSTSCROLL_PENDING)) != 0) { file_params_renamefile_activate(sfile, params); } /* check if we are editing a name */ for (i = 0; i < numfiles; ++i) { - if (filelist_entry_select_index_get(sfile->files, i, CHECK_ALL) ) { + if (filelist_entry_select_index_get(sfile->files, i, CHECK_ALL) & (FILE_SEL_EDITING | FILE_SEL_HIGHLIGHTED)) { edit_idx = i; break; } @@ -1609,7 +1611,7 @@ static int file_smoothscroll_invoke(bContext *C, wmOperator *UNUSED(op), const w if (edit_idx == -1) { /* Do not invalidate timer if filerename is still pending, we might still be building the filelist * and yet have to find edited entry... */ - if (params->renamefile[0] == '\0') { + if (params->rename_flag == 0) { WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), sfile->smoothscroll_timer); sfile->smoothscroll_timer = NULL; } @@ -1624,8 +1626,7 @@ static int file_smoothscroll_invoke(bContext *C, wmOperator *UNUSED(op), const w return OPERATOR_PASS_THROUGH; } - offset = ED_fileselect_layout_offset(sfile->layout, (int)ar->v2d.cur.xmin, (int)-ar->v2d.cur.ymax); - if (offset < 0) offset = 0; + offset = max_ii(0, ED_fileselect_layout_offset(sfile->layout, (int)ar->v2d.cur.xmin, (int)-ar->v2d.cur.ymax)); /* scroll offset is the first file in the row/column we are editing in */ if (sfile->scroll_offset == 0) { @@ -1640,11 +1641,20 @@ static int file_smoothscroll_invoke(bContext *C, wmOperator *UNUSED(op), const w } numfiles_layout = ED_fileselect_layout_numfiles(sfile->layout, ar); + /* Using margins helps avoiding scrolling to stop when target item is barely visible on one side of the screen + * (i.e. it centers a bit more the target). */ + int numfiles_layout_margin = max_ii(0, numfiles_layout / 3); /* check if we have reached our final scroll position */ - if ( (sfile->scroll_offset >= offset) && (sfile->scroll_offset < offset + numfiles_layout) ) { + if ((sfile->scroll_offset >= offset + numfiles_layout_margin) && + (sfile->scroll_offset < offset + numfiles_layout - numfiles_layout_margin)) { WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), sfile->smoothscroll_timer); sfile->smoothscroll_timer = NULL; + /* Postscroll (after rename has been validated by user) is done, rename process is totally finisehd, cleanup. */ + if ((params->rename_flag & FILE_PARAMS_RENAME_POSTSCROLL_ACTIVE) != 0) { + params->renamefile[0] = '\0'; + params->rename_flag = 0; + } return OPERATOR_FINISHED; } @@ -1812,9 +1822,13 @@ int file_directory_new_exec(bContext *C, wmOperator *op) /* now remember file to jump into editing */ BLI_strncpy(sfile->params->renamefile, name, FILE_MAXFILE); + sfile->params->rename_flag = FILE_PARAMS_RENAME_PENDING; /* set timer to smoothly view newly generated file */ /* max 30 frs/sec */ + if (sfile->smoothscroll_timer != NULL) { + WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), sfile->smoothscroll_timer); + } sfile->smoothscroll_timer = WM_event_add_timer(wm, CTX_wm_window(C), TIMER1, 1.0 / 1000.0); sfile->scroll_offset = 0; @@ -2203,8 +2217,9 @@ static int file_rename_exec(bContext *C, wmOperator *UNUSED(op)) if ((0 <= idx) && (idx < numfiles)) { FileDirEntry *file = filelist_file(sfile->files, idx); filelist_entry_select_index_set(sfile->files, idx, FILE_SEL_ADD, FILE_SEL_EDITING, CHECK_ALL); - BLI_strncpy(sfile->params->renameedit, file->relpath, FILE_MAXFILE); - sfile->params->renamefile[0] = '\0'; + BLI_strncpy(sfile->params->renamefile, file->relpath, FILE_MAXFILE); + /* We can skip the pending state, as we can directly set FILE_SEL_EDITING on the expected entry here. */ + sfile->params->rename_flag = FILE_PARAMS_RENAME_ACTIVE; } ED_area_tag_redraw(sa); } diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c index 7b642e75eac..5195fa818d6 100644 --- a/source/blender/editors/space_file/filesel.c +++ b/source/blender/editors/space_file/filesel.c @@ -738,19 +738,33 @@ void ED_fileselect_exit(wmWindowManager *wm, ScrArea *sa, SpaceFile *sfile) * params->renamefile name. */ void file_params_renamefile_activate(SpaceFile *sfile, FileSelectParams *params) { + BLI_assert(params->rename_flag != 0); + + if ((params->rename_flag & (FILE_PARAMS_RENAME_ACTIVE | FILE_PARAMS_RENAME_POSTSCROLL_ACTIVE)) != 0) { + return; + } + BLI_assert(params->renamefile[0] != '\0'); const int idx = filelist_file_findpath(sfile->files, params->renamefile); if (idx >= 0) { FileDirEntry *file = filelist_file(sfile->files, idx); - if (file) { + BLI_assert(file != NULL); + + if ((params->rename_flag & FILE_PARAMS_RENAME_PENDING) != 0) { filelist_entry_select_set(sfile->files, file, FILE_SEL_ADD, FILE_SEL_EDITING, CHECK_ALL); + params->rename_flag = FILE_PARAMS_RENAME_ACTIVE; + } + else if ((params->rename_flag & FILE_PARAMS_RENAME_POSTSCROLL_PENDING) != 0) { + filelist_entry_select_set(sfile->files, file, FILE_SEL_ADD, FILE_SEL_HIGHLIGHTED, CHECK_ALL); + params->renamefile[0] = '\0'; + params->rename_flag = FILE_PARAMS_RENAME_POSTSCROLL_ACTIVE; } } - BLI_strncpy(sfile->params->renameedit, sfile->params->renamefile, sizeof(sfile->params->renameedit)); - /* File listing is now async, do not clear renamefile if matching entry not found - * and dirlist is not finished! */ - if (idx >= 0 || filelist_is_ready(sfile->files)) { + /* File listing is now async, only reset renaming if matching entry is not found + * when file listing is not done. */ + else if (filelist_is_ready(sfile->files)) { params->renamefile[0] = '\0'; + params->rename_flag = 0; } } diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c index 3b40c4a0798..5a4b0e36ae1 100644 --- a/source/blender/editors/space_file/space_file.c +++ b/source/blender/editors/space_file/space_file.c @@ -259,7 +259,7 @@ static void file_refresh(const bContext *C, ScrArea *sa) } } - if (params->renamefile[0] != '\0') { + if (params->rename_flag != 0) { file_params_renamefile_activate(sfile, params); } diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index b9c50660d0b..afe80edfdd3 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -638,11 +638,10 @@ typedef struct FileSelectParams { * needs to be linked in, where foo.blend/Armature need adding */ char dir[1090]; - char _pad0[2]; char file[256]; + char renamefile[256]; - /** Annoying but the first is only used for initialization. */ - char renameedit[256]; + short rename_flag; /** List of filetypes to filter (FILE_MAXFILE). */ char filter_glob[256]; @@ -781,6 +780,18 @@ typedef enum eFileSel_Params_Flag { FILE_GROUP_INSTANCE = (1 << 10), } eFileSel_Params_Flag; +/* sfile->params->rename_flag */ +/* Note: short flag. Defined as bitflags, but currently only used as exclusive status markers... */ +typedef enum eFileSel_Params_RenameFlag { + /* Used when we only have the name of the entry we want to rename, but not yet access to its matching file entry. */ + FILE_PARAMS_RENAME_PENDING = 1 << 0, + /* We are actually renaming an entry. */ + FILE_PARAMS_RENAME_ACTIVE = 1 << 1, + /* Used to scroll to newly renamed entry. */ + FILE_PARAMS_RENAME_POSTSCROLL_PENDING = 1 << 2, + FILE_PARAMS_RENAME_POSTSCROLL_ACTIVE = 1 << 3, +} eFileSel_Params_RenameFlag; + /* files in filesel list: file types * Note we could use mere values (instead of bitflags) for file types themselves, * but since we do not lack of bytes currently... |