1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-13 13:31:48 +00:00

Merge pull request #87443 from YuriSizov/pms-hotter-younger-cousin

Improve layout and UX of the project manager
This commit is contained in:
Rémi Verschelde
2024-01-30 19:10:46 +01:00
committed by GitHub
14 changed files with 1090 additions and 425 deletions

View File

@@ -724,6 +724,9 @@
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.
</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="">
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>

View File

@@ -498,6 +498,8 @@ void EditorNode::_update_theme(bool p_skip_creation) {
update_preview_themes(CanvasItemEditor::THEME_PREVIEW_EDITOR);
}
// Update styles.
{
gui_base->add_theme_style_override("panel", theme->get_stylebox(SNAME("Background"), EditorStringName(EditorStyles)));
main_vbox->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT, Control::PRESET_MODE_MINSIZE, theme->get_constant(SNAME("window_border_margin"), EditorStringName(Editor)));
main_vbox->add_theme_constant_override("separation", theme->get_constant(SNAME("top_bar_separation"), EditorStringName(Editor)));
@@ -519,11 +521,6 @@ void EditorNode::_update_theme(bool p_skip_creation) {
help_menu->set_item_icon(help_menu->get_item_index(HELP_ABOUT), theme->get_icon(SNAME("Godot"), EditorStringName(EditorIcons)));
help_menu->set_item_icon(help_menu->get_item_index(HELP_SUPPORT_GODOT_DEVELOPMENT), theme->get_icon(SNAME("Heart"), EditorStringName(EditorIcons)));
for (int i = 0; i < main_editor_buttons.size(); i++) {
main_editor_buttons.write[i]->add_theme_font_override("font", theme->get_font(SNAME("main_button_font"), EditorStringName(EditorFonts)));
main_editor_buttons.write[i]->add_theme_font_size_override("font_size", theme->get_font_size(SNAME("main_button_font_size"), EditorStringName(EditorFonts)));
}
if (EditorDebuggerNode::get_singleton()->is_visible()) {
bottom_panel->add_theme_style_override("panel", theme->get_stylebox(SNAME("BottomPanelDebuggerOverride"), EditorStringName(EditorStyles)));
}
@@ -540,6 +537,7 @@ void EditorNode::_update_theme(bool p_skip_creation) {
}
}
}
}
void EditorNode::update_preview_themes(int p_mode) {
if (!scene_root->is_inside_tree()) {
@@ -3279,21 +3277,21 @@ void EditorNode::add_editor_plugin(EditorPlugin *p_editor, bool p_config_changed
Button *tb = memnew(Button);
tb->set_flat(true);
tb->set_toggle_mode(true);
tb->connect("pressed", callable_mp(singleton, &EditorNode::editor_select).bind(singleton->main_editor_buttons.size()));
tb->set_theme_type_variation("MainScreenButton");
tb->set_name(p_editor->get_name());
tb->set_text(p_editor->get_name());
Ref<Texture2D> icon = p_editor->get_icon();
if (icon.is_null() && singleton->theme->has_icon(p_editor->get_name(), EditorStringName(EditorIcons))) {
icon = singleton->theme->get_icon(p_editor->get_name(), EditorStringName(EditorIcons));
}
if (icon.is_valid()) {
tb->set_icon(icon);
// Make sure the control is updated if the icon is reimported.
icon->connect_changed(callable_mp((Control *)tb, &Control::update_minimum_size));
} else if (singleton->theme->has_icon(p_editor->get_name(), EditorStringName(EditorIcons))) {
tb->set_icon(singleton->theme->get_icon(p_editor->get_name(), EditorStringName(EditorIcons)));
}
tb->add_theme_font_override("font", singleton->theme->get_font(SNAME("main_button_font"), EditorStringName(EditorFonts)));
tb->add_theme_font_size_override("font_size", singleton->theme->get_font_size(SNAME("main_button_font_size"), EditorStringName(EditorFonts)));
tb->connect("pressed", callable_mp(singleton, &EditorNode::editor_select).bind(singleton->main_editor_buttons.size()));
singleton->main_editor_buttons.push_back(tb);
singleton->main_editor_button_hb->add_child(tb);

View File

@@ -770,15 +770,22 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
/* 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
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::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")
@@ -786,10 +793,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::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 */
// TRANSLATORS: Project Manager here refers to the tool used to create/manage Godot projects.

View File

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

View File

@@ -0,0 +1 @@
<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m1 1v14h14v-14zm3 7c1.104 0 2 .896 2 2s-.896 2-2 2-2-.896-2-2 .896-2 2-2zm9 1v2h-6v-2zm-9-7c1.104 0 2 .896 2 2s-.896 2-2 2-2-.896-2-2 .896-2 2-2zm3 1h6v2h-6z" fill="#e0e0e0" fill-rule="nonzero"/></svg>

After

Width:  |  Height:  |  Size: 294 B

View File

@@ -0,0 +1 @@
<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" viewBox="0 0 100 24" xmlns="http://www.w3.org/2000/svg"><path d="m40.122 11.514c-1.211-.019-2.597.234-2.597.234v2.364h1.393l-.015 1.052c0 .391-.387.587-1.159.587s-1.454-.328-2.045-.979c-.594-.654-.889-1.609-.889-2.867 0-1.261.288-2.19.865-2.79.577-.599 1.331-.899 2.261-.899.411.003.821.067 1.214.191.42.128.701.247.844.358.142.116.276.17.405.17.127 0 .332-.149.616-.45.286-.299.542-.754.767-1.359.224-.61.337-1.076.337-1.407 0-.328-.007-.555-.023-.674-.314-.345-.895-.618-1.744-.821-.845-.204-1.794-.304-2.844-.304-2.309 0-4.115.728-5.419 2.181-1.305 1.455-1.957 3.344-1.957 5.668 0 2.729.667 4.798 2.001 6.207 1.335 1.41 3.089 2.113 5.263 2.113 1.169 0 2.207-.101 3.114-.303.908-.202 1.511-.409 1.811-.619l.09-7.038c0-.408-1.079-.594-2.289-.615zm11.157-3.284c-.719 0-1.321.33-1.81.989-.487.66-.731 1.585-.731 2.776 0 1.193.232 2.108.698 2.745.465.638 1.075.957 1.832.957s1.372-.323 1.844-.969c.472-.644.709-1.566.709-2.766s-.244-2.122-.731-2.767c-.487-.643-1.091-.965-1.811-.965m-.011 11.85c-2.106 0-3.823-.689-5.15-2.067-1.326-1.38-1.989-3.393-1.989-6.039 0-2.647.67-4.652 2.011-6.017 1.343-1.364 3.074-2.046 5.196-2.046 2.121 0 3.835.67 5.138 2.014 1.306 1.341 1.957 3.374 1.957 6.094 0 2.721-.666 4.745-2.001 6.073-1.335 1.325-3.055 1.988-5.162 1.988m13.502-11.694v6.727c0 .314.023.512.068.595s.18.124.404.124c.826 0 1.451-.308 1.879-.923.428-.614.64-1.637.64-3.069s-.222-2.366-.663-2.799c-.442-.435-1.144-.655-2.103-.655zm-4.317 10.436v-13.492c0-.376.093-.672.282-.891.186-.217.43-.326.73-.326h3.756c2.383 0 4.194.601 5.429 1.801 1.238 1.199 1.857 3.087 1.857 5.666 0 5.517-2.354 8.276-7.063 8.276h-3.845c-.763 0-1.147-.344-1.147-1.034m20.734-10.592c-.72 0-1.325.33-1.812.989-.486.66-.73 1.585-.73 2.776 0 1.193.233 2.108.697 2.745.464.638 1.076.957 1.833.957s1.372-.323 1.844-.969c.472-.644.709-1.566.709-2.766s-.244-2.122-.731-2.767c-.487-.643-1.09-.965-1.81-.965m-.012 11.85c-2.107 0-3.823-.689-5.15-2.067-1.327-1.38-1.99-3.393-1.99-6.039 0-2.647.671-4.652 2.012-6.017 1.343-1.364 3.074-2.046 5.196-2.046s3.834.67 5.138 2.014c1.305 1.341 1.957 3.374 1.957 6.094 0 2.721-.667 4.745-2.002 6.073-1.334 1.325-3.055 1.988-5.161 1.988m15.587-.552c0 .298-.741.449-2.226.449-1.484 0-2.228-.151-2.228-.449v-11.29h-2.698c-.255 0-.434-.345-.539-1.036-.045-.335-.067-.673-.066-1.011 0-.344.021-.682.065-1.012.105-.688.285-1.036.54-1.036h9.783c.255 0 .434.347.541 1.036.089.671.089 1.352 0 2.023-.107.691-.286 1.036-.541 1.036h-2.631z" fill="#fff" fill-rule="nonzero"/><path d="m2.644 9.821v7.76c0 6.683 19.71 6.611 19.71-.072v-7.628c.485-.629.937-1.283 1.356-1.961-.565-.952-1.235-1.824-2.009-2.615-.695.323-1.356.702-1.986 1.138-.646-.597-1.356-1.114-2.131-1.55.113-.823.178-1.647.194-2.47-.952-.451-1.945-.79-2.978-1.017-.42.695-.791 1.413-1.114 2.155-.791-.112-1.582-.112-2.373 0-.323-.742-.694-1.46-1.114-2.155-1.033.227-2.026.566-2.979 1.017.017.824.081 1.647.194 2.47-.775.436-1.485.953-2.131 1.55-.629-.436-1.291-.815-1.985-1.138-.775.791-1.445 1.662-2.01 2.615.42.678.872 1.271 1.356 1.901z" fill="none" stroke="#fff" stroke-width="2"/><g fill="#fff" fill-rule="nonzero"><path d="m2.644 15.838 3.681.339c.193.016.315.129.363.339l.097 1.622 3.196.243.194-1.478c.032-.177.153-.298.363-.363h3.923c.21.064.331.186.363.363l.194 1.478 3.196-.243.097-1.622c.048-.21.169-.323.363-.339l3.68-.339-.024.799-3.244.29-.121 1.671c-.033.162-.146.267-.339.315l-3.923.267c-.194 0-.323-.089-.388-.267l-.242-1.574h-3.147l-.243 1.574c-.064.178-.193.267-.387.267l-3.922-.267c-.194-.048-.307-.153-.34-.315l-.121-1.671-3.269-.29z" stroke="#fff" stroke-linejoin="miter"/><path d="m11.801 13.556-.001-2.082c.073-.824 1.332-.824 1.405 0v2.082c-.072.823-1.332.823-1.404 0zm-4.463-3.735c1.203 0 2.18.976 2.18 2.179s-.977 2.179-2.18 2.179-2.179-.976-2.179-2.179.976-2.179 2.179-2.179zm10.322 0c1.203 0 2.18.976 2.18 2.179s-.977 2.179-2.18 2.179c-1.202 0-2.179-.976-2.179-2.179s.977-2.179 2.179-2.179z"/></g></svg>

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

@@ -643,6 +643,15 @@ void EditorAssetLibrary::_notification(int p_what) {
case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
_update_repository_options();
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;
}
}
@@ -929,9 +938,7 @@ void EditorAssetLibrary::_request_image(ObjectID p_for, String p_image_url, Imag
}
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_bottom_page->hide();
@@ -1036,6 +1043,7 @@ HBoxContainer *EditorAssetLibrary::_make_pages(int p_page, int p_page_count, int
Button *first = memnew(Button);
first->set_text(TTR("First", "Pagination"));
first->set_theme_type_variation("PanelBackgroundButton");
if (p_page != 0) {
first->connect("pressed", callable_mp(this, &EditorAssetLibrary::_search).bind(0));
} else {
@@ -1046,6 +1054,7 @@ HBoxContainer *EditorAssetLibrary::_make_pages(int p_page, int p_page_count, int
Button *prev = memnew(Button);
prev->set_text(TTR("Previous", "Pagination"));
prev->set_theme_type_variation("PanelBackgroundButton");
if (p_page > 0) {
prev->connect("pressed", callable_mp(this, &EditorAssetLibrary::_search).bind(p_page - 1));
} else {
@@ -1056,26 +1065,22 @@ HBoxContainer *EditorAssetLibrary::_make_pages(int p_page, int p_page_count, int
hbc->add_child(memnew(VSeparator));
for (int i = from; i < to; i++) {
if (i == p_page) {
Button *current = memnew(Button);
// Keep the extended padding for the currently active page (see below).
current->set_text(vformat(" %d ", i + 1));
current->set_disabled(true);
current->set_focus_mode(Control::FOCUS_NONE);
hbc->add_child(current);
} else {
Button *current = memnew(Button);
// Add padding to make page number buttons easier to click.
current->set_text(vformat(" %d ", i + 1));
current->set_theme_type_variation("PanelBackgroundButton");
if (i == p_page) {
current->set_disabled(true);
current->set_focus_mode(Control::FOCUS_NONE);
} else {
current->connect("pressed", callable_mp(this, &EditorAssetLibrary::_search).bind(i));
hbc->add_child(current);
}
hbc->add_child(current);
}
Button *next = memnew(Button);
next->set_text(TTR("Next", "Pagination"));
next->set_theme_type_variation("PanelBackgroundButton");
if (p_page < p_page_count - 1) {
next->connect("pressed", callable_mp(this, &EditorAssetLibrary::_search).bind(p_page + 1));
} else {
@@ -1087,6 +1092,7 @@ HBoxContainer *EditorAssetLibrary::_make_pages(int p_page, int p_page_count, int
Button *last = memnew(Button);
last->set_text(TTR("Last", "Pagination"));
last->set_theme_type_variation("PanelBackgroundButton");
if (p_page != p_page_count - 1) {
last->connect("pressed", callable_mp(this, &EditorAssetLibrary::_search).bind(p_page_count - 1));
} else {
@@ -1104,10 +1110,14 @@ void EditorAssetLibrary::_api_request(const String &p_request, RequestType p_req
if (requesting != REQUESTING_NONE) {
request->cancel_request();
}
error_hb->hide();
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;
}
requesting = p_request_type;
error_hb->hide();
request->request(host + "/" + p_request + p_arguments);
}
@@ -1156,8 +1166,7 @@ void EditorAssetLibrary::_http_request_completed(int p_status, int p_code, const
if (error_abort) {
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();
return;
@@ -1265,18 +1274,17 @@ void EditorAssetLibrary::_http_request_completed(int p_status, int p_code, const
}
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));
} else {
// No results, even though the user didn't search for anything specific.
// This is typically because the version number changed recently
// 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));
}
library_info->show();
} else {
library_info->hide();
library_message_box->hide();
}
for (int i = 0; i < result.size(); i++) {
@@ -1432,6 +1440,39 @@ void EditorAssetLibrary::_update_asset_items_columns() {
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() {
support->get_popup()->set_item_checked(SUPPORT_COMMUNITY, false);
}
@@ -1443,7 +1484,7 @@ void EditorAssetLibrary::_bind_methods() {
EditorAssetLibrary::EditorAssetLibrary(bool p_templates_only) {
requesting = REQUESTING_NONE;
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);
add_child(library_main);
@@ -1567,22 +1608,18 @@ EditorAssetLibrary::EditorAssetLibrary(bool p_templates_only) {
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_message_box = memnew(VBoxContainer);
library_message_box->hide();
library_vb->add_child(library_message_box);
library_error = memnew(VBoxContainer);
library_error->hide();
library_vb->add_child(library_error);
library_message = memnew(Label);
library_message->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
library_message_box->add_child(library_message);
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_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_button->set_theme_type_variation("PanelBackgroundButton");
library_message_box->add_child(library_message_button);
asset_top_page = memnew(HBoxContainer);
library_vb->add_child(asset_top_page);

View File

@@ -191,10 +191,14 @@ class EditorAssetLibrary : public PanelContainer {
PanelContainer *library_scroll_bg = nullptr;
ScrollContainer *library_scroll = 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;
Timer *filter_debounce_timer = nullptr;
OptionButton *categories = nullptr;
@@ -213,8 +217,11 @@ class EditorAssetLibrary : public PanelContainer {
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 {
SUPPORT_OFFICIAL,

File diff suppressed because it is too large Load Diff

View File

@@ -41,11 +41,15 @@ class EditorFileDialog;
class HFlowContainer;
class LineEdit;
class LinkButton;
class MarginContainer;
class OptionButton;
class PanelContainer;
class ProjectDialog;
class ProjectList;
class QuickSettingsDialog;
class RichTextLabel;
class TabContainer;
class VBoxContainer;
class ProjectManager : public Control {
GDCLASS(ProjectManager, Control);
@@ -63,42 +67,79 @@ class ProjectManager : public Control {
// Main layout.
Ref<Theme> theme;
void _update_size_limits();
void _update_theme(bool p_skip_creation = false);
MarginContainer *root_container = nullptr;
Panel *background_panel = nullptr;
Button *about_btn = nullptr;
LinkButton *version_btn = nullptr;
VBoxContainer *main_vbox = nullptr;
ConfirmationDialog *open_templates = nullptr;
EditorAbout *about = nullptr;
HBoxContainer *title_bar = nullptr;
Button *title_bar_logo = nullptr;
HBoxContainer *main_view_toggles = nullptr;
Button *quick_settings_button = nullptr;
void _show_about();
void _version_button_pressed();
enum MainViewTab {
MAIN_VIEW_PROJECTS,
MAIN_VIEW_ASSETLIB,
MAIN_VIEW_MAX
};
MainViewTab current_main_view = MAIN_VIEW_PROJECTS;
HashMap<MainViewTab, Control *> main_view_map;
HashMap<MainViewTab, Button *> main_view_toggle_map;
PanelContainer *main_view_container = nullptr;
Ref<ButtonGroup> main_view_toggles_group;
Button *_add_main_view(MainViewTab p_id, const String &p_name, const Ref<Texture2D> &p_icon, Control *p_view_control);
void _set_main_view_icon(MainViewTab p_id, const Ref<Texture2D> &p_icon);
void _select_main_view(int p_id);
TabContainer *tabs = nullptr;
VBoxContainer *local_projects_vb = nullptr;
EditorAssetLibrary *asset_library = nullptr;
void _on_tab_changed(int p_tab);
void _open_asset_library();
EditorAbout *about_dialog = nullptr;
void _show_about();
void _open_asset_library_confirmed();
AcceptDialog *error_dialog = nullptr;
void _show_error(const String &p_message, const Size2 &p_min_size = Size2());
void _dim_window();
// Quick settings.
OptionButton *language_btn = nullptr;
ConfirmationDialog *restart_required_dialog = nullptr;
QuickSettingsDialog *quick_settings_dialog = nullptr;
void _language_selected(int p_id);
void _restart_confirm();
void _dim_window();
void _show_quick_settings();
void _restart_confirmed();
// Footer.
LinkButton *version_btn = nullptr;
void _version_button_pressed();
// Project list.
ProjectList *_project_list = nullptr;
VBoxContainer *empty_list_placeholder = nullptr;
Button *empty_list_create_project = nullptr;
Button *empty_list_import_project = nullptr;
Button *empty_list_open_assetlib = nullptr;
Label *empty_list_online_warning = nullptr;
void _update_list_placeholder();
ProjectList *project_list = nullptr;
LineEdit *search_box = nullptr;
Label *loading_label = nullptr;
OptionButton *filter_option = nullptr;
PanelContainer *search_panel = nullptr;
PanelContainer *project_list_panel = nullptr;
Button *create_btn = nullptr;
Button *import_btn = nullptr;
@@ -121,11 +162,7 @@ class ProjectManager : public Control {
ConfirmationDialog *multi_open_ask = nullptr;
ConfirmationDialog *multi_run_ask = nullptr;
HBoxContainer *settings_hb = nullptr;
AcceptDialog *run_error_diag = nullptr;
AcceptDialog *dialog_error = nullptr;
ProjectDialog *npdialog = nullptr;
ProjectDialog *project_dialog = nullptr;
void _scan_projects();
void _run_project();

View File

@@ -0,0 +1,306 @@
/**************************************************************************/
/* quick_settings_dialog.cpp */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#include "quick_settings_dialog.h"
#include "core/config/project_settings.h"
#include "core/string/translation.h"
#include "editor/editor_settings.h"
#include "editor/editor_string_names.h"
#include "editor/themes/editor_scale.h"
#include "scene/gui/box_container.h"
#include "scene/gui/button.h"
#include "scene/gui/label.h"
#include "scene/gui/margin_container.h"
#include "scene/gui/option_button.h"
#include "scene/gui/panel_container.h"
void QuickSettingsDialog::_fetch_setting_values() {
editor_languages.clear();
editor_themes.clear();
editor_scales.clear();
editor_network_modes.clear();
{
List<PropertyInfo> editor_settings_properties;
EditorSettings::get_singleton()->get_property_list(&editor_settings_properties);
for (const PropertyInfo &pi : editor_settings_properties) {
if (pi.name == "interface/editor/editor_language") {
editor_languages = pi.hint_string.split(",");
} else if (pi.name == "interface/theme/preset") {
editor_themes = pi.hint_string.split(",");
} else if (pi.name == "interface/editor/display_scale") {
editor_scales = pi.hint_string.split(",");
} else if (pi.name == "network/connection/network_mode") {
editor_network_modes = pi.hint_string.split(",");
}
}
}
}
void QuickSettingsDialog::_update_current_values() {
// Language options.
{
const String current_lang = EDITOR_GET("interface/editor/editor_language");
for (int i = 0; i < editor_languages.size(); i++) {
const String &lang_value = editor_languages[i];
if (current_lang == lang_value) {
language_option_button->set_text(current_lang);
language_option_button->select(i);
}
}
}
// Theme options.
{
const String current_theme = EDITOR_GET("interface/theme/preset");
for (int i = 0; i < editor_themes.size(); i++) {
const String &theme_value = editor_themes[i];
if (current_theme == theme_value) {
theme_option_button->set_text(current_theme);
theme_option_button->select(i);
custom_theme_label->set_visible(current_theme == "Custom");
}
}
}
// Scale options.
{
const int current_scale = EDITOR_GET("interface/editor/display_scale");
for (int i = 0; i < editor_scales.size(); i++) {
const String &scale_value = editor_scales[i];
if (current_scale == i) {
scale_option_button->set_text(scale_value);
scale_option_button->select(i);
}
}
}
// Network mode options.
{
const int current_network_mode = EDITOR_GET("network/connection/network_mode");
for (int i = 0; i < editor_network_modes.size(); i++) {
const String &network_mode_value = editor_network_modes[i];
if (current_network_mode == i) {
network_mode_option_button->set_text(network_mode_value);
network_mode_option_button->select(i);
}
}
}
}
void QuickSettingsDialog::_add_setting_control(const String &p_text, Control *p_control) {
HBoxContainer *container = memnew(HBoxContainer);
settings_list->add_child(container);
Label *label = memnew(Label(p_text));
label->set_h_size_flags(Control::SIZE_EXPAND_FILL);
container->add_child(label);
p_control->set_h_size_flags(Control::SIZE_EXPAND_FILL);
p_control->set_stretch_ratio(2.0);
container->add_child(p_control);
}
void QuickSettingsDialog::_language_selected(int p_id) {
const String selected_language = language_option_button->get_item_metadata(p_id);
_set_setting_value("interface/editor/editor_language", selected_language, true);
}
void QuickSettingsDialog::_theme_selected(int p_id) {
const String selected_theme = theme_option_button->get_item_text(p_id);
_set_setting_value("interface/theme/preset", selected_theme);
custom_theme_label->set_visible(selected_theme == "Custom");
}
void QuickSettingsDialog::_scale_selected(int p_id) {
_set_setting_value("interface/editor/display_scale", p_id, true);
}
void QuickSettingsDialog::_network_mode_selected(int p_id) {
_set_setting_value("network/connection/network_mode", p_id);
}
void QuickSettingsDialog::_set_setting_value(const String &p_setting, const Variant &p_value, bool p_restart_required) {
EditorSettings::get_singleton()->set(p_setting, p_value);
EditorSettings::get_singleton()->notify_changes();
EditorSettings::get_singleton()->save();
if (p_restart_required) {
restart_required_label->show();
if (!restart_required_button) {
restart_required_button = add_button(TTR("Restart Now"), !GLOBAL_GET("gui/common/swap_cancel_ok"));
restart_required_button->connect("pressed", callable_mp(this, &QuickSettingsDialog::_request_restart));
}
}
}
void QuickSettingsDialog::_request_restart() {
emit_signal("restart_required");
}
void QuickSettingsDialog::update_size_limits(const Size2 &p_max_popup_size) {
language_option_button->get_popup()->set_max_size(p_max_popup_size);
}
void QuickSettingsDialog::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_THEME_CHANGED: {
settings_list_panel->add_theme_style_override("panel", get_theme_stylebox(SNAME("Background"), EditorStringName(EditorStyles)));
restart_required_label->add_theme_color_override("font_color", get_theme_color(SNAME("warning_color"), EditorStringName(Editor)));
custom_theme_label->add_theme_color_override("font_color", get_theme_color(SNAME("font_placeholder_color"), EditorStringName(Editor)));
} break;
case NOTIFICATION_VISIBILITY_CHANGED: {
if (is_visible()) {
_update_current_values();
}
} break;
}
}
void QuickSettingsDialog::_bind_methods() {
ADD_SIGNAL(MethodInfo("restart_required"));
}
QuickSettingsDialog::QuickSettingsDialog() {
set_title(TTR("Quick Settings"));
set_ok_button_text(TTR("Close"));
VBoxContainer *main_vbox = memnew(VBoxContainer);
add_child(main_vbox);
main_vbox->set_anchors_and_offsets_preset(Control::PRESET_FULL_RECT);
// Settings grid.
{
_fetch_setting_values();
settings_list_panel = memnew(PanelContainer);
main_vbox->add_child(settings_list_panel);
settings_list = memnew(VBoxContainer);
settings_list_panel->add_child(settings_list);
// Language options.
{
language_option_button = memnew(OptionButton);
language_option_button->set_fit_to_longest_item(false);
language_option_button->connect("item_selected", callable_mp(this, &QuickSettingsDialog::_language_selected));
for (int i = 0; i < editor_languages.size(); i++) {
const String &lang_value = editor_languages[i];
String lang_name = TranslationServer::get_singleton()->get_locale_name(lang_value);
language_option_button->add_item(vformat("[%s] %s", lang_value, lang_name), i);
language_option_button->set_item_metadata(i, lang_value);
}
_add_setting_control(TTR("Language"), language_option_button);
}
// Theme options.
{
theme_option_button = memnew(OptionButton);
theme_option_button->set_fit_to_longest_item(false);
theme_option_button->connect("item_selected", callable_mp(this, &QuickSettingsDialog::_theme_selected));
for (int i = 0; i < editor_themes.size(); i++) {
const String &theme_value = editor_themes[i];
theme_option_button->add_item(theme_value, i);
}
_add_setting_control(TTR("Interface Theme"), theme_option_button);
custom_theme_label = memnew(Label(TTR("Custom preset can be further configured in the editor.")));
custom_theme_label->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_RIGHT);
custom_theme_label->set_custom_minimum_size(Size2(220, 0) * EDSCALE);
custom_theme_label->set_autowrap_mode(TextServer::AUTOWRAP_WORD);
custom_theme_label->set_h_size_flags(Control::SIZE_EXPAND_FILL);
custom_theme_label->set_stretch_ratio(2.0);
custom_theme_label->hide();
settings_list->add_child(custom_theme_label);
}
// Scale options.
{
scale_option_button = memnew(OptionButton);
scale_option_button->set_fit_to_longest_item(false);
scale_option_button->connect("item_selected", callable_mp(this, &QuickSettingsDialog::_scale_selected));
for (int i = 0; i < editor_scales.size(); i++) {
const String &scale_value = editor_scales[i];
scale_option_button->add_item(scale_value, i);
}
_add_setting_control(TTR("Display Scale"), scale_option_button);
}
// Network mode options.
{
network_mode_option_button = memnew(OptionButton);
network_mode_option_button->set_fit_to_longest_item(false);
network_mode_option_button->connect("item_selected", callable_mp(this, &QuickSettingsDialog::_network_mode_selected));
for (int i = 0; i < editor_network_modes.size(); i++) {
const String &network_mode_value = editor_network_modes[i];
network_mode_option_button->add_item(network_mode_value, i);
}
_add_setting_control(TTR("Network Mode"), network_mode_option_button);
}
_update_current_values();
#ifdef ANDROID_ENABLED
// The language selection dropdown doesn't work on Android (as the setting isn't saved), see GH-60353.
// Also, the dropdown it spawns is very tall and can't be scrolled without a hardware mouse.
language_option_button->hide();
scale_option_button->hide();
#endif
}
// Restart required panel.
{
restart_required_label = memnew(Label(TTR("Settings changed! The project manager must be restarted for changes to take effect.")));
restart_required_label->set_custom_minimum_size(Size2(560, 0) * EDSCALE);
restart_required_label->set_autowrap_mode(TextServer::AUTOWRAP_WORD);
restart_required_label->set_h_size_flags(Control::SIZE_EXPAND_FILL);
restart_required_label->hide();
main_vbox->add_child(restart_required_label);
}
}

View File

@@ -0,0 +1,87 @@
/**************************************************************************/
/* quick_settings_dialog.h */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#ifndef QUICK_SETTINGS_DIALOG_H
#define QUICK_SETTINGS_DIALOG_H
#include "scene/gui/dialogs.h"
class Button;
class Label;
class MarginContainer;
class OptionButton;
class PanelContainer;
class VBoxContainer;
class QuickSettingsDialog : public AcceptDialog {
GDCLASS(QuickSettingsDialog, AcceptDialog);
Vector<String> editor_languages;
Vector<String> editor_themes;
Vector<String> editor_scales;
Vector<String> editor_network_modes;
void _fetch_setting_values();
void _update_current_values();
PanelContainer *settings_list_panel = nullptr;
VBoxContainer *settings_list = nullptr;
void _add_setting_control(const String &p_text, Control *p_control);
OptionButton *language_option_button = nullptr;
OptionButton *theme_option_button = nullptr;
OptionButton *scale_option_button = nullptr;
OptionButton *network_mode_option_button = nullptr;
Label *custom_theme_label = nullptr;
void _language_selected(int p_id);
void _theme_selected(int p_id);
void _scale_selected(int p_id);
void _network_mode_selected(int p_id);
void _set_setting_value(const String &p_setting, const Variant &p_value, bool p_restart_required = false);
Label *restart_required_label = nullptr;
Button *restart_required_button = nullptr;
void _request_restart();
protected:
void _notification(int p_what);
static void _bind_methods();
public:
void update_size_limits(const Size2 &p_max_popup_size);
QuickSettingsDialog();
};
#endif // QUICK_SETTINGS_DIALOG_H

View File

@@ -370,6 +370,9 @@ void editor_register_fonts(const Ref<Theme> &p_theme) {
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));
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.
p_theme->set_default_font(default_fc); // Default theme font config.
@@ -385,13 +388,19 @@ void editor_register_fonts(const Ref<Theme> &p_theme) {
p_theme->set_font("main_bold_msdf", EditorStringName(EditorFonts), bold_fc_msdf);
p_theme->set_font_size("bold_size", EditorStringName(EditorFonts), default_font_size);
p_theme->set_font("italic", EditorStringName(EditorFonts), italic_fc);
p_theme->set_font_size("italic_size", EditorStringName(EditorFonts), default_font_size);
// Title font.
p_theme->set_font("title", EditorStringName(EditorFonts), bold_fc);
p_theme->set_font_size("title_size", EditorStringName(EditorFonts), default_font_size + 1 * EDSCALE);
p_theme->set_font("main_button_font", EditorStringName(EditorFonts), bold_fc);
p_theme->set_font_size("main_button_font_size", EditorStringName(EditorFonts), default_font_size + 1 * EDSCALE);
p_theme->set_type_variation("MainScreenButton", "Button");
p_theme->set_font("font", "MainScreenButton", bold_fc);
p_theme->set_font_size("font_size", "MainScreenButton", default_font_size + 2 * EDSCALE);
// Labels.
p_theme->set_font("font", "Label", default_fc);
@@ -407,6 +416,11 @@ void editor_register_fonts(const Ref<Theme> &p_theme) {
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("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
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);

View File

@@ -1590,7 +1590,7 @@ void EditorThemeManager::_populate_standard_styles(const Ref<EditorTheme> &p_the
void EditorThemeManager::_populate_editor_styles(const Ref<EditorTheme> &p_theme, ThemeConfiguration &p_config) {
// Project manager.
{
p_theme->set_stylebox("search_panel", "ProjectManager", p_config.tree_panel_style);
p_theme->set_stylebox("project_list", "ProjectManager", p_config.tree_panel_style);
p_theme->set_constant("sidebar_button_icon_separation", "ProjectManager", int(6 * EDSCALE));
// ProjectTag.
@@ -1769,6 +1769,28 @@ void EditorThemeManager::_populate_editor_styles(const Ref<EditorTheme> &p_theme
p_theme->set_stylebox("pressed", "EditorLogFilterButton", editor_log_button_pressed);
}
// Buttons styles that stand out against the panel background (e.g. AssetLib).
{
p_theme->set_type_variation("PanelBackgroundButton", "Button");
Ref<StyleBoxFlat> panel_button_style = p_config.button_style->duplicate();
panel_button_style->set_bg_color(p_config.base_color.lerp(p_config.mono_color, 0.08));
Ref<StyleBoxFlat> panel_button_style_hover = p_config.button_style_hover->duplicate();
panel_button_style_hover->set_bg_color(p_config.base_color.lerp(p_config.mono_color, 0.16));
Ref<StyleBoxFlat> panel_button_style_pressed = p_config.button_style_pressed->duplicate();
panel_button_style_pressed->set_bg_color(p_config.base_color.lerp(p_config.mono_color, 0.20));
Ref<StyleBoxFlat> panel_button_style_disabled = p_config.button_style_disabled->duplicate();
panel_button_style_disabled->set_bg_color(p_config.disabled_bg_color);
p_theme->set_stylebox("normal", "PanelBackgroundButton", panel_button_style);
p_theme->set_stylebox("hover", "PanelBackgroundButton", panel_button_style_hover);
p_theme->set_stylebox("pressed", "PanelBackgroundButton", panel_button_style_pressed);
p_theme->set_stylebox("disabled", "PanelBackgroundButton", panel_button_style_disabled);
}
// Top bar selectors.
{
p_theme->set_type_variation("TopBarOptionButton", "OptionButton");