UI: File Loading Dialog #104666
|
@ -90,6 +90,8 @@
|
|||
#include "RNA_access.hh"
|
||||
#include "RNA_define.hh"
|
||||
|
||||
#include "GPU_immediate.h"
|
||||
|
||||
#include "IMB_imbuf.h"
|
||||
#include "IMB_imbuf_types.h"
|
||||
#include "IMB_thumbs.h"
|
||||
|
@ -830,6 +832,113 @@ static void wm_file_read_post(bContext *C,
|
|||
WM_cursor_wait(false);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name File Loading Dialog
|
||||
* \{ */
|
||||
|
||||
/**
|
||||
* Window callback to draw a darkened area behind the loading dialog.
|
||||
*/
|
||||
static void loading_dialog_background_cb(const wmWindow *win, void *)
|
||||
{
|
||||
GPU_blend(GPU_BLEND_ALPHA);
|
||||
GPUVertFormat *format = immVertexFormat();
|
||||
int pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
|
||||
immUniformColor4f(0.0f, 0.0f, 0.0f, 0.5f);
|
||||
immBegin(GPU_PRIM_TRI_STRIP, 4);
|
||||
immVertex2f(pos, WM_window_pixels_x(win), 0.0f);
|
||||
immVertex2f(pos, 0.0f, 0.0f);
|
||||
immVertex2f(pos, WM_window_pixels_x(win), WM_window_pixels_y(win));
|
||||
immVertex2f(pos, 0.0f, WM_window_pixels_y(win));
|
||||
immEnd();
|
||||
immUnbindProgram();
|
||||
}
|
||||
|
||||
/**
|
||||
* Dialog displayed during blend file loading, showing thumbnail and file name.
|
||||
*/
|
||||
static uiBlock *wm_block_create_loading(bContext *C, ARegion *region, void *arg)
|
||||
{
|
||||
const char *filepath = static_cast<const char *>(arg);
|
||||
short preview_width = int((114.0f * UI_SCALE_FAC));
|
||||
|
||||
/* First look for preview in the local thumbnail cache folder. */
|
||||
ImBuf *ibuf = IMB_thumb_read(filepath, THB_LARGE);
|
||||
|
||||
if (!ibuf) {
|
||||
/* Not in cache, so extract from the blend file itself. */
|
||||
BlendThumbnail *data = BLO_thumbnail_from_file(filepath);
|
||||
ibuf = data ? BKE_main_thumbnail_to_imbuf(nullptr, data) : nullptr;
|
||||
if (data) {
|
||||
MEM_freeN(data);
|
||||
}
|
||||
}
|
||||
|
||||
const uchar *color = nullptr;
|
||||
|
||||
if (!ibuf) {
|
||||
/* No thumbnails found, so just use Blender logo. */
|
||||
ibuf = UI_icon_alert_imbuf_get(ALERT_ICON_BLENDER);
|
||||
color = UI_GetTheme()->tui.wcol_menu_back.text_sel;
|
||||
IMB_premultiply_alpha(ibuf);
|
||||
}
|
||||
|
||||
/* Size to fit within preview_width x preview_width. */
|
||||
float scale = float(preview_width) / float(MAX2(ibuf->x, ibuf->y));
|
||||
IMB_scaleImBuf(ibuf, scale * ibuf->x, scale * ibuf->y);
|
||||
preview_width = ibuf->x;
|
||||
|
||||
const uiStyle *style = UI_style_get_dpi();
|
||||
const int text_points_max = MAX2(style->widget.points, style->widgetlabel.points);
|
||||
const int dialog_width = preview_width + (text_points_max * 23 * UI_SCALE_FAC);
|
||||
const float padding = 5.0f * UI_SCALE_FAC;
|
||||
const float split_factor = (float(preview_width) + padding) /
|
||||
float(dialog_width - style->columnspace);
|
||||
|
||||
uiBlock *block = UI_block_begin(C, region, "file_open_loading_popup", UI_EMBOSS);
|
||||
UI_block_theme_style_set(block, UI_BLOCK_THEME_STYLE_POPUP);
|
||||
|
||||
uiLayout *block_layout = UI_block_layout(
|
||||
block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, dialog_width, 0, 0, style);
|
||||
|
||||
/* Split layout to put preview on left side. */
|
||||
uiLayout *split_block = uiLayoutSplit(block_layout, split_factor, false);
|
||||
|
||||
/* Preview on the left. */
|
||||
uiLayout *layout = uiLayoutRow(split_block, false);
|
||||
/* Using 'align_left' with 'row' avoids stretching the icon along the width of column. */
|
||||
uiLayoutSetAlignment(layout, UI_LAYOUT_ALIGN_LEFT);
|
||||
|
||||
uiDefButImage(block, ibuf, 0, U.widget_unit, ibuf->x, ibuf->y, color);
|
||||
|
||||
/* The rest of the content on the right. */
|
||||
layout = uiLayoutColumn(split_block, false);
|
||||
|
||||
uiItemS(layout);
|
||||
|
||||
uiItemL_ex(layout, N_("Opening file..."), ICON_NONE, false, false);
|
||||
|
||||
char filename[FILE_MAX];
|
||||
BLI_path_split_file_part(filepath, filename, sizeof(filename));
|
||||
uiItemL_ex(layout, filename, ICON_NONE, true, false);
|
||||
|
||||
size_t filesize = BLI_file_size(filepath);
|
||||
if (filesize > 0) {
|
||||
char size_dec[BLI_STR_FORMAT_INT32_DECIMAL_UNIT_SIZE];
|
||||
BLI_str_format_decimal_unit(size_dec, filesize);
|
||||
uiItemL_ex(layout, size_dec, ICON_NONE, false, false);
|
||||
}
|
||||
|
||||
uiItemS(layout);
|
||||
|
||||
UI_block_bounds_set_centered(block, 5 * UI_SCALE_FAC);
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
static void wm_read_callback_pre_wrapper(bContext *C, const char *filepath)
|
||||
{
|
||||
/* NOTE: either #BKE_CB_EVT_LOAD_POST or #BKE_CB_EVT_LOAD_POST_FAIL must run.
|
||||
|
@ -1022,9 +1131,18 @@ bool WM_file_read(bContext *C, const char *filepath, ReportList *reports)
|
|||
CTX_wm_window_set(C, win);
|
||||
}
|
||||
if (win != nullptr) {
|
||||
/* Redraw to remove any open menus. */
|
||||
/* Draw a darkened background across the window. */
|
||||
void *cb = WM_draw_cb_activate(win, loading_dialog_background_cb, nullptr);
|
||||
|
||||
/* Set up the dialog. */
|
||||
UI_popup_block_invoke(C, wm_block_create_loading, (void *)filepath, nullptr);
|
||||
|
||||
/* Redraw to remove any open menus and show loading block. */
|
||||
WM_redraw_windows(C);
|
||||
|
||||
/* No more need for the window-darkening callback. */
|
||||
WM_draw_cb_exit(win, cb);
|
||||
|
||||
if (win_was_null) {
|
||||
CTX_wm_window_set(C, nullptr);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue