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:
Diffstat (limited to 'source/blender/editors/space_file/file_draw.c')
-rw-r--r--source/blender/editors/space_file/file_draw.c154
1 files changed, 104 insertions, 50 deletions
diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c
index 6e409d2f5a4..66aabe39e44 100644
--- a/source/blender/editors/space_file/file_draw.c
+++ b/source/blender/editors/space_file/file_draw.c
@@ -25,6 +25,8 @@
#include <math.h>
#include <string.h>
+#include "MEM_guardedalloc.h"
+
#include "BLI_alloca.h"
#include "BLI_blenlib.h"
#include "BLI_fileops_types.h"
@@ -80,6 +82,9 @@ void ED_file_path_button(bScreen *screen,
PointerRNA params_rna_ptr;
uiBut *but;
+ BLI_assert_msg(params != NULL,
+ "File select parameters not set. The caller is expected to check this.");
+
RNA_pointer_create(&screen->id, &RNA_FileSelectParams, params, &params_rna_ptr);
/* callbacks for operator check functions */
@@ -108,7 +113,7 @@ void ED_file_path_button(bScreen *screen,
UI_but_func_complete_set(but, autocomplete_directory, NULL);
UI_but_funcN_set(but, file_directory_enter_handle, NULL, but);
- /* TODO, directory editing is non-functional while a library is loaded
+ /* TODO: directory editing is non-functional while a library is loaded
* until this is properly supported just disable it. */
if (sfile && sfile->files && filelist_lib(sfile->files)) {
UI_but_flag_enable(but, UI_BUT_DISABLED);
@@ -165,10 +170,10 @@ static void file_draw_icon(const SpaceFile *sfile,
const float a2 = dimmed ? 0.3f : 0.0f;
but = uiDefIconBut(
block, UI_BTYPE_LABEL, 0, icon, x, y, width, height, NULL, 0.0f, 0.0f, a1, a2, NULL);
- UI_but_func_tooltip_set(but, file_draw_tooltip_func, BLI_strdup(path));
+ UI_but_func_tooltip_set(but, file_draw_tooltip_func, BLI_strdup(path), MEM_freeN);
if (drag) {
- /* TODO duplicated from file_draw_preview(). */
+ /* TODO: duplicated from file_draw_preview(). */
ID *id;
if ((id = filelist_file_get_id(file))) {
@@ -183,9 +188,9 @@ static void file_draw_icon(const SpaceFile *sfile,
BLI_assert(asset_params != NULL);
UI_but_drag_set_asset(but,
- file->name,
+ &(AssetHandle){.file_data = file},
BLI_strdup(blend_path),
- file->blentype,
+ file->asset_data,
asset_params->import_type,
icon,
preview_image,
@@ -238,8 +243,9 @@ static void file_draw_string(int sx,
}
/**
- * \param r_sx, r_sy: The lower right corner of the last line drawn. AKA the cursor position on
- * completion.
+ * \param r_sx, r_sy: The lower right corner of the last line drawn, plus the height of the last
+ * line. This is the cursor position on completion to allow drawing more text
+ * behind that.
*/
static void file_draw_string_multiline(int sx,
int sy,
@@ -461,6 +467,17 @@ static void file_draw_preview(const SpaceFile *sfile,
UI_icon_draw_ex(icon_x, icon_y, icon, 1.0f / U.dpi_fac, 0.6f, 0.0f, light, false);
}
+ const bool is_current_main_data = filelist_file_get_id(file) != NULL;
+ if (is_current_main_data) {
+ /* Smaller, fainter icon at the top-right indicating that the file represents data from the
+ * current file (from current #Main in fact). */
+ float icon_x, icon_y;
+ const uchar light[4] = {255, 255, 255, 255};
+ icon_x = xco + ex - UI_UNIT_X;
+ icon_y = yco + ey - UI_UNIT_Y;
+ UI_icon_draw_ex(icon_x, icon_y, ICON_FILE_BLEND, 1.0f / U.dpi_fac, 0.6f, 0.0f, light, false);
+ }
+
/* Contrasting outline around some preview types. */
if (show_outline) {
GPUVertFormat *format = immVertexFormat();
@@ -489,7 +506,8 @@ static void file_draw_preview(const SpaceFile *sfile,
UI_but_drag_set_id(but, id);
}
/* path is no more static, cannot give it directly to but... */
- else if (file->typeflag & FILE_TYPE_ASSET) {
+ else if (sfile->browse_mode == FILE_BROWSE_MODE_ASSETS &&
+ (file->typeflag & FILE_TYPE_ASSET) != 0) {
char blend_path[FILE_MAX_LIBEXTRA];
if (BLO_library_path_explode(path, blend_path, NULL, NULL)) {
@@ -497,9 +515,9 @@ static void file_draw_preview(const SpaceFile *sfile,
BLI_assert(asset_params != NULL);
UI_but_drag_set_asset(but,
- file->name,
+ &(AssetHandle){.file_data = file},
BLI_strdup(blend_path),
- file->blentype,
+ file->asset_data,
asset_params->import_type,
icon,
imb,
@@ -520,6 +538,7 @@ static void renamebutton_cb(bContext *C, void *UNUSED(arg1), char *oldname)
char orgname[FILE_MAX + 12];
char filename[FILE_MAX + 12];
wmWindowManager *wm = CTX_wm_manager(C);
+ wmWindow *win = CTX_wm_window(C);
SpaceFile *sfile = (SpaceFile *)CTX_wm_space_data(C);
ARegion *region = CTX_wm_region(C);
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
@@ -539,17 +558,15 @@ static void renamebutton_cb(bContext *C, void *UNUSED(arg1), char *oldname)
else {
/* If rename is successful, scroll to newly renamed entry. */
BLI_strncpy(params->renamefile, filename, sizeof(params->renamefile));
- 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;
+ file_params_invoke_rename_postscroll(wm, win, sfile);
}
/* to make sure we show what is on disk */
- ED_fileselect_clear(wm, CTX_data_scene(C), sfile);
+ ED_fileselect_clear(wm, sfile);
+ }
+ else {
+ /* Renaming failed, reset the name for further renaming handling. */
+ BLI_strncpy(params->renamefile, oldname, sizeof(params->renamefile));
}
ED_region_tag_redraw(region);
@@ -724,40 +741,45 @@ static void draw_columnheader_columns(const FileSelectParams *params,
/**
* Updates the stat string stored in file->entry if necessary.
*/
-static const char *filelist_get_details_column_string(FileAttributeColumnType column,
- const FileDirEntry *file,
- const bool small_size,
- const bool update_stat_strings)
+static const char *filelist_get_details_column_string(
+ FileAttributeColumnType column,
+ /* Generated string will be cached in the file, so non-const. */
+ FileDirEntry *file,
+ const bool small_size,
+ const bool update_stat_strings)
{
switch (column) {
case COLUMN_DATETIME:
if (!(file->typeflag & FILE_TYPE_BLENDERLIB) && !FILENAME_IS_CURRPAR(file->relpath)) {
- if ((file->entry->datetime_str[0] == '\0') || update_stat_strings) {
+ if ((file->draw_data.datetime_str[0] == '\0') || update_stat_strings) {
char date[FILELIST_DIRENTRY_DATE_LEN], time[FILELIST_DIRENTRY_TIME_LEN];
bool is_today, is_yesterday;
BLI_filelist_entry_datetime_to_string(
- NULL, file->entry->time, small_size, time, date, &is_today, &is_yesterday);
+ NULL, file->time, small_size, time, date, &is_today, &is_yesterday);
if (is_today || is_yesterday) {
BLI_strncpy(date, is_today ? N_("Today") : N_("Yesterday"), sizeof(date));
}
- BLI_snprintf(
- file->entry->datetime_str, sizeof(file->entry->datetime_str), "%s %s", date, time);
+ BLI_snprintf(file->draw_data.datetime_str,
+ sizeof(file->draw_data.datetime_str),
+ "%s %s",
+ date,
+ time);
}
- return file->entry->datetime_str;
+ return file->draw_data.datetime_str;
}
break;
case COLUMN_SIZE:
if ((file->typeflag & (FILE_TYPE_BLENDER | FILE_TYPE_BLENDER_BACKUP)) ||
!(file->typeflag & (FILE_TYPE_DIR | FILE_TYPE_BLENDERLIB))) {
- if ((file->entry->size_str[0] == '\0') || update_stat_strings) {
+ if ((file->draw_data.size_str[0] == '\0') || update_stat_strings) {
BLI_filelist_entry_size_to_string(
- NULL, file->entry->size, small_size, file->entry->size_str);
+ NULL, file->size, small_size, file->draw_data.size_str);
}
- return file->entry->size_str;
+ return file->draw_data.size_str;
}
break;
default:
@@ -769,7 +791,7 @@ static const char *filelist_get_details_column_string(FileAttributeColumnType co
static void draw_details_columns(const FileSelectParams *params,
const FileLayout *layout,
- const FileDirEntry *file,
+ FileDirEntry *file,
const int pos_x,
const int pos_y,
const uchar text_col[4])
@@ -810,6 +832,8 @@ static void draw_details_columns(const FileSelectParams *params,
void file_draw_list(const bContext *C, ARegion *region)
{
+ wmWindowManager *wm = CTX_wm_manager(C);
+ wmWindow *win = CTX_wm_window(C);
SpaceFile *sfile = CTX_wm_space_file(C);
FileSelectParams *params = ED_fileselect_get_active_params(sfile);
FileLayout *layout = ED_fileselect_get_layout(sfile, region);
@@ -880,12 +904,12 @@ void file_draw_list(const bContext *C, ARegion *region)
// printf("%s: preview task: %d\n", __func__, previews_running);
if (previews_running && !sfile->previews_timer) {
sfile->previews_timer = WM_event_add_timer_notifier(
- CTX_wm_manager(C), CTX_wm_window(C), NC_SPACE | ND_SPACE_FILE_PREVIEW, 0.01);
+ wm, win, NC_SPACE | ND_SPACE_FILE_PREVIEW, 0.01);
}
if (!previews_running && sfile->previews_timer) {
/* Preview is not running, no need to keep generating update events! */
// printf("%s: Inactive preview task, sleeping!\n", __func__);
- WM_event_remove_timer_notifier(CTX_wm_manager(C), CTX_wm_window(C), sfile->previews_timer);
+ WM_event_remove_timer_notifier(wm, win, sfile->previews_timer);
sfile->previews_timer = NULL;
}
}
@@ -996,8 +1020,19 @@ void file_draw_list(const bContext *C, ARegion *region)
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, region, block, but)) {
- file_selflag = filelist_entry_select_set(
- sfile->files, file, FILE_SEL_REMOVE, FILE_SEL_EDITING, CHECK_ALL);
+ /* Note that this is the only place where we can also handle a cancelled renaming. */
+
+ file_params_rename_end(wm, win, sfile, file);
+
+ /* After the rename button is removed, we need to make sure the view is redrawn once more,
+ * in case selection changed. Usually UI code would trigger that redraw, but the rename
+ * operator may have been called from a different region.
+ * Tagging regions for redrawing while drawing is rightfully prevented. However, this
+ * active button removing basically introduces handling logic to drawing code. So a
+ * notifier should be an acceptable workaround. */
+ WM_event_add_notifier_ex(wm, win, NC_SPACE | ND_SPACE_FILE_PARAMS, NULL);
+
+ file_selflag = filelist_entry_select_get(sfile->files, file, CHECK_ALL);
}
}
@@ -1032,7 +1067,9 @@ void file_draw_list(const bContext *C, ARegion *region)
layout->curr_size = params->thumbnail_size;
}
-static void file_draw_invalid_library_hint(const SpaceFile *sfile, const ARegion *region)
+static void file_draw_invalid_library_hint(const bContext *C,
+ const SpaceFile *sfile,
+ ARegion *region)
{
const FileAssetSelectParams *asset_params = ED_fileselect_get_asset_params(sfile);
@@ -1040,9 +1077,7 @@ static void file_draw_invalid_library_hint(const SpaceFile *sfile, const ARegion
file_path_to_ui_path(asset_params->base_params.dir, library_ui_path, sizeof(library_ui_path));
uchar text_col[4];
- uchar text_alert_col[4];
UI_GetThemeColor4ubv(TH_TEXT, text_col);
- UI_GetThemeColor4ubv(TH_REDALERT, text_alert_col);
const View2D *v2d = &region->v2d;
const int pad = sfile->layout->tile_border_x;
@@ -1053,23 +1088,42 @@ static void file_draw_invalid_library_hint(const SpaceFile *sfile, const ARegion
int sy = v2d->tot.ymax;
{
- const char *message = TIP_("Library not found");
- const int draw_string_str_len = strlen(message) + 2 + sizeof(library_ui_path);
- char *draw_string = alloca(draw_string_str_len);
- BLI_snprintf(draw_string, draw_string_str_len, "%s: %s", message, library_ui_path);
- file_draw_string_multiline(sx, sy, draw_string, width, line_height, text_alert_col, NULL, &sy);
+ const char *message = TIP_("Path to asset library does not exist:");
+ file_draw_string_multiline(sx, sy, message, width, line_height, text_col, NULL, &sy);
+
+ sy -= line_height;
+ file_draw_string(sx, sy, library_ui_path, width, line_height, UI_STYLE_TEXT_LEFT, text_col);
}
- /* Next line, but separate it a bit further. */
- sy -= line_height;
+ /* Separate a bit further. */
+ sy -= line_height * 2.2f;
{
UI_icon_draw(sx, sy - UI_UNIT_Y, ICON_INFO);
const char *suggestion = TIP_(
- "Set up the library or edit libraries in the Preferences, File Paths section");
+ "Asset Libraries are local directories that can contain .blend files with assets inside.\n"
+ "Manage Asset Libraries from the File Paths section in Preferences");
file_draw_string_multiline(
- sx + UI_UNIT_X, sy, suggestion, width - UI_UNIT_X, line_height, text_col, NULL, NULL);
+ sx + UI_UNIT_X, sy, suggestion, width - UI_UNIT_X, line_height, text_col, NULL, &sy);
+
+ uiBlock *block = UI_block_begin(C, region, __func__, UI_EMBOSS);
+ uiBut *but = uiDefIconTextButO(block,
+ UI_BTYPE_BUT,
+ "SCREEN_OT_userpref_show",
+ WM_OP_INVOKE_DEFAULT,
+ ICON_PREFERENCES,
+ NULL,
+ sx + UI_UNIT_X,
+ sy - line_height - UI_UNIT_Y * 1.2f,
+ UI_UNIT_X * 8,
+ UI_UNIT_Y,
+ NULL);
+ PointerRNA *but_opptr = UI_but_operator_ptr_get(but);
+ RNA_enum_set(but_opptr, "section", USER_SECTION_FILE_PATHS);
+
+ UI_block_end(C, block);
+ UI_block_draw(C, block);
}
}
@@ -1077,7 +1131,7 @@ static void file_draw_invalid_library_hint(const SpaceFile *sfile, const ARegion
* Draw a string hint if the file list is invalid.
* \return true if the list is invalid and a hint was drawn.
*/
-bool file_draw_hint_if_invalid(const SpaceFile *sfile, const ARegion *region)
+bool file_draw_hint_if_invalid(const bContext *C, const SpaceFile *sfile, ARegion *region)
{
FileAssetSelectParams *asset_params = ED_fileselect_get_asset_params(sfile);
/* Only for asset browser. */
@@ -1085,12 +1139,12 @@ bool file_draw_hint_if_invalid(const SpaceFile *sfile, const ARegion *region)
return false;
}
/* Check if the library exists. */
- if ((asset_params->asset_library.type == FILE_ASSET_LIBRARY_LOCAL) ||
+ if ((asset_params->asset_library_ref.type == ASSET_LIBRARY_LOCAL) ||
filelist_is_dir(sfile->files, asset_params->base_params.dir)) {
return false;
}
- file_draw_invalid_library_hint(sfile, region);
+ file_draw_invalid_library_hint(C, sfile, region);
return true;
}