diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/BKE_icons.h | 2 | ||||
-rw-r--r-- | source/blender/editors/include/UI_grid_view.hh | 6 | ||||
-rw-r--r-- | source/blender/editors/include/UI_interface.h | 10 | ||||
-rw-r--r-- | source/blender/editors/include/UI_interface_icons.h | 3 | ||||
-rw-r--r-- | source/blender/editors/interface/interface.cc | 55 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_icons.c | 26 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_intern.h | 3 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_widgets.c | 56 | ||||
-rw-r--r-- | source/blender/editors/interface/views/grid_view.cc | 36 | ||||
-rw-r--r-- | source/blender/editors/space_file/CMakeLists.txt | 1 | ||||
-rw-r--r-- | source/blender/editors/space_file/file_draw.c | 37 | ||||
-rw-r--r-- | source/blender/editors/space_file/file_intern.h | 8 | ||||
-rw-r--r-- | source/blender/editors/space_file/file_view_grid.cc | 190 | ||||
-rw-r--r-- | source/blender/editors/space_file/filelist.c | 5 | ||||
-rw-r--r-- | source/blender/editors/space_file/filelist.h | 1 | ||||
-rw-r--r-- | source/blender/editors/space_file/space_file.c | 8 |
16 files changed, 400 insertions, 47 deletions
diff --git a/source/blender/blenkernel/BKE_icons.h b/source/blender/blenkernel/BKE_icons.h index 8d9351806c4..4ab3a2ac904 100644 --- a/source/blender/blenkernel/BKE_icons.h +++ b/source/blender/blenkernel/BKE_icons.h @@ -77,7 +77,9 @@ struct PreviewImage; struct StudioLight; struct bGPDlayer; +#ifndef __cplusplus enum eIconSizes; +#endif void BKE_icons_init(int first_dyn_id); 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 = ®ion->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); } |