From b49abbec5fff29978d04572b9ac341c8a50b84cf Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Tue, 18 Sep 2018 17:44:14 +0200 Subject: [PATCH] Splash: add first time setup and templates to splash screen. The first time setup screen only has the interaction preset currently, some more work is needed to be able to set e.g. the language or compute device here as in the mockups. The splash screen stayed the same for now, to make room for the templates most of the links are now in the Help menu. If there are no recent files yet the links still show. The splash screen buttons implementation was fully moved to Python, in the WM_MT_splash menu. --- release/scripts/startup/bl_operators/wm.py | 190 ++++++++++++++++-- release/scripts/startup/bl_ui/space_topbar.py | 66 ++++-- .../scripts/startup/bl_ui/space_userpref.py | 47 ----- source/blender/editors/include/UI_interface.h | 2 + source/blender/editors/interface/interface.c | 6 +- .../editors/interface/interface_layout.c | 6 +- .../editors/interface/interface_templates.c | 20 ++ source/blender/makesrna/intern/rna_ui_api.c | 6 + .../windowmanager/intern/wm_event_system.c | 3 + .../windowmanager/intern/wm_operators.c | 84 +------- 10 files changed, 265 insertions(+), 165 deletions(-) diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py index 9b09ff86c08..18104468577 100644 --- a/release/scripts/startup/bl_operators/wm.py +++ b/release/scripts/startup/bl_operators/wm.py @@ -20,6 +20,7 @@ import bpy from bpy.types import ( + Menu, Operator, OperatorFileListElement ) @@ -1490,33 +1491,51 @@ class WM_OT_copy_prev_settings(Operator): bl_idname = "wm.copy_prev_settings" bl_label = "Copy Previous Settings" + @staticmethod + def previous_version(): + ver = bpy.app.version + ver_old = ((ver[0] * 100) + ver[1]) - 1 + return ver_old // 100, ver_old % 100 + + @staticmethod + def _old_path(): + ver = bpy.app.version + ver_old = ((ver[0] * 100) + ver[1]) - 1 + return bpy.utils.resource_path('USER', ver_old // 100, ver_old % 100) + + @staticmethod + def _new_path(): + return bpy.utils.resource_path('USER') + + @classmethod + def poll(cls, context): + import os + + old = cls._old_path() + new = cls._new_path() + if os.path.isdir(old) and not os.path.isdir(new): + return True + + old_userpref = os.path.join(old, "config", "userpref.blend") + new_userpref = os.path.join(new, "config", "userpref.blend") + return os.path.isfile(old_userpref) and not os.path.isfile(new_userpref) + def execute(self, context): import os import shutil - ver = bpy.app.version - ver_old = ((ver[0] * 100) + ver[1]) - 1 - path_src = bpy.utils.resource_path('USER', ver_old // 100, ver_old % 100) - path_dst = bpy.utils.resource_path('USER') - if os.path.isdir(path_dst): - self.report({'ERROR'}, "Target path %r exists" % path_dst) - elif not os.path.isdir(path_src): - self.report({'ERROR'}, "Source path %r does not exist" % path_src) + shutil.copytree(self._old_path(), self._new_path(), symlinks=True) + + # reload recent-files.txt + bpy.ops.wm.read_history() + + # don't loose users work if they open the splash later. + if bpy.data.is_saved is bpy.data.is_dirty is False: + bpy.ops.wm.read_homefile() else: - shutil.copytree(path_src, path_dst, symlinks=True) + self.report({'INFO'}, "Reload Start-Up file to restore settings") - # reload recent-files.txt - bpy.ops.wm.read_history() - - # don't loose users work if they open the splash later. - if bpy.data.is_saved is bpy.data.is_dirty is False: - bpy.ops.wm.read_homefile() - else: - self.report({'INFO'}, "Reload Start-Up file to restore settings") - - return {'FINISHED'} - - return {'CANCELLED'} + return {'FINISHED'} class WM_OT_keyconfig_test(Operator): @@ -2525,6 +2544,134 @@ class WM_OT_studiolight_userpref_show(Operator): return {'FINISHED'} +class WM_MT_splash(Menu): + bl_label = "Splash" + + def draw_setup(self, context): + layout = self.layout + layout.operator_context = 'EXEC_DEFAULT' + + layout.label(text="Quick Setup") + + split = layout.split(factor=0.25) + split.label() + split = split.split(factor=2.0/3.0) + + col = split.column() + + col.label() + + sub = col.column(align=True) + sub.label(text="Input and Shortcuts:") + text = bpy.path.display_name(context.window_manager.keyconfigs.active.name) + if not text: + text = "Blender (default)" + sub.menu("USERPREF_MT_appconfigs", text=text) + + col.separator() + + # We need to make switching to a language easier first + #sub = col.column(align=False) + #sub.label(text="Language:") + #userpref = context.user_preferences + #sub.prop(userpref.system, "language", text="") + + col.label() + + layout.label() + + row = layout.row() + + sub = row.row() + if bpy.types.WM_OT_copy_prev_settings.poll(context): + old_version = bpy.types.WM_OT_copy_prev_settings.previous_version() + sub.operator("wm.copy_prev_settings", text="Load %d.%d Settings" % old_version) + sub.operator("wm.save_userpref", text="Save New Settings") + else: + sub.label() + sub.label() + sub.operator("wm.save_userpref", text="Next") + + layout.separator() + + def draw(self, context): + # Draw setup screen if no user preferences have been saved yet. + import os + + user_path = bpy.utils.resource_path('USER') + userdef_path = os.path.join(user_path, "config", "userpref.blend") + + if not os.path.isfile(userdef_path): + self.draw_setup(context) + return + + # Pass + layout = self.layout + layout.operator_context = 'EXEC_DEFAULT' + layout.emboss = 'PULLDOWN_MENU' + + split = layout.split() + + # Templates + col1 = split.column() + col1.label(text="New File") + + bpy.types.TOPBAR_MT_file_new.draw_ex(col1, context, use_splash=True) + + # Recent + col2 = split.column() + col2_title = col2.row() + + found_recent = col2.template_recent_files() + + if found_recent: + col2_title.label(text="Recent Files") + else: + # Links if no recent files + col2_title.label(text="Getting Started") + + col2.operator( + "wm.url_open", text="Manual", icon='URL' + ).url = "https://docs.blender.org/manual/en/dev/" + col2.operator( + "wm.url_open", text="Release Notes", icon='URL', + ).url = "https://www.blender.org/download/releases/%d-%d/" % bpy.app.version[:2] + col2.operator( + "wm.url_open", text="Blender Website", icon='URL', + ).url = "https://www.blender.org" + col2.operator( + "wm.url_open", text="Credits", icon='URL', + ).url = "https://www.blender.org/about/credits/" + + layout.separator() + + split = layout.split() + + col1 = split.column() + sub = col1.row() + sub.operator_context = 'INVOKE_DEFAULT' + sub.operator("wm.open_mainfile", text="Open...", icon='FILE_FOLDER') + col1.operator("wm.recover_last_session", icon='RECOVER_LAST') + + col2 = split.column() + if found_recent: + col2.operator( + "wm.url_open", text="Release Notes", icon='URL', + ).url = "https://www.blender.org/download/releases/%d-%d/" % bpy.app.version[:2] + col2.operator( + "wm.url_open", text="Development Fund", icon='URL' + ).url = "https://www.blender.org/foundation/development-fund/" + else: + col2.operator( + "wm.url_open", text="Development Fund", icon='URL' + ).url = "https://www.blender.org/foundation/development-fund/" + col2.operator( + "wm.url_open", text="Donate", icon='URL' + ).url = "https://www.blender.org/foundation/donation-payment/" + + layout.separator() + + classes = ( BRUSH_OT_active_index_set, WM_OT_addon_disable, @@ -2584,4 +2731,5 @@ classes = ( WM_OT_studiolight_userpref_show, WM_OT_tool_set_by_name, WM_OT_toolbar, + WM_MT_splash, ) diff --git a/release/scripts/startup/bl_ui/space_topbar.py b/release/scripts/startup/bl_ui/space_topbar.py index 80a7215f90b..563bd0afcca 100644 --- a/release/scripts/startup/bl_ui/space_topbar.py +++ b/release/scripts/startup/bl_ui/space_topbar.py @@ -287,7 +287,7 @@ class TOPBAR_MT_file(Menu): layout = self.layout layout.operator_context = 'INVOKE_AREA' - layout.menu("TOPBAR_MT_file_new", text="New", icon='NEW') + layout.menu("TOPBAR_MT_file_new", text="New", icon='FILE') layout.operator("wm.open_mainfile", text="Open...", icon='FILE_FOLDER') layout.menu("TOPBAR_MT_file_open_recent") layout.operator("wm.revert_mainfile") @@ -373,25 +373,51 @@ class TOPBAR_MT_file_new(Menu): return sorted(app_templates) - def draw_ex(self, context, *, use_splash=False, use_default=False): - layout = self.layout - - # now draw the presets + def draw_ex(layout, context, *, use_splash=False, use_more=False): layout.operator_context = 'EXEC_DEFAULT' - if use_default: - props = layout.operator("wm.read_homefile", text="General") + # Limit number of templates in splash screen, spill over into more menu. + paths = TOPBAR_MT_file_new.app_template_paths() + splash_limit = 5 + + if use_splash: + icon = 'FILE' + show_more = len(paths) > (splash_limit - 1) + if show_more: + paths = paths[:splash_limit - 2] + elif use_more: + icon = 'FILE' + paths = paths[splash_limit - 2:] + show_more = False + else: + icon = 'NONE' + show_more = False + + # Draw application templates. + if not use_more: + props = layout.operator("wm.read_homefile", text="General", icon=icon) props.app_template = "" - for d in TOPBAR_MT_file_new.app_template_paths(): + for d in paths: props = layout.operator( "wm.read_homefile", text=bpy.path.display_name(d), + icon=icon, ) props.app_template = d + if show_more: + layout.menu("TOPBAR_MT_templates_more", text="...") + def draw(self, context): - self.draw_ex(context, use_splash=False, use_default=True) + TOPBAR_MT_file_new.draw_ex(self.layout, context) + + +class TOPBAR_MT_templates_more(Menu): + bl_label = "Templates" + + def draw(self, context): + bpy.types.TOPBAR_MT_file_new.draw_ex(self.layout, context, use_more=True) class TOPBAR_MT_file_import(Menu): @@ -591,13 +617,24 @@ class TOPBAR_MT_help(Menu): layout.operator( "wm.url_open", text="Blender Website", icon='URL', ).url = "https://www.blender.org" - layout.operator( - "wm.url_open", text="Blender Store", icon='URL', - ).url = "https://store.blender.org" - layout.operator( "wm.url_open", text="Release Notes", icon='URL', ).url = "https://www.blender.org/download/releases/%d-%d/" % bpy.app.version[:2] + layout.operator( + "wm.url_open", text="Credits", icon='URL', + ).url = "https://www.blender.org/about/credits/" + + layout.separator() + + layout.operator( + "wm.url_open", text="Blender Store", icon='URL', + ).url = "https://store.blender.org" + layout.operator( + "wm.url_open", text="Development Fund", icon='URL' + ).url = "https://www.blender.org/foundation/development-fund/" + layout.operator( + "wm.url_open", text="Donate", icon='URL', + ).url = "https://www.blender.org/foundation/donation-payment/" layout.separator() @@ -622,7 +659,7 @@ class TOPBAR_MT_file_specials(Menu): layout = self.layout layout.operator_context = 'INVOKE_AREA' - layout.operator("wm.read_homefile", text="New", icon='NEW') + layout.operator("wm.read_homefile", text="New", icon='FILE') layout.operator("wm.open_mainfile", text="Open...", icon='FILE_FOLDER') layout.separator() @@ -708,6 +745,7 @@ classes = ( TOPBAR_MT_editor_menus, TOPBAR_MT_file, TOPBAR_MT_file_new, + TOPBAR_MT_templates_more, TOPBAR_MT_file_import, TOPBAR_MT_file_export, TOPBAR_MT_file_external_data, diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py index b1604489605..dc8242c477c 100644 --- a/release/scripts/startup/bl_ui/space_userpref.py +++ b/release/scripts/startup/bl_ui/space_userpref.py @@ -81,14 +81,6 @@ class USERPREF_MT_interaction_presets(Menu): draw = Menu.draw_preset -class USERPREF_MT_templates_splash(Menu): - bl_label = "Startup Templates" - preset_subdir = "templates" - - def draw(self, context): - bpy.types.TOPBAR_MT_file_new.draw_ex(self, context, use_splash=True, use_default=True) - - class USERPREF_MT_appconfigs(Menu): bl_label = "AppPresets" preset_subdir = "keyconfig" @@ -101,42 +93,6 @@ class USERPREF_MT_appconfigs(Menu): Menu.draw_preset(self, context) -class USERPREF_MT_splash(Menu): - bl_label = "Splash" - - def draw(self, context): - layout = self.layout - - split = layout.split() - row = split.row() - - if any(bpy.utils.app_template_paths()): - row.label(text="Template:") - template = context.user_preferences.app_template - row.menu( - "USERPREF_MT_templates_splash", - text=bpy.path.display_name(template) if template else "Default", - ) - else: - row.label(text="") - - row = split.row() - row.label(text="Interaction:") - - text = bpy.path.display_name(context.window_manager.keyconfigs.active.name) - if not text: - text = "Blender (default)" - row.menu("USERPREF_MT_appconfigs", text=text) - - -# only for addons -class USERPREF_MT_splash_footer(Menu): - bl_label = "" - - def draw(self, context): - pass - - class USERPREF_PT_interface(Panel): bl_space_type = 'USER_PREFERENCES' bl_label = "Interface" @@ -1601,10 +1557,7 @@ classes = ( USERPREF_HT_header, USERPREF_PT_tabs, USERPREF_MT_interaction_presets, - USERPREF_MT_templates_splash, USERPREF_MT_appconfigs, - USERPREF_MT_splash, - USERPREF_MT_splash_footer, USERPREF_PT_interface, USERPREF_PT_edit, USERPREF_PT_system, diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 4e0a0711473..7936ace5c45 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -1130,6 +1130,8 @@ void uiTemplateMovieclipInformation(struct uiLayout *layout, struct PointerRNA * void uiTemplateColorspaceSettings(struct uiLayout *layout, struct PointerRNA *ptr, const char *propname); void uiTemplateColormanagedViewSettings(struct uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, const char *propname); +int uiTemplateRecentFiles(struct uiLayout *layout, int rows); + /* items */ void uiItemO(uiLayout *layout, const char *name, int icon, const char *opname); void uiItemEnumO_ptr(uiLayout *layout, struct wmOperatorType *ot, const char *name, int icon, const char *propname, int value); diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 96f13aad442..76e6f64a80c 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -1216,8 +1216,12 @@ static void ui_menu_block_set_keymaps(const bContext *C, uiBlock *block) BLI_assert(block->flag & (UI_BLOCK_LOOP | UI_BLOCK_SHOW_SHORTCUT_ALWAYS)); /* only do it before bounding */ - if (block->rect.xmin != block->rect.xmax) + if (block->rect.xmin != block->rect.xmax) { return; + } + if (STREQ(block->name, "splash")) { + return; + } if (block->flag & UI_BLOCK_RADIAL) { for (but = block->buttons.first; but; but = but->next) { diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index 91756f9ae27..c19dc770fb9 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -2314,11 +2314,11 @@ static uiBut *uiItemL_(uiLayout *layout, const char *name, int icon) w = ui_text_icon_width(layout, name, icon, 0); if (icon && name[0]) - but = uiDefIconTextBut(block, UI_BTYPE_LABEL, 0, icon, name, 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); + but = uiDefIconTextBut(block, UI_BTYPE_LABEL, 0, icon, name, 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "AAAAAAAa"); else if (icon) - but = uiDefIconBut(block, UI_BTYPE_LABEL, 0, icon, 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); + but = uiDefIconBut(block, UI_BTYPE_LABEL, 0, icon, 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "BBBBBBBBBBBB"); else - but = uiDefBut(block, UI_BTYPE_LABEL, 0, name, 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, ""); + but = uiDefBut(block, UI_BTYPE_LABEL, 0, name, 0, 0, w, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "CCCCCCCCCCCCC"); /* to compensate for string size padding in ui_text_icon_width, * make text aligned right if the layout is aligned right. diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index b7a553d1bd5..6dab9807574 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -50,6 +50,7 @@ #include "BLI_math.h" #include "BLI_listbase.h" #include "BLI_fnmatch.h" +#include "BLI_path_util.h" #include "BLI_timecode.h" #include "BLF_api.h" @@ -89,6 +90,8 @@ #include "WM_api.h" #include "WM_types.h" +#include "BLO_readfile.h" + #include "UI_interface.h" #include "UI_interface_icons.h" #include "interface_intern.h" @@ -4963,3 +4966,20 @@ void uiTemplateCacheFile(uiLayout *layout, bContext *C, PointerRNA *ptr, const c uiItemR(row, &fileptr, "up_axis", 0, "Up Axis", ICON_NONE); #endif } + +/******************************* Recent Files *******************************/ + +int uiTemplateRecentFiles(uiLayout *layout, int rows) +{ + const RecentFile *recent; + int i; + + for (recent = G.recent_files.first, i = 0; (i < rows) && (recent); recent = recent->next, i++) { + const char *filename = BLI_path_basename(recent->filepath); + uiItemStringO(layout, filename, + BLO_has_bfile_extension(filename) ? ICON_FILE_BLEND : ICON_FILE_BACKUP, + "WM_OT_open_mainfile", "filepath", recent->filepath); + } + + return i; +} diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c index 694d44a87e8..f340b471455 100644 --- a/source/blender/makesrna/intern/rna_ui_api.c +++ b/source/blender/makesrna/intern/rna_ui_api.c @@ -1103,6 +1103,12 @@ void RNA_api_ui_layout(StructRNA *srna) RNA_def_function_ui_description(func, "Item(s). User interface for selecting cache files and their source paths"); RNA_def_function_flag(func, FUNC_USE_CONTEXT); api_ui_item_rna_common(func); + + func = RNA_def_function(srna, "template_recent_files", "uiTemplateRecentFiles"); + RNA_def_function_ui_description(func, "Show list of recently saved .blend files"); + RNA_def_int(func, "rows", 5, 1, INT_MAX, "", "Maximum number of items to show", 1, INT_MAX); + parm = RNA_def_int(func, "found", 0, 0, INT_MAX, "", "Number of items drawn", 0, INT_MAX); + RNA_def_function_return(func, parm); } #endif diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index d9c8028c9bb..1bd441b7a97 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -3160,6 +3160,9 @@ void WM_event_add_fileselect(bContext *C, wmOperator *op) wmWindowManager *wm = CTX_wm_manager(C); wmWindow *win = CTX_wm_window(C); + /* Close any popups, like when opening a file browser from the splash. */ + UI_popup_handlers_remove_all(C, &win->modalhandlers); + /* only allow 1 file selector open per window */ for (handler = win->modalhandlers.first; handler; handler = handlernext) { handlernext = handler->next; diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index dfe2a5407b1..7b231e6fd6b 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -1380,39 +1380,11 @@ static void wm_block_splash_refreshmenu(bContext *C, void *UNUSED(arg_block), vo ED_region_tag_refresh_ui(ar_menu); } -static int wm_resource_check_prev(void) -{ - - const char *res = BKE_appdir_folder_id_version(BLENDER_RESOURCE_PATH_USER, BLENDER_VERSION, true); - - // if (res) printf("USER: %s\n", res); - -#if 0 /* ignore the local folder */ - if (res == NULL) { - /* with a local dir, copying old files isn't useful since local dir get priority for config */ - res = BKE_appdir_folder_id_version(BLENDER_RESOURCE_PATH_LOCAL, BLENDER_VERSION, true); - } -#endif - - // if (res) printf("LOCAL: %s\n", res); - if (res) { - return false; - } - else { - return (BKE_appdir_folder_id_version(BLENDER_RESOURCE_PATH_USER, BLENDER_VERSION - 1, true) != NULL); - } -} - static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(arg)) { uiBlock *block; uiBut *but; - uiLayout *layout, *split, *col; uiStyle *style = UI_style_get(); - const struct RecentFile *recent; - int i; - MenuType *mt = WM_menutype_find("USERPREF_MT_splash", true); - char url[96]; const char *version_suffix = NULL; #ifndef WITH_HEADLESS @@ -1485,7 +1457,7 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar } #endif - block = UI_block_begin(C, ar, "_popup", UI_EMBOSS); + block = UI_block_begin(C, ar, "splash", UI_EMBOSS); /* note on UI_BLOCK_NO_WIN_CLIP, the window size is not always synchronized * with the OS when the splash shows, window clipping in this case gives @@ -1558,59 +1530,13 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar } #endif /* WITH_BUILDINFO */ - layout = UI_block_layout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 10, 2, U.pixelsize * 480, U.pixelsize * 110, 0, style); + uiLayout *layout = UI_block_layout( + block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 10, 2, + U.pixelsize * 480, U.pixelsize * 110, 0, style); - UI_block_emboss_set(block, UI_EMBOSS); - /* show the splash menu (containing interaction presets), using python */ + MenuType *mt = WM_menutype_find("WM_MT_splash", true); if (mt) { UI_menutype_draw(C, mt, layout); - -// uiItemM(layout, "USERPREF_MT_keyconfigs", U.keyconfigstr, ICON_NONE); - } - - UI_block_emboss_set(block, UI_EMBOSS_PULLDOWN); - uiLayoutSetOperatorContext(layout, WM_OP_EXEC_REGION_WIN); - - split = uiLayoutSplit(layout, 0.0f, false); - col = uiLayoutColumn(split, false); - uiItemL(col, IFACE_("Links"), ICON_NONE); - uiItemStringO(col, IFACE_("Join the Development Fund"), ICON_URL, "WM_OT_url_open", "url", - "https://www.blender.org/foundation/development-fund/"); - uiItemStringO(col, IFACE_("Donate"), ICON_URL, "WM_OT_url_open", "url", - "https://www.blender.org/foundation/donation-payment/"); - uiItemS(col); - uiItemStringO(col, IFACE_("Manual"), ICON_URL, "WM_OT_url_open", "url", - "https://docs.blender.org/manual/en/dev/"); - BLI_snprintf(url, sizeof(url), "https://wiki.blender.org/wiki/Reference/Release_Notes/%d.%d", - BLENDER_VERSION / 100, BLENDER_VERSION % 100); - uiItemStringO(col, IFACE_("Release Notes"), ICON_URL, "WM_OT_url_open", "url", url); - uiItemStringO(col, IFACE_("Blender Website"), ICON_URL, "WM_OT_url_open", "url", "https://www.blender.org"); - uiItemStringO(col, IFACE_("Credits"), ICON_URL, "WM_OT_url_open", "url", - "https://www.blender.org/about/credits/"); - uiItemL(col, "", ICON_NONE); - - col = uiLayoutColumn(split, false); - - if (wm_resource_check_prev()) { - uiItemO(col, NULL, ICON_NEW, "WM_OT_copy_prev_settings"); - uiItemS(col); - } - - uiItemL(col, IFACE_("Recent"), ICON_NONE); - for (recent = G.recent_files.first, i = 0; (i < 5) && (recent); recent = recent->next, i++) { - const char *filename = BLI_path_basename(recent->filepath); - uiItemStringO(col, filename, - BLO_has_bfile_extension(filename) ? ICON_FILE_BLEND : ICON_FILE_BACKUP, - "WM_OT_open_mainfile", "filepath", recent->filepath); - } - - uiItemS(col); - uiItemO(col, NULL, ICON_RECOVER_LAST, "WM_OT_recover_last_session"); - uiItemL(col, "", ICON_NONE); - - mt = WM_menutype_find("USERPREF_MT_splash_footer", false); - if (mt) { - UI_menutype_draw(C, mt, uiLayoutColumn(layout, false)); } UI_block_bounds_set_centered(block, 0);