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')
-rw-r--r--source/blender/editors/include/UI_grid_view.hh6
-rw-r--r--source/blender/editors/include/UI_interface.h10
-rw-r--r--source/blender/editors/include/UI_interface_icons.h3
-rw-r--r--source/blender/editors/interface/interface.cc55
-rw-r--r--source/blender/editors/interface/interface_icons.c26
-rw-r--r--source/blender/editors/interface/interface_intern.h3
-rw-r--r--source/blender/editors/interface/interface_widgets.c56
-rw-r--r--source/blender/editors/interface/views/grid_view.cc36
-rw-r--r--source/blender/editors/space_file/CMakeLists.txt1
-rw-r--r--source/blender/editors/space_file/file_draw.c37
-rw-r--r--source/blender/editors/space_file/file_intern.h8
-rw-r--r--source/blender/editors/space_file/file_view_grid.cc190
-rw-r--r--source/blender/editors/space_file/filelist.c5
-rw-r--r--source/blender/editors/space_file/filelist.h1
-rw-r--r--source/blender/editors/space_file/space_file.c8
15 files changed, 398 insertions, 47 deletions
diff --git a/source/blender/editors/include/UI_grid_view.hh b/source/blender/editors/include/UI_grid_view.hh
index 402c0c8512f..2d5b5f941ed 100644
--- a/source/blender/editors/include/UI_grid_view.hh
+++ b/source/blender/editors/include/UI_grid_view.hh
@@ -194,7 +194,11 @@ class PreviewGridItem : public AbstractGridViewItem {
std::string label{};
int preview_icon_id = ICON_NONE;
- PreviewGridItem(StringRef identifier, StringRef label, int preview_icon_id);
+ PreviewGridItem(StringRef identifier, StringRef label, int preview_icon_id = ICON_NONE);
+
+ uiBut *add_preview_button(uiLayout &layout,
+ int preview_icon_id,
+ const uchar mono_color[4] = nullptr) const;
void build_grid_tile(uiLayout &layout) const override;
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index a8d25b75036..20f2a553a52 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -1228,6 +1228,15 @@ uiBut *uiDefIconButO_ptr(uiBlock *block,
short width,
short height,
const char *tip);
+uiBut *uiDefButPadding(uiBlock *block, int x, int y, short width, short height);
+uiBut *uiDefButPreviewTile(uiBlock *block,
+ int preview_icon_id,
+ const char *label,
+ int x,
+ int y,
+ short width,
+ short height,
+ const uchar mono_color[4]);
uiBut *uiDefButImage(
uiBlock *block, void *imbuf, int x, int y, short width, short height, const uchar color[4]);
uiBut *uiDefButAlert(uiBlock *block, int icon, int x, int y, short width, short height);
@@ -1746,6 +1755,7 @@ struct PointerRNA *UI_but_extra_operator_icon_opptr_get(struct uiButExtraOpIcon
int UI_preview_tile_size_x(void);
int UI_preview_tile_size_y(void);
int UI_preview_tile_size_y_no_label(void);
+rcti UI_preview_tile_but_preview_rect_get(const uiBut *but);
/* Autocomplete
*
diff --git a/source/blender/editors/include/UI_interface_icons.h b/source/blender/editors/include/UI_interface_icons.h
index a1a98a4b08c..1cfec698680 100644
--- a/source/blender/editors/include/UI_interface_icons.h
+++ b/source/blender/editors/include/UI_interface_icons.h
@@ -96,7 +96,8 @@ int UI_icon_preview_to_render_size(enum eIconSizes size);
*/
void UI_icon_draw(float x, float y, int icon_id);
void UI_icon_draw_alpha(float x, float y, int icon_id, float alpha);
-void UI_icon_draw_preview(float x, float y, int icon_id, float aspect, float alpha, int size);
+void UI_icon_draw_preview(
+ float x, float y, int icon_id, float aspect, float alpha, int size, const uchar mono_color[4]);
void UI_icon_draw_ex(float x,
float y,
diff --git a/source/blender/editors/interface/interface.cc b/source/blender/editors/interface/interface.cc
index 2f9e69137ed..b6d212b891e 100644
--- a/source/blender/editors/interface/interface.cc
+++ b/source/blender/editors/interface/interface.cc
@@ -4826,6 +4826,37 @@ uiBut *uiDefBut(uiBlock *block,
return but;
}
+uiBut *uiDefButPadding(uiBlock *block, int x, int y, short width, short height)
+{
+ uiBut *but = ui_def_but(
+ block, UI_BTYPE_LABEL, 0, "", x, y, width, height, nullptr, 0, 0, 0, 0, "");
+ ui_but_update(but);
+ return but;
+}
+
+uiBut *uiDefButPreviewTile(uiBlock *block,
+ int preview_icon_id,
+ const char *label,
+ int x,
+ int y,
+ short width,
+ short height,
+ const uchar mono_color[4])
+{
+ uiBut *but = ui_def_but(
+ block, UI_BTYPE_PREVIEW_TILE, 0, label, x, y, width, height, nullptr, 0, 0, 0, 0, "");
+ ui_def_but_icon(but,
+ preview_icon_id,
+ /* NOLINTNEXTLINE: bugprone-suspicious-enum-usage */
+ UI_HAS_ICON | UI_BUT_ICON_PREVIEW);
+ if (mono_color) {
+ copy_v4_v4_uchar(but->col, mono_color);
+ }
+
+ ui_but_update(but);
+ return but;
+}
+
uiBut *uiDefButImage(
uiBlock *block, void *imbuf, int x, int y, short width, short height, const uchar color[4])
{
@@ -4993,6 +5024,30 @@ int UI_preview_tile_size_y_no_label(void)
return round_fl_to_int((96.0f / 20.0f) * UI_UNIT_Y + 2.0f * pad);
}
+#define PREVIEW_PAD 4
+
+rcti UI_preview_tile_but_preview_rect_get(const uiBut *but)
+{
+ rcti rect;
+
+ BLI_rcti_rctf_copy_round(&rect, &but->rect);
+
+ if (but->drawstr[0]) {
+ const uiStyle *style = UI_style_get();
+ const uiFontStyle *fstyle = &style->widget;
+ float font_dims[2] = {0.0f, 0.0f};
+
+ UI_fontstyle_set(fstyle);
+ BLF_width_and_height(
+ fstyle->uifont_id, but->drawstr, BLF_DRAW_STR_DUMMY_MAX, &font_dims[0], &font_dims[1]);
+ /* draw icon in rect above the space reserved for the label */
+ rect.ymin += round_fl_to_int(font_dims[1] + 2 * PREVIEW_PAD);
+ }
+
+ return ui_preview_draw_rect_get(&rect);
+}
+
+#undef PREVIEW_PAD
#undef PREVIEW_TILE_PAD
static void ui_but_update_and_icon_set(uiBut *but, int icon)
diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c
index c19e842aad8..71bd61764c0 100644
--- a/source/blender/editors/interface/interface_icons.c
+++ b/source/blender/editors/interface/interface_icons.c
@@ -1503,6 +1503,7 @@ static void icon_draw_rect(float x,
int rh,
uint *rect,
float alpha,
+ const uchar mono_rgba[4],
const float desaturate)
{
int draw_w = w;
@@ -1518,7 +1519,12 @@ static void icon_draw_rect(float x,
return;
}
/* modulate color */
- const float col[4] = {alpha, alpha, alpha, alpha};
+ float col[4] = {alpha, alpha, alpha, alpha};
+ if (mono_rgba) {
+ /* Optionally use a mono color to recolor the image. */
+ rgba_uchar_to_float(col, mono_rgba);
+ mul_v4_fl(col, alpha);
+ }
float scale_x = 1.0f;
float scale_y = 1.0f;
@@ -1813,9 +1819,10 @@ static void icon_draw_size(float x,
if (di->type == ICON_TYPE_IMBUF) {
ImBuf *ibuf = icon->obj;
- GPU_blend(GPU_BLEND_ALPHA_PREMULT);
- icon_draw_rect(x, y, w, h, aspect, ibuf->x, ibuf->y, ibuf->rect, alpha, desaturate);
- GPU_blend(GPU_BLEND_ALPHA);
+ /* TODO preview images are premultiplied apparently (see ICON_TYPE_PREVIEW). */
+ // GPU_blend(GPU_BLEND_ALPHA_PREMULT);
+ icon_draw_rect(x, y, w, h, aspect, ibuf->x, ibuf->y, ibuf->rect, alpha, mono_rgba, desaturate);
+ // GPU_blend(GPU_BLEND_ALPHA);
}
else if (di->type == ICON_TYPE_VECTOR) {
/* vector icons use the uiBlock transformation, they are not drawn
@@ -1854,7 +1861,7 @@ static void icon_draw_size(float x,
}
GPU_blend(GPU_BLEND_ALPHA_PREMULT);
- icon_draw_rect(x, y, w, h, aspect, w, h, ibuf->rect, alpha, desaturate);
+ icon_draw_rect(x, y, w, h, aspect, w, h, ibuf->rect, alpha, NULL, desaturate);
GPU_blend(GPU_BLEND_ALPHA);
}
else if (di->type == ICON_TYPE_EVENT) {
@@ -1922,7 +1929,7 @@ static void icon_draw_size(float x,
return;
}
- icon_draw_rect(x, y, w, h, aspect, iimg->w, iimg->h, iimg->rect, alpha, desaturate);
+ icon_draw_rect(x, y, w, h, aspect, iimg->w, iimg->h, iimg->rect, alpha, NULL, desaturate);
}
else if (di->type == ICON_TYPE_PREVIEW) {
PreviewImage *pi = (icon->id_type != 0) ? BKE_previewimg_id_ensure((ID *)icon->obj) :
@@ -1938,7 +1945,7 @@ static void icon_draw_size(float x,
/* Preview images use premultiplied alpha. */
GPU_blend(GPU_BLEND_ALPHA_PREMULT);
icon_draw_rect(
- x, y, w, h, aspect, pi->w[size], pi->h[size], pi->rect[size], alpha, desaturate);
+ x, y, w, h, aspect, pi->w[size], pi->h[size], pi->rect[size], alpha, NULL, desaturate);
GPU_blend(GPU_BLEND_ALPHA);
}
}
@@ -2433,9 +2440,10 @@ void UI_icon_draw_alpha(float x, float y, int icon_id, float alpha)
UI_icon_draw_ex(x, y, icon_id, U.inv_dpi_fac, alpha, 0.0f, NULL, false);
}
-void UI_icon_draw_preview(float x, float y, int icon_id, float aspect, float alpha, int size)
+void UI_icon_draw_preview(
+ float x, float y, int icon_id, float aspect, float alpha, int size, const uchar mono_color[4])
{
- icon_draw_size(x, y, icon_id, aspect, alpha, ICON_SIZE_PREVIEW, size, false, NULL, false);
+ icon_draw_size(x, y, icon_id, aspect, alpha, ICON_SIZE_PREVIEW, size, 0.0f, mono_color, false);
}
void UI_icon_draw_ex(float x,
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index 03b9d03a6e3..ade238a86ef 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -1236,6 +1236,8 @@ void ui_draw_preview_item(const struct uiFontStyle *fstyle,
int iconid,
int but_flag,
eFontStyle_Align text_align);
+rcti ui_preview_draw_rect_get(const rcti *bounds_rect);
+
/**
* Version of #ui_draw_preview_item() that does not draw the menu background and item text based on
* state. It just draws the preview and text directly.
@@ -1245,6 +1247,7 @@ void ui_draw_preview_item_stateless(const struct uiFontStyle *fstyle,
const char *name,
int iconid,
const uchar text_col[4],
+ const uchar mono_col[4],
eFontStyle_Align text_align);
#define UI_TEXT_MARGIN_X 0.4f
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index c939ba461c9..b0400f687aa 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -1316,22 +1316,40 @@ static float widget_alpha_factor(const uiWidgetStateInfo *state)
return 1.0f;
}
-static void widget_draw_preview(BIFIconID icon, float alpha, const rcti *rect)
+rcti ui_preview_draw_rect_get(const rcti *bounds_rect)
{
- if (icon == ICON_NONE) {
- return;
+ const int max_width = BLI_rcti_size_x(bounds_rect);
+ const int max_height = BLI_rcti_size_y(bounds_rect);
+
+ rcti rect = {0};
+
+ const int draw_size = MIN2(max_width, max_height) - PREVIEW_PAD * 2;
+ if (draw_size > 0) {
+ rect.xmin = bounds_rect->xmin + max_width / 2 - draw_size / 2;
+ rect.ymin = bounds_rect->ymin + max_height / 2 - draw_size / 2;
+ rect.xmax = rect.xmin + draw_size;
+ rect.ymax = rect.ymin + draw_size;
}
- const int w = BLI_rcti_size_x(rect);
- const int h = BLI_rcti_size_y(rect);
- const int size = MIN2(w, h) - PREVIEW_PAD * 2;
+ return rect;
+}
- if (size > 0) {
- const int x = rect->xmin + w / 2 - size / 2;
- const int y = rect->ymin + h / 2 - size / 2;
+static void widget_draw_preview(BIFIconID icon,
+ float alpha,
+ const rcti *rect,
+ const uchar mono_color[4])
+{
+ if (icon == ICON_NONE) {
+ return;
+ }
- UI_icon_draw_preview(x, y, icon, 1.0f, alpha, size);
+ const rcti draw_rect = ui_preview_draw_rect_get(rect);
+ if (BLI_rcti_is_empty(&draw_rect)) {
+ return;
}
+
+ UI_icon_draw_preview(
+ draw_rect.xmin, draw_rect.ymin, icon, 1.0f, alpha, BLI_rcti_size_x(&draw_rect), mono_color);
}
static int ui_but_draw_menu_icon(const uiBut *but)
@@ -1346,7 +1364,7 @@ static void widget_draw_icon(
{
if (but->flag & UI_BUT_ICON_PREVIEW) {
GPU_blend(GPU_BLEND_ALPHA);
- widget_draw_preview(icon, alpha, rect);
+ widget_draw_preview(icon, alpha, rect, mono_color);
GPU_blend(GPU_BLEND_NONE);
return;
}
@@ -2313,7 +2331,7 @@ static void widget_draw_text_icon(const uiFontStyle *fstyle,
/* draw icon in rect above the space reserved for the label */
rect->ymin += text_size;
GPU_blend(GPU_BLEND_ALPHA);
- widget_draw_preview(icon, alpha, rect);
+ widget_draw_preview(icon, alpha, rect, but->col[3] != 0 ? but->col : NULL);
GPU_blend(GPU_BLEND_NONE);
/* offset rect to draw label in */
@@ -4002,8 +4020,13 @@ static void widget_preview_tile(uiBut *but,
const float UNUSED(zoom))
{
const uiStyle *style = UI_style_get();
- ui_draw_preview_item_stateless(
- &style->widget, rect, but->drawstr, but->icon, wcol->text, UI_STYLE_TEXT_CENTER);
+ ui_draw_preview_item_stateless(&style->widget,
+ rect,
+ but->drawstr,
+ but->icon,
+ wcol->text,
+ but->col[3] ? but->col : NULL,
+ UI_STYLE_TEXT_CENTER);
}
static void widget_menuiconbut(uiWidgetColors *wcol,
@@ -5510,6 +5533,7 @@ void ui_draw_preview_item_stateless(const uiFontStyle *fstyle,
const char *name,
int iconid,
const uchar text_col[4],
+ const uchar mono_col[4],
eFontStyle_Align text_align)
{
rcti trect = *rect;
@@ -5526,7 +5550,7 @@ void ui_draw_preview_item_stateless(const uiFontStyle *fstyle,
rect->ymin += round_fl_to_int(font_dims[1] + 2 * padding);
}
GPU_blend(GPU_BLEND_ALPHA);
- widget_draw_preview(iconid, 1.0f, rect);
+ widget_draw_preview(iconid, 1.0f, rect, mono_col);
GPU_blend(GPU_BLEND_NONE);
if (!has_text) {
@@ -5573,7 +5597,7 @@ void ui_draw_preview_item(const uiFontStyle *fstyle,
wt->state(wt, &state, UI_EMBOSS_UNDEFINED);
wt->draw(&wt->wcol, rect, &STATE_INFO_NULL, 0, 1.0f);
- ui_draw_preview_item_stateless(fstyle, rect, name, iconid, wt->wcol.text, text_align);
+ ui_draw_preview_item_stateless(fstyle, rect, name, iconid, wt->wcol.text, NULL, text_align);
}
/** \} */
diff --git a/source/blender/editors/interface/views/grid_view.cc b/source/blender/editors/interface/views/grid_view.cc
index 52ff1460cbd..edc33fcf944 100644
--- a/source/blender/editors/interface/views/grid_view.cc
+++ b/source/blender/editors/interface/views/grid_view.cc
@@ -8,6 +8,7 @@
#include <stdexcept>
#include "BLI_index_range.hh"
+#include "BLI_math_vector.h"
#include "WM_types.h"
@@ -410,29 +411,26 @@ PreviewGridItem::PreviewGridItem(StringRef identifier, StringRef label, int prev
{
}
-void PreviewGridItem::build_grid_tile(uiLayout &layout) const
+uiBut *PreviewGridItem::add_preview_button(uiLayout &layout,
+ const int preview_icon_id,
+ const uchar mono_color[4]) const
{
const GridViewStyle &style = get_view().get_style();
uiBlock *block = uiLayoutGetBlock(&layout);
- uiBut *but = uiDefBut(block,
- UI_BTYPE_PREVIEW_TILE,
- 0,
- label.c_str(),
- 0,
- 0,
- style.tile_width,
- style.tile_height,
- nullptr,
- 0,
- 0,
- 0,
- 0,
- "");
- ui_def_but_icon(but,
- preview_icon_id,
- /* NOLINTNEXTLINE: bugprone-suspicious-enum-usage */
- UI_HAS_ICON | UI_BUT_ICON_PREVIEW);
+ return uiDefButPreviewTile(block,
+ preview_icon_id,
+ label.c_str(),
+ 0,
+ 0,
+ style.tile_width,
+ style.tile_height,
+ mono_color);
+}
+
+void PreviewGridItem::build_grid_tile(uiLayout &layout) const
+{
+ add_preview_button(layout, preview_icon_id);
}
void PreviewGridItem::set_on_activate_fn(ActivateFn fn)
diff --git a/source/blender/editors/space_file/CMakeLists.txt b/source/blender/editors/space_file/CMakeLists.txt
index b8c28e354da..e932feef2aa 100644
--- a/source/blender/editors/space_file/CMakeLists.txt
+++ b/source/blender/editors/space_file/CMakeLists.txt
@@ -28,6 +28,7 @@ set(SRC
file_ops.c
file_panels.c
file_utils.c
+ file_view_grid.cc
filelist.c
filesel.c
fsmenu.c
diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c
index f3359336b14..8a0f40f9045 100644
--- a/source/blender/editors/space_file/file_draw.c
+++ b/source/blender/editors/space_file/file_draw.c
@@ -1161,3 +1161,40 @@ bool file_draw_hint_if_invalid(const bContext *C, const SpaceFile *sfile, ARegio
return true;
}
+
+void file_view_preview_grid_draw(const bContext *C, ARegion *region)
+{
+ SpaceFile *sfile = CTX_wm_space_file(C);
+ // bScreen *screen = CTX_wm_screen(C);
+ View2D *v2d = &region->v2d;
+
+ const uiStyle *style = UI_style_get_dpi();
+ const float padding = style->panelouter;
+ uiBlock *block = UI_block_begin(C, region, __func__, UI_EMBOSS);
+ uiLayout *layout = UI_block_layout(
+ block,
+ UI_LAYOUT_VERTICAL,
+ UI_LAYOUT_PANEL,
+ padding,
+ -padding,
+ /* 3x (instead of 2x) padding to add extra space for the scrollbar on the right. */
+ region->winx - 3 * padding,
+ 1,
+ 0,
+ style);
+
+ // PointerRNA asset_space_ptr;
+ // RNA_pointer_create(&screen->id, &RNA_SpaceAssetBrowser, asset_space, &asset_space_ptr);
+ // PropertyRNA *active_asset_idx_prop = RNA_struct_find_property(&asset_space_ptr,
+ // "active_asset_idx");
+
+ file_grid_view_create_in_layout(sfile->files, v2d, layout);
+
+ /* Update main region View2d dimensions. */
+ int layout_width, layout_height;
+ UI_block_layout_resolve(block, &layout_width, &layout_height);
+ UI_view2d_totRect_set(v2d, layout_width, layout_height);
+
+ UI_block_end(C, block);
+ UI_block_draw(C, block);
+}
diff --git a/source/blender/editors/space_file/file_intern.h b/source/blender/editors/space_file/file_intern.h
index ce0a2e8fc04..50493b4865c 100644
--- a/source/blender/editors/space_file/file_intern.h
+++ b/source/blender/editors/space_file/file_intern.h
@@ -19,6 +19,7 @@ struct ARegion;
struct ARegionType;
struct AssetLibrary;
struct FileAssetSelectParams;
+struct FileList;
struct FileSelectParams;
struct SpaceFile;
struct View2D;
@@ -38,6 +39,7 @@ void file_draw_list(const bContext *C, ARegion *region);
* \return true if the list is invalid and a hint was drawn.
*/
bool file_draw_hint_if_invalid(const bContext *C, const SpaceFile *sfile, ARegion *region);
+void file_view_preview_grid_draw(const bContext *C, ARegion *region);
void file_draw_check_ex(bContext *C, struct ScrArea *area);
void file_draw_check(bContext *C);
@@ -196,6 +198,12 @@ void file_tile_boundbox(const ARegion *region, FileLayout *layout, int file, rct
*/
void file_path_to_ui_path(const char *path, char *r_pathi, int max_size);
+/* file_view_grid.cc */
+
+void file_grid_view_create_in_layout(struct FileList *files,
+ const View2D *v2d,
+ struct uiLayout *layout);
+
/* asset_catalog_tree_view.cc */
void file_create_asset_catalog_tree_view_in_layout(struct AssetLibrary *asset_library,
diff --git a/source/blender/editors/space_file/file_view_grid.cc b/source/blender/editors/space_file/file_view_grid.cc
new file mode 100644
index 00000000000..348ec921e0c
--- /dev/null
+++ b/source/blender/editors/space_file/file_view_grid.cc
@@ -0,0 +1,190 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+/** \file
+ * \ingroup spfile
+ */
+
+#include "DNA_ID_enums.h"
+#include "DNA_screen_types.h"
+#include "DNA_space_types.h"
+
+#include "BKE_context.h"
+#include "BKE_icons.h"
+
+#include "BLI_fileops.h"
+#include "BLI_math_vector.h"
+#include "BLI_rect.h"
+
+/* TODO temp for static ImBuf -> icon_id map. */
+#include "BLI_map.hh"
+#include "IMB_imbuf.h"
+
+#include "ED_fileselect.h"
+
+#include "UI_grid_view.hh"
+#include "UI_interface.h"
+#include "UI_interface.hh"
+
+#include "file_intern.h"
+#include "filelist.h"
+
+namespace blender::ed::file_browser {
+
+class FilePreviewGridView : public ui::AbstractGridView {
+ friend class FilePreviewGridItem;
+
+ FileList &files_;
+
+ public:
+ FilePreviewGridView(FileList &filelist);
+ void build_items() override;
+
+ BIFIconID file_preview_icon_id_get(const FileDirEntry &file);
+};
+
+class FilePreviewGridItem : public ui::PreviewGridItem {
+ const FileDirEntry &file_;
+ std::string file_identifier_;
+ /* Index in the file list. */
+ const int file_idx_;
+
+ public:
+ FilePreviewGridItem(const FileDirEntry &file, int file_idx);
+
+ void build_grid_tile(uiLayout &layout) const override;
+
+ FileList &get_file_list() const;
+ void icon_mono_color_get(uchar r_mono_color[4]);
+ void add_big_combined_file_icon(uiLayout &overlap) const;
+};
+
+FilePreviewGridView::FilePreviewGridView(FileList &files) : files_(files)
+{
+}
+
+void FilePreviewGridView::build_items()
+{
+
+ const int numfiles = filelist_files_ensure(&files_);
+
+ for (int file_idx = 0; file_idx < numfiles; file_idx++) {
+ const FileDirEntry *file = filelist_file(&files_, file_idx);
+
+ add_item<FilePreviewGridItem>(*file, file_idx);
+ }
+}
+
+FilePreviewGridItem::FilePreviewGridItem(const FileDirEntry &file, const int file_idx)
+ : ui::PreviewGridItem(file.relpath, file.name),
+ file_(file),
+ /* Get a copy so the identifier is always available (the file data may be freed). */
+ file_identifier_(identifier_),
+ file_idx_(file_idx)
+{
+ /* Update reference so we don't point into the possibly freed file data. */
+ /* TODO always store the identifier as std::string in the item base class? Avoids these issues.
+ */
+ identifier_ = file_identifier_;
+}
+
+FileList &FilePreviewGridItem::get_file_list() const
+{
+ const FilePreviewGridView &view = dynamic_cast<const FilePreviewGridView &>(get_view());
+ return view.files_;
+}
+
+static BIFIconID file_big_file_icon_get(const FileDirEntry &file)
+{
+ /* TODO temp!! Needs proper lifetime/memory management */
+ static Map<const ImBuf *, BIFIconID> imbuf_icon_map;
+
+ ImBuf *imb = filelist_file_geticon_image(&file);
+ return imbuf_icon_map.lookup_or_add_cb(imb,
+ [&]() { return (BIFIconID)BKE_icon_imbuf_create(imb); });
+}
+
+static void file_icon_mono_color_get(const FileDirEntry &file, uchar r_col[4])
+{
+ uchar col[4] = {255, 255, 255, 255};
+ if (file.typeflag & FILE_TYPE_DIR) {
+ UI_GetThemeColor4ubv(TH_ICON_FOLDER, col);
+ }
+ else {
+ UI_GetThemeColor4ubv(TH_TEXT, col);
+ }
+
+ const bool is_hidden = (file.attributes & FILE_ATTR_HIDDEN);
+ if (is_hidden) {
+ col[3] *= 0.3f;
+ }
+
+ copy_v4_v4_uchar(r_col, col);
+}
+
+void FilePreviewGridItem::add_big_combined_file_icon(uiLayout &layout) const
+{
+ uiLayout *overlap = uiLayoutOverlap(&layout);
+
+ BIFIconID file_icon_id = file_big_file_icon_get(file_);
+ uiBut *preview_but = nullptr;
+ if (file_icon_id != ICON_NONE) {
+ uchar mono_col[4];
+ file_icon_mono_color_get(file_, mono_col);
+
+ preview_but = add_preview_button(*overlap, file_icon_id, mono_col);
+ }
+
+ /* Smaller file type icon in the middle of image, scaled to fit container and UI scale */
+ {
+ float icon_opacity = 0.3f;
+ uchar icon_color[4] = {0, 0, 0, 255};
+ float bgcolor[4];
+ UI_GetThemeColor4fv(TH_ICON_FOLDER, bgcolor);
+ if (rgb_to_grayscale(bgcolor) < 0.5f) {
+ icon_color[0] = 255;
+ icon_color[1] = 255;
+ icon_color[2] = 255;
+ }
+ icon_color[3] *= icon_opacity;
+
+ FileList &files = get_file_list();
+ const int icon_id = filelist_geticon(&files, file_idx_, false);
+
+ // uiLayoutSetAlignment(col, UI_LAYOUT_ALIGN_CENTER);
+ const ui::GridViewStyle &style = get_view().get_style();
+ int icon_size = style.tile_width / 3.5f;
+
+ uiLayout *col = uiLayoutColumn(overlap, false);
+ uiBlock *block = uiLayoutGetBlock(col);
+
+ /* Add padding to vertically center the icon. */
+ const rcti preview_img_rect = UI_preview_tile_but_preview_rect_get(preview_but);
+ const int icon_ofs_y = style.tile_height - BLI_rcti_cent_y(&preview_img_rect) -
+ (icon_size * ((file_.typeflag & FILE_TYPE_DIR) ? 0.78f : 0.75f)) / 2;
+ uiDefButPadding(block, 0, 0, 0, icon_ofs_y);
+ uiDefButPreviewTile(block, icon_id, "", 0, 0, icon_size, icon_size, icon_color);
+ }
+}
+
+void FilePreviewGridItem::build_grid_tile(uiLayout &layout) const
+{
+ uiLayout &overlap = *uiLayoutOverlap(&layout);
+ add_big_combined_file_icon(overlap);
+}
+
+} // namespace blender::ed::file_browser
+
+namespace ui = blender::ui;
+using namespace blender::ed::file_browser;
+
+void file_grid_view_create_in_layout(FileList *files, const View2D *v2d, uiLayout *layout)
+{
+ uiBlock *block = uiLayoutGetBlock(layout);
+ UI_block_layout_set_current(block, layout);
+
+ ui::AbstractGridView *grid_view = UI_block_add_view(
+ *block, "file preview grid view", std::make_unique<FilePreviewGridView>(*files));
+
+ ui::GridViewBuilder builder(*block);
+ builder.build_grid_view(*grid_view, *v2d);
+}
diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c
index 1859e7ccdfc..4b3873bac64 100644
--- a/source/blender/editors/space_file/filelist.c
+++ b/source/blender/editors/space_file/filelist.c
@@ -1331,6 +1331,11 @@ ImBuf *filelist_geticon_image(struct FileList *filelist, const int index)
return filelist_geticon_image_ex(file);
}
+ImBuf *filelist_file_geticon_image(const FileDirEntry *file)
+{
+ return filelist_geticon_image_ex(file);
+}
+
static int filelist_geticon_ex(const FileDirEntry *file,
const char *root,
const bool is_main,
diff --git a/source/blender/editors/space_file/filelist.h b/source/blender/editors/space_file/filelist.h
index d8297226a8d..fc86744c6ba 100644
--- a/source/blender/editors/space_file/filelist.h
+++ b/source/blender/editors/space_file/filelist.h
@@ -85,6 +85,7 @@ struct ImBuf *filelist_getimage(struct FileList *filelist, int index);
struct ImBuf *filelist_file_getimage(const FileDirEntry *file);
struct ImBuf *filelist_geticon_image_ex(const FileDirEntry *file);
struct ImBuf *filelist_geticon_image(struct FileList *filelist, int index);
+struct ImBuf *filelist_file_geticon_image(const FileDirEntry *file);
int filelist_geticon(struct FileList *filelist, int index, bool is_main);
int /* ThumbSource */ filelist_preview_source_get(int /* eFileSel_File_Types */ file_type);
diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c
index a462476aae0..720e33cfedb 100644
--- a/source/blender/editors/space_file/space_file.c
+++ b/source/blender/editors/space_file/space_file.c
@@ -653,7 +653,13 @@ static void file_main_region_draw(const bContext *C, ARegion *region)
file_highlight_set(sfile, region, event->xy[0], event->xy[1]);
}
- if (!file_draw_hint_if_invalid(C, sfile, region)) {
+ if (file_draw_hint_if_invalid(C, sfile, region)) {
+ /* Pass. */
+ }
+ else if (params->display == FILE_IMGDISPLAY) {
+ file_view_preview_grid_draw(C, region);
+ }
+ else {
file_draw_list(C, region);
}