Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSybren A. Stüvel <sybren@blender.org>2021-03-08 15:57:15 +0300
committerSybren A. Stüvel <sybren@blender.org>2021-03-08 17:21:34 +0300
commit5a67407d5aa8800faf78f40811b703d07e8f7300 (patch)
tree3b10f385b1d26d6399d6fdaa75f5792a18384369
parente20b31504a2381011e60c5eadffb67f18918bc71 (diff)
File Browser: scroll selected files into view
Add operator `FILE_OT_view_selected` to the file browser (and thus also to the asset browser) that scrolls selected files into view. This includes the active file, even though it is not selected. In certain cases the active file can loose its selected state (clicking next to it, or refreshing the asset browser), but then it's still shown in the right-hand sidebar. Because of this, I found it important to take it into account when scrolling. This also includes a change to the keymaps: - Blender default: {key NUMPAD_PERIOD} is removed from the "reload" operator, and assigned to the new "view selected files" operator. The reload operator was already doubly bound, and now {key R} is the only remaining hotkey for it. - Industry compatible: {key F} is assigned to the new "view selected files" operator. This is consistent with the other "view selected" operators in other editors. Reviewed By: Severin Differential Revision: https://developer.blender.org/D10583
-rw-r--r--release/scripts/presets/keyconfig/keymap_data/blender_default.py2
-rw-r--r--release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py1
-rw-r--r--release/scripts/startup/bl_ui/space_filebrowser.py1
-rw-r--r--source/blender/editors/space_file/file_intern.h1
-rw-r--r--source/blender/editors/space_file/file_ops.c105
-rw-r--r--source/blender/editors/space_file/filelist.c13
-rw-r--r--source/blender/editors/space_file/filelist.h1
-rw-r--r--source/blender/editors/space_file/space_file.c1
8 files changed, 114 insertions, 11 deletions
diff --git a/release/scripts/presets/keyconfig/keymap_data/blender_default.py b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
index 949cfcae2b1..577448554b7 100644
--- a/release/scripts/presets/keyconfig/keymap_data/blender_default.py
+++ b/release/scripts/presets/keyconfig/keymap_data/blender_default.py
@@ -2011,7 +2011,6 @@ def km_file_browser_main(params):
# operator (i.e. in regular editor mode).
("file.select", {"type": 'LEFTMOUSE', "value": 'DOUBLE_CLICK'},
{"properties": [("open", True), ("deselect_all", not params.legacy)]}),
- ("file.refresh", {"type": 'NUMPAD_PERIOD', "value": 'PRESS'}, None),
("file.select", {"type": 'LEFTMOUSE', "value": 'PRESS'},
{"properties": [("open", False), ("deselect_all", not params.legacy)]}),
("file.select", {"type": 'LEFTMOUSE', "value": 'CLICK', "ctrl": True},
@@ -2053,6 +2052,7 @@ def km_file_browser_main(params):
{"properties": [("mode", 'SUB')]}),
("file.highlight", {"type": 'MOUSEMOVE', "value": 'ANY', "any": True}, None),
("file.sort_column_ui_context", {"type": 'LEFTMOUSE', "value": 'PRESS', "any": True}, None),
+ ("file.view_selected", {"type": 'NUMPAD_PERIOD', "value": 'PRESS'}, None),
])
return keymap
diff --git a/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py b/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py
index 234781b7bc8..214b8f98ff6 100644
--- a/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py
+++ b/release/scripts/presets/keyconfig/keymap_data/industry_compatible_data.py
@@ -1309,6 +1309,7 @@ def km_file_browser_main(params):
{"properties": [("mode", 'ADD')]}),
("file.highlight", {"type": 'MOUSEMOVE', "value": 'ANY', "any": True}, None),
("file.sort_column_ui_context", {"type": 'LEFTMOUSE', "value": 'PRESS', "any": True}, None),
+ ("file.view_selected", {"type": 'F', "value": 'PRESS'}, None),
])
return keymap
diff --git a/release/scripts/startup/bl_ui/space_filebrowser.py b/release/scripts/startup/bl_ui/space_filebrowser.py
index ef4f47c9399..b236b2ee7cf 100644
--- a/release/scripts/startup/bl_ui/space_filebrowser.py
+++ b/release/scripts/startup/bl_ui/space_filebrowser.py
@@ -494,6 +494,7 @@ class FILEBROWSER_MT_view(Menu):
layout.prop(st, "show_region_toolbar", text="Source List")
layout.prop(st, "show_region_ui", text="File Path")
+ layout.operator("file.view_selected")
layout.separator()
diff --git a/source/blender/editors/space_file/file_intern.h b/source/blender/editors/space_file/file_intern.h
index deb32812f44..309b280177c 100644
--- a/source/blender/editors/space_file/file_intern.h
+++ b/source/blender/editors/space_file/file_intern.h
@@ -75,6 +75,7 @@ void FILE_OT_rename(struct wmOperatorType *ot);
void FILE_OT_smoothscroll(struct wmOperatorType *ot);
void FILE_OT_filepath_drop(struct wmOperatorType *ot);
void FILE_OT_start_filter(struct wmOperatorType *ot);
+void FILE_OT_view_selected(struct wmOperatorType *ot);
void file_directory_enter_handle(bContext *C, void *arg_unused, void *arg_but);
void file_filename_enter_handle(bContext *C, void *arg_unused, void *arg_but);
diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c
index 985c92f19b6..b82290205c7 100644
--- a/source/blender/editors/space_file/file_ops.c
+++ b/source/blender/editors/space_file/file_ops.c
@@ -256,6 +256,33 @@ static bool file_is_any_selected(struct FileList *files)
return false;
}
+static FileSelection file_current_selection_range_get(struct FileList *files)
+{
+ const int numfiles = filelist_files_ensure(files);
+ FileSelection selection = {-1, -1};
+
+ /* Iterate over the files once but in two loops, one to find the first selected file, and the
+ * other to find the last. */
+
+ int file_index;
+ for (file_index = 0; file_index < numfiles; file_index++) {
+ if (filelist_entry_is_selected(files, file_index)) {
+ /* First selected entry found. */
+ selection.first = file_index;
+ break;
+ }
+ }
+
+ for (; file_index < numfiles; file_index++) {
+ if (filelist_entry_is_selected(files, file_index)) {
+ selection.last = file_index;
+ /* Keep looping, we may find more selected files. */
+ }
+ }
+
+ return selection;
+}
+
/**
* If \a file is outside viewbounds, this adjusts view to make sure it's inside
*/
@@ -299,6 +326,24 @@ static void file_ensure_inside_viewbounds(ARegion *region, SpaceFile *sfile, con
}
}
+static void file_ensure_selection_inside_viewbounds(ARegion *region,
+ SpaceFile *sfile,
+ FileSelection *sel)
+{
+ const FileLayout *layout = ED_fileselect_get_layout(sfile, region);
+
+ if (((layout->flag & FILE_LAYOUT_HOR) && region->winx <= (1.2f * layout->tile_w)) &&
+ ((layout->flag & FILE_LAYOUT_VER) && region->winy <= (2.0f * layout->tile_h))) {
+ return;
+ }
+
+ /* Adjust view to display selection. Doing iterations for first and last
+ * selected item makes view showing as much of the selection possible.
+ * Not really useful if tiles are (almost) bigger than viewbounds though. */
+ file_ensure_inside_viewbounds(region, sfile, sel->last);
+ file_ensure_inside_viewbounds(region, sfile, sel->first);
+}
+
static FileSelect file_select(
bContext *C, const rcti *rect, FileSelType select, bool fill, bool do_diropen)
{
@@ -330,16 +375,7 @@ static FileSelect file_select(
}
else if (sel.last >= 0) {
ARegion *region = CTX_wm_region(C);
- const FileLayout *layout = ED_fileselect_get_layout(sfile, region);
-
- /* Adjust view to display selection. Doing iterations for first and last
- * selected item makes view showing as much of the selection possible.
- * Not really useful if tiles are (almost) bigger than viewbounds though. */
- if (((layout->flag & FILE_LAYOUT_HOR) && region->winx > (1.2f * layout->tile_w)) ||
- ((layout->flag & FILE_LAYOUT_VER) && region->winy > (2.0f * layout->tile_h))) {
- file_ensure_inside_viewbounds(region, sfile, sel.last);
- file_ensure_inside_viewbounds(region, sfile, sel.first);
- }
+ file_ensure_selection_inside_viewbounds(region, sfile, &sel);
}
/* update operator for name change event */
@@ -926,6 +962,55 @@ void FILE_OT_select_all(wmOperatorType *ot)
/** \} */
/* -------------------------------------------------------------------- */
+/** \name Select All Operator
+ * \{ */
+
+static int file_view_selected_exec(bContext *C, wmOperator *UNUSED(op))
+{
+ SpaceFile *sfile = CTX_wm_space_file(C);
+ FileSelection sel = file_current_selection_range_get(sfile->files);
+ FileSelectParams *params = ED_fileselect_get_active_params(sfile);
+
+ if (sel.first == -1 && sel.last == -1 && params->active_file == -1) {
+ /* Nothing was selected. */
+ return OPERATOR_CANCELLED;
+ }
+
+ /* Extend the selection area with the active file, as it may not be selected but still is
+ * important to have in view. */
+ if (sel.first == -1 || params->active_file < sel.first) {
+ sel.first = params->active_file;
+ }
+ if (sel.last == -1 || params->active_file > sel.last) {
+ sel.last = params->active_file;
+ }
+
+ ScrArea *area = CTX_wm_area(C);
+ ARegion *region = CTX_wm_region(C);
+ file_ensure_selection_inside_viewbounds(region, sfile, &sel);
+
+ file_draw_check(C);
+ WM_event_add_mousemove(CTX_wm_window(C));
+ ED_area_tag_redraw(area);
+
+ return OPERATOR_FINISHED;
+}
+
+void FILE_OT_view_selected(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Frame Selected";
+ ot->description = "Scroll the selected files into view";
+ ot->idname = "FILE_OT_view_selected";
+
+ /* api callbacks */
+ ot->exec = file_view_selected_exec;
+ ot->poll = ED_operator_file_active;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name Select Bookmark Operator
* \{ */
diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c
index 757ec7c741f..f5ec9a0e8a1 100644
--- a/source/blender/editors/space_file/filelist.c
+++ b/source/blender/editors/space_file/filelist.c
@@ -2701,6 +2701,19 @@ uint filelist_entry_select_index_get(FileList *filelist, const int index, FileCh
return 0;
}
+bool filelist_entry_is_selected(FileList *filelist, const int index)
+{
+ BLI_assert(index >= 0 && index < filelist->filelist.nbr_entries_filtered);
+ FileListInternEntry *intern_entry = filelist->filelist_intern.filtered[index];
+
+ /* BLI_ghash_lookup returns NULL if not found, which gets mapped to 0, which gets mapped to
+ * "not selected". */
+ const uint selection_state = POINTER_AS_UINT(
+ BLI_ghash_lookup(filelist->selection_state, intern_entry->uuid));
+
+ return selection_state != 0;
+}
+
/**
* Set selection of the '..' parent entry, but only if it's actually visible.
*/
diff --git a/source/blender/editors/space_file/filelist.h b/source/blender/editors/space_file/filelist.h
index 7eecd7a05de..9eb70dd8437 100644
--- a/source/blender/editors/space_file/filelist.h
+++ b/source/blender/editors/space_file/filelist.h
@@ -128,6 +128,7 @@ unsigned int filelist_entry_select_get(struct FileList *filelist,
unsigned int filelist_entry_select_index_get(struct FileList *filelist,
const int index,
FileCheckType check);
+bool filelist_entry_is_selected(struct FileList *filelist, const int index);
void filelist_entry_parent_select_set(struct FileList *filelist,
FileSelType select,
unsigned int flag,
diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c
index 2c9c2688e88..4373bd88473 100644
--- a/source/blender/editors/space_file/space_file.c
+++ b/source/blender/editors/space_file/space_file.c
@@ -659,6 +659,7 @@ static void file_operatortypes(void)
WM_operatortype_append(FILE_OT_smoothscroll);
WM_operatortype_append(FILE_OT_filepath_drop);
WM_operatortype_append(FILE_OT_start_filter);
+ WM_operatortype_append(FILE_OT_view_selected);
}
/* NOTE: do not add .blend file reading on this level */