Refactor: File Browser: Extract preview loading icon drawing
As mentioned ine072853e63,fb6ac24514and9a6beb915d, `file_draw_preview()` is a rather overloaded and confusing function. I'm trying to make it more readable. This splits off the drawing for the loading icon displayed while the previews are pending/loading still, removing the loading case handling from `file_draw_preview()`. There was also some implicit logic here: While loading previews we'd always pass a "special image" to the preview drawing, so the `is_special_file_image` boolean would always be true. This is untangled too now, so code paths are more explicit/clear. `file_add_preview_drag_but()` can't access data returned by `file_draw_preview()` anymore (it may not be called), so I made it independent which is an improvement too. While working on this I noticed the loading icon isn't centered correctly. For now I made sure the position remains the same, I'll fix the positioning in a followup.
This commit is contained in:
@@ -509,48 +509,9 @@ void file_calc_previews(const bContext *C, ARegion *region)
|
|||||||
UI_view2d_totRect_set(v2d, sfile->layout->width, sfile->layout->height);
|
UI_view2d_totRect_set(v2d, sfile->layout->width, sfile->layout->height);
|
||||||
}
|
}
|
||||||
|
|
||||||
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 icon,
|
|
||||||
const float scale)
|
|
||||||
{
|
|
||||||
/* Invisible button for dragging. */
|
|
||||||
rcti drag_rect = *tile_draw_rect;
|
|
||||||
/* A bit smaller than the full tile, to increase the gap between items that users can drag from
|
|
||||||
* for box select. */
|
|
||||||
BLI_rcti_pad(&drag_rect, -layout->tile_border_x, -layout->tile_border_y);
|
|
||||||
|
|
||||||
uiBut *but = uiDefBut(block,
|
|
||||||
UI_BTYPE_LABEL,
|
|
||||||
0,
|
|
||||||
"",
|
|
||||||
drag_rect.xmin,
|
|
||||||
drag_rect.ymin,
|
|
||||||
BLI_rcti_size_x(&drag_rect),
|
|
||||||
BLI_rcti_size_y(&drag_rect),
|
|
||||||
nullptr,
|
|
||||||
0.0,
|
|
||||||
0.0,
|
|
||||||
nullptr);
|
|
||||||
file_but_enable_drag(but, sfile, file, path, preview_image, icon, scale);
|
|
||||||
|
|
||||||
if (file->asset) {
|
|
||||||
UI_but_func_tooltip_set(but, file_draw_asset_tooltip_func, file->asset, nullptr);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
UI_but_func_tooltip_custom_set(
|
|
||||||
but, file_draw_tooltip_custom_func, file_tooltip_data_create(sfile, file), MEM_freeN);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::tuple<int, int, float> preview_image_scaled_dimensions_get(const int image_width,
|
static std::tuple<int, int, float> preview_image_scaled_dimensions_get(const int image_width,
|
||||||
const int image_height,
|
const int image_height,
|
||||||
FileLayout &layout,
|
const FileLayout &layout,
|
||||||
const bool never_scale_up)
|
const bool never_scale_up)
|
||||||
{
|
{
|
||||||
const float ui_imbx = image_width * UI_SCALE_FAC;
|
const float ui_imbx = image_width * UI_SCALE_FAC;
|
||||||
@@ -581,19 +542,60 @@ static std::tuple<int, int, float> preview_image_scaled_dimensions_get(const int
|
|||||||
return std::make_tuple(int(scaledx), int(scaledy), scale);
|
return std::make_tuple(int(scaledx), int(scaledy), scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void file_draw_preview(const FileList *files,
|
static void file_add_preview_drag_but(const SpaceFile *sfile,
|
||||||
const FileDirEntry *file,
|
uiBlock *block,
|
||||||
|
FileLayout *layout,
|
||||||
|
const FileDirEntry *file,
|
||||||
|
const char *path,
|
||||||
|
const rcti *tile_draw_rect,
|
||||||
|
const ImBuf *preview_image,
|
||||||
|
const int icon,
|
||||||
|
const bool is_special_file_image)
|
||||||
|
{
|
||||||
|
/* Invisible button for dragging. */
|
||||||
|
rcti drag_rect = *tile_draw_rect;
|
||||||
|
/* A bit smaller than the full tile, to increase the gap between items that users can drag from
|
||||||
|
* for box select. */
|
||||||
|
BLI_rcti_pad(&drag_rect, -layout->tile_border_x, -layout->tile_border_y);
|
||||||
|
|
||||||
|
uiBut *but = uiDefBut(block,
|
||||||
|
UI_BTYPE_LABEL,
|
||||||
|
0,
|
||||||
|
"",
|
||||||
|
drag_rect.xmin,
|
||||||
|
drag_rect.ymin,
|
||||||
|
BLI_rcti_size_x(&drag_rect),
|
||||||
|
BLI_rcti_size_y(&drag_rect),
|
||||||
|
nullptr,
|
||||||
|
0.0,
|
||||||
|
0.0,
|
||||||
|
nullptr);
|
||||||
|
|
||||||
|
/* Unlike thumbnails, icons are not scaled up. */
|
||||||
|
const bool never_scale_up = is_special_file_image;
|
||||||
|
|
||||||
|
const auto [scaled_width, scaled_height, scale] = preview_image_scaled_dimensions_get(
|
||||||
|
preview_image->x, preview_image->y, *layout, never_scale_up);
|
||||||
|
file_but_enable_drag(but, sfile, file, path, preview_image, icon, scale);
|
||||||
|
|
||||||
|
if (file->asset) {
|
||||||
|
UI_but_func_tooltip_set(but, file_draw_asset_tooltip_func, file->asset, nullptr);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
UI_but_func_tooltip_custom_set(
|
||||||
|
but, file_draw_tooltip_custom_func, file_tooltip_data_create(sfile, file), MEM_freeN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void file_draw_preview(const FileDirEntry *file,
|
||||||
const rcti *tile_draw_rect,
|
const rcti *tile_draw_rect,
|
||||||
const float icon_aspect,
|
const float icon_aspect,
|
||||||
const ImBuf *imb,
|
const ImBuf *imb,
|
||||||
const int file_type_icon,
|
const int file_type_icon,
|
||||||
FileLayout *layout,
|
FileLayout *layout,
|
||||||
const bool is_special_file_image,
|
const bool is_special_file_image,
|
||||||
const bool dimmed,
|
const bool dimmed)
|
||||||
float *r_scale)
|
|
||||||
{
|
{
|
||||||
const bool is_loading = filelist_file_is_preview_pending(files, file);
|
|
||||||
|
|
||||||
BLI_assert(imb != nullptr);
|
BLI_assert(imb != nullptr);
|
||||||
|
|
||||||
/* Unlike thumbnails, icons are not scaled up. */
|
/* Unlike thumbnails, icons are not scaled up. */
|
||||||
@@ -641,43 +643,39 @@ static void file_draw_preview(const FileList *files,
|
|||||||
GPU_blend(GPU_BLEND_ALPHA_PREMULT);
|
GPU_blend(GPU_BLEND_ALPHA_PREMULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_loading) {
|
if (is_special_file_image) {
|
||||||
/* Don't show outer document image if loading - too flashy. */
|
/* Draw large folder or document icon. */
|
||||||
if (is_special_file_image) {
|
const int icon_large = (file->typeflag & FILE_TYPE_DIR) ? ICON_FILE_FOLDER_LARGE :
|
||||||
/* Draw large folder or document icon. */
|
ICON_FILE_LARGE;
|
||||||
const int icon_large = (file->typeflag & FILE_TYPE_DIR) ? ICON_FILE_FOLDER_LARGE :
|
uchar icon_col[4];
|
||||||
ICON_FILE_LARGE;
|
rgba_float_to_uchar(icon_col, document_img_col);
|
||||||
uchar icon_col[4];
|
float icon_x = float(xmin) + (file->typeflag & FILE_TYPE_DIR ? 0.0f : scaled_width * -0.142f);
|
||||||
rgba_float_to_uchar(icon_col, document_img_col);
|
float icon_y = float(ymin) + (file->typeflag & FILE_TYPE_DIR ? scaled_width * -0.11f : 0.0f);
|
||||||
float icon_x = float(xmin) +
|
UI_icon_draw_ex(icon_x,
|
||||||
(file->typeflag & FILE_TYPE_DIR ? 0.0f : scaled_width * -0.142f);
|
icon_y,
|
||||||
float icon_y = float(ymin) + (file->typeflag & FILE_TYPE_DIR ? scaled_width * -0.11f : 0.0f);
|
icon_large,
|
||||||
UI_icon_draw_ex(icon_x,
|
icon_aspect / 4.0f / UI_SCALE_FAC,
|
||||||
icon_y,
|
document_img_col[3],
|
||||||
icon_large,
|
0.0f,
|
||||||
icon_aspect / 4.0f / UI_SCALE_FAC,
|
icon_col,
|
||||||
document_img_col[3],
|
false,
|
||||||
0.0f,
|
UI_NO_ICON_OVERLAY_TEXT);
|
||||||
icon_col,
|
}
|
||||||
false,
|
else {
|
||||||
UI_NO_ICON_OVERLAY_TEXT);
|
IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_3D_IMAGE_COLOR);
|
||||||
}
|
immDrawPixelsTexTiled_scaling(&state,
|
||||||
else {
|
float(xmin),
|
||||||
IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_3D_IMAGE_COLOR);
|
float(ymin),
|
||||||
immDrawPixelsTexTiled_scaling(&state,
|
imb->x,
|
||||||
float(xmin),
|
imb->y,
|
||||||
float(ymin),
|
GPU_RGBA8,
|
||||||
imb->x,
|
true,
|
||||||
imb->y,
|
imb->byte_buffer.data,
|
||||||
GPU_RGBA8,
|
scale,
|
||||||
true,
|
scale,
|
||||||
imb->byte_buffer.data,
|
1.0f,
|
||||||
scale,
|
1.0f,
|
||||||
scale,
|
document_img_col);
|
||||||
1.0f,
|
|
||||||
1.0f,
|
|
||||||
document_img_col);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file_type_icon && is_special_file_image) {
|
if (file_type_icon && is_special_file_image) {
|
||||||
@@ -691,17 +689,12 @@ static void file_draw_preview(const FileList *files,
|
|||||||
icon_color[2] = 255;
|
icon_color[2] = 255;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_loading) {
|
|
||||||
/* Contrast with background since we are not showing the large document image. */
|
|
||||||
UI_GetThemeColor4ubv(TH_TEXT, icon_color);
|
|
||||||
}
|
|
||||||
|
|
||||||
icon_x = xmin +
|
icon_x = xmin +
|
||||||
(file->typeflag & FILE_TYPE_DIR ? scaled_width * 0.31f : scaled_width * 0.178f);
|
(file->typeflag & FILE_TYPE_DIR ? scaled_width * 0.31f : scaled_width * 0.178f);
|
||||||
icon_y = ymin + (file->typeflag & FILE_TYPE_DIR ? scaled_width * 0.19f : scaled_width * 0.15f);
|
icon_y = ymin + (file->typeflag & FILE_TYPE_DIR ? scaled_width * 0.19f : scaled_width * 0.15f);
|
||||||
UI_icon_draw_ex(icon_x,
|
UI_icon_draw_ex(icon_x,
|
||||||
icon_y,
|
icon_y,
|
||||||
is_loading ? ICON_TEMP : file_type_icon,
|
file_type_icon,
|
||||||
icon_aspect / UI_SCALE_FAC / (file->typeflag & FILE_TYPE_DIR ? 1.5f : 2.0f),
|
icon_aspect / UI_SCALE_FAC / (file->typeflag & FILE_TYPE_DIR ? 1.5f : 2.0f),
|
||||||
icon_opacity,
|
icon_opacity,
|
||||||
0.0f,
|
0.0f,
|
||||||
@@ -738,10 +731,40 @@ static void file_draw_preview(const FileList *files,
|
|||||||
}
|
}
|
||||||
|
|
||||||
GPU_blend(GPU_BLEND_NONE);
|
GPU_blend(GPU_BLEND_NONE);
|
||||||
|
}
|
||||||
|
|
||||||
if (r_scale) {
|
static void file_draw_loading_icon(const rcti *tile_draw_rect,
|
||||||
*r_scale = scale;
|
const float preview_icon_aspect,
|
||||||
}
|
const FileLayout *layout)
|
||||||
|
{
|
||||||
|
/* Small icon in the middle of large image, scaled to fit container and UI scale */
|
||||||
|
float icon_opacity = 0.4f;
|
||||||
|
|
||||||
|
uchar icon_color[4] = {0, 0, 0, 255};
|
||||||
|
/* Contrast with background since we are not showing the large document image. */
|
||||||
|
UI_GetThemeColor4ubv(TH_TEXT, icon_color);
|
||||||
|
|
||||||
|
const auto [scaled_width, scaled_height, scale] = preview_image_scaled_dimensions_get(
|
||||||
|
200, 256, *layout, true);
|
||||||
|
|
||||||
|
/* Additional offset to keep the scaled image centered. Difference between maximum
|
||||||
|
* width/height and the actual width/height, divided by two for centering. */
|
||||||
|
const float ofs_x = (float(layout->prv_w) - float(scaled_width)) / 2.0f;
|
||||||
|
const float ofs_y = (float(layout->prv_h) - float(scaled_height)) / 2.0f;
|
||||||
|
const int xmin = tile_draw_rect->xmin + layout->prv_border_x + int(ofs_x + 0.5f);
|
||||||
|
const int ymin = tile_draw_rect->ymax - layout->prv_border_y - layout->prv_h + int(ofs_y + 0.5f);
|
||||||
|
|
||||||
|
const float icon_x = xmin + scaled_width * 0.178f;
|
||||||
|
const float icon_y = ymin + scaled_width * 0.15f;
|
||||||
|
UI_icon_draw_ex(icon_x,
|
||||||
|
icon_y,
|
||||||
|
ICON_TEMP,
|
||||||
|
preview_icon_aspect / UI_SCALE_FAC / 2.0f,
|
||||||
|
icon_opacity,
|
||||||
|
0.0f,
|
||||||
|
icon_color,
|
||||||
|
false,
|
||||||
|
UI_NO_ICON_OVERLAY_TEXT);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void file_draw_indicator_icons(const FileList *files,
|
static void file_draw_indicator_icons(const FileList *files,
|
||||||
@@ -1275,23 +1298,34 @@ void file_draw_list(const bContext *C, ARegion *region)
|
|||||||
is_special_file_image = true;
|
is_special_file_image = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
float scale = 0;
|
const bool is_loading = filelist_file_is_preview_pending(files, file);
|
||||||
file_draw_preview(files,
|
if (is_loading) {
|
||||||
file,
|
file_draw_loading_icon(&tile_draw_rect, thumb_icon_aspect, layout);
|
||||||
&tile_draw_rect,
|
}
|
||||||
thumb_icon_aspect,
|
else {
|
||||||
imb,
|
file_draw_preview(file,
|
||||||
file_type_icon,
|
&tile_draw_rect,
|
||||||
layout,
|
thumb_icon_aspect,
|
||||||
is_special_file_image,
|
imb,
|
||||||
is_hidden,
|
file_type_icon,
|
||||||
/* Returns the scale which is needed below. */
|
layout,
|
||||||
&scale);
|
is_special_file_image,
|
||||||
|
is_hidden);
|
||||||
|
}
|
||||||
|
|
||||||
file_draw_indicator_icons(
|
file_draw_indicator_icons(
|
||||||
files, file, &tile_draw_rect, thumb_icon_aspect, file_type_icon, is_special_file_image);
|
files, file, &tile_draw_rect, thumb_icon_aspect, file_type_icon, is_special_file_image);
|
||||||
|
|
||||||
if (do_drag) {
|
if (do_drag) {
|
||||||
file_add_preview_drag_but(
|
file_add_preview_drag_but(sfile,
|
||||||
sfile, block, layout, file, path, &tile_draw_rect, imb, file_type_icon, scale);
|
block,
|
||||||
|
layout,
|
||||||
|
file,
|
||||||
|
path,
|
||||||
|
&tile_draw_rect,
|
||||||
|
imb,
|
||||||
|
file_type_icon,
|
||||||
|
is_special_file_image);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
Reference in New Issue
Block a user