[Bf-blender-cvs] [bbfe065] asset-experiments: FileBrowser: rewrite 'entry selection' code.

Bastien Montagne noreply at git.blender.org
Sat Apr 4 12:49:45 CEST 2015


Commit: bbfe0652eb780fdaf4a44dcbcec0b1f1eb153ff2
Author: Bastien Montagne
Date:   Sat Apr 4 12:43:53 2015 +0200
Branches: asset-experiments
https://developer.blender.org/rBbbfe0652eb780fdaf4a44dcbcec0b1f1eb153ff2

FileBrowser: rewrite 'entry selection' code.

Since we do not store anymore ell entries, we cannot use them to hold selection status.

So we now use a ghash in FileList struct, with entry UUID's as keys.

Also cleanuped up / refactored selection handling, filelist.c now features a nice intern
api and all other code uses it instead of accessing directly entries' selflag!

===================================================================

M	source/blender/editors/space_file/file_draw.c
M	source/blender/editors/space_file/file_ops.c
M	source/blender/editors/space_file/filelist.c
M	source/blender/editors/space_file/filelist.h
M	source/blender/editors/space_file/filesel.c
M	source/blender/editors/space_file/space_file.c
M	source/blender/makesdna/DNA_space_types.h

===================================================================

diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c
index 294b72d..5cc9282 100644
--- a/source/blender/editors/space_file/file_draw.c
+++ b/source/blender/editors/space_file/file_draw.c
@@ -502,24 +502,26 @@ void file_draw_list(const bContext *C, ARegion *ar)
 	}
 
 	for (i = offset; (i < numfiles) && (i < offset + numfiles_layout); i++) {
+		unsigned int file_selflag;
 		char path[FILE_MAX_LIBEXTRA];
 		ED_fileselect_layout_tilepos(layout, i, &sx, &sy);
 		sx += (int)(v2d->tot.xmin + 0.1f * UI_UNIT_X);
 		sy = (int)(v2d->tot.ymax - sy);
 
 		file = filelist_file(files, i);
+		file_selflag = filelist_entry_select_get(sfile->files, file, CHECK_ALL);
 
 		BLI_join_dirfile(path, sizeof(path), root, file->relpath);
 
 		UI_ThemeColor4(TH_TEXT);
 
 
-		if (!(file->selflag & FILE_SEL_EDITING)) {
-			if ((params->active_file == i) || (file->selflag & FILE_SEL_HIGHLIGHTED) ||
-			    (file->selflag & FILE_SEL_SELECTED))
+		if (!(file_selflag & FILE_SEL_EDITING)) {
+			if ((params->active_file == i) || (file_selflag & FILE_SEL_HIGHLIGHTED) ||
+			    (file_selflag & FILE_SEL_SELECTED))
 			{
-				int colorid = (file->selflag & FILE_SEL_SELECTED) ? TH_HILITE : TH_BACK;
-				int shade = (params->active_file == i) || (file->selflag & FILE_SEL_HIGHLIGHTED) ? 20 : 0;
+				int colorid = (file_selflag & FILE_SEL_SELECTED) ? TH_HILITE : TH_BACK;
+				int shade = (params->active_file == i) || (file_selflag & FILE_SEL_HIGHLIGHTED) ? 20 : 0;
 
 				/* readonly files (".." and ".") must not be drawn as selected - set color back to normal */
 				if (FILENAME_IS_CURRPAR(file->relpath)) {
@@ -553,7 +555,7 @@ void file_draw_list(const bContext *C, ARegion *ar)
 
 		UI_ThemeColor4(TH_TEXT);
 
-		if (file->selflag & FILE_SEL_EDITING) {
+		if (file_selflag & FILE_SEL_EDITING) {
 			uiBut *but;
 			short width;
 
@@ -576,11 +578,11 @@ void file_draw_list(const bContext *C, ARegion *ar)
 			UI_but_flag_enable(but, UI_BUT_NO_UTF8); /* allow non utf8 names */
 			UI_but_flag_disable(but, UI_BUT_UNDO);
 			if (false == UI_but_active_only(C, ar, block, but)) {
-				file->selflag &= ~FILE_SEL_EDITING;
+				file_selflag = filelist_entry_select_set(sfile->files, file, FILE_SEL_REMOVE, FILE_SEL_EDITING, CHECK_ALL);
 			}
 		}
 
-		if (!(file->selflag & FILE_SEL_EDITING)) {
+		if (!(file_selflag& FILE_SEL_EDITING)) {
 			int tpos = (FILE_IMGDISPLAY == params->display) ? sy - layout->tile_h + layout->textheight : sy;
 			file_draw_string(sx + 1, tpos, file->name, (float)textwidth, textheight, align);
 		}
diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c
index ddf3bd2..0516248 100644
--- a/source/blender/editors/space_file/file_ops.c
+++ b/source/blender/editors/space_file/file_ops.c
@@ -101,7 +101,7 @@ static void file_deselect_all(SpaceFile *sfile, unsigned int flag)
 	sel.first = 0;
 	sel.last = filelist_numfiles(sfile->files) - 1;
 	
-	filelist_select(sfile->files, &sel, FILE_SEL_REMOVE, flag, CHECK_ALL);
+	filelist_entries_select_index_range_set(sfile->files, &sel, FILE_SEL_REMOVE, flag, CHECK_ALL);
 }
 
 typedef enum FileSelect { 
@@ -152,7 +152,7 @@ static FileSelection file_selection_get(bContext *C, const rcti *rect, bool fill
 	if (fill && (sel.last >= 0) && (sel.last < numfiles) ) {
 		int f = sel.last;
 		while (f >= 0) {
-			if (filelist_is_selected(sfile->files, f, CHECK_ALL) )
+			if (filelist_entry_select_index_get(sfile->files, f, CHECK_ALL) )
 				break;
 			f--;
 		}
@@ -229,7 +229,7 @@ static FileSelect file_select(bContext *C, const rcti *rect, FileSelType select,
 	const FileCheckType check_type = (sfile->params->flag & FILE_DIRSEL_ONLY) ? CHECK_DIRS : CHECK_ALL;
 	
 	/* flag the files as selected in the filelist */
-	filelist_select(sfile->files, &sel, select, FILE_SEL_SELECTED, check_type);
+	filelist_entries_select_index_range_set(sfile->files, &sel, select, FILE_SEL_SELECTED, check_type);
 	
 	/* Don't act on multiple selected files */
 	if (sel.first != sel.last) select = 0;
@@ -237,7 +237,7 @@ static FileSelect file_select(bContext *C, const rcti *rect, FileSelType select,
 	/* Do we have a valid selection and are we actually selecting */
 	if ((sel.last >= 0) && ((select == FILE_SEL_ADD) || (select == FILE_SEL_TOGGLE))) {
 		/* Check last selection, if selected, act on the file or dir */
-		if (filelist_is_selected(sfile->files, sel.last, check_type)) {
+		if (filelist_entry_select_index_get(sfile->files, sel.last, check_type)) {
 			retval = file_select_do(C, sel.last, do_diropen);
 		}
 	}
@@ -271,7 +271,7 @@ static int file_border_select_modal(bContext *C, wmOperator *op, const wmEvent *
 			int idx;
 
 			file_deselect_all(sfile, FILE_SEL_HIGHLIGHTED);
-			filelist_select(sfile->files, &sel, FILE_SEL_ADD, FILE_SEL_HIGHLIGHTED, CHECK_ALL);
+			filelist_entries_select_index_range_set(sfile->files, &sel, FILE_SEL_ADD, FILE_SEL_HIGHLIGHTED, CHECK_ALL);
 			WM_event_add_notifier(C, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL);
 
 			/* dont highlight readonly file (".." or ".") on border select */
@@ -279,7 +279,7 @@ static int file_border_select_modal(bContext *C, wmOperator *op, const wmEvent *
 				struct FileDirEntry *file = filelist_file(sfile->files, idx);
 
 				if (FILENAME_IS_CURRPAR(file->relpath)) {
-					file->selflag &= ~FILE_SEL_HIGHLIGHTED;
+					filelist_entry_select_set(sfile->files, file, FILE_SEL_REMOVE, FILE_SEL_HIGHLIGHTED, CHECK_ALL);
 				}
 
 				/* active_file gets highlighted as well - make sure it is no readonly file */
@@ -429,18 +429,18 @@ static int file_select_all_exec(bContext *C, wmOperator *UNUSED(op))
 
 	/* Is any file selected ? */
 	for (i = 0; i < numfiles; ++i) {
-		if (filelist_is_selected(sfile->files, i, CHECK_ALL)) {
+		if (filelist_entry_select_index_get(sfile->files, i, CHECK_ALL)) {
 			is_selected = true;
 			break;
 		}
 	}
 	/* select all only if previously no file was selected */
 	if (is_selected) {
-		filelist_select(sfile->files, &sel, FILE_SEL_REMOVE, FILE_SEL_SELECTED, CHECK_ALL);
+		filelist_entries_select_index_range_set(sfile->files, &sel, FILE_SEL_REMOVE, FILE_SEL_SELECTED, CHECK_ALL);
 	}
 	else {
 		const FileCheckType check_type = (sfile->params->flag & FILE_DIRSEL_ONLY) ? CHECK_DIRS : CHECK_FILES;
-		filelist_select(sfile->files, &sel, FILE_SEL_ADD, FILE_SEL_SELECTED, check_type);
+		filelist_entries_select_index_range_set(sfile->files, &sel, FILE_SEL_ADD, FILE_SEL_SELECTED, check_type);
 	}
 	file_draw_check(C);
 	ED_area_tag_redraw(sa);
@@ -872,7 +872,7 @@ void file_sfile_to_operator(wmOperator *op, SpaceFile *sfile, char *filepath)
 			int num_files = 0;
 			RNA_property_collection_clear(op->ptr, prop);
 			for (i = 0; i < numfiles; i++) {
-				if (filelist_is_selected(sfile->files, i, CHECK_FILES)) {
+				if (filelist_entry_select_index_get(sfile->files, i, CHECK_FILES)) {
 					FileDirEntry *file = filelist_file(sfile->files, i);
 					RNA_property_collection_add(op->ptr, prop, &itemptr);
 					RNA_string_set(&itemptr, "name", file->relpath);
@@ -891,7 +891,7 @@ void file_sfile_to_operator(wmOperator *op, SpaceFile *sfile, char *filepath)
 			int num_dirs = 0;
 			RNA_property_collection_clear(op->ptr, prop);
 			for (i = 0; i < numfiles; i++) {
-				if (filelist_is_selected(sfile->files, i, CHECK_DIRS)) {
+				if (filelist_entry_select_index_get(sfile->files, i, CHECK_DIRS)) {
 					FileDirEntry *file = filelist_file(sfile->files, i);
 					RNA_property_collection_add(op->ptr, prop, &itemptr);
 					RNA_string_set(&itemptr, "name", file->relpath);
@@ -996,7 +996,7 @@ int file_exec(bContext *C, wmOperator *exec_op)
 			int i, active = 0;
 			
 			for (i = 0; i < filelist_numfiles(sfile->files); i++) {
-				if (filelist_is_selected(sfile->files, i, CHECK_ALL)) {
+				if (filelist_entry_select_index_get(sfile->files, i, CHECK_ALL)) {
 					active = 1;
 					break;
 				}
@@ -1191,7 +1191,7 @@ static int file_smoothscroll_invoke(bContext *C, wmOperator *UNUSED(op), const w
 
 	/* check if we are editing a name */
 	for (i = 0; i < numfiles; ++i) {
-		if (filelist_is_selected(sfile->files, i, CHECK_ALL) ) {
+		if (filelist_entry_select_index_get(sfile->files, i, CHECK_ALL) ) {
 			edit_idx = i;
 			break;
 		}
@@ -1684,7 +1684,7 @@ static int file_rename_exec(bContext *C, wmOperator *UNUSED(op))
 		int numfiles = filelist_numfiles(sfile->files);
 		if ( (0 <= idx) && (idx < numfiles) ) {
 			FileDirEntry *file = filelist_file(sfile->files, idx);
-			filelist_select_file(sfile->files, idx, FILE_SEL_ADD, FILE_SEL_EDITING, CHECK_ALL);
+			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';
 		}
@@ -1749,7 +1749,7 @@ static int file_delete_poll(bContext *C)
 
 		if (filelist_islibrary(sfile->files, dir, NULL)) poll = 0;
 		for (i = 0; i < numfiles; i++) {
-			if (filelist_is_selected(sfile->files, i, CHECK_FILES)) {
+			if (filelist_entry_select_index_get(sfile->files, i, CHECK_FILES)) {
 				num_selected++;
 			}
 		}
@@ -1773,7 +1773,7 @@ int file_delete_exec(bContext *C, wmOperator *UNUSED(op))
 	int i;
 
 	for (i = 0; i < numfiles; i++) {
-		if (filelist_is_selected(sfile->files, i, CHECK_FILES)) {
+		if (filelist_entry_select_index_get(sfile->files, i, CHECK_FILES)) {
 			file = filelist_file(sfile->files, i);
 			BLI_make_file_string(G.main->name, str, sfile->params->dir, file->relpath);
 			BLI_delete(str, false, false);
diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c
index 67c832e..bda4477 100644
--- a/source/blender/editors/space_file/filelist.c
+++ b/source/blender/editors/space_file/filelist.c
@@ -265,6 +265,8 @@ typedef struct FileList {
 
 	struct FileListEntryCache filelist_cache;
 
+	GHash *selection_state;
+
 	short max_recursion;
 	short recursion_level;
 
@@ -1183,6 +1185,8 @@ FileList *filelist_new(short type)
 
 	filelist_cache_init(&p->filelist_cache);
 
+	p->selection_state = BLI_ghash_new(BLI_ghashutil_uinthash_v4_p, BLI_ghashutil_uinthash_v4_cmp, __func__);
+
 	switch (type) {
 		case FILE_MAIN:
 			p->checkdirf = filelist_checkdir_main;
@@ -1216,6 +1220,10 @@

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list