Browse Source

Add a network mode setting to bring the editor offline

This PR also adds default font styles for RichTextLabels
in the editor, and improves the introduction dialog
when you don't have any local projects available.

The offline mode is implemented in the asset library
plugin, alongside some code improvements.
Yuri Sizov 1 year ago
parent
commit
4d97c33503

+ 4 - 1
doc/classes/EditorSettings.xml

@@ -666,7 +666,7 @@
 		</member>
 		</member>
 		<member name="interface/theme/additional_spacing" type="int" setter="" getter="">
 		<member name="interface/theme/additional_spacing" type="int" setter="" getter="">
 			The extra spacing to add to various GUI elements in the editor (in pixels). Increasing this value is useful to improve usability on touch screens, at the cost of reducing the amount of usable screen real estate.
 			The extra spacing to add to various GUI elements in the editor (in pixels). Increasing this value is useful to improve usability on touch screens, at the cost of reducing the amount of usable screen real estate.
-			 See also [member interface/theme/spacing_preset].
+			See also [member interface/theme/spacing_preset].
 		</member>
 		</member>
 		<member name="interface/theme/base_color" type="Color" setter="" getter="">
 		<member name="interface/theme/base_color" type="Color" setter="" getter="">
 			The base color to use for user interface elements in the editor. Secondary colors (such as darker/lighter variants) are derived from this color.
 			The base color to use for user interface elements in the editor. Secondary colors (such as darker/lighter variants) are derived from this color.
@@ -724,6 +724,9 @@
 			Specify the multiplier to apply to the scale for the editor gizmo handles to improve usability on touchscreen devices.
 			Specify the multiplier to apply to the scale for the editor gizmo handles to improve usability on touchscreen devices.
 			[b]Note:[/b] Defaults to [code]1[/code] on non-touchscreen devices.
 			[b]Note:[/b] Defaults to [code]1[/code] on non-touchscreen devices.
 		</member>
 		</member>
+		<member name="network/connection/network_mode" type="int" setter="" getter="">
+			Determines whether online features are enabled in the editor, such as the Asset Library. Setting this property to "Offline" is recommended to limit editor's internet activity, especially if privacy is a concern.
+		</member>
 		<member name="network/debug/remote_host" type="String" setter="" getter="">
 		<member name="network/debug/remote_host" type="String" setter="" getter="">
 			The address to listen to when starting the remote debugger. This can be set to [code]0.0.0.0[/code] to allow external clients to connect to the remote debugger (instead of restricting the remote debugger to connections from [code]localhost[/code]).
 			The address to listen to when starting the remote debugger. This can be set to [code]0.0.0.0[/code] to allow external clients to connect to the remote debugger (instead of restricting the remote debugger to connections from [code]localhost[/code]).
 		</member>
 		</member>

+ 11 - 8
editor/editor_settings.cpp

@@ -766,15 +766,22 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
 
 
 	/* Network */
 	/* Network */
 
 
-	// Debug
-	_initial_set("network/debug/remote_host", "127.0.0.1"); // Hints provided in setup_network
+	// General
+	EDITOR_SETTING(Variant::INT, PROPERTY_HINT_ENUM, "network/connection/network_mode", 0, "Offline,Online");
 
 
-	EDITOR_SETTING(Variant::INT, PROPERTY_HINT_RANGE, "network/debug/remote_port", 6007, "1,65535,1")
+	// HTTP Proxy
+	_initial_set("network/http_proxy/host", "");
+	EDITOR_SETTING(Variant::INT, PROPERTY_HINT_RANGE, "network/http_proxy/port", 8080, "1,65535,1")
 
 
 	// SSL
 	// SSL
 	EDITOR_SETTING_USAGE(Variant::STRING, PROPERTY_HINT_GLOBAL_FILE, "network/tls/editor_tls_certificates", _SYSTEM_CERTS_PATH, "*.crt,*.pem", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
 	EDITOR_SETTING_USAGE(Variant::STRING, PROPERTY_HINT_GLOBAL_FILE, "network/tls/editor_tls_certificates", _SYSTEM_CERTS_PATH, "*.crt,*.pem", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
 
 
-	// Debugger/profiler
+	// Debug
+	_initial_set("network/debug/remote_host", "127.0.0.1"); // Hints provided in setup_network
+	EDITOR_SETTING(Variant::INT, PROPERTY_HINT_RANGE, "network/debug/remote_port", 6007, "1,65535,1")
+
+	/* Debugger/profiler */
+
 	EDITOR_SETTING(Variant::BOOL, PROPERTY_HINT_NONE, "debugger/auto_switch_to_remote_scene_tree", false, "")
 	EDITOR_SETTING(Variant::BOOL, PROPERTY_HINT_NONE, "debugger/auto_switch_to_remote_scene_tree", false, "")
 	EDITOR_SETTING(Variant::INT, PROPERTY_HINT_RANGE, "debugger/profiler_frame_history_size", 3600, "60,10000,1")
 	EDITOR_SETTING(Variant::INT, PROPERTY_HINT_RANGE, "debugger/profiler_frame_history_size", 3600, "60,10000,1")
 	EDITOR_SETTING(Variant::INT, PROPERTY_HINT_RANGE, "debugger/profiler_frame_max_functions", 64, "16,512,1")
 	EDITOR_SETTING(Variant::INT, PROPERTY_HINT_RANGE, "debugger/profiler_frame_max_functions", 64, "16,512,1")
@@ -782,10 +789,6 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
 	EDITOR_SETTING(Variant::FLOAT, PROPERTY_HINT_RANGE, "debugger/remote_inspect_refresh_interval", 0.2, "0.02,10,0.01,or_greater")
 	EDITOR_SETTING(Variant::FLOAT, PROPERTY_HINT_RANGE, "debugger/remote_inspect_refresh_interval", 0.2, "0.02,10,0.01,or_greater")
 	EDITOR_SETTING(Variant::BOOL, PROPERTY_HINT_NONE, "debugger/profile_native_calls", false, "")
 	EDITOR_SETTING(Variant::BOOL, PROPERTY_HINT_NONE, "debugger/profile_native_calls", false, "")
 
 
-	// HTTP Proxy
-	_initial_set("network/http_proxy/host", "");
-	EDITOR_SETTING(Variant::INT, PROPERTY_HINT_RANGE, "network/http_proxy/port", 8080, "1,65535,1")
-
 	/* Extra config */
 	/* Extra config */
 
 
 	// TRANSLATORS: Project Manager here refers to the tool used to create/manage Godot projects.
 	// TRANSLATORS: Project Manager here refers to the tool used to create/manage Godot projects.

+ 5 - 0
editor/editor_settings.h

@@ -57,6 +57,11 @@ public:
 		Vector<String> install_files;
 		Vector<String> install_files;
 	};
 	};
 
 
+	enum NetworkMode {
+		NETWORK_OFFLINE,
+		NETWORK_ONLINE,
+	};
+
 private:
 private:
 	struct VariantContainer {
 	struct VariantContainer {
 		int order = 0;
 		int order = 0;

+ 63 - 26
editor/plugins/asset_library_editor_plugin.cpp

@@ -643,6 +643,15 @@ void EditorAssetLibrary::_notification(int p_what) {
 		case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
 		case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
 			_update_repository_options();
 			_update_repository_options();
 			setup_http_request(request);
 			setup_http_request(request);
+
+			const bool loading_blocked_new = ((int)EDITOR_GET("network/connection/network_mode") == EditorSettings::NETWORK_OFFLINE);
+			if (loading_blocked_new != loading_blocked) {
+				loading_blocked = loading_blocked_new;
+
+				if (!loading_blocked && is_visible()) {
+					_request_current_config(); // Reload config now that the network is available.
+				}
+			}
 		} break;
 		} break;
 	}
 	}
 }
 }
@@ -929,9 +938,7 @@ void EditorAssetLibrary::_request_image(ObjectID p_for, String p_image_url, Imag
 }
 }
 
 
 void EditorAssetLibrary::_repository_changed(int p_repository_id) {
 void EditorAssetLibrary::_repository_changed(int p_repository_id) {
-	library_error->hide();
-	library_info->set_text(TTR("Loading..."));
-	library_info->show();
+	_set_library_message(TTR("Loading..."));
 
 
 	asset_top_page->hide();
 	asset_top_page->hide();
 	asset_bottom_page->hide();
 	asset_bottom_page->hide();
@@ -1104,10 +1111,14 @@ void EditorAssetLibrary::_api_request(const String &p_request, RequestType p_req
 	if (requesting != REQUESTING_NONE) {
 	if (requesting != REQUESTING_NONE) {
 		request->cancel_request();
 		request->cancel_request();
 	}
 	}
+	error_hb->hide();
 
 
-	requesting = p_request_type;
+	if (loading_blocked) {
+		_set_library_message_with_action(TTR("The Asset Library requires an online connection and involves sending data over the internet."), TTR("Go Online"), callable_mp(this, &EditorAssetLibrary::_force_online_mode));
+		return;
+	}
 
 
-	error_hb->hide();
+	requesting = p_request_type;
 	request->request(host + "/" + p_request + p_arguments);
 	request->request(host + "/" + p_request + p_arguments);
 }
 }
 
 
@@ -1156,8 +1167,7 @@ void EditorAssetLibrary::_http_request_completed(int p_status, int p_code, const
 
 
 	if (error_abort) {
 	if (error_abort) {
 		if (requesting == REQUESTING_CONFIG) {
 		if (requesting == REQUESTING_CONFIG) {
-			library_info->hide();
-			library_error->show();
+			_set_library_message_with_action(TTR("Failed to get repository configuration."), TTR("Retry"), callable_mp(this, &EditorAssetLibrary::_request_current_config));
 		}
 		}
 		error_hb->show();
 		error_hb->show();
 		return;
 		return;
@@ -1265,18 +1275,17 @@ void EditorAssetLibrary::_http_request_completed(int p_status, int p_code, const
 				}
 				}
 
 
 				if (!filter->get_text().is_empty()) {
 				if (!filter->get_text().is_empty()) {
-					library_info->set_text(
+					_set_library_message(
 							vformat(TTR("No results for \"%s\" for support level(s): %s."), filter->get_text(), support_list));
 							vformat(TTR("No results for \"%s\" for support level(s): %s."), filter->get_text(), support_list));
 				} else {
 				} else {
 					// No results, even though the user didn't search for anything specific.
 					// No results, even though the user didn't search for anything specific.
 					// This is typically because the version number changed recently
 					// This is typically because the version number changed recently
 					// and no assets compatible with the new version have been published yet.
 					// and no assets compatible with the new version have been published yet.
-					library_info->set_text(
+					_set_library_message(
 							vformat(TTR("No results compatible with %s %s for support level(s): %s.\nCheck the enabled support levels using the 'Support' button in the top-right corner."), String(VERSION_SHORT_NAME).capitalize(), String(VERSION_BRANCH), support_list));
 							vformat(TTR("No results compatible with %s %s for support level(s): %s.\nCheck the enabled support levels using the 'Support' button in the top-right corner."), String(VERSION_SHORT_NAME).capitalize(), String(VERSION_BRANCH), support_list));
 				}
 				}
-				library_info->show();
 			} else {
 			} else {
-				library_info->hide();
+				library_message_box->hide();
 			}
 			}
 
 
 			for (int i = 0; i < result.size(); i++) {
 			for (int i = 0; i < result.size(); i++) {
@@ -1432,6 +1441,39 @@ void EditorAssetLibrary::_update_asset_items_columns() {
 	asset_items_column_width = (get_size().x / new_columns) - (100 * EDSCALE);
 	asset_items_column_width = (get_size().x / new_columns) - (100 * EDSCALE);
 }
 }
 
 
+void EditorAssetLibrary::_set_library_message(const String &p_message) {
+	library_message->set_text(p_message);
+
+	if (library_message_action.is_valid()) {
+		library_message_button->disconnect("pressed", library_message_action);
+		library_message_action = Callable();
+	}
+	library_message_button->hide();
+
+	library_message_box->show();
+}
+
+void EditorAssetLibrary::_set_library_message_with_action(const String &p_message, const String &p_action_text, const Callable &p_action) {
+	library_message->set_text(p_message);
+
+	library_message_button->set_text(p_action_text);
+	if (library_message_action.is_valid()) {
+		library_message_button->disconnect("pressed", library_message_action);
+		library_message_action = Callable();
+	}
+	library_message_action = p_action;
+	library_message_button->connect("pressed", library_message_action);
+	library_message_button->show();
+
+	library_message_box->show();
+}
+
+void EditorAssetLibrary::_force_online_mode() {
+	EditorSettings::get_singleton()->set_setting("network/connection/network_mode", EditorSettings::NETWORK_ONLINE);
+	EditorSettings::get_singleton()->notify_changes();
+	EditorSettings::get_singleton()->save();
+}
+
 void EditorAssetLibrary::disable_community_support() {
 void EditorAssetLibrary::disable_community_support() {
 	support->get_popup()->set_item_checked(SUPPORT_COMMUNITY, false);
 	support->get_popup()->set_item_checked(SUPPORT_COMMUNITY, false);
 }
 }
@@ -1443,7 +1485,7 @@ void EditorAssetLibrary::_bind_methods() {
 EditorAssetLibrary::EditorAssetLibrary(bool p_templates_only) {
 EditorAssetLibrary::EditorAssetLibrary(bool p_templates_only) {
 	requesting = REQUESTING_NONE;
 	requesting = REQUESTING_NONE;
 	templates_only = p_templates_only;
 	templates_only = p_templates_only;
-	initial_loading = true;
+	loading_blocked = ((int)EDITOR_GET("network/connection/network_mode") == EditorSettings::NETWORK_OFFLINE);
 
 
 	VBoxContainer *library_main = memnew(VBoxContainer);
 	VBoxContainer *library_main = memnew(VBoxContainer);
 	add_child(library_main);
 	add_child(library_main);
@@ -1567,22 +1609,17 @@ EditorAssetLibrary::EditorAssetLibrary(bool p_templates_only) {
 
 
 	library_vb_border->add_child(library_vb);
 	library_vb_border->add_child(library_vb);
 
 
-	library_info = memnew(Label);
-	library_info->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
-	library_vb->add_child(library_info);
-
-	library_error = memnew(VBoxContainer);
-	library_error->hide();
-	library_vb->add_child(library_error);
+	library_message_box = memnew(VBoxContainer);
+	library_message_box->hide();
+	library_vb->add_child(library_message_box);
 
 
-	library_error_label = memnew(Label(TTR("Failed to get repository configuration.")));
-	library_error_label->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
-	library_error->add_child(library_error_label);
+	library_message = memnew(Label);
+	library_message->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
+	library_message_box->add_child(library_message);
 
 
-	library_error_retry = memnew(Button(TTR("Retry")));
-	library_error_retry->set_h_size_flags(SIZE_SHRINK_CENTER);
-	library_error_retry->connect("pressed", callable_mp(this, &EditorAssetLibrary::_request_current_config));
-	library_error->add_child(library_error_retry);
+	library_message_button = memnew(Button);
+	library_message_button->set_h_size_flags(SIZE_SHRINK_CENTER);
+	library_message_box->add_child(library_message_button);
 
 
 	asset_top_page = memnew(HBoxContainer);
 	asset_top_page = memnew(HBoxContainer);
 	library_vb->add_child(asset_top_page);
 	library_vb->add_child(asset_top_page);

+ 13 - 6
editor/plugins/asset_library_editor_plugin.h

@@ -191,10 +191,14 @@ class EditorAssetLibrary : public PanelContainer {
 	PanelContainer *library_scroll_bg = nullptr;
 	PanelContainer *library_scroll_bg = nullptr;
 	ScrollContainer *library_scroll = nullptr;
 	ScrollContainer *library_scroll = nullptr;
 	VBoxContainer *library_vb = nullptr;
 	VBoxContainer *library_vb = nullptr;
-	Label *library_info = nullptr;
-	VBoxContainer *library_error = nullptr;
-	Label *library_error_label = nullptr;
-	Button *library_error_retry = nullptr;
+	VBoxContainer *library_message_box = nullptr;
+	Label *library_message = nullptr;
+	Button *library_message_button = nullptr;
+	Callable library_message_action;
+
+	void _set_library_message(const String &p_message);
+	void _set_library_message_with_action(const String &p_message, const String &p_action_text, const Callable &p_action);
+
 	LineEdit *filter = nullptr;
 	LineEdit *filter = nullptr;
 	Timer *filter_debounce_timer = nullptr;
 	Timer *filter_debounce_timer = nullptr;
 	OptionButton *categories = nullptr;
 	OptionButton *categories = nullptr;
@@ -213,8 +217,11 @@ class EditorAssetLibrary : public PanelContainer {
 
 
 	HTTPRequest *request = nullptr;
 	HTTPRequest *request = nullptr;
 
 
-	bool templates_only;
-	bool initial_loading;
+	bool templates_only = false;
+	bool initial_loading = true;
+	bool loading_blocked = false;
+
+	void _force_online_mode();
 
 
 	enum Support {
 	enum Support {
 		SUPPORT_OFFICIAL,
 		SUPPORT_OFFICIAL,

+ 53 - 23
editor/project_manager.cpp

@@ -59,6 +59,7 @@
 #include "scene/gui/margin_container.h"
 #include "scene/gui/margin_container.h"
 #include "scene/gui/option_button.h"
 #include "scene/gui/option_button.h"
 #include "scene/gui/panel_container.h"
 #include "scene/gui/panel_container.h"
+#include "scene/gui/rich_text_label.h"
 #include "scene/gui/separator.h"
 #include "scene/gui/separator.h"
 #include "scene/gui/texture_rect.h"
 #include "scene/gui/texture_rect.h"
 #include "scene/main/window.h"
 #include "scene/main/window.h"
@@ -137,21 +138,15 @@ void ProjectManager::_notification(int p_what) {
 		} break;
 		} break;
 
 
 		case NOTIFICATION_READY: {
 		case NOTIFICATION_READY: {
-			int default_sorting = (int)EDITOR_GET("project_manager/sorting_order");
+			const int default_sorting = (int)EDITOR_GET("project_manager/sorting_order");
 			filter_option->select(default_sorting);
 			filter_option->select(default_sorting);
 			_project_list->set_order_option(default_sorting);
 			_project_list->set_order_option(default_sorting);
 
 
-#ifndef ANDROID_ENABLED
-			if (_project_list->get_project_count() >= 1) {
-				// Focus on the search box immediately to allow the user
-				// to search without having to reach for their mouse
-				search_box->grab_focus();
-			}
-#endif
+			_select_main_view(MAIN_VIEW_PROJECTS);
 
 
 			// Suggest browsing asset library to get templates/demos.
 			// Suggest browsing asset library to get templates/demos.
-			if (asset_library && open_templates && _project_list->get_project_count() == 0) {
-				open_templates->popup_centered();
+			if (asset_library && _project_list->get_project_count() == 0) {
+				_suggest_asset_library();
 			}
 			}
 		} break;
 		} break;
 
 
@@ -303,10 +298,54 @@ void ProjectManager::_select_main_view(int p_id) {
 }
 }
 
 
 void ProjectManager::_show_about() {
 void ProjectManager::_show_about() {
-	about->popup_centered(Size2(780, 500) * EDSCALE);
+	about_dialog->popup_centered(Size2(780, 500) * EDSCALE);
+}
+
+void ProjectManager::_suggest_asset_library() {
+	if (!suggest_asset_library_dialog) {
+		suggest_asset_library_dialog = memnew(ConfirmationDialog);
+		suggest_asset_library_dialog->set_title(TTR("Getting Started with Godot"));
+		add_child(suggest_asset_library_dialog);
+		suggest_asset_library_dialog->connect("confirmed", callable_mp(this, &ProjectManager::_open_asset_library_confirmed));
+
+		VBoxContainer *suggest_vbox = memnew(VBoxContainer);
+		suggest_asset_library_dialog->add_child(suggest_vbox);
+
+		suggest_asset_library_label = memnew(RichTextLabel);
+		suggest_asset_library_label->set_use_bbcode(true);
+		suggest_asset_library_label->set_fit_content(true);
+		suggest_asset_library_label->set_h_size_flags(SIZE_EXPAND_FILL);
+		suggest_asset_library_label->add_theme_style_override("normal", memnew(StyleBoxEmpty));
+		suggest_vbox->add_child(suggest_asset_library_label);
+	}
+
+	const int network_mode = EDITOR_GET("network/connection/network_mode");
+	if (network_mode == EditorSettings::NETWORK_OFFLINE) {
+		const String line1 = TTR("You don't have any projects yet.");
+		const String line2 = TTR("Get started with one of the official project templates from the Asset Library!");
+		const String line3 = TTR("Note: The Asset Library requires an online connection and involves sending data over the internet.");
+
+		suggest_asset_library_label->set_text(vformat("%s\n\n[b]%s[/b]\n\n[i]%s[/i]", line1, line2, line3));
+		suggest_asset_library_dialog->set_ok_button_text(TTR("Go Online and Open Asset Library"));
+	} else {
+		const String line1 = TTR("You don't have any projects yet.");
+		const String line2 = TTR("Get started with one of the official project templates from the Asset Library!");
+
+		suggest_asset_library_label->set_text(vformat("%s\n\n[b]%s[/b]", line1, line2));
+		suggest_asset_library_dialog->set_ok_button_text(TTR("Open Asset Library"));
+	}
+
+	suggest_asset_library_dialog->popup_centered(Size2(540, 100) * EDSCALE);
 }
 }
 
 
-void ProjectManager::_open_asset_library() {
+void ProjectManager::_open_asset_library_confirmed() {
+	const int network_mode = EDITOR_GET("network/connection/network_mode");
+	if (network_mode == EditorSettings::NETWORK_OFFLINE) {
+		EditorSettings::get_singleton()->set_setting("network/connection/network_mode", EditorSettings::NETWORK_ONLINE);
+		EditorSettings::get_singleton()->notify_changes();
+		EditorSettings::get_singleton()->save();
+	}
+
 	asset_library->disable_community_support();
 	asset_library->disable_community_support();
 	_select_main_view(MAIN_VIEW_ASSETLIB);
 	_select_main_view(MAIN_VIEW_ASSETLIB);
 }
 }
@@ -1339,16 +1378,8 @@ ProjectManager::ProjectManager() {
 		dialog_error = memnew(AcceptDialog);
 		dialog_error = memnew(AcceptDialog);
 		add_child(dialog_error);
 		add_child(dialog_error);
 
 
-		if (asset_library) {
-			open_templates = memnew(ConfirmationDialog);
-			open_templates->set_text(TTR("You currently don't have any projects.\nWould you like to explore official example projects in the Asset Library?"));
-			open_templates->set_ok_button_text(TTR("Open Asset Library"));
-			open_templates->connect("confirmed", callable_mp(this, &ProjectManager::_open_asset_library));
-			add_child(open_templates);
-		}
-
-		about = memnew(EditorAbout);
-		add_child(about);
+		about_dialog = memnew(EditorAbout);
+		add_child(about_dialog);
 	}
 	}
 
 
 	// Tag management.
 	// Tag management.
@@ -1453,7 +1484,6 @@ ProjectManager::ProjectManager() {
 	}
 	}
 
 
 	_update_size_limits();
 	_update_size_limits();
-	_select_main_view(MAIN_VIEW_PROJECTS);
 }
 }
 
 
 ProjectManager::~ProjectManager() {
 ProjectManager::~ProjectManager() {

+ 6 - 3
editor/project_manager.h

@@ -46,6 +46,7 @@ class OptionButton;
 class PanelContainer;
 class PanelContainer;
 class ProjectDialog;
 class ProjectDialog;
 class ProjectList;
 class ProjectList;
+class RichTextLabel;
 class TabContainer;
 class TabContainer;
 class VBoxContainer;
 class VBoxContainer;
 
 
@@ -96,11 +97,13 @@ class ProjectManager : public Control {
 	VBoxContainer *local_projects_vb = nullptr;
 	VBoxContainer *local_projects_vb = nullptr;
 	EditorAssetLibrary *asset_library = nullptr;
 	EditorAssetLibrary *asset_library = nullptr;
 
 
-	ConfirmationDialog *open_templates = nullptr;
-	EditorAbout *about = nullptr;
+	ConfirmationDialog *suggest_asset_library_dialog = nullptr;
+	RichTextLabel *suggest_asset_library_label = nullptr;
+	EditorAbout *about_dialog = nullptr;
 
 
 	void _show_about();
 	void _show_about();
-	void _open_asset_library();
+	void _suggest_asset_library();
+	void _open_asset_library_confirmed();
 
 
 	// Quick settings.
 	// Quick settings.
 
 

+ 10 - 0
editor/themes/editor_fonts.cpp

@@ -370,6 +370,9 @@ void editor_register_fonts(const Ref<Theme> &p_theme) {
 	Ref<FontVariation> italic_fc = default_fc->duplicate();
 	Ref<FontVariation> italic_fc = default_fc->duplicate();
 	italic_fc->set_variation_transform(Transform2D(1.0, 0.2, 0.0, 1.0, 0.0, 0.0));
 	italic_fc->set_variation_transform(Transform2D(1.0, 0.2, 0.0, 1.0, 0.0, 0.0));
 
 
+	Ref<FontVariation> bold_italic_fc = bold_fc->duplicate();
+	bold_italic_fc->set_variation_transform(Transform2D(1.0, 0.2, 0.0, 1.0, 0.0, 0.0));
+
 	// Setup theme.
 	// Setup theme.
 
 
 	p_theme->set_default_font(default_fc); // Default theme font config.
 	p_theme->set_default_font(default_fc); // Default theme font config.
@@ -394,6 +397,8 @@ void editor_register_fonts(const Ref<Theme> &p_theme) {
 	p_theme->set_font("font", "MainScreenButton", bold_fc);
 	p_theme->set_font("font", "MainScreenButton", bold_fc);
 	p_theme->set_font_size("font_size", "MainScreenButton", default_font_size + 2 * EDSCALE);
 	p_theme->set_font_size("font_size", "MainScreenButton", default_font_size + 2 * EDSCALE);
 
 
+	// Labels.
+
 	p_theme->set_font("font", "Label", default_fc);
 	p_theme->set_font("font", "Label", default_fc);
 
 
 	p_theme->set_type_variation("HeaderSmall", "Label");
 	p_theme->set_type_variation("HeaderSmall", "Label");
@@ -408,6 +413,11 @@ void editor_register_fonts(const Ref<Theme> &p_theme) {
 	p_theme->set_font("font", "HeaderLarge", bold_fc);
 	p_theme->set_font("font", "HeaderLarge", bold_fc);
 	p_theme->set_font_size("font_size", "HeaderLarge", default_font_size + 3 * EDSCALE);
 	p_theme->set_font_size("font_size", "HeaderLarge", default_font_size + 3 * EDSCALE);
 
 
+	p_theme->set_font("normal_font", "RichTextLabel", default_fc);
+	p_theme->set_font("bold_font", "RichTextLabel", bold_fc);
+	p_theme->set_font("italics_font", "RichTextLabel", italic_fc);
+	p_theme->set_font("bold_italics_font", "RichTextLabel", bold_italic_fc);
+
 	// Documentation fonts
 	// Documentation fonts
 	p_theme->set_font_size("doc_size", EditorStringName(EditorFonts), int(EDITOR_GET("text_editor/help/help_font_size")) * EDSCALE);
 	p_theme->set_font_size("doc_size", EditorStringName(EditorFonts), int(EDITOR_GET("text_editor/help/help_font_size")) * EDSCALE);
 	p_theme->set_font("doc", EditorStringName(EditorFonts), default_fc);
 	p_theme->set_font("doc", EditorStringName(EditorFonts), default_fc);