From a210b8297f5afe6eaf2d001e57c1e8b7e8429c52 Mon Sep 17 00:00:00 2001 From: Harley Acheson Date: Sat, 14 Mar 2020 11:05:09 -0700 Subject: UI: Larger Alert Icons Adding a set of larger icons for use in informational dialogs. Differential Revision: https://developer.blender.org/D6859 Reviewed by Campbell Barton --- source/blender/blenkernel/BKE_blender_version.h | 2 +- .../blender/blenloader/intern/versioning_userdef.c | 4 + source/blender/editors/datafiles/CMakeLists.txt | 1 + source/blender/editors/include/ED_datafiles.h | 3 + source/blender/editors/include/UI_interface.h | 5 +- .../blender/editors/include/UI_interface_icons.h | 11 ++ source/blender/editors/interface/interface.c | 42 +++++++ source/blender/editors/interface/interface_draw.c | 24 ++-- source/blender/editors/interface/interface_icons.c | 24 ++++ source/blender/editors/space_image/image_ops.c | 9 +- source/blender/windowmanager/intern/wm_files.c | 125 +++++++++++++-------- .../windowmanager/intern/wm_splash_screen.c | 22 ++-- 12 files changed, 193 insertions(+), 79 deletions(-) (limited to 'source/blender') diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h index eb7078213da..2a4394ee096 100644 --- a/source/blender/blenkernel/BKE_blender_version.h +++ b/source/blender/blenkernel/BKE_blender_version.h @@ -27,7 +27,7 @@ * \note Use #STRINGIFY() rather than defining with quotes. */ #define BLENDER_VERSION 283 -#define BLENDER_SUBVERSION 8 +#define BLENDER_SUBVERSION 9 /** Several breakages with 280, e.g. collections vs layers. */ #define BLENDER_MINVERSION 280 #define BLENDER_MINSUBVERSION 0 diff --git a/source/blender/blenloader/intern/versioning_userdef.c b/source/blender/blenloader/intern/versioning_userdef.c index 2fefa56fbe5..205106d7820 100644 --- a/source/blender/blenloader/intern/versioning_userdef.c +++ b/source/blender/blenloader/intern/versioning_userdef.c @@ -192,6 +192,10 @@ static void do_versions_theme(const UserDef *userdef, bTheme *btheme) btheme->space_node.grid_levels = U_theme_default.space_node.grid_levels; } + if (!USER_VERSION_ATLEAST(283, 9)) { + FROM_DEFAULT_V4_UCHAR(space_info.info_warning); + } + /** * Versioning code until next subversion bump goes here. * diff --git a/source/blender/editors/datafiles/CMakeLists.txt b/source/blender/editors/datafiles/CMakeLists.txt index 3b56e39dcac..1b147663a7e 100644 --- a/source/blender/editors/datafiles/CMakeLists.txt +++ b/source/blender/editors/datafiles/CMakeLists.txt @@ -782,6 +782,7 @@ if(WITH_BLENDER) # images data_to_c_simple(../../../../release/datafiles/splash.png SRC) data_to_c_simple(../../../../release/datafiles/splash_2x.png SRC) + data_to_c_simple(../../../../release/datafiles/alert_icons.png SRC) # XXX These are handy, but give nasty "false changes" in svn :/ # svg_to_png(../../../../release/datafiles/blender_icons.svg # ../../../../release/datafiles/blender_icons16.png diff --git a/source/blender/editors/include/ED_datafiles.h b/source/blender/editors/include/ED_datafiles.h index c1f5eddd8df..a2ad343da37 100644 --- a/source/blender/editors/include/ED_datafiles.h +++ b/source/blender/editors/include/ED_datafiles.h @@ -48,6 +48,9 @@ extern char datatoc_blender_icons32_png[]; extern int datatoc_prvicons_png_size; extern char datatoc_prvicons_png[]; +extern int datatoc_alert_icons_png_size; +extern char datatoc_alert_icons_png[]; + extern int datatoc_splash_png_size; extern char datatoc_splash_png[]; diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index dba95c5106e..71263a65a36 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -1124,7 +1124,10 @@ uiBut *uiDefIconButO_ptr(uiBlock *block, short width, short height, const char *tip); - +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); uiBut *uiDefIconTextBut(uiBlock *block, int type, int retval, diff --git a/source/blender/editors/include/UI_interface_icons.h b/source/blender/editors/include/UI_interface_icons.h index 6bf0cb8952d..a304c76bc9d 100644 --- a/source/blender/editors/include/UI_interface_icons.h +++ b/source/blender/editors/include/UI_interface_icons.h @@ -52,6 +52,17 @@ typedef struct IconFile { #define PREVIEW_DEFAULT_HEIGHT 128 +typedef enum eAlertIcon { + ALERT_ICON_WARNING = 0, + ALERT_ICON_QUESTION = 1, + ALERT_ICON_ERROR = 2, + ALERT_ICON_INFO = 3, + ALERT_ICON_BLENDER = 4, + ALERT_ICON_MAX, +} eAlertIcon; + +struct ImBuf *UI_alert_image(eAlertIcon icon); + /* * Resizable Icons for Blender */ diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index a0a3d0a3b85..b5fce7ea99f 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -4439,6 +4439,48 @@ uiBut *uiDefBut(uiBlock *block, return but; } +uiBut *uiDefButImage( + uiBlock *block, void *imbuf, int x, int y, short width, short height, const uchar color[4]) +{ + uiBut *but = ui_def_but( + block, UI_BTYPE_IMAGE, 0, "", x, y, width, height, imbuf, 0, 0, 0, 0, ""); + if (color) { + copy_v4_v4_uchar(but->col, color); + } + else { + but->col[0] = 255; + but->col[1] = 255; + but->col[2] = 255; + but->col[3] = 255; + } + ui_but_update(but); + return but; +} + +uiBut *uiDefButAlert(uiBlock *block, int icon, int x, int y, short width, short height) +{ + struct ImBuf *ibuf = UI_alert_image(icon); + + if (icon == ALERT_ICON_BLENDER) { + return uiDefButImage(block, ibuf, x, y, width, height, NULL); + } + else { + uchar icon_color[4]; + ThemeColorID color_id = TH_INFO_WARNING; + if (icon == ALERT_ICON_ERROR) { + color_id = TH_INFO_ERROR; + } + else if (icon == ALERT_ICON_INFO) { + color_id = TH_INFO_INFO; + } + else if (icon == ALERT_ICON_QUESTION) { + color_id = TH_INFO_PROPERTY; + } + UI_GetThemeColorType4ubv(color_id, SPACE_INFO, icon_color); + return uiDefButImage(block, ibuf, x, y, width, height, icon_color); + } +} + /** * if \a _x_ is a power of two (only one bit) return the power, * otherwise return -1. diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c index e8e74e77425..2800d808889 100644 --- a/source/blender/editors/interface/interface_draw.c +++ b/source/blender/editors/interface/interface_draw.c @@ -707,9 +707,6 @@ void ui_draw_but_IMAGE(ARegion *UNUSED(region), return; } - float facx = 1.0f; - float facy = 1.0f; - int w = BLI_rcti_size_x(rect); int h = BLI_rcti_size_y(rect); @@ -722,10 +719,18 @@ void ui_draw_but_IMAGE(ARegion *UNUSED(region), # endif GPU_blend(true); + /* Combine with premultiplied alpha. */ + GPU_blend_set_func_separate(GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); if (w != ibuf->x || h != ibuf->y) { - facx = (float)w / (float)ibuf->x; - facy = (float)h / (float)ibuf->y; + /* We scale the bitmap, rather than have OGL do a worse job. */ + IMB_scaleImBuf(ibuf, w, h); + } + + float col[4] = {1.0f, 1.0f, 1.0f, 1.0f}; + if (but->col[3] != 0) { + /* Optionally use uiBut's col to recolor the image. */ + rgba_uchar_to_float(col, but->col); } IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR); @@ -738,11 +743,14 @@ void ui_draw_but_IMAGE(ARegion *UNUSED(region), GL_UNSIGNED_BYTE, GL_NEAREST, ibuf->rect, - facx, - facy, - NULL); + 1.0f, + 1.0f, + col); GPU_blend(false); + /* Reset default. */ + GPU_blend_set_func_separate( + GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); # if 0 // restore scissortest diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c index 3e07023e52d..8dd449b4b67 100644 --- a/source/blender/editors/interface/interface_icons.c +++ b/source/blender/editors/interface/interface_icons.c @@ -177,6 +177,30 @@ static const IconType icontypes[] = { # include "UI_icons.h" }; +/* ********** Alert Icons ********** */ + +# define ALERT_IMG_SIZE 256 + +ImBuf *UI_alert_image(eAlertIcon icon) +{ +# ifdef WITH_HEADLESS + return NULL +# else + ImBuf *ibuf; + icon = MIN2(icon, ALERT_ICON_MAX - 1); + const int left = icon * ALERT_IMG_SIZE; + const rcti crop = {left, left + ALERT_IMG_SIZE - 1, 0, ALERT_IMG_SIZE - 1}; + ibuf = IMB_ibImageFromMemory((const uchar *)datatoc_alert_icons_png, + datatoc_alert_icons_png_size, + IB_rect, + NULL, + "alert_icon"); + IMB_rect_crop(ibuf, &crop); + IMB_premultiply_alpha(ibuf); + return ibuf; +#endif +} + /* **************************************************** */ static DrawInfo *def_internal_icon( diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index 34ff61749b2..8710b02e2a5 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -2351,7 +2351,7 @@ int ED_image_save_all_modified_info(const Main *bmain, ReportList *reports) else { BKE_reportf(reports, RPT_WARNING, - "Packed library image: %s from library %s can't be saved", + "Packed library image can't be saved: \"%s\" from \"%s\"", ima->id.name + 2, ima->id.lib->name); } @@ -2359,7 +2359,7 @@ int ED_image_save_all_modified_info(const Main *bmain, ReportList *reports) else if (!is_format_writable) { BKE_reportf(reports, RPT_WARNING, - "Image %s can't be saved automatically, must use a different file format", + "Image can't be saved, use a different file format: \"%s\"", ima->id.name + 2); } else { @@ -2368,7 +2368,7 @@ int ED_image_save_all_modified_info(const Main *bmain, ReportList *reports) if (BLI_gset_haskey(unique_paths, ima->name)) { BKE_reportf(reports, RPT_WARNING, - "File path used by more than one saved image: %s", + "Multiple images can't be saved to an identical path: \"%s\"", ima->name); } else { @@ -2378,8 +2378,7 @@ int ED_image_save_all_modified_info(const Main *bmain, ReportList *reports) else { BKE_reportf(reports, RPT_WARNING, - "Image %s can't be saved, no valid file path: %s", - ima->id.name + 2, + "Image can't be saved, no valid file path: \"%s\"", ima->name); } } diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index 83355ecb786..4c96b03f333 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -113,6 +113,7 @@ #include "GHOST_Path-api.h" #include "UI_interface.h" +#include "UI_interface_icons.h" #include "UI_resources.h" #include "UI_view2d.h" @@ -3055,58 +3056,77 @@ static uiBlock *block_create__close_file_dialog(struct bContext *C, { wmGenericCallback *post_action = (wmGenericCallback *)arg1; Main *bmain = CTX_data_main(C); - uiStyle *style = UI_style_get(); - uiFontStyle *fs = &style->widgetlabel; - - /* Filename */ - const char *blendfile_pathpath = BKE_main_blendfile_path(bmain); - char filename[FILE_MAX]; - if (blendfile_pathpath[0] != '\0') { - BLI_split_file_part(blendfile_pathpath, filename, sizeof(filename)); - BLI_path_extension_replace(filename, sizeof(filename), ""); - } - else { - STRNCPY(filename, IFACE_("Untitled")); - } + uiStyle *style = UI_style_get_dpi(); + const int dialog_width = U.widget_unit * 22; + const short icon_size = 64 * U.dpi_fac; - /* Title */ - char title[FILE_MAX + 100]; - UI_text_clip_middle_ex( - fs, filename, U.widget_unit * 9, U.widget_unit * 2, sizeof(filename), '\0'); - BLI_snprintf(title, sizeof(title), TIP_("Save changes to \"%s\" before closing?"), filename); - int title_width = MAX2(UI_fontstyle_string_width(fs, title), U.widget_unit * 22); + /* Calculate icon column factor. */ + const float split_factor = (float)icon_size / (float)(dialog_width - style->columnspace); - /* Create dialog */ uiBlock *block = UI_block_begin(C, region, close_file_dialog_name, UI_EMBOSS); - style = UI_style_get_dpi(); UI_block_flag_enable( block, UI_BLOCK_KEEP_OPEN | UI_BLOCK_LOOP | UI_BLOCK_NO_WIN_CLIP | UI_BLOCK_NUMSELECT); UI_block_theme_style_set(block, UI_BLOCK_THEME_STYLE_POPUP); UI_block_emboss_set(block, UI_EMBOSS); - uiLayout *layout = UI_block_layout(block, - UI_LAYOUT_VERTICAL, - UI_LAYOUT_PANEL, - 10, - 2, - U.widget_unit * 2 + title_width, - U.widget_unit * 6, - 0, - style); + uiLayout *block_layout = UI_block_layout( + block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, dialog_width, 0, 0, style); + + /* Split layout to put alert icon on left side. */ + uiLayout *split_block = uiLayoutSplit(block_layout, split_factor, false); + + /* Alert Icon. */ + uiLayout *layout = uiLayoutColumn(split_block, false); + uiDefButAlert(block, ALERT_ICON_WARNING, 0, 0, 0, icon_size); - /* Title */ - uiItemL_ex(layout, title, ICON_ERROR, true, false); + /* The rest of the content on the right. */ + layout = uiLayoutColumn(split_block, false); - /* Image Saving */ + /* Title. */ + uiItemL_ex(layout, TIP_("Save changes before closing?"), ICON_NONE, true, false); + + /* Filename. */ + const char *blendfile_pathpath = BKE_main_blendfile_path(CTX_data_main(C)); + char filename[FILE_MAX]; + if (blendfile_pathpath[0] != '\0') { + BLI_split_file_part(blendfile_pathpath, filename, sizeof(filename)); + BLI_path_extension_replace(filename, sizeof(filename), ""); + } + else { + STRNCPY(filename, IFACE_("Untitled")); + } + uiItemL(layout, filename, ICON_NONE); + + /* Image Saving Warnings. */ ReportList reports; BKE_reports_init(&reports, RPT_STORE); uint modified_images_count = ED_image_save_all_modified_info(bmain, &reports); LISTBASE_FOREACH (Report *, report, &reports.list) { - uiItemL_ex(layout, report->message, ICON_CANCEL, false, true); + uiLayout *row = uiLayoutColumn(layout, false); + uiLayoutSetScaleY(row, 0.6f); + uiItemS_ex(row, 1.2f); + + /* Error messages created in ED_image_save_all_modified_info() can be long, + * but are made to separate into two parts at first colon between text and paths. + */ + char *message = BLI_strdupn(report->message, report->len); + char *path_info = strstr(message, ": "); + if (path_info) { + /* Terminate message string at colon. */ + path_info[1] = '\0'; + /* Skip over the ": " */ + path_info += 2; + } + uiItemL_ex(row, message, ICON_NONE, false, true); + if (path_info) { + uiItemL_ex(row, path_info, ICON_NONE, false, true); + } + MEM_freeN(message); } + /* Modified Images Checkbox. */ if (modified_images_count > 0) { char message[64]; BLI_snprintf(message, @@ -3114,7 +3134,7 @@ static uiBlock *block_create__close_file_dialog(struct bContext *C, (modified_images_count == 1) ? "Save %u modified image" : "Save %u modified images", modified_images_count); - uiItemS(layout); + uiItemS_ex(layout, 2.0f); uiDefButBitC(block, UI_BTYPE_CHECKBOX, 1, @@ -3134,9 +3154,9 @@ static uiBlock *block_create__close_file_dialog(struct bContext *C, BKE_reports_clear(&reports); - uiItemS_ex(layout, 3.0f); + uiItemS_ex(layout, 1.0f); - /* Buttons */ + /* Buttons. */ #ifdef _WIN32 const bool windows_layout = true; #else @@ -3146,37 +3166,44 @@ static uiBlock *block_create__close_file_dialog(struct bContext *C, if (windows_layout) { /* Windows standard layout. */ - uiLayout *split = uiLayoutSplit(layout, 0.18f, true); + uiLayout *split = uiLayoutSplit(block_layout, 0.174f, true); uiLayoutSetScaleY(split, 1.2f); - uiLayout *col = uiLayoutColumn(split, false); - uiItemS(col); + uiLayoutColumn(split, false); + uiItemS(layout); - col = uiLayoutColumn(split, false); + uiLayoutColumn(split, false); wm_block_file_close_save_button(block, post_action); - col = uiLayoutColumn(split, false); + uiLayoutColumn(split, false); wm_block_file_close_discard_button(block, post_action); - col = uiLayoutColumn(split, false); + uiLayoutColumn(split, false); wm_block_file_close_cancel_button(block, post_action); } else { /* macOS and Linux standard layout. */ - uiLayout *split = uiLayoutSplit(layout, 0.0f, true); + uiLayout *split = uiLayoutSplit(block_layout, 0.167f, true); uiLayoutSetScaleY(split, 1.2f); - uiLayout *col = uiLayoutColumn(split, true); + layout = uiLayoutColumn(split, false); + uiItemS(layout); + + /* Split button area into two sections: 40/60. */ + uiLayout *mac_left = uiLayoutSplit(split, 0.40f, true); + + /* First button uses 75% of left side (30% of original). */ + uiLayoutSplit(mac_left, 0.75f, true); wm_block_file_close_discard_button(block, post_action); - col = uiLayoutColumn(split, true); - uiItemS(col); + /* The right side is split 50/50 (each 30% of original). */ + uiLayout *mac_right = uiLayoutSplit(mac_left, 0.50f, true); - col = uiLayoutColumn(split, true); + uiLayoutColumn(mac_right, false); wm_block_file_close_cancel_button(block, post_action); - col = uiLayoutColumn(split, false); + uiLayoutColumn(mac_right, false); wm_block_file_close_save_button(block, post_action); } diff --git a/source/blender/windowmanager/intern/wm_splash_screen.c b/source/blender/windowmanager/intern/wm_splash_screen.c index 97490f7cc3b..6e77cb23ed3 100644 --- a/source/blender/windowmanager/intern/wm_splash_screen.c +++ b/source/blender/windowmanager/intern/wm_splash_screen.c @@ -272,21 +272,13 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *region, void *UNUSE /* Size before dpi scaling (halved for hi-dpi image). */ int ibuf_unit_size[2]; ImBuf *ibuf = wm_block_splash_image(ibuf_unit_size); - but = uiDefBut(block, - UI_BTYPE_IMAGE, - 0, - "", - 0, - 0.5f * U.widget_unit, - U.dpi_fac * ibuf_unit_size[0], - U.dpi_fac * ibuf_unit_size[1], - /* Button owns the imbuf now. */ - ibuf, - 0.0, - 0.0, - 0, - 0, - ""); + but = uiDefButImage(block, + ibuf, + 0, + 0.5f * U.widget_unit, + U.dpi_fac * ibuf_unit_size[0], + U.dpi_fac * ibuf_unit_size[1], + NULL); UI_but_func_set(but, wm_block_splash_close, block, NULL); UI_block_func_set(block, wm_block_splash_refreshmenu, block, NULL); -- cgit v1.2.3