Refactor: File Browser: Readability of preview image scale calculations

As mentioned in 9a6beb915d, `file_draw_preview()` is a rather
overloaded and confusing function. I'm trying to make it more readable.

Move image scale calculations to a separate function, reducing perceived
complexity of the function and the number of local variables. Also
rename or remove some variables to be more clear, add comments and move
variables closer to where they are used.
This commit is contained in:
Julian Eisel
2024-12-16 16:44:04 +01:00
parent 630c3ce94e
commit fb6ac24514

View File

@@ -548,6 +548,39 @@ static void file_add_preview_drag_but(const SpaceFile *sfile,
}
}
static std::tuple<int, int, float> preview_image_scaled_dimensions_get(const int image_width,
const int image_height,
FileLayout &layout,
const bool never_scale_up)
{
const float ui_imbx = image_width * UI_SCALE_FAC;
const float ui_imby = image_height * UI_SCALE_FAC;
float scale;
float scaledx, scaledy;
if (((ui_imbx > layout.prv_w) || (ui_imby > layout.prv_h)) ||
(!never_scale_up && ((ui_imbx < layout.prv_w) || (ui_imby < layout.prv_h))))
{
if (image_width > image_height) {
scaledx = float(layout.prv_w);
scaledy = (float(image_height) / float(image_width)) * layout.prv_w;
scale = scaledx / image_width;
}
else {
scaledy = float(layout.prv_h);
scaledx = (float(image_width) / float(image_height)) * layout.prv_h;
scale = scaledy / image_height;
}
}
else {
scaledx = ui_imbx;
scaledy = ui_imby;
scale = UI_SCALE_FAC;
}
return std::make_tuple(int(scaledx), int(scaledy), scale);
}
static void file_draw_preview(const FileList *files,
const FileDirEntry *file,
const rcti *tile_draw_rect,
@@ -560,52 +593,23 @@ static void file_draw_preview(const FileList *files,
const bool is_link,
float *r_scale)
{
float fx, fy;
float dx, dy;
int xco, yco;
float ui_imbx, ui_imby;
float scaledx, scaledy;
float scale;
int ex, ey;
bool show_outline = !is_special_file_image &&
(file->typeflag & (FILE_TYPE_IMAGE | FILE_TYPE_OBJECT_IO | FILE_TYPE_MOVIE |
FILE_TYPE_BLENDER));
const bool is_offline = (file->attributes & FILE_ATTR_OFFLINE);
const bool is_loading = filelist_file_is_preview_pending(files, file);
BLI_assert(imb != nullptr);
ui_imbx = imb->x * UI_SCALE_FAC;
ui_imby = imb->y * UI_SCALE_FAC;
/* Unlike thumbnails, icons are not scaled up. */
if (((ui_imbx > layout->prv_w) || (ui_imby > layout->prv_h)) ||
(!is_special_file_image && ((ui_imbx < layout->prv_w) || (ui_imby < layout->prv_h))))
{
if (imb->x > imb->y) {
scaledx = float(layout->prv_w);
scaledy = (float(imb->y) / float(imb->x)) * layout->prv_w;
scale = scaledx / imb->x;
}
else {
scaledy = float(layout->prv_h);
scaledx = (float(imb->x) / float(imb->y)) * layout->prv_h;
scale = scaledy / imb->y;
}
}
else {
scaledx = ui_imbx;
scaledy = ui_imby;
scale = UI_SCALE_FAC;
}
const bool never_scale_up = is_special_file_image;
ex = int(scaledx);
ey = int(scaledy);
fx = (float(layout->prv_w) - float(ex)) / 2.0f;
fy = (float(layout->prv_h) - float(ey)) / 2.0f;
dx = (fx + 0.5f + layout->prv_border_x);
dy = (fy + 0.5f - layout->prv_border_y);
xco = tile_draw_rect->xmin + int(dx);
yco = tile_draw_rect->ymax - layout->prv_h + int(dy);
const auto [scaled_width, scaled_height, scale] = preview_image_scaled_dimensions_get(
imb->x, imb->y, *layout, never_scale_up);
/* 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);
GPU_blend(GPU_BLEND_ALPHA);
@@ -630,7 +634,8 @@ static void file_draw_preview(const FileList *files,
if (!is_special_file_image && ELEM(file->typeflag, FILE_TYPE_IMAGE, FILE_TYPE_OBJECT_IO)) {
/* Draw checker pattern behind image previews in case they have transparency. */
imm_draw_box_checker_2d(float(xco), float(yco), float(xco + ex), float(yco + ey));
imm_draw_box_checker_2d(
float(xmin), float(ymin), float(xmin + scaled_width), float(ymin + scaled_height));
}
if (!is_special_file_image && file->typeflag & FILE_TYPE_BLENDERLIB) {
@@ -646,8 +651,9 @@ static void file_draw_preview(const FileList *files,
ICON_FILE_LARGE;
uchar icon_col[4];
rgba_float_to_uchar(icon_col, document_img_col);
float icon_x = float(xco) + (file->typeflag & FILE_TYPE_DIR ? 0.0f : ex * -0.142f);
float icon_y = float(yco) + (file->typeflag & FILE_TYPE_DIR ? ex * -0.11f : 0.0f);
float icon_x = float(xmin) +
(file->typeflag & FILE_TYPE_DIR ? 0.0f : scaled_width * -0.142f);
float icon_y = float(ymin) + (file->typeflag & FILE_TYPE_DIR ? scaled_width * -0.11f : 0.0f);
UI_icon_draw_ex(icon_x,
icon_y,
icon_large,
@@ -661,8 +667,8 @@ static void file_draw_preview(const FileList *files,
else {
IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_3D_IMAGE_COLOR);
immDrawPixelsTexTiled_scaling(&state,
float(xco),
float(yco),
float(xmin),
float(ymin),
imb->x,
imb->y,
GPU_RGBA8,
@@ -692,8 +698,9 @@ static void file_draw_preview(const FileList *files,
UI_GetThemeColor4ubv(TH_TEXT, icon_color);
}
icon_x = xco + (file->typeflag & FILE_TYPE_DIR ? ex * 0.31f : ex * 0.178f);
icon_y = yco + (file->typeflag & FILE_TYPE_DIR ? ex * 0.19f : ex * 0.15f);
icon_x = xmin +
(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);
UI_icon_draw_ex(icon_x,
icon_y,
is_loading ? ICON_TEMP : file_type_icon,
@@ -768,6 +775,9 @@ static void file_draw_preview(const FileList *files,
UI_NO_ICON_OVERLAY_TEXT);
}
const bool show_outline = !is_special_file_image &&
(file->typeflag & (FILE_TYPE_IMAGE | FILE_TYPE_OBJECT_IO |
FILE_TYPE_MOVIE | FILE_TYPE_BLENDER));
/* Contrasting outline around some preview types. */
if (show_outline) {
GPU_blend(GPU_BLEND_ALPHA);
@@ -784,7 +794,11 @@ static void file_draw_preview(const FileList *files,
border_color[2] = 0.0f;
}
immUniformColor4fv(border_color);
imm_draw_box_wire_2d(pos, float(xco), float(yco), float(xco + ex + 1), float(yco + ey + 1));
imm_draw_box_wire_2d(pos,
float(xmin),
float(ymin),
float(xmin + scaled_width + 1),
float(ymin + scaled_height + 1));
immUnbindProgram();
}