Blender  V3.3
wm_splash_screen.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2007 Blender Foundation. All rights reserved. */
3 
16 #include <string.h>
17 
18 #include "CLG_log.h"
19 
20 #include "DNA_ID.h"
21 #include "DNA_scene_types.h"
22 #include "DNA_screen_types.h"
23 #include "DNA_userdef_types.h"
25 
26 #include "BLI_blenlib.h"
27 #include "BLI_math.h"
28 #include "BLI_utildefines.h"
29 
30 #include "BKE_appdir.h"
31 #include "BKE_blender_version.h"
32 #include "BKE_context.h"
33 #include "BKE_screen.h"
34 
35 #include "BLT_translation.h"
36 
37 #include "BLF_api.h"
38 
39 #include "IMB_imbuf.h"
40 #include "IMB_imbuf_types.h"
41 
42 #include "ED_screen.h"
43 
44 #include "UI_interface.h"
45 #include "UI_interface_icons.h"
46 #include "UI_resources.h"
47 
48 #include "WM_api.h"
49 #include "WM_types.h"
50 
51 #include "wm.h"
52 
53 static void wm_block_close(bContext *C, void *arg_block, void *UNUSED(arg))
54 {
55  wmWindow *win = CTX_wm_window(C);
56  UI_popup_block_close(C, win, arg_block);
57 }
58 
59 static void wm_block_splash_add_label(uiBlock *block, const char *label, int x, int y)
60 {
61  if (!(label && label[0])) {
62  return;
63  }
64 
66 
67  uiBut *but = uiDefBut(
68  block, UI_BTYPE_LABEL, 0, label, 0, y, x, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
71 
72  /* 1 = UI_SELECT, internal flag to draw in white. */
73  UI_but_flag_enable(but, 1);
75 }
76 
77 #ifndef WITH_HEADLESS
79 {
80  uchar *rct = (uchar *)ibuf->rect;
81 
82  if (rct) {
83  bTheme *btheme = UI_GetTheme();
84  const float roundness = btheme->tui.wcol_menu_back.roundness * U.dpi_fac;
85  const int size = roundness * 20;
86 
87  if (size < ibuf->x && size < ibuf->y) {
88  /* Y-axis initial offset. */
89  rct += 4 * (ibuf->y - size) * ibuf->x;
90 
91  for (int y = 0; y < size; y++) {
92  for (int x = 0; x < size; x++, rct += 4) {
93  const float pixel = 1.0 / size;
94  const float u = pixel * x;
95  const float v = pixel * y;
96  const float distance = sqrt(u * u + v * v);
97 
98  /* Pointer offset to the alpha value of pixel. */
99  /* NOTE: the left corner is flipped in the X-axis. */
100  const int offset_l = 4 * (size - x - x - 1) + 3;
101  const int offset_r = 4 * (ibuf->x - size) + 3;
102 
103  if (distance > 1.0) {
104  rct[offset_l] = 0;
105  rct[offset_r] = 0;
106  }
107  else {
108  /* Create a single pixel wide transition for anti-aliasing.
109  * Invert the distance and map its range [0, 1] to [0, pixel]. */
110  const float fac = (1.0 - distance) * size;
111 
112  if (fac > 1.0) {
113  continue;
114  }
115 
116  const uchar alpha = unit_float_to_uchar_clamp(fac);
117  rct[offset_l] = alpha;
118  rct[offset_r] = alpha;
119  }
120  }
121 
122  /* X-axis offset to the next row. */
123  rct += 4 * (ibuf->x - size);
124  }
125  }
126  }
127 }
128 #endif /* WITH_HEADLESS */
129 
130 static ImBuf *wm_block_splash_image(int width, int *r_height)
131 {
132 #ifndef WITH_HEADLESS
133  extern char datatoc_splash_png[];
134  extern int datatoc_splash_png_size;
135 
136  ImBuf *ibuf = NULL;
137  if (U.app_template[0] != '\0') {
138  char splash_filepath[FILE_MAX];
139  char template_directory[FILE_MAX];
141  U.app_template, template_directory, sizeof(template_directory))) {
142  BLI_join_dirfile(splash_filepath, sizeof(splash_filepath), template_directory, "splash.png");
143  ibuf = IMB_loadiffname(splash_filepath, IB_rect, NULL);
144  }
145  }
146 
147  if (ibuf == NULL) {
148  const uchar *splash_data = (const uchar *)datatoc_splash_png;
149  size_t splash_data_size = datatoc_splash_png_size;
150  ibuf = IMB_ibImageFromMemory(splash_data, splash_data_size, IB_rect, NULL, "<splash screen>");
151  }
152 
153  int height = 0;
154  if (ibuf) {
155  height = (width * ibuf->y) / ibuf->x;
156  if (width != ibuf->x || height != ibuf->y) {
157  IMB_scaleImBuf(ibuf, width, height);
158  }
159 
161  IMB_premultiply_alpha(ibuf);
162  }
163 
164  *r_height = height;
165 
166  return ibuf;
167 #else
168  UNUSED_VARS(width, r_height);
169  return NULL;
170 #endif
171 }
172 
173 static uiBlock *wm_block_create_splash(bContext *C, ARegion *region, void *UNUSED(arg))
174 {
175  const uiStyle *style = UI_style_get_dpi();
176 
177  uiBlock *block = UI_block_begin(C, region, "splash", UI_EMBOSS);
178 
179  /* note on UI_BLOCK_NO_WIN_CLIP, the window size is not always synchronized
180  * with the OS when the splash shows, window clipping in this case gives
181  * ugly results and clipping the splash isn't useful anyway, just disable it T32938. */
184 
185  const int text_points_max = MAX2(style->widget.points, style->widgetlabel.points);
186  int splash_width = text_points_max * 45 * U.dpi_fac;
187  CLAMP_MAX(splash_width, CTX_wm_window(C)->sizex * 0.7f);
188  int splash_height;
189 
190  /* Would be nice to support caching this, so it only has to be re-read (and likely resized) on
191  * first draw or if the image changed. */
192  ImBuf *ibuf = wm_block_splash_image(splash_width, &splash_height);
193 
194  uiBut *but = uiDefButImage(
195  block, ibuf, 0, 0.5f * U.widget_unit, splash_width, splash_height, NULL);
196 
197  UI_but_func_set(but, wm_block_close, block, NULL);
198 
201  splash_width - 8.0 * U.dpi_fac,
202  splash_height - 13.0 * U.dpi_fac);
203 
204  const int layout_margin_x = U.dpi_fac * 26;
205  uiLayout *layout = UI_block_layout(block,
208  layout_margin_x,
209  0,
210  splash_width - (layout_margin_x * 2),
211  U.dpi_fac * 110,
212  0,
213  style);
214 
215  MenuType *mt;
216  char userpref[FILE_MAX];
217  const char *const cfgdir = BKE_appdir_folder_id(BLENDER_USER_CONFIG, NULL);
218 
219  if (cfgdir) {
220  BLI_path_join(userpref, sizeof(userpref), cfgdir, BLENDER_USERPREF_FILE, NULL);
221  }
222 
223  /* Draw setup screen if no preferences have been saved yet. */
224  if (!BLI_exists(userpref)) {
225  mt = WM_menutype_find("WM_MT_splash_quick_setup", true);
226 
227  /* The #UI_BLOCK_QUICK_SETUP flag prevents the button text from being left-aligned,
228  * as it is for all menus due to the #UI_BLOCK_LOOP flag, see in #ui_def_but. */
230  }
231  else {
232  mt = WM_menutype_find("WM_MT_splash", true);
233  }
234 
235  if (mt) {
236  UI_menutype_draw(C, mt, layout);
237  }
238 
240 
241  return block;
242 }
243 
244 static int wm_splash_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
245 {
247 
248  return OPERATOR_FINISHED;
249 }
250 
252 {
253  ot->name = "Splash Screen";
254  ot->idname = "WM_OT_splash";
255  ot->description = "Open the splash screen with release info";
256 
259 }
260 
261 static uiBlock *wm_block_create_about(bContext *C, ARegion *region, void *UNUSED(arg))
262 {
263  const uiStyle *style = UI_style_get_dpi();
264  const int text_points_max = MAX2(style->widget.points, style->widgetlabel.points);
265  const int dialog_width = text_points_max * 42 * U.dpi_fac;
266 
267  uiBlock *block = UI_block_begin(C, region, "about", UI_EMBOSS);
268 
271 
272  uiLayout *layout = UI_block_layout(
273  block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, dialog_width, 0, 0, style);
274 
275  /* Blender logo. */
276 #ifndef WITH_HEADLESS
277  extern char datatoc_blender_logo_png[];
279 
280  const uchar *blender_logo_data = (const uchar *)datatoc_blender_logo_png;
281  size_t blender_logo_data_size = datatoc_blender_logo_png_size;
283  blender_logo_data, blender_logo_data_size, IB_rect, NULL, "blender_logo");
284 
285  if (ibuf) {
286  int width = 0.5 * dialog_width;
287  int height = (width * ibuf->y) / ibuf->x;
288 
289  IMB_premultiply_alpha(ibuf);
290  IMB_scaleImBuf(ibuf, width, height);
291 
292  bTheme *btheme = UI_GetTheme();
293  const uchar *color = btheme->tui.wcol_menu_back.text_sel;
294 
295  /* The top margin. */
296  uiLayout *row = uiLayoutRow(layout, false);
297  uiItemS_ex(row, 0.2f);
298 
299  /* The logo image. */
300  row = uiLayoutRow(layout, false);
302  uiDefButImage(block, ibuf, 0, U.widget_unit, width, height, color);
303 
304  /* Padding below the logo. */
305  row = uiLayoutRow(layout, false);
306  uiItemS_ex(row, 2.7f);
307  }
308 #endif /* WITH_HEADLESS */
309 
310  uiLayout *col = uiLayoutColumn(layout, true);
311 
312  uiItemL_ex(col, IFACE_("Blender"), ICON_NONE, true, false);
313 
314  MenuType *mt = WM_menutype_find("WM_MT_splash_about", true);
315  if (mt) {
316  UI_menutype_draw(C, mt, col);
317  }
318 
319  UI_block_bounds_set_centered(block, 22 * U.dpi_fac);
320 
321  return block;
322 }
323 
324 static int wm_about_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
325 {
327 
328  return OPERATOR_FINISHED;
329 }
330 
332 {
333  ot->name = "About Blender";
334  ot->idname = "WM_OT_splash_about";
335  ot->description = "Open a window with information about Blender";
336 
339 }
#define BLENDER_USERPREF_FILE
Definition: BKE_appdir.h:176
const char * BKE_appdir_folder_id(int folder_id, const char *subfolder)
Definition: appdir.c:672
bool BKE_appdir_app_template_id_search(const char *app_template, char *path, size_t path_len)
Definition: appdir.c:980
@ BLENDER_USER_CONFIG
Definition: BKE_appdir.h:157
const char * BKE_blender_version_string(void)
Definition: blender.c:124
struct wmWindow * CTX_wm_window(const bContext *C)
Definition: context.c:723
sqrt(x)+1/max(0
int BLI_exists(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: storage.c:314
#define FILE_MAX
size_t BLI_path_join(char *__restrict dst, size_t dst_len, const char *path_first,...) ATTR_NONNULL(1
void BLI_join_dirfile(char *__restrict dst, size_t maxlen, const char *__restrict dir, const char *__restrict file) ATTR_NONNULL()
Definition: path_util.c:1531
unsigned char uchar
Definition: BLI_sys_types.h:70
#define CLAMP_MAX(a, c)
#define UNUSED_VARS(...)
#define UNUSED(x)
#define MAX2(a, b)
#define IFACE_(msgid)
ID and Library types, which are fundamental for sdna.
@ OPERATOR_FINISHED
const char datatoc_blender_logo_png[]
int datatoc_splash_png_size
int datatoc_blender_logo_png_size
const char datatoc_splash_png[]
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei height
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei width
bool IMB_scaleImBuf(struct ImBuf *ibuf, unsigned int newx, unsigned int newy)
Definition: scaling.c:1644
struct ImBuf * IMB_loadiffname(const char *filepath, int flags, char colorspace[IM_MAX_SPACE])
Definition: readimage.c:209
void IMB_premultiply_alpha(struct ImBuf *ibuf)
Definition: filter.c:662
struct ImBuf * IMB_ibImageFromMemory(const unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE], const char *descr)
Definition: readimage.c:84
Contains defines and structs used throughout the imbuf module.
@ IB_rect
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to used to fine tune the interpolation of the input Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert a color
#define C
Definition: RandGen.cpp:25
@ UI_LAYOUT_ALIGN_LEFT
void uiItemS_ex(uiLayout *layout, float factor)
@ UI_BUT_TEXT_RIGHT
Definition: UI_interface.h:261
@ UI_BUT_TEXT_LEFT
Definition: UI_interface.h:259
@ UI_LAYOUT_VERTICAL
#define UI_UNIT_Y
@ UI_EMBOSS_NONE
Definition: UI_interface.h:109
@ UI_EMBOSS
Definition: UI_interface.h:108
const struct uiStyle * UI_style_get_dpi(void)
void UI_block_theme_style_set(uiBlock *block, char theme_style)
Definition: interface.cc:3634
uiBut * uiDefButImage(uiBlock *block, void *imbuf, int x, int y, short width, short height, const uchar color[4])
Definition: interface.cc:4829
void UI_popup_block_close(struct bContext *C, struct wmWindow *win, uiBlock *block)
uiLayout * uiLayoutColumn(uiLayout *layout, bool align)
void UI_menutype_draw(struct bContext *C, struct MenuType *mt, struct uiLayout *layout)
uiBut * uiDefBut(uiBlock *block, int type, int retval, const char *str, int x, int y, short width, short height, void *poin, float min, float max, float a1, float a2, const char *tip)
Definition: interface.cc:4806
@ UI_BLOCK_THEME_STYLE_POPUP
Definition: UI_interface.h:770
@ UI_LAYOUT_PANEL
void UI_but_drawflag_enable(uiBut *but, int flag)
Definition: interface.cc:5873
void uiLayoutSetAlignment(uiLayout *layout, char alignment)
uiLayout * uiLayoutRow(uiLayout *layout, bool align)
void UI_block_emboss_set(uiBlock *block, eUIEmbossType emboss)
Definition: interface.cc:3629
void UI_but_drawflag_disable(uiBut *but, int flag)
Definition: interface.cc:5878
uiLayout * UI_block_layout(uiBlock *block, int dir, int type, int x, int y, int size, int em, int padding, const struct uiStyle *style)
void UI_but_func_set(uiBut *but, uiButHandleFunc func, void *arg1, void *arg2)
Definition: interface.cc:6000
uiBlock * UI_block_begin(const struct bContext *C, struct ARegion *region, const char *name, eUIEmbossType emboss)
void UI_block_bounds_set_centered(uiBlock *block, int addval)
Definition: interface.cc:624
void UI_block_flag_enable(uiBlock *block, int flag)
Definition: interface.cc:5848
@ UI_BTYPE_LABEL
Definition: UI_interface.h:354
void uiItemL_ex(uiLayout *layout, const char *name, int icon, bool highlight, bool redalert)
void UI_popup_block_invoke(struct bContext *C, uiBlockCreateFunc func, void *arg, uiFreeArgFunc arg_free)
void UI_but_flag_enable(uiBut *but, int flag)
Definition: interface.cc:5858
@ UI_BLOCK_LOOP
Definition: UI_interface.h:135
@ UI_BLOCK_KEEP_OPEN
Definition: UI_interface.h:144
@ UI_BLOCK_QUICK_SETUP
Definition: UI_interface.h:167
@ UI_BLOCK_NO_WIN_CLIP
Definition: UI_interface.h:140
struct bTheme * UI_GetTheme(void)
Definition: resources.c:1067
ATTR_WARN_UNUSED_RESULT const BMVert * v
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
unsigned int U
Definition: btGjkEpa3.h:78
const char * label
uint col
MINLINE unsigned char unit_float_to_uchar_clamp(float val)
T distance(const T &a, const T &b)
unsigned int * rect
uiWidgetColors wcol_menu_back
ThemeUI tui
uiFontStyle widget
uiFontStyle widgetlabel
unsigned char text_sel[4]
int(* invoke)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:919
const char * name
Definition: WM_types.h:888
const char * idname
Definition: WM_types.h:890
bool(* poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:943
const char * description
Definition: WM_types.h:893
wmOperatorType * ot
Definition: wm_files.c:3479
MenuType * WM_menutype_find(const char *idname, bool quiet)
Definition: wm_menu_type.c:30
bool WM_operator_winactive(bContext *C)
void WM_OT_splash_about(wmOperatorType *ot)
static uiBlock * wm_block_create_about(bContext *C, ARegion *region, void *UNUSED(arg))
static ImBuf * wm_block_splash_image(int width, int *r_height)
static int wm_splash_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
static void wm_block_splash_add_label(uiBlock *block, const char *label, int x, int y)
static void wm_block_close(bContext *C, void *arg_block, void *UNUSED(arg))
static int wm_about_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
static uiBlock * wm_block_create_splash(bContext *C, ARegion *region, void *UNUSED(arg))
static void wm_block_splash_image_roundcorners_add(ImBuf *ibuf)
void WM_OT_splash(wmOperatorType *ot)