Blender  V2.93
wm_splash_screen.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2007 Blender Foundation.
17  * All rights reserved.
18  */
19 
32 #include <string.h>
33 
34 #include "CLG_log.h"
35 
36 #include "DNA_ID.h"
37 #include "DNA_scene_types.h"
38 #include "DNA_screen_types.h"
39 #include "DNA_userdef_types.h"
41 
42 #include "BLI_blenlib.h"
43 #include "BLI_math.h"
44 #include "BLI_utildefines.h"
45 
46 #include "BKE_appdir.h"
47 #include "BKE_blender_version.h"
48 #include "BKE_context.h"
49 #include "BKE_screen.h"
50 
51 #include "BLT_translation.h"
52 
53 #include "BLF_api.h"
54 
55 #include "IMB_imbuf.h"
56 #include "IMB_imbuf_types.h"
57 
58 #include "ED_screen.h"
59 
60 #include "UI_interface.h"
61 #include "UI_interface_icons.h"
62 #include "UI_resources.h"
63 
64 #include "WM_api.h"
65 #include "WM_types.h"
66 
67 #include "wm.h"
68 
69 static void wm_block_close(bContext *C, void *arg_block, void *UNUSED(arg))
70 {
71  wmWindow *win = CTX_wm_window(C);
72  UI_popup_block_close(C, win, arg_block);
73 }
74 
75 static void wm_block_splash_add_label(uiBlock *block, const char *label, int x, int y)
76 {
77  if (!(label && label[0])) {
78  return;
79  }
80 
82 
83  uiBut *but = uiDefBut(
84  block, UI_BTYPE_LABEL, 0, label, 0, y, x, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
87 
88  /* 1 = UI_SELECT, internal flag to draw in white. */
89  UI_but_flag_enable(but, 1);
91 }
92 
93 #ifndef WITH_HEADLESS
95 {
96  uchar *rct = (uchar *)ibuf->rect;
97 
98  if (rct) {
99  bTheme *btheme = UI_GetTheme();
100  const float roundness = btheme->tui.wcol_menu_back.roundness * U.dpi_fac;
101  const int size = roundness * 20;
102 
103  if (size < ibuf->x && size < ibuf->y) {
104  /* Y-axis initial offset. */
105  rct += 4 * (ibuf->y - size) * ibuf->x;
106 
107  for (int y = 0; y < size; y++) {
108  for (int x = 0; x < size; x++, rct += 4) {
109  const float pixel = 1.0 / size;
110  const float u = pixel * x;
111  const float v = pixel * y;
112  const float distance = sqrt(u * u + v * v);
113 
114  /* Pointer offset to the alpha value of pixel. */
115  /* Note, the left corner is flipped in the X-axis. */
116  const int offset_l = 4 * (size - x - x - 1) + 3;
117  const int offset_r = 4 * (ibuf->x - size) + 3;
118 
119  if (distance > 1.0) {
120  rct[offset_l] = 0;
121  rct[offset_r] = 0;
122  }
123  else {
124  /* Create a single pixel wide transition for anti-aliasing.
125  * Invert the distance and map its range [0, 1] to [0, pixel]. */
126  const float fac = (1.0 - distance) * size;
127 
128  if (fac > 1.0) {
129  continue;
130  }
131 
133  rct[offset_l] = alpha;
134  rct[offset_r] = alpha;
135  }
136  }
137 
138  /* X-axis offset to the next row. */
139  rct += 4 * (ibuf->x - size);
140  }
141  }
142  }
143 }
144 #endif /* WITH_HEADLESS */
145 
146 static ImBuf *wm_block_splash_image(int width, int *r_height)
147 {
148 #ifndef WITH_HEADLESS
149  extern char datatoc_splash_png[];
150  extern int datatoc_splash_png_size;
151 
152  ImBuf *ibuf = NULL;
153  if (U.app_template[0] != '\0') {
154  char splash_filepath[FILE_MAX];
155  char template_directory[FILE_MAX];
157  U.app_template, template_directory, sizeof(template_directory))) {
158  BLI_join_dirfile(splash_filepath, sizeof(splash_filepath), template_directory, "splash.png");
159  ibuf = IMB_loadiffname(splash_filepath, IB_rect, NULL);
160  }
161  }
162 
163  if (ibuf == NULL) {
164  const uchar *splash_data = (const uchar *)datatoc_splash_png;
165  size_t splash_data_size = datatoc_splash_png_size;
166  ibuf = IMB_ibImageFromMemory(splash_data, splash_data_size, IB_rect, NULL, "<splash screen>");
167  }
168 
169  int height = 0;
170  if (ibuf) {
171  height = (width * ibuf->y) / ibuf->x;
172  if (width != ibuf->x || height != ibuf->y) {
173  IMB_scaleImBuf(ibuf, width, height);
174  }
175 
177  IMB_premultiply_alpha(ibuf);
178  }
179 
180  *r_height = height;
181 
182  return ibuf;
183 #else
184  UNUSED_VARS(width, r_height);
185  return NULL;
186 #endif
187 }
188 
189 static uiBlock *wm_block_create_splash(bContext *C, ARegion *region, void *UNUSED(arg))
190 {
191  const uiStyle *style = UI_style_get_dpi();
192 
193  uiBlock *block = UI_block_begin(C, region, "splash", UI_EMBOSS);
194 
195  /* note on UI_BLOCK_NO_WIN_CLIP, the window size is not always synchronized
196  * with the OS when the splash shows, window clipping in this case gives
197  * ugly results and clipping the splash isn't useful anyway, just disable it T32938. */
200 
201  const int text_points_max = MAX2(style->widget.points, style->widgetlabel.points);
202  int splash_width = text_points_max * 45 * U.dpi_fac;
203  CLAMP_MAX(splash_width, CTX_wm_window(C)->sizex * 0.7f);
204  int splash_height;
205 
206  /* Would be nice to support caching this, so it only has to be re-read (and likely resized) on
207  * first draw or if the image changed. */
208  ImBuf *ibuf = wm_block_splash_image(splash_width, &splash_height);
209 
210  uiBut *but = uiDefButImage(
211  block, ibuf, 0, 0.5f * U.widget_unit, splash_width, splash_height, NULL);
212 
213  UI_but_func_set(but, wm_block_close, block, NULL);
214 
216  block, BKE_blender_version_string(), splash_width, splash_height - 13.0 * U.dpi_fac);
217 
218  const int layout_margin_x = U.dpi_fac * 26;
219  uiLayout *layout = UI_block_layout(block,
222  layout_margin_x,
223  0,
224  splash_width - (layout_margin_x * 2),
225  U.dpi_fac * 110,
226  0,
227  style);
228 
229  MenuType *mt;
230  char userpref[FILE_MAX];
231  const char *const cfgdir = BKE_appdir_folder_id(BLENDER_USER_CONFIG, NULL);
232 
233  if (cfgdir) {
234  BLI_path_join(userpref, sizeof(userpref), cfgdir, BLENDER_USERPREF_FILE, NULL);
235  }
236 
237  /* Draw setup screen if no preferences have been saved yet. */
238  if (!BLI_exists(userpref)) {
239  mt = WM_menutype_find("WM_MT_splash_quick_setup", true);
240 
241  /* The UI_BLOCK_QUICK_SETUP flag prevents the button text from being left-aligned,
242  as it is for all menus due to the UI_BLOCK_LOOP flag, see in 'ui_def_but'. */
244  }
245  else {
246  mt = WM_menutype_find("WM_MT_splash", true);
247  }
248 
249  if (mt) {
250  UI_menutype_draw(C, mt, layout);
251  }
252 
254 
255  return block;
256 }
257 
258 static int wm_splash_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
259 {
261 
262  return OPERATOR_FINISHED;
263 }
264 
266 {
267  ot->name = "Splash Screen";
268  ot->idname = "WM_OT_splash";
269  ot->description = "Open the splash screen with release info";
270 
273 }
274 
275 static uiBlock *wm_block_create_about(bContext *C, ARegion *region, void *UNUSED(arg))
276 {
277  const uiStyle *style = UI_style_get_dpi();
278  const int text_points_max = MAX2(style->widget.points, style->widgetlabel.points);
279  const int dialog_width = text_points_max * 42 * U.dpi_fac;
280 
281  uiBlock *block = UI_block_begin(C, region, "about", UI_EMBOSS);
282 
285 
286  uiLayout *layout = UI_block_layout(
287  block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, dialog_width, 0, 0, style);
288 
289  /* Blender logo. */
290 #ifndef WITH_HEADLESS
291  extern char datatoc_blender_logo_png[];
293 
294  const uchar *blender_logo_data = (const uchar *)datatoc_blender_logo_png;
295  size_t blender_logo_data_size = datatoc_blender_logo_png_size;
297  blender_logo_data, blender_logo_data_size, IB_rect, NULL, "blender_logo");
298 
299  if (ibuf) {
300  int width = 0.5 * dialog_width;
301  int height = (width * ibuf->y) / ibuf->x;
302 
303  IMB_premultiply_alpha(ibuf);
304  IMB_scaleImBuf(ibuf, width, height);
305 
306  bTheme *btheme = UI_GetTheme();
307  const uchar *color = btheme->tui.wcol_menu_back.text_sel;
308 
309  /* The top margin. */
310  uiLayout *row = uiLayoutRow(layout, false);
311  uiItemS_ex(row, 0.2f);
312 
313  /* The logo image. */
314  row = uiLayoutRow(layout, false);
316  uiDefButImage(block, ibuf, 0, U.widget_unit, width, height, color);
317 
318  /* Padding below the logo. */
319  row = uiLayoutRow(layout, false);
320  uiItemS_ex(row, 2.7f);
321  }
322 #endif /* WITH_HEADLESS */
323 
324  uiLayout *col = uiLayoutColumn(layout, true);
325 
326  uiItemL_ex(col, N_("Blender"), ICON_NONE, true, false);
327 
328  MenuType *mt = WM_menutype_find("WM_MT_splash_about", true);
329  if (mt) {
330  UI_menutype_draw(C, mt, col);
331  }
332 
333  UI_block_bounds_set_centered(block, 22 * U.dpi_fac);
334 
335  return block;
336 }
337 
338 static int wm_about_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *UNUSED(event))
339 {
341 
342  return OPERATOR_FINISHED;
343 }
344 
346 {
347  ot->name = "About Blender";
348  ot->idname = "WM_OT_splash_about";
349  ot->description = "Open a window with information about Blender";
350 
353 }
@ BLENDER_USER_CONFIG
Definition: BKE_appdir.h:81
#define BLENDER_USERPREF_FILE
Definition: BKE_appdir.h:100
const char * BKE_appdir_folder_id(const int folder_id, const char *subfolder)
Definition: appdir.c:674
bool BKE_appdir_app_template_id_search(const char *app_template, char *path, size_t path_len)
Definition: appdir.c:1001
const char * BKE_blender_version_string(void)
Definition: blender.c:142
struct wmWindow * CTX_wm_window(const bContext *C)
Definition: context.c:699
sqrt(x)+1/max(0
int BLI_exists(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: storage.c:349
#define FILE_MAX
void BLI_join_dirfile(char *__restrict dst, const size_t maxlen, const char *__restrict dir, const char *__restrict file) ATTR_NONNULL()
Definition: path_util.c:1737
size_t BLI_path_join(char *__restrict dst, const size_t dst_len, const char *path_first,...) ATTR_NONNULL(1
unsigned char uchar
Definition: BLI_sys_types.h:86
#define CLAMP_MAX(a, c)
#define UNUSED_VARS(...)
#define UNUSED(x)
#define MAX2(a, b)
#define N_(msgid)
ID and Library types, which are fundamental for sdna.
@ OPERATOR_FINISHED
int datatoc_splash_png_size
int datatoc_blender_logo_png_size
char datatoc_splash_png[]
char datatoc_blender_logo_png[]
_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
_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
bool IMB_scaleImBuf(struct ImBuf *ibuf, unsigned int newx, unsigned int newy)
Definition: scaling.c:1667
struct ImBuf * IMB_loadiffname(const char *filepath, int flags, char colorspace[IM_MAX_SPACE])
Definition: readimage.c:224
void IMB_premultiply_alpha(struct ImBuf *ibuf)
Definition: filter.c:687
struct ImBuf * IMB_ibImageFromMemory(const unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE], const char *descr)
Definition: readimage.c:99
Contains defines and structs used throughout the imbuf module.
@ IB_rect
#define C
Definition: RandGen.cpp:39
void uiItemS_ex(uiLayout *layout, float factor)
#define UI_UNIT_Y
void uiItemL_ex(uiLayout *layout, const char *name, int icon, const bool highlight, const bool redalert)
@ UI_BUT_TEXT_RIGHT
Definition: UI_interface.h:261
@ UI_BUT_TEXT_LEFT
Definition: UI_interface.h:259
@ UI_EMBOSS_NONE
Definition: UI_interface.h:108
@ UI_EMBOSS
Definition: UI_interface.h:107
const struct uiStyle * UI_style_get_dpi(void)
void UI_block_theme_style_set(uiBlock *block, char theme_style)
Definition: interface.c:3547
uiBut * uiDefButImage(uiBlock *block, void *imbuf, int x, int y, short width, short height, const uchar color[4])
Definition: interface.c:4710
void UI_popup_block_close(struct bContext *C, struct wmWindow *win, uiBlock *block)
uiLayout * uiLayoutColumn(uiLayout *layout, bool align)
@ UI_LAYOUT_PANEL
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.c:4687
void UI_but_drawflag_enable(uiBut *but, int flag)
Definition: interface.c:6092
void uiLayoutSetAlignment(uiLayout *layout, char alignment)
uiLayout * uiLayoutRow(uiLayout *layout, bool align)
@ UI_LAYOUT_ALIGN_LEFT
void UI_popup_block_invoke(struct bContext *C, uiBlockCreateFunc func, void *arg, void(*arg_free)(void *arg))
void UI_block_emboss_set(uiBlock *block, eUIEmbossType emboss)
Definition: interface.c:3542
void UI_but_drawflag_disable(uiBut *but, int flag)
Definition: interface.c:6097
@ UI_BLOCK_LOOP
Definition: UI_interface.h:140
@ UI_BLOCK_KEEP_OPEN
Definition: UI_interface.h:149
@ UI_BLOCK_QUICK_SETUP
Definition: UI_interface.h:170
@ UI_BLOCK_NO_WIN_CLIP
Definition: UI_interface.h:145
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.c:6294
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.c:626
@ UI_LAYOUT_VERTICAL
void UI_block_flag_enable(uiBlock *block, int flag)
Definition: interface.c:6067
@ UI_BTYPE_LABEL
Definition: UI_interface.h:358
@ UI_BLOCK_THEME_STYLE_POPUP
Definition: UI_interface.h:671
void UI_but_flag_enable(uiBut *but, int flag)
Definition: interface.c:6077
struct bTheme * UI_GetTheme(void)
Definition: resources.c:1086
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
static CCL_NAMESPACE_BEGIN const double alpha
uint col
MINLINE unsigned char unit_float_to_uchar_clamp(float val)
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:752
const char * name
Definition: WM_types.h:721
const char * idname
Definition: WM_types.h:723
bool(* poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:776
const char * description
Definition: WM_types.h:726
ccl_device_inline float distance(const float2 &a, const float2 &b)
wmOperatorType * ot
Definition: wm_files.c:3156
MenuType * WM_menutype_find(const char *idname, bool quiet)
Definition: wm_menu_type.c:44
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)