Blender V4.5
file_draw.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2008 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include <algorithm>
10#include <cerrno>
11#include <cstring>
12#include <string>
13
14#include <fmt/format.h>
15
16#include "MEM_guardedalloc.h"
17
19
20#include "BLI_fileops.h"
21#include "BLI_fileops_types.h"
22#include "BLI_listbase.h"
23#include "BLI_math_color.h"
24#include "BLI_math_vector.h"
25#include "BLI_path_utils.hh"
26#include "BLI_string.h"
27#include "BLI_utildefines.h"
28
29#ifdef WIN32
30# include "BLI_winstuff.h"
31#endif
32
33#include "BIF_glutil.hh"
34
35#include "BKE_blendfile.hh"
36#include "BKE_context.hh"
37#include "BKE_report.hh"
38
39#include "BLO_readfile.hh"
40
41#include "BLT_translation.hh"
42
43#include "BLF_api.hh"
44
45#include "IMB_imbuf.hh"
46#include "IMB_imbuf_types.hh"
47#include "IMB_metadata.hh"
48#include "IMB_thumbs.hh"
49
50#include "DNA_userdef_types.h"
52
53#include "RNA_access.hh"
54#include "RNA_prototypes.hh"
55
56#include "ED_asset.hh"
57#include "ED_fileselect.hh"
58#include "ED_screen.hh"
59
60#include "UI_interface.hh"
61#include "UI_interface_icons.hh"
62#include "UI_resources.hh"
63#include "UI_view2d.hh"
64
65#include "WM_api.hh"
66#include "WM_types.hh"
67
68#include "GPU_immediate.hh"
69#include "GPU_immediate_util.hh"
70#include "GPU_state.hh"
71
72#include "filelist.hh"
73
74#include "file_intern.hh" /* own include */
75
77 const SpaceFile *sfile,
79 uiBlock *block)
80{
81 uiBut *but;
82
83 BLI_assert_msg(params != nullptr,
84 "File select parameters not set. The caller is expected to check this.");
85
87 &screen->id, &RNA_FileSelectParams, params);
88
89 /* callbacks for operator check functions */
90 UI_block_func_set(block, file_draw_check_cb, nullptr, nullptr);
91
92 but = uiDefButR(block,
94 -1,
95 "",
96 0,
97 0,
98 UI_UNIT_X * 10,
100 &params_rna_ptr,
101 "directory",
102 0,
103 0.0f,
104 float(FILE_MAX),
105 TIP_("File path"));
106
109
112
113 /* TODO: directory editing is non-functional while a library is loaded
114 * until this is properly supported just disable it. */
115 if (sfile && sfile->files && filelist_lib(sfile->files)) {
117 }
118
119 /* clear func */
120 UI_block_func_set(block, nullptr, nullptr, nullptr);
121}
122
127
129{
131 data->sfile = sfile;
132 data->file = file;
133 return data;
134}
135
136static void file_draw_tooltip_custom_func(bContext & /*C*/, uiTooltipData &tip, void *argN)
137{
138 FileTooltipData *file_data = static_cast<FileTooltipData *>(argN);
139 const SpaceFile *sfile = file_data->sfile;
140 const FileList *files = sfile->files;
142 const FileDirEntry *file = file_data->file;
143
144 BLI_assert_msg(!file->asset, "Asset tooltip should never be overridden here.");
145
146 /* Check the FileDirEntry first to see if the preview is already loaded. */
148
149 /* Only free if it is loaded later. */
150 bool free_imbuf = (thumb == nullptr);
151
154
155 if (!(file->typeflag & FILE_TYPE_BLENDERLIB)) {
156
157 char full_path[FILE_MAX_LIBEXTRA];
158 filelist_file_get_full_path(files, file, full_path);
159
160 if (params->recursion_level > 0) {
161 char root[FILE_MAX];
162 BLI_path_split_dir_part(full_path, root, FILE_MAX);
164 }
165
166 if (file->redirection_path) {
168 fmt::format("{}: {}", N_("Link target"), file->redirection_path),
169 {},
172 }
173 if (file->attributes & FILE_ATTR_OFFLINE) {
175 tip, N_("This file is offline"), {}, UI_TIP_STYLE_NORMAL, UI_TIP_LC_ALERT);
176 }
177 if (file->attributes & FILE_ATTR_READONLY) {
179 tip, N_("This file is read-only"), {}, UI_TIP_STYLE_NORMAL, UI_TIP_LC_ALERT);
180 }
183 tip, N_("This is a restricted system file"), {}, UI_TIP_STYLE_NORMAL, UI_TIP_LC_ALERT);
184 }
185
187 char version_str[128] = {0};
188 if (!thumb) {
189 /* Load the thumbnail from cache if existing, but don't create if not. */
190 thumb = IMB_thumb_read(full_path, THB_LARGE);
191 }
192 if (thumb) {
193 /* Look for version in existing thumbnail if available. */
195 thumb->metadata, "Thumb::Blender::Version", version_str, sizeof(version_str));
196 }
197
198 if (!version_str[0] && !(file->attributes & FILE_ATTR_OFFLINE)) {
199 /* Load Blender version directly from the file. */
200 short version = BLO_version_from_file(full_path);
201 if (version != 0) {
202 SNPRINTF(version_str, "%d.%01d", version / 100, version % 100);
203 }
204 }
205
206 if (version_str[0]) {
208 fmt::format("Blender {}", version_str),
209 {},
213 }
214 }
215 else if (file->typeflag & FILE_TYPE_IMAGE) {
216 if (!thumb) {
217 /* Load the thumbnail from cache if existing, create if not. */
218 thumb = IMB_thumb_manage(full_path, THB_LARGE, THB_SOURCE_IMAGE);
219 }
220 if (thumb) {
221 char value1[128];
222 char value2[128];
224 thumb->metadata, "Thumb::Image::Width", value1, sizeof(value1)) &&
226 thumb->metadata, "Thumb::Image::Height", value2, sizeof(value2)))
227 {
229 fmt::format("{} \u00D7 {}", value1, value2),
230 {},
234 }
235 }
236 }
237 else if (file->typeflag & FILE_TYPE_MOVIE) {
238 if (!thumb) {
239 /* This could possibly take a while. */
240 thumb = IMB_thumb_manage(full_path, THB_LARGE, THB_SOURCE_MOVIE);
241 }
242 if (thumb) {
243 char value1[128];
244 char value2[128];
245 char value3[128];
247 thumb->metadata, "Thumb::Video::Width", value1, sizeof(value1)) &&
249 thumb->metadata, "Thumb::Video::Height", value2, sizeof(value2)))
250 {
252 fmt::format("{} \u00D7 {}", value1, value2),
253 {},
256 }
258 thumb->metadata, "Thumb::Video::Frames", value1, sizeof(value1)) &&
259 IMB_metadata_get_field(thumb->metadata, "Thumb::Video::FPS", value2, sizeof(value2)) &&
261 thumb->metadata, "Thumb::Video::Duration", value3, sizeof(value3)))
262 {
264 tip,
265 fmt::format("{} {} @ {} {}", value1, N_("Frames"), value2, N_("FPS")),
266 {},
270 fmt::format("{} {}", value3, N_("seconds")),
271 {},
275 }
276 }
277 }
278
280 bool is_today, is_yesterday;
281 std::string day_string;
283 nullptr, file->time, false, time_str, date_str, &is_today, &is_yesterday);
284 if (is_today || is_yesterday) {
285 day_string = (is_today ? N_("Today") : N_("Yesterday")) + std::string(" ");
286 }
288 fmt::format("{}: {}{}{}",
289 N_("Modified"),
290 day_string,
291 (is_today || is_yesterday) ? "" : date_str,
292 (is_today || is_yesterday) ? time_str : ""),
293 {},
296
297 if (!(file->typeflag & FILE_TYPE_DIR) && file->size > 0) {
298 char size[16];
299 BLI_filelist_entry_size_to_string(nullptr, file->size, false, size);
300 if (file->size < 10000) {
302 BLI_str_format_uint64_grouped(size_full, file->size);
304 tip,
305 fmt::format("{}: {} ({} {})", N_("Size"), size, size_full, N_("bytes")),
306 {},
309 }
310 else {
312 fmt::format("{}: {}", N_("Size"), size),
313 {},
316 }
317 }
318 }
319
320 if (thumb && params->display != FILE_IMGDISPLAY) {
323
324 uiTooltipImage image_data;
325 float scale = (96.0f * UI_SCALE_FAC) / float(std::max(thumb->x, thumb->y));
326 image_data.ibuf = thumb;
327 image_data.width = short(float(thumb->x) * scale);
328 image_data.height = short(float(thumb->y) * scale);
329 image_data.border = true;
330 image_data.background = uiTooltipImageBackground::Checkerboard_Themed;
331 image_data.premultiplied = true;
332 UI_tooltip_image_field_add(tip, image_data);
333 }
334
335 if (thumb && free_imbuf) {
336 IMB_freeImBuf(thumb);
337 }
338}
339
340static void file_draw_asset_tooltip_custom_func(bContext & /*C*/, uiTooltipData &tip, void *argN)
341{
342 const auto *asset = static_cast<blender::asset_system::AssetRepresentation *>(argN);
344}
345
346static void draw_tile_background(const rcti *draw_rect, int colorid, int shade)
347{
348 float color[4];
349 rctf draw_rect_fl;
350 BLI_rctf_rcti_copy(&draw_rect_fl, draw_rect);
351
352 UI_GetThemeColorShade4fv(colorid, shade, color);
354 UI_draw_roundbox_aa(&draw_rect_fl, true, 5.0f, color);
355}
356
358 const SpaceFile *sfile,
359 const FileDirEntry *file,
360 const char *path,
361 const ImBuf *preview_image,
362 int icon,
363 float scale)
364{
365 ID *id;
366
367 if ((id = filelist_file_get_id(file))) {
368 UI_but_drag_set_id(but, id);
369 if (preview_image) {
370 UI_but_drag_attach_image(but, preview_image, scale);
371 }
372 }
373 else if (sfile->browse_mode == FILE_BROWSE_MODE_ASSETS &&
374 (file->typeflag & FILE_TYPE_ASSET) != 0)
375 {
376 const int import_method = ED_fileselect_asset_import_method_get(sfile, file);
377 BLI_assert(import_method > -1);
378 if (import_method > -1) {
379 AssetImportSettings import_settings{};
380 import_settings.method = eAssetImportMethod(import_method);
381 import_settings.use_instance_collections =
382 (sfile->asset_params->import_flags &
383 (import_method == ASSET_IMPORT_LINK ?
386
387 UI_but_drag_set_asset(but, file->asset, import_settings, icon, file->preview_icon_id);
388 }
389 }
390 else if (preview_image) {
391 UI_but_drag_set_image(but, path, icon, preview_image, scale);
392 }
393 else {
394 /* path is no more static, cannot give it directly to but... */
395 UI_but_drag_set_path(but, path);
396 }
397}
398
399static void file_but_tooltip_func_set(const SpaceFile *sfile, const FileDirEntry *file, uiBut *but)
400{
401 if (file->asset) {
403 }
404 else {
407 }
408}
409
410static uiBut *file_add_icon_but(const SpaceFile *sfile,
411 uiBlock *block,
412 const char * /*path*/,
413 const FileDirEntry *file,
414 const rcti *tile_draw_rect,
415 int icon,
416 int width,
417 int height,
418 int padx,
419 bool dimmed)
420{
421 uiBut *but;
422
423 const int x = tile_draw_rect->xmin + padx;
424 const int y = tile_draw_rect->ymin +
425 round_fl_to_int((BLI_rcti_size_y(tile_draw_rect) - height) / 2.0f);
426
427 if (icon < BIFICONID_LAST_STATIC) {
428 /* Small built-in icon. Draw centered in given width. */
429 but = uiDefIconBut(
430 block, UI_BTYPE_LABEL, 0, icon, x, y, width, height, nullptr, 0.0f, 0.0f, std::nullopt);
431 /* Center the icon. */
433 }
434 else {
435 /* Larger preview icon. Fills available width/height. */
437 block, UI_BTYPE_LABEL, 0, icon, x, y, width, height, nullptr, 0.0f, 0.0f, std::nullopt);
438 }
439 UI_but_label_alpha_factor_set(but, dimmed ? 0.3f : 1.0f);
440 file_but_tooltip_func_set(sfile, file, but);
441
442 return but;
443}
444
445static uiBut *file_add_overlay_icon_but(uiBlock *block, int pos_x, int pos_y, int icon)
446{
447 uiBut *but = uiDefIconBut(block,
449 0,
450 icon,
451 pos_x,
452 pos_y,
455 nullptr,
456 0.0f,
457 0.0f,
458 std::nullopt);
459 /* Otherwise a left hand padding will be added. */
462 const uchar light[4] = {255, 255, 255, 255};
463 UI_but_color_set(but, light);
464
465 return but;
466}
467
468static void file_draw_string(int sx,
469 int sy,
470 const char *string,
471 float width,
472 int height,
473 eFontStyle_Align align,
474 const uchar col[4])
475{
476 uiFontStyle fs;
477 rcti rect;
478 char filename[FILE_MAXFILE];
479
480 if (string[0] == '\0' || width < 1) {
481 return;
482 }
483
484 const uiStyle *style = UI_style_get();
485 fs = style->widget;
486
487 STRNCPY(filename, string);
488 UI_text_clip_middle_ex(&fs, filename, width, UI_ICON_SIZE, sizeof(filename), '\0');
489
490 /* no text clipping needed, UI_fontstyle_draw does it but is a bit too strict
491 * (for buttons it works) */
492 rect.xmin = sx;
493 rect.xmax = sx + round_fl_to_int(width);
494 rect.ymin = sy - height;
495 rect.ymax = sy;
496
497 uiFontStyleDraw_Params font_style_params{};
498 font_style_params.align = align;
499
500 UI_fontstyle_draw(&fs, &rect, filename, sizeof(filename), col, &font_style_params);
501}
502
507 const char *string,
508 eFontStyle_Align align,
509 const uchar col[4])
510{
511 if (string[0] == '\0' || BLI_rcti_size_x(rect) < 1) {
512 return;
513 }
514
515 const uiStyle *style = UI_style_get();
516 uiFontStyle fs = style->widget;
517
518 UI_fontstyle_draw_multiline_clipped(&fs, rect, string, col, align);
519}
520
526static void file_draw_string_multiline(int sx,
527 int sy,
528 const char *string,
529 int wrap_width,
530 int line_height,
531 const uchar text_col[4],
532 int *r_sx,
533 int *r_sy)
534{
535 rcti rect;
536
537 if (string[0] == '\0' || wrap_width < 1) {
538 return;
539 }
540
541 const uiStyle *style = UI_style_get();
542 int font_id = style->widget.uifont_id;
543 int len = strlen(string);
544
545 rcti textbox;
546 BLF_wordwrap(font_id, wrap_width);
547 BLF_enable(font_id, BLF_WORD_WRAP);
548 BLF_boundbox(font_id, string, len, &textbox);
549 BLF_disable(font_id, BLF_WORD_WRAP);
550
551 /* no text clipping needed, UI_fontstyle_draw does it but is a bit too strict
552 * (for buttons it works) */
553 rect.xmin = sx;
554 rect.xmax = sx + wrap_width;
555 /* Need to increase the clipping rect by one more line, since the #UI_fontstyle_draw_ex() will
556 * actually start drawing at (ymax - line-height). */
557 rect.ymin = sy - BLI_rcti_size_y(&textbox) - line_height;
558 rect.ymax = sy;
559
560 uiFontStyleDraw_Params font_style_params{};
561 font_style_params.align = UI_STYLE_TEXT_LEFT;
562 font_style_params.word_wrap = true;
563
566 &style->widget, &rect, string, len, text_col, &font_style_params, nullptr, nullptr, &result);
567 if (r_sx) {
568 *r_sx = result.width;
569 }
570 if (r_sy) {
571 *r_sy = rect.ymin + line_height;
572 }
573}
574
576{
577 SpaceFile *sfile = CTX_wm_space_file(C);
578 View2D *v2d = &region->v2d;
579
580 ED_fileselect_init_layout(sfile, region);
581 UI_view2d_totRect_set(v2d, sfile->layout->width, sfile->layout->height);
582}
583
584static std::tuple<int, int, float> preview_image_scaled_dimensions_get(const int image_width,
585 const int image_height,
586 const FileLayout &layout)
587{
588 const float ui_imbx = image_width * UI_SCALE_FAC;
589 const float ui_imby = image_height * UI_SCALE_FAC;
590
591 float scale;
592 float scaledx, scaledy;
593 if (((ui_imbx > layout.prv_w) || (ui_imby > layout.prv_h)) ||
594 ((ui_imbx < layout.prv_w) || (ui_imby < layout.prv_h)))
595 {
597 scaledx = float(layout.prv_w);
598 scaledy = (float(image_height) / float(image_width)) * layout.prv_w;
599 scale = scaledx / image_width;
600 }
601 else {
602 scaledy = float(layout.prv_h);
603 scaledx = (float(image_width) / float(image_height)) * layout.prv_h;
604 scale = scaledy / image_height;
605 }
606 }
607 else {
608 scaledx = ui_imbx;
609 scaledy = ui_imby;
610 scale = UI_SCALE_FAC;
611 }
612
613 return std::make_tuple(int(scaledx), int(scaledy), scale);
614}
615
616static void file_add_preview_drag_but(const SpaceFile *sfile,
617 uiBlock *block,
618 FileLayout *layout,
619 const FileDirEntry *file,
620 const char *path,
621 const rcti *tile_draw_rect,
622 const ImBuf *preview_image,
623 const int file_type_icon)
624{
625 /* Invisible button for dragging. */
626 rcti drag_rect = *tile_draw_rect;
627 /* A bit smaller than the full tile, to increase the gap between items that users can drag from
628 * for box select. */
629 BLI_rcti_pad(&drag_rect, -layout->tile_border_x, -layout->tile_border_y);
630
631 uiBut *but = uiDefBut(block,
633 0,
634 "",
635 drag_rect.xmin,
636 drag_rect.ymin,
637 BLI_rcti_size_x(&drag_rect),
638 BLI_rcti_size_y(&drag_rect),
639 nullptr,
640 0.0,
641 0.0,
642 std::nullopt);
643
644 const ImBuf *drag_image = preview_image ? preview_image :
645 /* Larger directory or document icon. */
647 const float scale = (PREVIEW_DRAG_DRAW_SIZE * UI_SCALE_FAC) /
648 std::max(drag_image->x, drag_image->y);
649 file_but_enable_drag(but, sfile, file, path, drag_image, file_type_icon, scale);
650 file_but_tooltip_func_set(sfile, file, but);
651}
652
653static void file_draw_preview(const FileDirEntry *file,
654 const rcti *tile_draw_rect,
655 const ImBuf *imb,
656 FileLayout *layout,
657 const bool dimmed)
658{
659 BLI_assert(imb != nullptr);
660
661 const auto [scaled_width, scaled_height, scale] = preview_image_scaled_dimensions_get(
662 imb->x, imb->y, *layout);
663
664 /* Additional offset to keep the scaled image centered. Difference between maximum
665 * width/height and the actual width/height, divided by two for centering. */
666 const float ofs_x = (float(layout->prv_w) - float(scaled_width)) / 2.0f;
667 const float ofs_y = (float(layout->prv_h) - float(scaled_height)) / 2.0f;
668 const int xmin = tile_draw_rect->xmin + layout->prv_border_x + int(ofs_x + 0.5f);
669 const int ymin = tile_draw_rect->ymax - layout->prv_border_y - layout->prv_h + int(ofs_y + 0.5f);
670
672
673 float document_img_col[4] = {1.0f, 1.0f, 1.0f, 1.0f};
674 if (file->typeflag & FILE_TYPE_FTFONT) {
675 UI_GetThemeColor4fv(TH_TEXT, document_img_col);
676 }
677 if (dimmed) {
678 document_img_col[3] *= 0.3f;
679 }
680
682 /* Draw checker pattern behind image previews in case they have transparency. */
684 float(xmin), float(ymin), float(xmin + scaled_width), float(ymin + scaled_height));
685 }
686
687 if (file->typeflag & FILE_TYPE_BLENDERLIB) {
688 /* Datablock preview images use premultiplied alpha. */
690 }
691
694 float(xmin),
695 float(ymin),
696 imb->x,
697 imb->y,
698 GPU_RGBA8,
699 true,
700 imb->byte_buffer.data,
701 scale,
702 scale,
703 1.0f,
704 1.0f,
705 document_img_col);
706
707 const bool show_outline = (file->typeflag & (FILE_TYPE_IMAGE | FILE_TYPE_OBJECT_IO |
709 /* Contrasting outline around some preview types. */
710 if (show_outline) {
712
716 float border_color[4] = {1.0f, 1.0f, 1.0f, 0.15f};
717 float bgcolor[4];
719 if (srgb_to_grayscale(bgcolor) > 0.5f) {
720 border_color[0] = 0.0f;
721 border_color[1] = 0.0f;
722 border_color[2] = 0.0f;
723 }
724 immUniformColor4fv(border_color);
726 float(xmin),
727 float(ymin),
728 float(xmin + scaled_width + 1),
729 float(ymin + scaled_height + 1));
731 }
732
734}
735
736static void file_draw_special_image(const FileDirEntry *file,
737 const rcti *tile_draw_rect,
738 const int file_type_icon,
739 const float icon_aspect,
740 const FileLayout *layout,
741 const bool dimmed)
742{
743 float document_img_col[4] = {1.0f, 1.0f, 1.0f, 1.0f};
744 if (file->typeflag & FILE_TYPE_DIR) {
745 UI_GetThemeColor4fv(TH_ICON_FOLDER, document_img_col);
746 }
747 else {
748 UI_GetThemeColor4fv(TH_TEXT, document_img_col);
749 }
750
751 if (dimmed) {
752 document_img_col[3] *= 0.3f;
753 }
754
756
757 const int cent_x = tile_draw_rect->xmin + layout->prv_border_x + (layout->prv_w / 2.0f) + 0.5f;
758 const int cent_y = tile_draw_rect->ymax - layout->prv_border_y - (layout->prv_h / 2.0f) + 0.5f;
759 const float aspect = icon_aspect / UI_SCALE_FAC;
760
761 {
762 /* Draw large folder or document icon. */
763 const int icon_large = (file->typeflag & FILE_TYPE_DIR) ? ICON_FILE_FOLDER_LARGE :
764 ICON_FILE_LARGE;
765
766 uchar icon_col[4];
767 rgba_float_to_uchar(icon_col, document_img_col);
768
769 const float scale = 4.0f;
770 const float ofs_y = (file->typeflag & FILE_TYPE_DIR ? -0.02f : 0.0f) * layout->prv_h;
771
772 UI_icon_draw_ex(cent_x - (ICON_DEFAULT_WIDTH * scale / aspect / 2.0f),
773 cent_y - (ICON_DEFAULT_HEIGHT * scale / aspect / 2.0f) + ofs_y,
774 icon_large,
775 icon_aspect / UI_SCALE_FAC / scale,
776 document_img_col[3],
777 0.0f,
778 icon_col,
779 false,
781 }
782
783 if (file_type_icon) {
784 /* Small icon in the middle of large image, scaled to fit container and UI scale */
785 float icon_opacity = 0.4f;
786 uchar icon_color[4] = {0, 0, 0, 255};
787 if (srgb_to_grayscale(document_img_col) < 0.5f) {
788 icon_color[0] = 255;
789 icon_color[1] = 255;
790 icon_color[2] = 255;
791 }
792
793 const float scale = file->typeflag & FILE_TYPE_DIR ? 1.5f : 2.0f;
794 const float ofs_y = (file->typeflag & FILE_TYPE_DIR ? -0.035f : -0.135f) * layout->prv_h;
795
796 UI_icon_draw_ex(cent_x - (ICON_DEFAULT_WIDTH * scale / aspect / 2.0f),
797 cent_y - (ICON_DEFAULT_HEIGHT * scale / aspect / 2.0f) + ofs_y,
798 file_type_icon,
799 icon_aspect / UI_SCALE_FAC / scale,
800 icon_opacity,
801 0.0f,
802 icon_color,
803 false,
805 }
806
808}
809
810static void file_draw_loading_icon(const rcti *tile_draw_rect,
811 const float preview_icon_aspect,
812 const FileLayout *layout)
813{
814 uchar icon_color[4] = {0, 0, 0, 255};
815 /* Contrast with background since we are not showing the large document image. */
816 UI_GetThemeColor4ubv(TH_TEXT, icon_color);
817
818 const int cent_x = tile_draw_rect->xmin + layout->prv_border_x + (layout->prv_w / 2.0f) + 0.5f;
819 const int cent_y = tile_draw_rect->ymax - layout->prv_border_y - (layout->prv_h / 2.0f) + 0.5f;
820 const float aspect = preview_icon_aspect / UI_SCALE_FAC;
821
822 UI_icon_draw_ex(cent_x - (ICON_DEFAULT_WIDTH / aspect / 2.0f),
823 cent_y - (ICON_DEFAULT_HEIGHT / aspect / 2.0f),
824 ICON_PREVIEW_LOADING,
825 aspect,
826 1.0f,
827 0.0f,
828 icon_color,
829 false,
831}
832
833static void file_draw_indicator_icons(const FileList *files,
834 const FileDirEntry *file,
835 const FileLayout *layout,
836 const rcti *tile_draw_rect,
837 const float preview_icon_aspect,
838 const int file_type_icon,
839 const bool has_special_file_image)
840{
841 const bool is_offline = (file->attributes & FILE_ATTR_OFFLINE);
842 const bool is_link = (file->attributes & FILE_ATTR_ANY_LINK);
843 const bool is_loading = filelist_file_is_preview_pending(files, file);
844
845 /* Don't draw these icons if the preview image is small. They are just indicators and shouldn't
846 * cover the preview. */
847 if (preview_icon_aspect < 2.0f) {
848 const float icon_x = float(tile_draw_rect->xmin) + (3.0f * UI_SCALE_FAC);
849 const float icon_y = float(tile_draw_rect->ymax) - layout->prv_border_y - layout->prv_h;
850 const uchar light[4] = {255, 255, 255, 255};
851 if (is_offline) {
852 /* Icon at bottom to indicate the file is offline. */
853 UI_icon_draw_ex(icon_x,
854 icon_y,
855 ICON_INTERNET,
856 1.0f / UI_SCALE_FAC,
857 0.6f,
858 0.0f,
859 light,
860 true,
862 }
863 else if (is_link) {
864 /* Icon at bottom to indicate it is a shortcut, link, or alias. */
865 UI_icon_draw_ex(icon_x,
866 icon_y,
867 ICON_FILE_ALIAS,
868 1.0f / UI_SCALE_FAC,
869 0.6f,
870 0.0f,
871 nullptr,
872 false,
874 }
875 else if (file_type_icon) {
876 /* Smaller, fainter type icon at bottom-left.
877 *
878 * Always draw while loading, the preview shows a loading icon and doesn't indicate the type
879 * yet then. After loading, the special file image may already draw the type icon in
880 * #file_draw_preview(), don't draw it again here. Also don't draw it for font files, they
881 * render a font preview already, the type indicator would be redundant.
882 */
883 if (is_loading || !(has_special_file_image || (file->typeflag & FILE_TYPE_FTFONT))) {
884 UI_icon_draw_ex(icon_x,
885 icon_y,
886 file_type_icon,
887 1.0f / UI_SCALE_FAC,
888 0.6f,
889 0.0f,
890 light,
891 true,
893 }
894 }
895 }
896
897 const bool is_current_main_data = filelist_file_get_id(file) != nullptr;
898 if (is_current_main_data) {
899 /* Smaller, fainter icon at the top-right indicating that the file represents data from the
900 * current file (from current #Main in fact). */
901 float icon_x, icon_y;
902 const uchar light[4] = {255, 255, 255, 255};
903 icon_x = float(tile_draw_rect->xmax) - (16.0f * UI_SCALE_FAC);
904 icon_y = float(tile_draw_rect->ymax) - (20.0f * UI_SCALE_FAC);
905 UI_icon_draw_ex(icon_x,
906 icon_y,
907 ICON_CURRENT_FILE,
908 1.0f / UI_SCALE_FAC,
909 0.6f,
910 0.0f,
911 light,
912 true,
914 }
915}
916
917static void renamebutton_cb(bContext *C, void * /*arg1*/, char *oldname)
918{
919 char newname[FILE_MAX + 12];
920 char orgname[FILE_MAX + 12];
921 char filename[FILE_MAX + 12];
923 wmWindow *win = CTX_wm_window(C);
925 ARegion *region = CTX_wm_region(C);
927
928 BLI_path_join(orgname, sizeof(orgname), params->dir, oldname);
929 STRNCPY(filename, params->renamefile);
931 BLI_path_join(newname, sizeof(newname), params->dir, filename);
932
933 if (!STREQ(orgname, newname)) {
934 errno = 0;
935 if ((BLI_rename(orgname, newname) != 0) || !BLI_exists(newname)) {
937 RPT_ERROR, "Could not rename: %s", errno ? strerror(errno) : "unknown error");
938 WM_report_banner_show(wm, win);
939 /* Renaming failed, reset the name for further renaming handling. */
940 STRNCPY(params->renamefile, oldname);
941 }
942 else {
943 /* If rename is successful, set renamefile to newly renamed entry.
944 * This is used later to select and scroll to the file.
945 */
946 STRNCPY(params->renamefile, filename);
947 }
948
949 /* Ensure we select and scroll to the renamed file.
950 * This is done even if the rename fails as we want to make sure that the file we tried to
951 * rename is still selected and in view. (it can move if something added files/folders to the
952 * directory while we were renaming.
953 */
955 /* to make sure we show what is on disk */
956 ED_fileselect_clear(wm, sfile);
957 ED_region_tag_redraw(region);
958 }
959}
960
961static void draw_background(FileLayout *layout, View2D *v2d)
962{
963 const int item_height = layout->tile_h + (2 * layout->tile_border_y);
964 int i;
965 int sy;
966
969 float col_alternating[4];
970 UI_GetThemeColor4fv(TH_ROW_ALTERNATE, col_alternating);
972
973 /* alternating flat shade background */
974 for (i = 2; (i <= layout->rows + 1); i += 2) {
975 sy = int(v2d->cur.ymax) - layout->offset_top - i * item_height - layout->list_padding_top;
976
977 /* Offset pattern slightly to add scroll effect. */
978 sy += round_fl_to_int(item_height * (v2d->tot.ymax - v2d->cur.ymax) / item_height);
979
981 v2d->cur.xmin,
982 float(sy),
983 v2d->cur.xmax,
984 float(sy + layout->tile_h + 2 * layout->tile_border_y));
985 }
986
988}
989
990static void draw_dividers(FileLayout *layout, View2D *v2d)
991{
992 /* vertical column dividers */
993
994 const int step = (layout->tile_w + 2 * layout->tile_border_x);
995
996 uint vertex_len = 0;
997 int sx = int(v2d->tot.xmin);
998 while (sx < v2d->cur.xmax) {
999 sx += step;
1000 vertex_len += 4; /* vertex_count = 2 points per line * 2 lines per divider */
1001 }
1002
1003 if (vertex_len > 0) {
1004 float v1[2], v2[2];
1005 float col_hi[3], col_lo[3];
1006
1007 UI_GetThemeColorShade3fv(TH_BACK, 30, col_hi);
1008 UI_GetThemeColorShade3fv(TH_BACK, -30, col_lo);
1009
1010 v1[1] = v2d->cur.ymax - layout->tile_border_y;
1011 v2[1] = v2d->cur.ymin;
1012
1016
1018 immBegin(GPU_PRIM_LINES, vertex_len);
1019
1020 sx = int(v2d->tot.xmin);
1021 while (sx < v2d->cur.xmax) {
1022 sx += step;
1023
1024 v1[0] = v2[0] = sx;
1025 immAttrSkip(color);
1026 immVertex2fv(pos, v1);
1027 immAttr3fv(color, col_lo);
1029
1030 v1[0] = v2[0] = sx + 1;
1031 immAttrSkip(color);
1032 immVertex2fv(pos, v1);
1033 immAttr3fv(color, col_hi);
1035 }
1036
1037 immEnd();
1039 }
1040}
1041
1042static void draw_columnheader_background(const FileLayout *layout, const View2D *v2d)
1043{
1045
1048
1049 immRectf(pos,
1050 v2d->cur.xmin,
1051 v2d->cur.ymax - layout->attribute_column_header_h,
1052 v2d->cur.xmax,
1053 v2d->cur.ymax);
1054
1056}
1057
1059 FileLayout *layout,
1060 const View2D *v2d,
1061 const uchar text_col[4])
1062{
1063 const float divider_pad = 0.2 * layout->attribute_column_header_h;
1064 int sx = v2d->cur.xmin, sy = v2d->cur.ymax;
1065
1066 for (int column_type = 0; column_type < ATTRIBUTE_COLUMN_MAX; column_type++) {
1068 {
1069 continue;
1070 }
1071 const FileAttributeColumn *column = &layout->attribute_columns[column_type];
1072
1073 /* Active sort type triangle */
1074 if (params->sort == column->sort_type) {
1075 float tri_color[4];
1076
1077 rgba_uchar_to_float(tri_color, text_col);
1078 UI_draw_icon_tri(sx + column->width - (0.3f * U.widget_unit) -
1080 sy + (0.1f * U.widget_unit) - (layout->attribute_column_header_h / 2),
1081 (params->flag & FILE_SORT_INVERT) ? 't' : 'v',
1082 tri_color);
1083 }
1084
1086 sy - layout->tile_border_y,
1087 IFACE_(column->name),
1088 column->width - 2 * ATTRIBUTE_COLUMN_PADDING,
1089 layout->attribute_column_header_h - layout->tile_border_y,
1091 text_col);
1092
1093 /* Separator line */
1094 if (column_type != COLUMN_NAME) {
1097
1101 immVertex2f(pos, sx - 1, sy - divider_pad);
1102 immVertex2f(pos, sx - 1, sy - layout->attribute_column_header_h + divider_pad);
1103 immEnd();
1105 }
1106
1107 sx += column->width;
1108 }
1109
1110 /* Vertical separator lines line */
1111 {
1116 immVertex2f(pos, v2d->cur.xmin, sy);
1117 immVertex2f(pos, v2d->cur.xmax, sy);
1118 immVertex2f(pos, v2d->cur.xmin, sy - layout->attribute_column_header_h);
1119 immVertex2f(pos, v2d->cur.xmax, sy - layout->attribute_column_header_h);
1120 immEnd();
1122 }
1123}
1124
1130 /* Generated string will be cached in the file, so non-const. */
1131 FileDirEntry *file,
1132 const bool compact,
1133 const bool update_stat_strings)
1134{
1135 switch (column) {
1136 case COLUMN_DATETIME:
1137 if (!(file->typeflag & FILE_TYPE_BLENDERLIB) && !FILENAME_IS_CURRPAR(file->relpath)) {
1138 if (file->draw_data.datetime_str[0] == '\0' || update_stat_strings) {
1140 bool is_today, is_yesterday;
1141
1143 nullptr, file->time, compact, time, date, &is_today, &is_yesterday);
1144
1145 if (!compact && (is_today || is_yesterday)) {
1146 STRNCPY(date, is_today ? IFACE_("Today") : IFACE_("Yesterday"));
1147 }
1148 SNPRINTF(file->draw_data.datetime_str, compact ? "%s" : "%s %s", date, time);
1149 }
1150
1151 return file->draw_data.datetime_str;
1152 }
1153 break;
1154 case COLUMN_SIZE:
1157 {
1158 if (file->draw_data.size_str[0] == '\0' || update_stat_strings) {
1160 nullptr, file->size, compact, file->draw_data.size_str);
1161 }
1162
1163 return file->draw_data.size_str;
1164 }
1165 break;
1166 default:
1167 break;
1168 }
1169
1170 return nullptr;
1171}
1172
1174 const FileLayout *layout,
1175 FileDirEntry *file,
1176 const rcti *tile_draw_rect,
1177 const uchar text_col[4])
1178{
1179 const bool compact = FILE_LAYOUT_COMPACT(layout);
1180 const bool update_stat_strings = layout->width != layout->curr_size;
1181 int sx = tile_draw_rect->xmin - layout->tile_border_x;
1182
1183 for (int column_type = 0; column_type < ATTRIBUTE_COLUMN_MAX; column_type++) {
1184 const FileAttributeColumn *column = &layout->attribute_columns[column_type];
1185
1186 /* Name column is not a detail column (should already be drawn), always skip here. */
1187 if (column_type == COLUMN_NAME) {
1188 sx += column->width;
1189 continue;
1190 }
1192 {
1193 continue;
1194 }
1195
1197 FileAttributeColumnType(column_type), file, compact, update_stat_strings);
1198
1199 if (str) {
1201 tile_draw_rect->ymax,
1202 IFACE_(str),
1203 column->width - 2 * ATTRIBUTE_COLUMN_PADDING,
1204 layout->tile_h,
1206 text_col);
1207 }
1208
1209 sx += column->width;
1210 }
1211}
1212
1213static rcti tile_draw_rect_get(const View2D *v2d, const FileLayout *layout, const int file_idx)
1214{
1215 int tile_pos_x, tile_pos_y;
1216 ED_fileselect_layout_tilepos(layout, file_idx, &tile_pos_x, &tile_pos_y);
1217 tile_pos_x += int(v2d->tot.xmin);
1218 tile_pos_y = int(v2d->tot.ymax - tile_pos_y);
1219
1220 rcti rect;
1221 rect.xmin = tile_pos_x;
1222 rect.xmax = rect.xmin + layout->tile_w;
1223 rect.ymax = tile_pos_y;
1224 rect.ymin = rect.ymax - layout->tile_h;
1225
1226 return rect;
1227}
1228
1233 const eFileDisplayType display_type,
1234 const FileLayout *layout,
1235 const int file_idx,
1236 const int icon_ofs_x)
1237{
1238 rcti tile_rect = tile_draw_rect_get(v2d, layout, file_idx);
1239
1240 rcti rect = tile_rect;
1241 if (display_type == FILE_IMGDISPLAY) {
1242 rect.ymin += round_fl_to_int(layout->prv_border_y * 0.5f);
1243 rect.ymax = rect.ymin + layout->text_line_height * layout->text_lines_count;
1244 }
1245 else {
1246 rect.xmin += icon_ofs_x + 1;
1247 rect.xmax = tile_rect.xmin + round_fl_to_int(layout->attribute_columns[COLUMN_NAME].width) -
1248 layout->tile_border_x;
1249 }
1250
1251 return rect;
1252}
1253
1254void file_draw_list(const bContext *C, ARegion *region)
1255{
1257 wmWindow *win = CTX_wm_window(C);
1258 SpaceFile *sfile = CTX_wm_space_file(C);
1260 FileLayout *layout = ED_fileselect_get_layout(sfile, region);
1261 View2D *v2d = &region->v2d;
1262 FileList *files = sfile->files;
1263 FileDirEntry *file;
1264 uiBlock *block = UI_block_begin(C, region, __func__, blender::ui::EmbossType::Emboss);
1265 int numfiles;
1266 int numfiles_layout;
1267 int offset;
1268 int i;
1269 eFontStyle_Align align;
1270 bool do_drag;
1271 uchar text_col[4];
1272 const bool draw_columnheader = (params->display == FILE_VERTICALDISPLAY);
1273 const float thumb_icon_aspect = std::min(64.0f / float(params->thumbnail_size), 4.0f);
1274
1275 numfiles = filelist_files_ensure(files);
1276
1277 if (params->display != FILE_IMGDISPLAY) {
1278 draw_background(layout, v2d);
1279 draw_dividers(layout, v2d);
1280 }
1281
1283 layout, int(region->v2d.cur.xmin), int(-region->v2d.cur.ymax));
1284 offset = std::max(offset, 0);
1285
1286 numfiles_layout = ED_fileselect_layout_numfiles(layout, region);
1287
1288 /* adjust, so the next row is already drawn when scrolling */
1289 if (layout->flag & FILE_LAYOUT_HOR) {
1290 numfiles_layout += layout->rows;
1291 }
1292 else {
1293 numfiles_layout += layout->flow_columns;
1294 }
1295
1296 filelist_file_cache_slidingwindow_set(files, numfiles_layout);
1297
1299
1300 if (numfiles > 0) {
1301 const bool success = filelist_file_cache_block(
1302 files, min_ii(offset + (numfiles_layout / 2), numfiles - 1));
1303 BLI_assert(success);
1304 UNUSED_VARS_NDEBUG(success);
1305
1307
1308 /* Handle preview timer here,
1309 * since it's filelist_file_cache_block() and filelist_cache_previews_update()
1310 * which controls previews task. */
1311 {
1312 const bool previews_running = filelist_cache_previews_running(files) &&
1314 // printf("%s: preview task: %d\n", __func__, previews_running);
1315 if (previews_running && !sfile->previews_timer) {
1317 wm, win, NC_SPACE | ND_SPACE_FILE_PREVIEW, 0.01);
1318 }
1319 if (!previews_running && sfile->previews_timer) {
1320 /* Preview is not running, no need to keep generating update events! */
1321 // printf("%s: Inactive preview task, sleeping!\n", __func__);
1323 sfile->previews_timer = nullptr;
1324 }
1325 }
1326 }
1327
1329
1330 UI_GetThemeColor4ubv(TH_TEXT, text_col);
1331
1332 for (i = offset; (i < numfiles) && (i < offset + numfiles_layout); i++) {
1333 eDirEntry_SelectFlag file_selflag;
1334 const int padx = 0.1f * UI_UNIT_X;
1335 int icon_ofs = 0;
1336
1337 const rcti tile_draw_rect = tile_draw_rect_get(v2d, layout, i);
1338
1339 file = filelist_file(files, i);
1340 file_selflag = filelist_entry_select_get(sfile->files, file, CHECK_ALL);
1341
1342 char path[FILE_MAX_LIBEXTRA];
1343 filelist_file_get_full_path(files, file, path);
1344
1345 if (!(file_selflag & FILE_SEL_EDITING)) {
1346 if ((params->highlight_file == i) || (file_selflag & FILE_SEL_HIGHLIGHTED) ||
1347 (file_selflag & FILE_SEL_SELECTED))
1348 {
1349 int colorid = (file_selflag & FILE_SEL_SELECTED) ? TH_HILITE : TH_BACK;
1350 int shade = (params->highlight_file == i) || (file_selflag & FILE_SEL_HIGHLIGHTED) ? 35 :
1351 0;
1352 BLI_assert(i == 0 || !FILENAME_IS_CURRPAR(file->relpath));
1353
1354 draw_tile_background(&tile_draw_rect, colorid, shade);
1355 }
1356 }
1358
1359 /* don't drag parent or refresh items */
1360 do_drag = !FILENAME_IS_CURRPAR(file->relpath);
1361 const bool is_hidden = (file->attributes & FILE_ATTR_HIDDEN);
1362
1363 if (FILE_IMGDISPLAY == params->display) {
1364 const int file_type_icon = filelist_geticon_file_type(files, i, false);
1365 const ImBuf *preview_imb = filelist_get_preview_image(files, i);
1366
1367 bool has_special_file_image = false;
1368
1369 const bool is_loading = filelist_file_is_preview_pending(files, file);
1370 if (is_loading) {
1371 file_draw_loading_icon(&tile_draw_rect, thumb_icon_aspect, layout);
1372 }
1373 else if (preview_imb) {
1374 file_draw_preview(file, &tile_draw_rect, preview_imb, layout, is_hidden);
1375 }
1376 else {
1377 /* Larger folder or document icon, with file/folder type icon in the middle (if any). */
1379 file, &tile_draw_rect, file_type_icon, thumb_icon_aspect, layout, is_hidden);
1380 has_special_file_image = true;
1381 }
1382
1384 file,
1385 layout,
1386 &tile_draw_rect,
1387 thumb_icon_aspect,
1388 file_type_icon,
1389 has_special_file_image);
1390
1391 if (do_drag) {
1393 sfile, block, layout, file, path, &tile_draw_rect, preview_imb, file_type_icon);
1394 }
1395 }
1396 else {
1397 const bool filelist_loading = !filelist_is_ready(files);
1398 const BIFIconID icon = [&]() {
1399 if (file->asset) {
1400 file->asset->ensure_previewable();
1401
1402 if (filelist_loading) {
1403 return BIFIconID(ICON_PREVIEW_LOADING);
1404 }
1406 }
1407 return filelist_geticon_file_type(files, i, true);
1408 }();
1409
1410 icon_ofs += layout->prv_w + 2 * padx;
1411
1412 /* Add dummy draggable button covering the icon and the label. */
1413 if (do_drag) {
1414 const uiStyle *style = UI_style_get();
1415 const int str_width = UI_fontstyle_string_width(&style->widget, file->name);
1416 const int drag_width = std::min(
1417 str_width + icon_ofs,
1419 if (drag_width > 0) {
1420 /* Uses full row height (tile height plus 2 * tile border padding) so there's no space
1421 * between rows. */
1422 uiBut *drag_but = uiDefBut(block,
1424 0,
1425 "",
1426 tile_draw_rect.xmin,
1427 tile_draw_rect.ymin - layout->tile_border_y,
1428 drag_width,
1429 layout->tile_h + layout->tile_border_y * 2,
1430 nullptr,
1431 0,
1432 0,
1433 std::nullopt);
1435 file_but_enable_drag(drag_but, sfile, file, path, nullptr, icon, UI_SCALE_FAC);
1436 file_but_tooltip_func_set(sfile, file, drag_but);
1437 }
1438 }
1439
1440 /* Add this after the fake draggable button, so the icon button tooltip is displayed. */
1441 uiBut *icon_but = file_add_icon_but(sfile,
1442 block,
1443 path,
1444 file,
1445 &tile_draw_rect,
1446 icon,
1447 layout->prv_w,
1448 layout->prv_h,
1449 padx,
1450 is_hidden);
1451 if (do_drag) {
1452 /* For some reason the dragging is unreliable for the icon button if we don't explicitly
1453 * enable dragging, even though the dummy drag button above covers the same area. */
1454 file_but_enable_drag(icon_but, sfile, file, path, nullptr, icon, UI_SCALE_FAC);
1455 }
1456
1457 if (layout->prv_w >= round_fl_to_int(ICON_DEFAULT_WIDTH_SCALE * 2) &&
1458 (filelist_loading || icon >= BIFICONID_LAST_STATIC))
1459 {
1460 const BIFIconID type_icon = filelist_geticon_file_type(files, i, true);
1462 tile_draw_rect.xmin + padx - 2,
1463 tile_draw_rect.ymin - 2 * UI_SCALE_FAC,
1464 type_icon);
1465 }
1466 }
1467
1468 const rcti text_rect = text_draw_rect_get(
1469 v2d, eFileDisplayType(params->display), layout, i, icon_ofs);
1470
1471 if (file_selflag & FILE_SEL_EDITING) {
1472 const int but_height =
1473 (params->display == FILE_IMGDISPLAY) ?
1474 layout->text_line_height * 1.4f :
1475 /* Just a little smaller than the tile height, clamped to #UI_UNIT_Y as maximum. */
1476 std::min(short(BLI_rcti_size_y(&text_rect) - 1.0f * UI_SCALE_FAC), UI_UNIT_Y);
1477 uiBut *but = uiDefBut(block,
1479 1,
1480 "",
1481 text_rect.xmin,
1482 /* First line only, when name is displayed in multiple lines. */
1483 text_rect.ymax - but_height,
1484 BLI_rcti_size_x(&text_rect),
1485 but_height,
1486 params->renamefile,
1487 1.0f,
1488 float(sizeof(params->renamefile)),
1489 "");
1491 UI_but_flag_enable(but, UI_BUT_NO_UTF8); /* Allow non UTF8 names. */
1493 if (false == UI_but_active_only(C, region, block, but)) {
1494 /* Note that this is the only place where we can also handle a cancelled renaming. */
1495
1496 file_params_rename_end(wm, win, sfile, file);
1497
1498 /* After the rename button is removed, we need to make sure the view is redrawn once more,
1499 * in case selection changed. Usually UI code would trigger that redraw, but the rename
1500 * operator may have been called from a different region.
1501 * Tagging regions for redrawing while drawing is rightfully prevented. However, this
1502 * active button removing basically introduces handling logic to drawing code. So a
1503 * notifier should be an acceptable workaround. */
1505
1506 file_selflag = filelist_entry_select_get(sfile->files, file, CHECK_ALL);
1507 }
1508 }
1509
1510 /* file_selflag might have been modified by branch above. */
1511 if ((file_selflag & FILE_SEL_EDITING) == 0) {
1512 if (layout->text_lines_count == 1) {
1513 file_draw_string(text_rect.xmin,
1514 text_rect.ymax,
1515 file->name,
1516 BLI_rcti_size_x(&text_rect),
1517 BLI_rcti_size_y(&text_rect),
1518 align,
1519 text_col);
1520 }
1521 else {
1522 file_draw_string_mulitline_clipped(&text_rect, file->name, align, text_col);
1523 }
1524 }
1525
1526 if (params->display != FILE_IMGDISPLAY) {
1527 draw_details_columns(params, layout, file, &tile_draw_rect, text_col);
1528 }
1529 }
1530
1531 if (numfiles < 1) {
1532 const rcti tile_draw_rect = tile_draw_rect_get(v2d, layout, 0);
1533 const uiStyle *style = UI_style_get();
1534
1535 const bool is_filtered = params->filter_search[0] != '\0';
1536
1537 uchar text_col_mod[4];
1538 copy_v4_v4_uchar(text_col_mod, text_col);
1539 if (!is_filtered) {
1540 text_col_mod[3] /= 2;
1541 }
1542
1543 const char *message = [&]() {
1544 if (!filelist_is_ready(files)) {
1545 return IFACE_("Loading...");
1546 }
1547 if (is_filtered) {
1548 return IFACE_("No results match the search filter");
1549 }
1550 return IFACE_("No items");
1551 }();
1552
1554 tile_draw_rect.xmin + UI_UNIT_X,
1555 tile_draw_rect.ymax - UI_UNIT_Y,
1556 message,
1557 text_col_mod);
1558 }
1559
1561
1562 UI_block_end(C, block);
1563 UI_block_draw(C, block);
1564
1565 /* Draw last, on top of file list. */
1566 if (draw_columnheader) {
1567 draw_columnheader_background(layout, v2d);
1568 draw_columnheader_columns(params, layout, v2d, text_col);
1569 }
1570
1571 if (numfiles != -1) {
1572 /* Only save current size if there is something to show. */
1573 layout->curr_size = layout->width;
1574 }
1575}
1576
1578 const SpaceFile *sfile,
1579 ARegion *region,
1580 FileAssetSelectParams *asset_params)
1581{
1582 char library_ui_path[FILE_MAX_LIBEXTRA];
1583 file_path_to_ui_path(asset_params->base_params.dir, library_ui_path, sizeof(library_ui_path));
1584
1585 uchar text_col[4];
1586 UI_GetThemeColor4ubv(TH_TEXT, text_col);
1587
1588 const View2D *v2d = &region->v2d;
1589 const int pad = sfile->layout->tile_border_x;
1590 const int width = BLI_rctf_size_x(&v2d->tot) - (2 * pad);
1591 const int line_height = sfile->layout->text_line_height;
1592 int sx = v2d->tot.xmin + pad;
1593 /* For some reason no padding needed. */
1594 int sy = v2d->tot.ymax;
1595
1596 {
1597 const char *message = RPT_("Path to asset library does not exist:");
1598 file_draw_string_multiline(sx, sy, message, width, line_height, text_col, nullptr, &sy);
1599
1600 sy -= line_height;
1601 file_draw_string(sx, sy, library_ui_path, width, line_height, UI_STYLE_TEXT_LEFT, text_col);
1602 }
1603
1604 /* Separate a bit further. */
1605 sy -= line_height * 2.2f;
1606
1607 {
1608 UI_icon_draw(sx, sy - UI_UNIT_Y, ICON_INFO);
1609
1610 const char *suggestion = RPT_(
1611 "Asset Libraries are local directories that can contain .blend files with assets inside.\n"
1612 "Manage Asset Libraries from the File Paths section in Preferences");
1614 sx + UI_UNIT_X, sy, suggestion, width - UI_UNIT_X, line_height, text_col, nullptr, &sy);
1615
1616 uiBlock *block = UI_block_begin(C, region, __func__, blender::ui::EmbossType::Emboss);
1617 wmOperatorType *ot = WM_operatortype_find("SCREEN_OT_userpref_show", false);
1618 uiBut *but = uiDefIconTextButO_ptr(block,
1620 ot,
1622 ICON_PREFERENCES,
1623 WM_operatortype_name(ot, nullptr),
1624 sx + UI_UNIT_X,
1625 sy - line_height - UI_UNIT_Y * 1.2f,
1626 UI_UNIT_X * 8,
1627 UI_UNIT_Y,
1628 std::nullopt);
1629 PointerRNA *but_opptr = UI_but_operator_ptr_ensure(but);
1630 RNA_enum_set(but_opptr, "section", USER_SECTION_FILE_PATHS);
1631
1632 UI_block_end(C, block);
1633 UI_block_draw(C, block);
1634 }
1635}
1636
1638 const SpaceFile *sfile,
1639 ARegion *region,
1640 const char *blendfile_path,
1642{
1643 uchar text_col[4];
1644 UI_GetThemeColor4ubv(TH_TEXT, text_col);
1645
1646 const View2D *v2d = &region->v2d;
1647 const int pad = sfile->layout->tile_border_x;
1648 const int width = BLI_rctf_size_x(&v2d->tot) - (2 * pad);
1649 const int line_height = sfile->layout->text_line_height;
1650 int sx = v2d->tot.xmin + pad;
1651 /* For some reason no padding needed. */
1652 int sy = v2d->tot.ymax;
1653
1654 {
1655 const char *message = RPT_("Unreadable Blender library file:");
1656 file_draw_string_multiline(sx, sy, message, width, line_height, text_col, nullptr, &sy);
1657
1658 sy -= line_height;
1659 file_draw_string(sx, sy, blendfile_path, width, line_height, UI_STYLE_TEXT_LEFT, text_col);
1660 }
1661
1662 /* Separate a bit further. */
1663 sy -= line_height * 2.2f;
1664
1665 LISTBASE_FOREACH (Report *, report, &reports->list) {
1666 const short report_type = report->type;
1667 if (report_type <= RPT_INFO) {
1668 continue;
1669 }
1670
1671 int icon = ICON_INFO;
1672 if (report_type > RPT_WARNING) {
1673 icon = ICON_ERROR;
1674 }
1675 UI_icon_draw(sx, sy - UI_UNIT_Y, icon);
1676
1678 sy,
1679 RPT_(report->message),
1680 width - UI_UNIT_X,
1681 line_height,
1682 text_col,
1683 nullptr,
1684 &sy);
1685 sy -= line_height;
1686 }
1687}
1688
1689bool file_draw_hint_if_invalid(const bContext *C, const SpaceFile *sfile, ARegion *region)
1690{
1691 char blendfile_path[FILE_MAX_LIBEXTRA];
1692 const bool is_asset_browser = ED_fileselect_is_asset_browser(sfile);
1693 const bool is_library_browser = !is_asset_browser &&
1694 filelist_islibrary(sfile->files, blendfile_path, nullptr);
1695
1696 if (is_asset_browser) {
1698
1699 /* Check if the asset library exists. */
1700 if (!((asset_params->asset_library_ref.type == ASSET_LIBRARY_LOCAL) ||
1701 filelist_is_dir(sfile->files, asset_params->base_params.dir)))
1702 {
1703 file_draw_invalid_asset_library_hint(C, sfile, region, asset_params);
1704 return true;
1705 }
1706 }
1707
1708 /* Check if the blendfile library is valid (has entries). */
1709 if (is_library_browser) {
1710 if (!filelist_is_ready(sfile->files)) {
1711 return false;
1712 }
1713
1714 const int numfiles = filelist_files_num_entries(sfile->files);
1715 if (numfiles > 0) {
1716 return false;
1717 }
1718
1719 /* This could all be part of the file-list loading:
1720 * - When loading fails this could be saved in the file-list, e.g. when
1721 * `BLO_blendhandle_from_file()` returns null in `filelist_readjob_list_lib()`, a
1722 * `FL_HAS_INVALID_LIBRARY` file-list flag could be set.
1723 * - Reports from it could also be stored in `FileList` rather than being ignored
1724 * (`RPT_STORE` must be set!).
1725 * - Then we could just check for `is_library_browser` and the `FL_HAS_INVALID_LIBRARY` flag
1726 * here, and draw the hint with the reports in the file-list. (We would not draw a hint for
1727 * recursive loading, even if the file-list has the "has invalid library" flag set, which
1728 * seems like the wanted behavior.)
1729 * - The call to BKE_blendfile_is_readable() would not be needed then.
1730 */
1731 if (!sfile->runtime->is_blendfile_status_set) {
1734 blendfile_path, &sfile->runtime->is_blendfile_readable_reports);
1735 sfile->runtime->is_blendfile_status_set = true;
1736 }
1737 if (!sfile->runtime->is_blendfile_readable) {
1739 C, sfile, region, blendfile_path, &sfile->runtime->is_blendfile_readable_reports);
1740 return true;
1741 }
1742 }
1743
1744 return false;
1745}
Main runtime representation of an asset.
void immDrawPixelsTexTiled_scaling(IMMDrawPixelsTexState *state, float x, float y, int img_w, int img_h, eGPUTextureFormat gpu_format, bool use_filter, const void *rect, float scaleX, float scaleY, float xzoom, float yzoom, const float color[4])
Definition glutil.cc:296
IMMDrawPixelsTexState immDrawPixelsTexSetup(int builtin)
Definition glutil.cc:36
bool BKE_blendfile_is_readable(const char *path, ReportList *reports)
Definition blendfile.cc:153
SpaceFile * CTX_wm_space_file(const bContext *C)
wmWindow * CTX_wm_window(const bContext *C)
SpaceLink * CTX_wm_space_data(const bContext *C)
ARegion * CTX_wm_region(const bContext *C)
wmWindowManager * CTX_wm_manager(const bContext *C)
void BKE_reports_clear(ReportList *reports)
Definition report.cc:82
@ BLF_WORD_WRAP
Definition BLF_api.hh:439
void BLF_batch_draw_begin()
Definition blf.cc:531
void BLF_boundbox(int fontid, const char *str, size_t str_len, rcti *r_box, ResultBLF *r_info=nullptr) ATTR_NONNULL(2)
Definition blf.cc:775
void BLF_disable(int fontid, int option)
Definition blf.cc:329
void BLF_batch_draw_end()
Definition blf.cc:544
void BLF_wordwrap(int fontid, int wrap_width, BLFWrapMode mode=BLFWrapMode::Minimal)
Definition blf.cc:918
void BLF_enable(int fontid, int option)
Definition blf.cc:320
#define BLI_assert(a)
Definition BLI_assert.h:46
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:53
File and directory operations.
int BLI_exists(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition storage.cc:373
#define FILE_ATTR_ANY_LINK
void BLI_filelist_entry_size_to_string(const struct stat *st, uint64_t st_size_fallback, bool compact, char r_size[FILELIST_DIRENTRY_SIZE_LEN])
int BLI_rename(const char *from, const char *to) ATTR_NONNULL()
Definition fileops_c.cc:438
void BLI_filelist_entry_datetime_to_string(const struct stat *st, int64_t ts, bool compact, char r_time[FILELIST_DIRENTRY_TIME_LEN], char r_date[FILELIST_DIRENTRY_DATE_LEN], bool *r_is_today, bool *r_is_yesterday)
@ FILE_ATTR_HIDDEN
@ FILE_ATTR_READONLY
@ FILE_ATTR_RESTRICTED
@ FILE_ATTR_SYSTEM
@ FILE_ATTR_OFFLINE
Some types for dealing with directories.
#define FILELIST_DIRENTRY_DATE_LEN
#define FILELIST_DIRENTRY_TIME_LEN
#define LISTBASE_FOREACH(type, var, list)
MINLINE int round_fl_to_int(float a)
MINLINE int min_ii(int a, int b)
void rgba_uchar_to_float(float r_col[4], const unsigned char col_ub[4])
void rgba_float_to_uchar(unsigned char r_col[4], const float col_f[4])
MINLINE float srgb_to_grayscale(const float rgb[3])
static constexpr int image_width
static constexpr int image_height
MINLINE void copy_v4_v4_uchar(unsigned char r[4], const unsigned char a[4])
#define FILE_MAXFILE
#define FILE_MAX
#define BLI_path_join(...)
#define FILENAME_IS_CURRPAR(_n)
void void BLI_path_split_dir_part(const char *filepath, char *dir, size_t dir_maxncpy) ATTR_NONNULL(1
bool BLI_path_make_safe_filename(char *filename) ATTR_NONNULL(1)
BLI_INLINE int BLI_rcti_size_y(const struct rcti *rct)
Definition BLI_rect.h:198
void BLI_rcti_pad(struct rcti *rect, int pad_x, int pad_y)
Definition rct.cc:629
BLI_INLINE int BLI_rcti_size_x(const struct rcti *rct)
Definition BLI_rect.h:194
void BLI_rctf_rcti_copy(struct rctf *dst, const struct rcti *src)
BLI_INLINE float BLI_rctf_size_x(const struct rctf *rct)
Definition BLI_rect.h:202
#define SNPRINTF(dst, format,...)
Definition BLI_string.h:599
#define BLI_STR_FORMAT_UINT64_GROUPED_SIZE
Definition BLI_string.h:22
char * STRNCPY(char(&dst)[N], const char *src)
Definition BLI_string.h:688
size_t BLI_str_format_uint64_grouped(char dst[BLI_STR_FORMAT_UINT64_GROUPED_SIZE], uint64_t num) ATTR_NONNULL(1)
Definition string.cc:1193
unsigned char uchar
unsigned int uint
#define UNUSED_VARS_NDEBUG(...)
#define ELEM(...)
#define STREQ(a, b)
Compatibility-like things for windows.
external readfile function prototypes.
short BLO_version_from_file(const char *filepath)
Definition readfile.cc:1494
#define RPT_(msgid)
#define TIP_(msgid)
#define IFACE_(msgid)
eAssetImportMethod
@ ASSET_IMPORT_LINK
@ ASSET_LIBRARY_LOCAL
@ FILE_TYPE_BLENDER
@ FILE_TYPE_ASSET
@ FILE_TYPE_BLENDER_BACKUP
@ FILE_TYPE_MOVIE
@ FILE_TYPE_OBJECT_IO
@ FILE_TYPE_FTFONT
@ FILE_TYPE_BLENDERLIB
@ FILE_TYPE_IMAGE
@ FILE_TYPE_DIR
@ FILE_BROWSE_MODE_ASSETS
eDirEntry_SelectFlag
@ FILE_SEL_EDITING
@ FILE_SEL_HIGHLIGHTED
@ FILE_SEL_SELECTED
eFileDisplayType
@ FILE_VERTICALDISPLAY
@ FILE_IMGDISPLAY
@ FILE_SORT_INVERT
@ FILE_ASSET_IMPORT_INSTANCE_COLLECTIONS_ON_LINK
@ FILE_ASSET_IMPORT_INSTANCE_COLLECTIONS_ON_APPEND
#define FILE_MAX_LIBEXTRA
#define UI_SCALE_FAC
#define UI_ICON_SIZE
@ USER_SECTION_FILE_PATHS
int BIFIconID
Definition ED_asset.hh:29
#define FILE_LAYOUT_HOR
int ED_fileselect_layout_numfiles(FileLayout *layout, ARegion *region)
Definition filesel.cc:742
FileSelectParams * ED_fileselect_get_active_params(const SpaceFile *sfile)
Definition filesel.cc:382
int ED_fileselect_layout_offset(FileLayout *layout, int x, int y)
Definition filesel.cc:829
FileLayout * ED_fileselect_get_layout(SpaceFile *sfile, ARegion *region)
Definition filesel.cc:1149
bool ED_fileselect_is_asset_browser(const SpaceFile *sfile)
Definition filesel.cc:470
FileAssetSelectParams * ED_fileselect_get_asset_params(const SpaceFile *sfile)
Definition filesel.cc:405
FileAttributeColumnType
@ COLUMN_DATETIME
@ ATTRIBUTE_COLUMN_MAX
@ COLUMN_NAME
@ COLUMN_SIZE
void ED_fileselect_init_layout(SpaceFile *sfile, ARegion *region)
Definition filesel.cc:1038
void ED_fileselect_clear(wmWindowManager *wm, SpaceFile *sfile)
Definition filesel.cc:1298
void ED_fileselect_layout_tilepos(const FileLayout *layout, int tile, int *x, int *y)
Definition filesel.cc:881
int ED_fileselect_asset_import_method_get(const SpaceFile *sfile, const FileDirEntry *file)
Definition filesel.cc:515
void ED_region_tag_redraw(ARegion *region)
Definition area.cc:639
void immEnd()
void immUnbindProgram()
void immAttrSkip(uint attr_id)
void immVertex2f(uint attr_id, float x, float y)
void immUniformThemeColorShade(int color_id, int offset)
void immBindBuiltinProgram(eGPUBuiltinShader shader_id)
void immVertex2fv(uint attr_id, const float data[2])
GPUVertFormat * immVertexFormat()
void immUniformColor4fv(const float rgba[4])
void immUniformThemeColorBlend(int color_id1, int color_id2, float fac)
void immAttr3fv(uint attr_id, const float data[3])
void immBegin(GPUPrimType, uint vertex_len)
void imm_draw_box_wire_2d(uint pos, float x1, float y1, float x2, float y2)
void imm_draw_box_checker_2d(float x1, float y1, float x2, float y2)
void immRectf(uint pos, float x1, float y1, float x2, float y2)
@ GPU_PRIM_LINES
@ GPU_SHADER_3D_UNIFORM_COLOR
@ GPU_SHADER_3D_FLAT_COLOR
@ GPU_SHADER_3D_IMAGE_COLOR
@ GPU_BLEND_NONE
Definition GPU_state.hh:85
@ GPU_BLEND_ALPHA
Definition GPU_state.hh:87
@ GPU_BLEND_ALPHA_PREMULT
Definition GPU_state.hh:88
void GPU_blend(eGPUBlend blend)
Definition gpu_state.cc:42
@ GPU_RGBA8
@ GPU_FETCH_FLOAT
uint GPU_vertformat_attr_add(GPUVertFormat *, blender::StringRef name, GPUVertCompType, uint comp_len, GPUVertFetchMode)
@ GPU_COMP_F32
void IMB_freeImBuf(ImBuf *ibuf)
bool IMB_metadata_get_field(const IDProperty *metadata, const char *key, char *value, size_t value_maxncpy)
Definition metadata.cc:41
ImBuf * IMB_thumb_read(const char *file_or_lib_path, ThumbSize size)
Definition thumbs.cc:500
@ THB_LARGE
Definition IMB_thumbs.hh:23
@ THB_SOURCE_IMAGE
Definition IMB_thumbs.hh:28
@ THB_SOURCE_MOVIE
Definition IMB_thumbs.hh:29
ImBuf * IMB_thumb_manage(const char *file_or_lib_path, ThumbSize size, ThumbSource source)
Definition thumbs.cc:534
Read Guarded memory(de)allocation.
#define C
Definition RandGen.cpp:29
void UI_but_flag_disable(uiBut *but, int flag)
#define UI_UNIT_Y
void UI_but_drag_attach_image(uiBut *but, const ImBuf *imb, float scale)
void UI_fontstyle_draw_simple(const uiFontStyle *fs, float x, float y, const char *str, const uchar col[4])
@ UI_CNR_ALL
@ UI_CNR_NONE
void UI_but_func_tooltip_custom_set(uiBut *but, uiButToolTipCustomFunc func, void *arg, uiFreeArgFunc free_arg)
uiBlock * UI_block_begin(const bContext *C, ARegion *region, std::string name, blender::ui::EmbossType emboss)
void UI_draw_icon_tri(float x, float y, char dir, const float[4])
void UI_tooltip_image_field_add(uiTooltipData &data, const uiTooltipImage &image_data)
@ UI_BUT_ICON_LEFT
void UI_but_color_set(uiBut *but, const uchar color[4])
uiBut * uiDefBut(uiBlock *block, int type, int retval, blender::StringRef str, int x, int y, short width, short height, void *poin, float min, float max, std::optional< blender::StringRef > tip)
void UI_tooltip_text_field_add(uiTooltipData &data, std::string text, std::string suffix, const uiTooltipStyle style, const uiTooltipColorID color_id, const bool is_pad=false)
bool UI_but_is_utf8(const uiBut *but)
void UI_but_drag_set_image(uiBut *but, const char *path, int icon, const ImBuf *imb, float scale)
void UI_draw_roundbox_corner_set(int type)
void UI_fontstyle_draw_ex(const uiFontStyle *fs, const rcti *rect, const char *str, size_t str_len, const uchar col[4], const uiFontStyleDraw_Params *fs_params, int *r_xofs, int *r_yofs, ResultBLF *r_info)
eFontStyle_Align
@ UI_STYLE_TEXT_LEFT
@ UI_STYLE_TEXT_CENTER
uiBut * uiDefIconPreviewBut(uiBlock *block, int type, int retval, int icon, int x, int y, short width, short height, void *poin, float min, float max, std::optional< blender::StringRef > tip)
const uiStyle * UI_style_get()
void UI_but_dragflag_enable(uiBut *but, int flag)
void UI_but_drag_set_path(uiBut *but, const char *path)
PointerRNA * UI_but_operator_ptr_ensure(uiBut *but)
@ UI_TIP_STYLE_NORMAL
@ UI_TIP_STYLE_SPACER
@ UI_TIP_STYLE_HEADER
void UI_block_func_set(uiBlock *block, uiButHandleFunc func, void *arg1, void *arg2)
float UI_text_clip_middle_ex(const uiFontStyle *fstyle, char *str, float okwidth, float minwidth, size_t max_len, char rpart_sep, bool clip_right_if_tight=true)
void UI_but_func_rename_set(uiBut *but, uiButHandleRenameFunc func, void *arg1)
void UI_but_drawflag_disable(uiBut *but, int flag)
void UI_block_draw(const bContext *C, uiBlock *block)
uiBut * uiDefIconBut(uiBlock *block, int type, int retval, int icon, int x, int y, short width, short height, void *poin, float min, float max, std::optional< blender::StringRef > tip)
void UI_but_drag_set_asset(uiBut *but, const blender::asset_system::AssetRepresentation *asset, const AssetImportSettings &import_settings, int icon, int preview_icon)
int UI_fontstyle_string_width(const uiFontStyle *fs, const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1
void UI_fontstyle_draw_multiline_clipped(const uiFontStyle *fs, const rcti *rect, const char *str, const uchar col[4], eFontStyle_Align align)
uiBut * uiDefIconTextButO_ptr(uiBlock *block, int type, wmOperatorType *ot, wmOperatorCallContext opcontext, int icon, blender::StringRef str, int x, int y, short width, short height, std::optional< blender::StringRef > tip)
@ UI_BUT_DRAG_FULL_BUT
bool UI_but_active_only(const bContext *C, ARegion *region, uiBlock *block, uiBut *but)
void UI_fontstyle_draw(const uiFontStyle *fs, const rcti *rect, const char *str, size_t str_len, const uchar col[4], const uiFontStyleDraw_Params *fs_params)
void UI_but_label_alpha_factor_set(uiBut *but, float alpha_factor)
@ UI_TIP_LC_ALERT
@ UI_TIP_LC_MAIN
@ UI_TIP_LC_NORMAL
void UI_but_func_complete_set(uiBut *but, uiButCompleteFunc func, void *arg)
#define UI_UNIT_X
@ UI_BTYPE_BUT
@ UI_BTYPE_TEXT
@ UI_BTYPE_LABEL
void UI_but_drag_set_id(uiBut *but, ID *id)
uiBut * uiDefButR(uiBlock *block, int type, int retval, std::optional< blender::StringRef > str, int x, int y, short width, short height, PointerRNA *ptr, blender::StringRefNull propname, int index, float min, float max, std::optional< blender::StringRef > tip)
void UI_draw_roundbox_aa(const rctf *rect, bool filled, float rad, const float color[4])
void UI_but_funcN_set(uiBut *but, uiButHandleNFunc funcN, void *argN, void *arg2, uiButArgNFree func_argN_free_fn=MEM_freeN, uiButArgNCopy func_argN_copy_fn=MEM_dupallocN)
void UI_block_end(const bContext *C, uiBlock *block)
@ UI_BUT_UNDO
@ UI_BUT_DISABLED
@ UI_BUT_NO_UTF8
void UI_but_flag_enable(uiBut *but, int flag)
bool UI_but_flag_is_set(uiBut *but, int flag)
#define ICON_DEFAULT_HEIGHT
void UI_icon_draw(float x, float y, int icon_id)
#define ICON_DEFAULT_WIDTH_SCALE
#define UI_NO_ICON_OVERLAY_TEXT
#define PREVIEW_DRAG_DRAW_SIZE
#define ICON_DEFAULT_HEIGHT_SCALE
void UI_icon_draw_ex(float x, float y, int icon_id, float aspect, float alpha, float desaturate, const uchar mono_color[4], bool mono_border, const IconTextOverlay *text_overlay, const bool inverted=false)
#define ICON_DEFAULT_WIDTH
@ TH_ROW_ALTERNATE
@ TH_ICON_FOLDER
@ TH_BACK
@ TH_HILITE
@ TH_TEXT
void UI_GetThemeColorShade3fv(int colorid, int offset, float col[3])
void UI_GetThemeColor4fv(int colorid, float col[4])
void UI_GetThemeColorShade4fv(int colorid, int offset, float col[4])
@ BIFICONID_LAST_STATIC
void UI_GetThemeColor4ubv(int colorid, unsigned char col[4])
void UI_view2d_totRect_set(View2D *v2d, int width, int height)
Definition view2d.cc:1036
ReportList * reports
Definition WM_types.hh:1025
#define ND_SPACE_FILE_PREVIEW
Definition WM_types.hh:537
@ WM_OP_INVOKE_DEFAULT
Definition WM_types.hh:238
#define ND_SPACE_FILE_PARAMS
Definition WM_types.hh:520
#define NC_SPACE
Definition WM_types.hh:389
int pad[32 - sizeof(int)]
#define U
BMesh const char void * data
ATTR_WARN_UNUSED_RESULT const BMVert * v2
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
#define str(s)
static void file_draw_indicator_icons(const FileList *files, const FileDirEntry *file, const FileLayout *layout, const rcti *tile_draw_rect, const float preview_icon_aspect, const int file_type_icon, const bool has_special_file_image)
Definition file_draw.cc:833
static void draw_dividers(FileLayout *layout, View2D *v2d)
Definition file_draw.cc:990
static void draw_details_columns(const FileSelectParams *params, const FileLayout *layout, FileDirEntry *file, const rcti *tile_draw_rect, const uchar text_col[4])
static void file_but_tooltip_func_set(const SpaceFile *sfile, const FileDirEntry *file, uiBut *but)
Definition file_draw.cc:399
void file_calc_previews(const bContext *C, ARegion *region)
Definition file_draw.cc:575
static void file_draw_invalid_asset_library_hint(const bContext *C, const SpaceFile *sfile, ARegion *region, FileAssetSelectParams *asset_params)
static void draw_tile_background(const rcti *draw_rect, int colorid, int shade)
Definition file_draw.cc:346
static void file_add_preview_drag_but(const SpaceFile *sfile, uiBlock *block, FileLayout *layout, const FileDirEntry *file, const char *path, const rcti *tile_draw_rect, const ImBuf *preview_image, const int file_type_icon)
Definition file_draw.cc:616
static void file_draw_asset_tooltip_custom_func(bContext &, uiTooltipData &tip, void *argN)
Definition file_draw.cc:340
static void draw_columnheader_columns(const FileSelectParams *params, FileLayout *layout, const View2D *v2d, const uchar text_col[4])
static FileTooltipData * file_tooltip_data_create(const SpaceFile *sfile, const FileDirEntry *file)
Definition file_draw.cc:128
static void file_draw_string_multiline(int sx, int sy, const char *string, int wrap_width, int line_height, const uchar text_col[4], int *r_sx, int *r_sy)
Definition file_draw.cc:526
bool file_draw_hint_if_invalid(const bContext *C, const SpaceFile *sfile, ARegion *region)
static void file_draw_special_image(const FileDirEntry *file, const rcti *tile_draw_rect, const int file_type_icon, const float icon_aspect, const FileLayout *layout, const bool dimmed)
Definition file_draw.cc:736
static uiBut * file_add_icon_but(const SpaceFile *sfile, uiBlock *block, const char *, const FileDirEntry *file, const rcti *tile_draw_rect, int icon, int width, int height, int padx, bool dimmed)
Definition file_draw.cc:410
static void file_draw_string_mulitline_clipped(const rcti *rect, const char *string, eFontStyle_Align align, const uchar col[4])
Definition file_draw.cc:506
static uiBut * file_add_overlay_icon_but(uiBlock *block, int pos_x, int pos_y, int icon)
Definition file_draw.cc:445
static void file_draw_preview(const FileDirEntry *file, const rcti *tile_draw_rect, const ImBuf *imb, FileLayout *layout, const bool dimmed)
Definition file_draw.cc:653
static void file_draw_tooltip_custom_func(bContext &, uiTooltipData &tip, void *argN)
Definition file_draw.cc:136
static void draw_columnheader_background(const FileLayout *layout, const View2D *v2d)
static void renamebutton_cb(bContext *C, void *, char *oldname)
Definition file_draw.cc:917
static rcti tile_draw_rect_get(const View2D *v2d, const FileLayout *layout, const int file_idx)
void ED_file_path_button(bScreen *screen, const SpaceFile *sfile, FileSelectParams *params, uiBlock *block)
Definition file_draw.cc:76
static rcti text_draw_rect_get(const View2D *v2d, const eFileDisplayType display_type, const FileLayout *layout, const int file_idx, const int icon_ofs_x)
static void draw_background(FileLayout *layout, View2D *v2d)
Definition file_draw.cc:961
static const char * filelist_get_details_column_string(FileAttributeColumnType column, FileDirEntry *file, const bool compact, const bool update_stat_strings)
static std::tuple< int, int, float > preview_image_scaled_dimensions_get(const int image_width, const int image_height, const FileLayout &layout)
Definition file_draw.cc:584
static void file_draw_string(int sx, int sy, const char *string, float width, int height, eFontStyle_Align align, const uchar col[4])
Definition file_draw.cc:468
void file_draw_list(const bContext *C, ARegion *region)
static void file_draw_invalid_library_hint(const bContext *, const SpaceFile *sfile, ARegion *region, const char *blendfile_path, ReportList *reports)
static void file_draw_loading_icon(const rcti *tile_draw_rect, const float preview_icon_aspect, const FileLayout *layout)
Definition file_draw.cc:810
static void file_but_enable_drag(uiBut *but, const SpaceFile *sfile, const FileDirEntry *file, const char *path, const ImBuf *preview_image, int icon, float scale)
Definition file_draw.cc:357
void file_path_to_ui_path(const char *path, char *r_path, int r_path_maxncpy)
Definition file_utils.cc:32
bool file_attribute_column_type_enabled(const FileSelectParams *params, FileAttributeColumnType column, const FileLayout *layout)
Definition filesel.cc:907
void file_params_rename_end(wmWindowManager *wm, wmWindow *win, SpaceFile *sfile, const FileDirEntry *rename_file)
Definition filesel.cc:1380
void file_params_invoke_rename_postscroll(wmWindowManager *wm, wmWindow *win, SpaceFile *sfile)
Definition filesel.cc:1367
int autocomplete_directory(bContext *C, char *str, void *arg_v)
Definition filesel.cc:1230
#define FILE_LAYOUT_COMPACT(_layout)
void file_directory_enter_handle(bContext *C, void *arg_unused, void *arg_but)
Definition file_ops.cc:2888
#define ATTRIBUTE_COLUMN_PADDING
void file_draw_check_cb(bContext *C, void *arg1, void *arg2)
Definition file_ops.cc:1772
int filelist_files_num_entries(FileList *filelist)
Definition filelist.cc:2015
bool filelist_islibrary(FileList *filelist, char *dir, char **r_group)
Definition filelist.cc:3017
BlendHandle * filelist_lib(FileList *filelist)
Definition filelist.cc:2010
bool filelist_file_is_preview_pending(const FileList *filelist, const FileDirEntry *file)
Definition filelist.cc:1163
bool filelist_cache_previews_running(FileList *filelist)
Definition filelist.cc:2709
bool filelist_file_cache_block(FileList *filelist, const int index)
Definition filelist.cc:2410
bool filelist_cache_previews_done(FileList *filelist)
Definition filelist.cc:2716
ImBuf * filelist_get_preview_image(FileList *filelist, const int index)
Definition filelist.cc:1178
ImBuf * filelist_geticon_special_file_image_ex(const FileDirEntry *file)
Definition filelist.cc:1199
ID * filelist_file_get_id(const FileDirEntry *file)
Definition filelist.cc:2315
bool filelist_cache_previews_update(FileList *filelist)
Definition filelist.cc:2651
int filelist_geticon_file_type(FileList *filelist, const int index, const bool is_main)
Definition filelist.cc:1341
void filelist_file_cache_slidingwindow_set(FileList *filelist, size_t window_size)
Definition filelist.cc:2348
ImBuf * filelist_file_get_preview_image(const FileDirEntry *file)
Definition filelist.cc:1185
bool filelist_is_dir(const FileList *filelist, const char *path)
Definition filelist.cc:2070
int filelist_files_ensure(FileList *filelist)
Definition filelist.cc:2138
void filelist_file_get_full_path(const FileList *filelist, const FileDirEntry *file, char r_filepath[FILE_MAX_LIBEXTRA])
Definition filelist.cc:1149
FileDirEntry * filelist_file(FileList *filelist, int index)
Definition filelist.cc:2255
bool filelist_is_ready(const FileList *filelist)
Definition filelist.cc:2123
eDirEntry_SelectFlag filelist_entry_select_get(FileList *filelist, FileDirEntry *entry, FileCheckType check)
Definition filelist.cc:2963
@ CHECK_ALL
Definition filelist.hh:44
uint pos
uint col
VecBase< float, D > step(VecOp< float, D >, VecOp< float, D >) RET
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
format
void * MEM_mallocN(size_t len, const char *str)
Definition mallocn.cc:128
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
static ulong state[N]
void asset_tooltip(const asset_system::AssetRepresentation &asset, uiTooltipData &tip, const bool include_name)
BIFIconID asset_preview_or_icon(const asset_system::AssetRepresentation &asset)
void RNA_enum_set(PointerRNA *ptr, const char *name, int value)
PointerRNA RNA_pointer_create_discrete(ID *id, StructRNA *type, void *data)
eAssetImportMethod method
AssetLibraryReference asset_library_ref
FileSelectParams base_params
char datetime_str[16+8]
AssetRepresentationHandle * asset
char * redirection_path
const char * name
struct FileDirEntry::@222065214376236372341127200120273075020053120355 draw_data
FileAttributeColumn attribute_columns[ATTRIBUTE_COLUMN_MAX]
int attribute_column_header_h
const FileDirEntry * file
Definition file_draw.cc:125
const SpaceFile * sfile
Definition file_draw.cc:124
Definition DNA_ID.h:404
ImBufByteBuffer byte_buffer
IDProperty * metadata
ReportList is_blendfile_readable_reports
struct FileLayout * layout
struct FileList * files
struct wmTimer * previews_timer
FileAssetSelectParams * asset_params
SpaceFile_Runtime * runtime
float xmax
float xmin
float ymax
float ymin
int ymin
int ymax
int xmin
int xmax
uiFontStyle widget
i
Definition text_draw.cc:230
uint len
#define N_(msgid)
void WM_event_add_notifier_ex(wmWindowManager *wm, const wmWindow *win, uint type, void *reference)
void WM_global_reportf(eReportType type, const char *format,...)
void WM_report_banner_show(wmWindowManager *wm, wmWindow *win)
wmOperatorType * ot
Definition wm_files.cc:4225
std::string WM_operatortype_name(wmOperatorType *ot, PointerRNA *properties)
wmOperatorType * WM_operatortype_find(const char *idname, bool quiet)
wmTimer * WM_event_timer_add_notifier(wmWindowManager *wm, wmWindow *win, const uint type, const double time_step)
void WM_event_timer_remove_notifier(wmWindowManager *wm, wmWindow *win, wmTimer *timer)