UI: Round splash image corners according to theme preferences

Round the corners of the splash screen image according to the theme's
User Interface > Menu Back > Roundness preference.

Previously the rounding was added to the image itself, which was fiddly
to do. The rounded corners of the popup background would not match
the one of the image if the preference was changed.

The current splash image will likely be updated to not include rounded
corners in a separate commit.

Differential Revision: https://developer.blender.org/D6847

Reviewed by: Julian Eisel (with some changes)
This commit is contained in:
Yevgeny Makarov 2020-04-15 11:27:56 +02:00 committed by Julian Eisel
parent 69419b5f00
commit 04828b7d99
Notes: blender-bot 2023-02-14 11:21:43 +01:00
Referenced by commit f17e7e0b62, UI: Tweak development branch splash image to exclude rounded corners
1 changed files with 71 additions and 5 deletions

View File

@ -40,6 +40,7 @@
#include "DNA_windowmanager_types.h"
#include "BLI_blenlib.h"
#include "BLI_math.h"
#include "BLI_utildefines.h"
#include "BKE_appdir.h"
@ -55,6 +56,7 @@
#include "ED_screen.h"
#include "UI_interface.h"
#include "UI_resources.h"
#include "WM_api.h"
#include "WM_types.h"
@ -178,13 +180,65 @@ static void wm_block_splash_add_labels(uiBlock *block, int x, int y)
#endif /* WITH_BUILDINFO */
}
static ImBuf *wm_block_splash_image(void)
static void wm_block_splash_image_roundcorners_add(ImBuf *ibuf)
{
uchar *rct = (uchar *)ibuf->rect;
if (rct) {
bTheme *btheme = UI_GetTheme();
const float roundness = btheme->tui.wcol_menu_back.roundness * U.dpi_fac;
const int size = roundness * 20;
if (size < ibuf->x && size < ibuf->y) {
/* Y-axis initial offset. */
rct += 4 * (ibuf->y - size) * ibuf->x;
for (int y = 0; y < size; y++) {
for (int x = 0; x < size; x++, rct += 4) {
const float pixel = 1.0 / size;
const float u = pixel * x;
const float v = pixel * y;
const float distance = sqrt(u * u + v * v);
/* Pointer offset to the alpha value of pixel. */
/* Note, the left corner is flipped in the X-axis. */
const int offset_l = 4 * (size - x - x - 1) + 3;
const int offset_r = 4 * (ibuf->x - size) + 3;
if (distance > 1.0) {
rct[offset_l] = 0;
rct[offset_r] = 0;
}
else {
/* Create a single pixel wide transition for anti-aliasing.
* Invert the distance and map its range [0, 1] to [0, pixel]. */
const float fac = (1.0 - distance) * size;
if (fac > 1.0) {
continue;
}
const uchar alpha = unit_float_to_uchar_clamp(fac);
rct[offset_l] = alpha;
rct[offset_r] = alpha;
}
}
/* X-axis offset to the next row. */
rct += 4 * (ibuf->x - size);
}
}
}
}
static ImBuf *wm_block_splash_image(int width, int *r_height)
{
#ifndef WITH_HEADLESS
extern char datatoc_splash_png[];
extern int datatoc_splash_png_size;
ImBuf *ibuf = NULL;
int height = 0;
if (U.app_template[0] != '\0') {
char splash_filepath[FILE_MAX];
@ -202,6 +256,18 @@ static ImBuf *wm_block_splash_image(void)
ibuf = IMB_ibImageFromMemory(splash_data, splash_data_size, IB_rect, NULL, "<splash screen>");
}
if (ibuf) {
height = (width * ibuf->y) / ibuf->x;
if (width != ibuf->x || height != ibuf->y) {
IMB_scaleImBuf(ibuf, width, height);
}
wm_block_splash_image_roundcorners_add(ibuf);
IMB_premultiply_alpha(ibuf);
}
*r_height = height;
return ibuf;
#else
UNUSED_VARS(r_unit_size);
@ -223,12 +289,12 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *region, void *UNUSE
UI_block_flag_enable(block, UI_BLOCK_LOOP | UI_BLOCK_KEEP_OPEN | UI_BLOCK_NO_WIN_CLIP);
UI_block_theme_style_set(block, UI_BLOCK_THEME_STYLE_POPUP);
int splash_width = 500.0f * U.dpi_fac;
int splash_height;
/* Would be nice to support caching this, so it only has to be re-read (and likely resized) on
* first draw or if the image changed. */
ImBuf *ibuf = wm_block_splash_image();
float splash_width = 500.0f * U.dpi_fac;
float splash_height = (splash_width * ibuf->y) / ibuf->x;
ImBuf *ibuf = wm_block_splash_image(splash_width, &splash_height);
but = uiDefButImage(block, ibuf, 0, 0.5f * U.widget_unit, splash_width, splash_height, NULL);