diff options
Diffstat (limited to 'editor')
29 files changed, 463 insertions, 236 deletions
diff --git a/editor/debugger/editor_debugger_node.cpp b/editor/debugger/editor_debugger_node.cpp index bc28b11a71..e13af59d69 100644 --- a/editor/debugger/editor_debugger_node.cpp +++ b/editor/debugger/editor_debugger_node.cpp @@ -103,6 +103,7 @@ ScriptEditorDebugger *EditorDebuggerNode::_add_debugger() { node->connect("remote_object_updated", callable_mp(this, &EditorDebuggerNode::_remote_object_updated), varray(id)); node->connect("remote_object_property_updated", callable_mp(this, &EditorDebuggerNode::_remote_object_property_updated), varray(id)); node->connect("remote_object_requested", callable_mp(this, &EditorDebuggerNode::_remote_object_requested), varray(id)); + node->connect("errors_cleared", callable_mp(this, &EditorDebuggerNode::_update_errors)); if (tabs->get_tab_count() > 0) { get_debugger(0)->clear_style(); @@ -267,40 +268,7 @@ void EditorDebuggerNode::_notification(int p_what) { } server->poll(); - // Errors and warnings - int error_count = 0; - int warning_count = 0; - _for_all(tabs, [&](ScriptEditorDebugger *dbg) { - error_count += dbg->get_error_count(); - warning_count += dbg->get_warning_count(); - }); - - if (error_count != last_error_count || warning_count != last_warning_count) { - _for_all(tabs, [&](ScriptEditorDebugger *dbg) { - dbg->update_tabs(); - }); - - if (error_count == 0 && warning_count == 0) { - debugger_button->set_text(TTR("Debugger")); - debugger_button->remove_theme_color_override("font_color"); - debugger_button->set_icon(Ref<Texture2D>()); - } else { - debugger_button->set_text(TTR("Debugger") + " (" + itos(error_count + warning_count) + ")"); - if (error_count >= 1 && warning_count >= 1) { - debugger_button->set_icon(get_theme_icon(SNAME("ErrorWarning"), SNAME("EditorIcons"))); - // Use error color to represent the highest level of severity reported. - debugger_button->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), SNAME("Editor"))); - } else if (error_count >= 1) { - debugger_button->set_icon(get_theme_icon(SNAME("Error"), SNAME("EditorIcons"))); - debugger_button->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), SNAME("Editor"))); - } else { - debugger_button->set_icon(get_theme_icon(SNAME("Warning"), SNAME("EditorIcons"))); - debugger_button->add_theme_color_override("font_color", get_theme_color(SNAME("warning_color"), SNAME("Editor"))); - } - } - last_error_count = error_count; - last_warning_count = warning_count; - } + _update_errors(); // Remote scene tree update remote_scene_tree_timeout -= get_process_delta_time(); @@ -361,6 +329,42 @@ void EditorDebuggerNode::_notification(int p_what) { } } +void EditorDebuggerNode::_update_errors() { + int error_count = 0; + int warning_count = 0; + _for_all(tabs, [&](ScriptEditorDebugger *dbg) { + error_count += dbg->get_error_count(); + warning_count += dbg->get_warning_count(); + }); + + if (error_count != last_error_count || warning_count != last_warning_count) { + _for_all(tabs, [&](ScriptEditorDebugger *dbg) { + dbg->update_tabs(); + }); + + if (error_count == 0 && warning_count == 0) { + debugger_button->set_text(TTR("Debugger")); + debugger_button->remove_theme_color_override("font_color"); + debugger_button->set_icon(Ref<Texture2D>()); + } else { + debugger_button->set_text(TTR("Debugger") + " (" + itos(error_count + warning_count) + ")"); + if (error_count >= 1 && warning_count >= 1) { + debugger_button->set_icon(get_theme_icon(SNAME("ErrorWarning"), SNAME("EditorIcons"))); + // Use error color to represent the highest level of severity reported. + debugger_button->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), SNAME("Editor"))); + } else if (error_count >= 1) { + debugger_button->set_icon(get_theme_icon(SNAME("Error"), SNAME("EditorIcons"))); + debugger_button->add_theme_color_override("font_color", get_theme_color(SNAME("error_color"), SNAME("Editor"))); + } else { + debugger_button->set_icon(get_theme_icon(SNAME("Warning"), SNAME("EditorIcons"))); + debugger_button->add_theme_color_override("font_color", get_theme_color(SNAME("warning_color"), SNAME("Editor"))); + } + } + last_error_count = error_count; + last_warning_count = warning_count; + } +} + void EditorDebuggerNode::_debugger_stopped(int p_id) { ScriptEditorDebugger *dbg = get_debugger(p_id); ERR_FAIL_COND(!dbg); diff --git a/editor/debugger/editor_debugger_node.h b/editor/debugger/editor_debugger_node.h index 87457fc09a..8dc53690eb 100644 --- a/editor/debugger/editor_debugger_node.h +++ b/editor/debugger/editor_debugger_node.h @@ -116,6 +116,7 @@ private: ScriptEditorDebugger *_add_debugger(); EditorDebuggerRemoteObject *get_inspected_remote_object(); + void _update_errors(); friend class DebuggerEditorPlugin; friend class DebugAdapterParser; diff --git a/editor/debugger/script_editor_debugger.cpp b/editor/debugger/script_editor_debugger.cpp index 9184846408..05409dbeeb 100644 --- a/editor/debugger/script_editor_debugger.cpp +++ b/editor/debugger/script_editor_debugger.cpp @@ -1465,6 +1465,7 @@ void ScriptEditorDebugger::_clear_errors_list() { error_tree->clear(); error_count = 0; warning_count = 0; + emit_signal(SNAME("errors_cleared")); update_tabs(); expand_all_button->set_disabled(true); @@ -1626,6 +1627,7 @@ void ScriptEditorDebugger::_bind_methods() { ADD_SIGNAL(MethodInfo("debug_data", PropertyInfo(Variant::STRING, "msg"), PropertyInfo(Variant::ARRAY, "data"))); ADD_SIGNAL(MethodInfo("set_breakpoint", PropertyInfo("script"), PropertyInfo(Variant::INT, "line"), PropertyInfo(Variant::BOOL, "enabled"))); ADD_SIGNAL(MethodInfo("clear_breakpoints")); + ADD_SIGNAL(MethodInfo("errors_cleared")); } void ScriptEditorDebugger::add_debugger_plugin(const Ref<Script> &p_script) { diff --git a/editor/dependency_editor.cpp b/editor/dependency_editor.cpp index 7b73a392b4..97699d0349 100644 --- a/editor/dependency_editor.cpp +++ b/editor/dependency_editor.cpp @@ -349,7 +349,7 @@ void DependencyEditorOwners::show(const String &p_path) { _fill_owners(EditorFileSystem::get_singleton()->get_filesystem()); popup_centered_ratio(0.3); - set_title(TTR("Owners Of:") + " " + p_path.get_file()); + set_title(vformat(TTR("Owners of: %s (Total: %d)"), p_path.get_file(), owners->get_item_count())); } DependencyEditorOwners::DependencyEditorOwners() { diff --git a/editor/editor_export.cpp b/editor/editor_export.cpp index f4a81521df..bb9d930cf5 100644 --- a/editor/editor_export.cpp +++ b/editor/editor_export.cpp @@ -46,6 +46,7 @@ #include "editor/editor_file_system.h" #include "editor/editor_node.h" #include "editor/editor_paths.h" +#include "editor/editor_scale.h" #include "editor/editor_settings.h" #include "editor/plugins/script_editor_plugin.h" #include "scene/resources/resource_format_text.h" @@ -252,6 +253,83 @@ String EditorExportPreset::get_script_encryption_key() const { /////////////////////////////////// +bool EditorExportPlatform::fill_log_messages(RichTextLabel *p_log, Error p_err) { + bool has_messages = false; + + int msg_count = get_message_count(); + + p_log->add_text(TTR("Project export for platform:") + " "); + p_log->add_image(get_logo(), 16 * EDSCALE, 16 * EDSCALE, Color(1.0, 1.0, 1.0), INLINE_ALIGNMENT_CENTER); + p_log->add_text(" "); + p_log->add_text(get_name()); + p_log->add_text(" - "); + if (p_err == OK) { + if (get_worst_message_type() >= EditorExportPlatform::EXPORT_MESSAGE_WARNING) { + p_log->add_image(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("StatusWarning"), SNAME("EditorIcons")), 16 * EDSCALE, 16 * EDSCALE, Color(1.0, 1.0, 1.0), INLINE_ALIGNMENT_CENTER); + p_log->add_text(" "); + p_log->add_text(TTR("Completed with errors.")); + has_messages = true; + } else { + p_log->add_image(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("StatusSuccess"), SNAME("EditorIcons")), 16 * EDSCALE, 16 * EDSCALE, Color(1.0, 1.0, 1.0), INLINE_ALIGNMENT_CENTER); + p_log->add_text(" "); + p_log->add_text(TTR("Completed sucessfully.")); + if (msg_count > 0) { + has_messages = true; + } + } + } else { + p_log->add_image(EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("StatusError"), SNAME("EditorIcons")), 16 * EDSCALE, 16 * EDSCALE, Color(1.0, 1.0, 1.0), INLINE_ALIGNMENT_CENTER); + p_log->add_text(" "); + p_log->add_text(TTR("Failed.")); + has_messages = true; + } + p_log->add_newline(); + + if (msg_count) { + p_log->push_table(2); + p_log->set_table_column_expand(0, false); + p_log->set_table_column_expand(1, true); + for (int m = 0; m < msg_count; m++) { + EditorExportPlatform::ExportMessage msg = get_message(m); + Color color = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("font_color"), SNAME("Label")); + Ref<Texture> icon; + + switch (msg.msg_type) { + case EditorExportPlatform::EXPORT_MESSAGE_INFO: { + color = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("font_color"), SNAME("Editor")) * Color(1, 1, 1, 0.6); + } break; + case EditorExportPlatform::EXPORT_MESSAGE_WARNING: { + icon = EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Warning"), SNAME("EditorIcons")); + color = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("warning_color"), SNAME("Editor")); + } break; + case EditorExportPlatform::EXPORT_MESSAGE_ERROR: { + icon = EditorNode::get_singleton()->get_gui_base()->get_theme_icon(SNAME("Error"), SNAME("EditorIcons")); + color = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("error_color"), SNAME("Editor")); + } break; + default: + break; + } + + p_log->push_cell(); + p_log->add_text("\t"); + if (icon.is_valid()) { + p_log->add_image(icon); + } + p_log->pop(); + + p_log->push_cell(); + p_log->push_color(color); + p_log->add_text(vformat("[%s]: %s", msg.category, msg.text)); + p_log->pop(); + p_log->pop(); + } + p_log->pop(); + p_log->add_newline(); + } + p_log->add_newline(); + return has_messages; +} + void EditorExportPlatform::gen_debug_flags(Vector<String> &r_flags, int p_flags) { String host = EditorSettings::get_singleton()->get("network/debug/remote_host"); int remote_port = (int)EditorSettings::get_singleton()->get("network/debug/remote_port"); @@ -1134,7 +1212,10 @@ Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, b String tmppath = EditorPaths::get_singleton()->get_cache_dir().plus_file("packtmp"); Ref<FileAccess> ftmp = FileAccess::open(tmppath, FileAccess::WRITE); - ERR_FAIL_COND_V_MSG(ftmp.is_null(), ERR_CANT_CREATE, "Cannot create file '" + tmppath + "'."); + if (ftmp.is_null()) { + add_message(EXPORT_MESSAGE_ERROR, TTR("Save PCK"), vformat(TTR("Cannot create file \"%s\"."), tmppath)); + return ERR_CANT_CREATE; + } PackData pd; pd.ep = &ep; @@ -1149,7 +1230,7 @@ Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, b if (err != OK) { DirAccess::remove_file_or_error(tmppath); - ERR_PRINT("Failed to export project files"); + add_message(EXPORT_MESSAGE_ERROR, TTR("Save PCK"), TTR("Failed to export project files.")); return err; } @@ -1162,14 +1243,16 @@ Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, b f = FileAccess::open(p_path, FileAccess::WRITE); if (f.is_null()) { DirAccess::remove_file_or_error(tmppath); - ERR_FAIL_V(ERR_CANT_CREATE); + add_message(EXPORT_MESSAGE_ERROR, TTR("Save PCK"), vformat(TTR("Can't open file to read from path \"%s\"."), tmppath)); + return ERR_CANT_CREATE; } } else { // Append to executable f = FileAccess::open(p_path, FileAccess::READ_WRITE); if (f.is_null()) { DirAccess::remove_file_or_error(tmppath); - ERR_FAIL_V(ERR_FILE_CANT_OPEN); + add_message(EXPORT_MESSAGE_ERROR, TTR("Save PCK"), vformat(TTR("Can't open executable file from path \"%s\"."), tmppath)); + return ERR_FILE_CANT_OPEN; } f->seek_end(); @@ -1245,10 +1328,16 @@ Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, b } } fae.instantiate(); - ERR_FAIL_COND_V(fae.is_null(), ERR_SKIP); + if (fae.is_null()) { + add_message(EXPORT_MESSAGE_ERROR, TTR("Save PCK"), TTR("Can't create encrypted file.")); + return ERR_CANT_CREATE; + } err = fae->open_and_parse(f, key, FileAccessEncrypted::MODE_WRITE_AES256, false); - ERR_FAIL_COND_V(err != OK, ERR_SKIP); + if (err != OK) { + add_message(EXPORT_MESSAGE_ERROR, TTR("Save PCK"), TTR("Can't open encrypted file to write.")); + return ERR_CANT_CREATE; + } fhead = fae; } @@ -1293,7 +1382,8 @@ Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, b ftmp = FileAccess::open(tmppath, FileAccess::READ); if (ftmp.is_null()) { DirAccess::remove_file_or_error(tmppath); - ERR_FAIL_V_MSG(ERR_CANT_CREATE, "Can't open file to read from path '" + String(tmppath) + "'."); + add_message(EXPORT_MESSAGE_ERROR, TTR("Save PCK"), vformat(TTR("Can't open file to read from path \"%s\"."), tmppath)); + return ERR_CANT_CREATE; } const int bufsize = 16384; @@ -1344,7 +1434,7 @@ Error EditorExportPlatform::save_zip(const Ref<EditorExportPreset> &p_preset, bo Error err = export_project_files(p_preset, p_debug, _save_zip_file, &zd); if (err != OK && err != ERR_SKIP) { - ERR_PRINT("Failed to export project files"); + add_message(EXPORT_MESSAGE_ERROR, TTR("Save ZIP"), TTR("Failed to export project files.")); } zipClose(zip, nullptr); @@ -1835,6 +1925,7 @@ Error EditorExportPlatformPC::export_project(const Ref<EditorExportPreset> &p_pr Error EditorExportPlatformPC::prepare_template(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) { if (!DirAccess::exists(p_path.get_base_dir())) { + add_message(EXPORT_MESSAGE_ERROR, TTR("Prepare Template"), TTR("The given export path doesn't exist.")); return ERR_FILE_BAD_PATH; } @@ -1850,13 +1941,16 @@ Error EditorExportPlatformPC::prepare_template(const Ref<EditorExportPreset> &p_ } if (!template_path.is_empty() && !FileAccess::exists(template_path)) { - EditorNode::get_singleton()->show_warning(TTR("Template file not found:") + "\n" + template_path); + add_message(EXPORT_MESSAGE_ERROR, TTR("Prepare Template"), vformat(TTR("Template file not found: \"%s\"."), template_path)); return ERR_FILE_NOT_FOUND; } Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); da->make_dir_recursive(p_path.get_base_dir()); Error err = da->copy(template_path, p_path, get_chmod_flags()); + if (err != OK) { + add_message(EXPORT_MESSAGE_ERROR, TTR("Prepare Template"), TTR("Failed to copy export template.")); + } return err; } @@ -1876,7 +1970,7 @@ Error EditorExportPlatformPC::export_project_data(const Ref<EditorExportPreset> Error err = save_pack(p_preset, p_debug, pck_path, &so_files, p_preset->get("binary_format/embed_pck"), &embedded_pos, &embedded_size); if (err == OK && p_preset->get("binary_format/embed_pck")) { if (embedded_size >= 0x100000000 && !p_preset->get("binary_format/64_bits")) { - EditorNode::get_singleton()->show_warning(TTR("On 32-bit exports the embedded PCK cannot be bigger than 4 GiB.")); + add_message(EXPORT_MESSAGE_ERROR, TTR("PCK Embedding"), TTR("On 32-bit exports the embedded PCK cannot be bigger than 4 GiB.")); return ERR_INVALID_PARAMETER; } diff --git a/editor/editor_export.h b/editor/editor_export.h index daf6d8ef23..6f41736d2d 100644 --- a/editor/editor_export.h +++ b/editor/editor_export.h @@ -33,6 +33,7 @@ #include "core/io/dir_access.h" #include "core/io/resource.h" +#include "scene/gui/rich_text_label.h" #include "scene/main/node.h" #include "scene/main/timer.h" #include "scene/resources/texture.h" @@ -170,6 +171,19 @@ public: typedef Error (*EditorExportSaveFunction)(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total, const Vector<String> &p_enc_in_filters, const Vector<String> &p_enc_ex_filters, const Vector<uint8_t> &p_key); typedef Error (*EditorExportSaveSharedObject)(void *p_userdata, const SharedObject &p_so); + enum ExportMessageType { + EXPORT_MESSAGE_NONE, + EXPORT_MESSAGE_INFO, + EXPORT_MESSAGE_WARNING, + EXPORT_MESSAGE_ERROR, + }; + + struct ExportMessage { + ExportMessageType msg_type; + String category; + String text; + }; + private: struct SavedData { uint64_t ofs = 0; @@ -200,6 +214,8 @@ private: Vector<String> features_pv; }; + Vector<ExportMessage> messages; + void _export_find_resources(EditorFileSystemDirectory *p_dir, HashSet<String> &p_paths); void _export_find_dependencies(const String &p_path, HashSet<String> &p_paths); @@ -240,6 +256,47 @@ public: virtual Ref<EditorExportPreset> create_preset(); + virtual void clear_messages() { messages.clear(); } + virtual void add_message(ExportMessageType p_type, const String &p_category, const String &p_message) { + ExportMessage msg; + msg.category = p_category; + msg.text = p_message; + msg.msg_type = p_type; + messages.push_back(msg); + switch (p_type) { + case EXPORT_MESSAGE_INFO: { + print_line(vformat("%s: %s\n", msg.category, msg.text)); + } break; + case EXPORT_MESSAGE_WARNING: { + WARN_PRINT(vformat("%s: %s\n", msg.category, msg.text)); + } break; + case EXPORT_MESSAGE_ERROR: { + ERR_PRINT(vformat("%s: %s\n", msg.category, msg.text)); + } break; + default: + break; + } + } + + virtual int get_message_count() const { + return messages.size(); + } + + virtual ExportMessage get_message(int p_index) const { + ERR_FAIL_INDEX_V(p_index, messages.size(), ExportMessage()); + return messages[p_index]; + } + + virtual ExportMessageType get_worst_message_type() const { + ExportMessageType worst_type = EXPORT_MESSAGE_NONE; + for (int i = 0; i < messages.size(); i++) { + worst_type = MAX(worst_type, messages[i].msg_type); + } + return worst_type; + } + + virtual bool fill_log_messages(RichTextLabel *p_log, Error p_err); + virtual void get_export_options(List<ExportOption> *r_options) = 0; virtual bool should_update_export_options() { return false; } virtual bool get_export_option_visibility(const String &p_option, const HashMap<StringName, Variant> &p_options) const { return true; } @@ -459,7 +516,7 @@ public: int get_chmod_flags() const; void set_chmod_flags(int p_flags); - virtual Error fixup_embedded_pck(const String &p_path, int64_t p_embedded_start, int64_t p_embedded_size) const { + virtual Error fixup_embedded_pck(const String &p_path, int64_t p_embedded_start, int64_t p_embedded_size) { return Error::OK; } }; diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index 92ea162962..0f31e3e7bb 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -62,7 +62,7 @@ Size2 EditorProperty::get_minimum_size() const { Size2 ms; Ref<Font> font = get_theme_font(SNAME("font"), SNAME("Tree")); int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Tree")); - ms.height = font->get_height(font_size); + ms.height = font->get_height(font_size) + 4 * EDSCALE; for (int i = 0; i < get_child_count(); i++) { Control *c = Object::cast_to<Control>(get_child(i)); @@ -132,7 +132,7 @@ void EditorProperty::_notification(int p_what) { int child_room = size.width * (1.0 - split_ratio); Ref<Font> font = get_theme_font(SNAME("font"), SNAME("Tree")); int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Tree")); - int height = font->get_height(font_size); + int height = font->get_height(font_size) + 4 * EDSCALE; bool no_children = true; //compute room needed @@ -236,30 +236,24 @@ void EditorProperty::_notification(int p_what) { case NOTIFICATION_DRAW: { Ref<Font> font = get_theme_font(SNAME("font"), SNAME("Tree")); int font_size = get_theme_font_size(SNAME("font_size"), SNAME("Tree")); - Color dark_color = get_theme_color(SNAME("dark_color_2"), SNAME("Editor")); bool rtl = is_layout_rtl(); Size2 size = get_size(); if (bottom_editor) { - size.height = bottom_editor->get_offset(SIDE_TOP); + size.height = bottom_editor->get_offset(SIDE_TOP) - get_theme_constant(SNAME("v_separation")); } else if (label_reference) { size.height = label_reference->get_size().height; } - Ref<StyleBox> sb; - if (selected) { - sb = get_theme_stylebox(SNAME("bg_selected")); - } else { - sb = get_theme_stylebox(SNAME("bg")); - } - + Ref<StyleBox> sb = get_theme_stylebox(selected ? SNAME("bg_selected") : SNAME("bg")); draw_style_box(sb, Rect2(Vector2(), size)); + Ref<StyleBox> bg_stylebox = get_theme_stylebox(SNAME("child_bg")); if (draw_top_bg && right_child_rect != Rect2()) { - draw_rect(right_child_rect, dark_color); + draw_style_box(bg_stylebox, right_child_rect); } if (bottom_child_rect != Rect2()) { - draw_rect(bottom_child_rect, dark_color); + draw_style_box(bg_stylebox, bottom_child_rect); } Color color; @@ -1075,7 +1069,7 @@ void EditorInspectorPlugin::_bind_methods() { void EditorInspectorCategory::_notification(int p_what) { switch (p_what) { case NOTIFICATION_DRAW: { - Ref<StyleBox> sb = get_theme_stylebox(SNAME("prop_category_style"), SNAME("Editor")); + Ref<StyleBox> sb = get_theme_stylebox(SNAME("bg")); draw_style_box(sb, Rect2(Vector2(), get_size())); diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index e23c36c1d4..61f8ab1936 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -968,21 +968,14 @@ void EditorNode::_fs_changed() { ERR_PRINT(vformat("Cannot export project with preset \"%s\" due to configuration errors:\n%s", preset_name, config_error)); err = missing_templates ? ERR_FILE_NOT_FOUND : ERR_UNCONFIGURED; } else { + platform->clear_messages(); err = platform->export_project(export_preset, export_defer.debug, export_path); } } - switch (err) { - case OK: - break; - case ERR_FILE_NOT_FOUND: - export_error = vformat("Project export failed for preset \"%s\". The export template appears to be missing.", preset_name); - break; - case ERR_FILE_BAD_PATH: - export_error = vformat("Project export failed for preset \"%s\". The target path \"%s\" appears to be invalid.", preset_name, export_path); - break; - default: - export_error = vformat("Project export failed with error code %d for preset \"%s\".", (int)err, preset_name); - break; + if (err != OK) { + export_error = vformat("Project export for preset \"%s\" failed.", preset_name); + } else if (platform->get_worst_message_type() >= EditorExportPlatform::EXPORT_MESSAGE_WARNING) { + export_error = vformat("Project export for preset \"%s\" completed with errors.", preset_name); } } } diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp index e3d4f1cab0..ddf1974070 100644 --- a/editor/editor_properties.cpp +++ b/editor/editor_properties.cpp @@ -173,6 +173,7 @@ void EditorPropertyMultilineText::_bind_methods() { EditorPropertyMultilineText::EditorPropertyMultilineText() { HBoxContainer *hb = memnew(HBoxContainer); + hb->add_theme_constant_override("separation", 0); add_child(hb); set_bottom_editor(hb); text = memnew(TextEdit); @@ -1258,12 +1259,13 @@ void EditorPropertyInteger::update_property() { void EditorPropertyInteger::_bind_methods() { } -void EditorPropertyInteger::setup(int64_t p_min, int64_t p_max, int64_t p_step, bool p_allow_greater, bool p_allow_lesser) { +void EditorPropertyInteger::setup(int64_t p_min, int64_t p_max, int64_t p_step, bool p_allow_greater, bool p_allow_lesser, const String &p_suffix) { spin->set_min(p_min); spin->set_max(p_max); spin->set_step(p_step); spin->set_allow_greater(p_allow_greater); spin->set_allow_lesser(p_allow_lesser); + spin->set_suffix(p_suffix); } EditorPropertyInteger::EditorPropertyInteger() { @@ -2948,6 +2950,7 @@ void EditorPropertyNodePath::_bind_methods() { EditorPropertyNodePath::EditorPropertyNodePath() { HBoxContainer *hbc = memnew(HBoxContainer); + hbc->add_theme_constant_override("separation", 0); add_child(hbc); assign = memnew(Button); assign->set_flat(true); @@ -3134,17 +3137,15 @@ void EditorPropertyResource::_update_property_bg() { count_subinspectors = MIN(15, count_subinspectors); add_theme_color_override("property_color", get_theme_color(SNAME("sub_inspector_property_color"), SNAME("Editor"))); - add_theme_style_override("bg_selected", get_theme_stylebox("sub_inspector_property_bg_selected" + itos(count_subinspectors), SNAME("Editor"))); + add_theme_style_override("bg_selected", get_theme_stylebox("sub_inspector_property_bg" + itos(count_subinspectors), SNAME("Editor"))); add_theme_style_override("bg", get_theme_stylebox("sub_inspector_property_bg" + itos(count_subinspectors), SNAME("Editor"))); - add_theme_constant_override("font_offset", get_theme_constant(SNAME("sub_inspector_font_offset"), SNAME("Editor"))); add_theme_constant_override("v_separation", 0); } else { add_theme_color_override("property_color", get_theme_color(SNAME("property_color"), SNAME("EditorProperty"))); add_theme_style_override("bg_selected", get_theme_stylebox(SNAME("bg_selected"), SNAME("EditorProperty"))); add_theme_style_override("bg", get_theme_stylebox(SNAME("bg"), SNAME("EditorProperty"))); add_theme_constant_override("v_separation", get_theme_constant(SNAME("v_separation"), SNAME("EditorProperty"))); - add_theme_constant_override("font_offset", get_theme_constant(SNAME("font_offset"), SNAME("EditorProperty"))); } updating_theme = false; @@ -3492,7 +3493,7 @@ EditorProperty *EditorInspectorDefaultPlugin::get_editor_for_property(Object *p_ EditorPropertyInteger *editor = memnew(EditorPropertyInteger); EditorPropertyRangeHint hint = _parse_range_hint(p_hint, p_hint_text, 1); - editor->setup(hint.min, hint.max, hint.step, hint.greater, hint.lesser); + editor->setup(hint.min, hint.max, hint.step, hint.greater, hint.lesser, hint.suffix); return editor; } diff --git a/editor/editor_properties.h b/editor/editor_properties.h index a3990db678..6513eb0390 100644 --- a/editor/editor_properties.h +++ b/editor/editor_properties.h @@ -368,7 +368,7 @@ protected: public: virtual void update_property() override; - void setup(int64_t p_min, int64_t p_max, int64_t p_step, bool p_allow_greater, bool p_allow_lesser); + void setup(int64_t p_min, int64_t p_max, int64_t p_step, bool p_allow_greater, bool p_allow_lesser, const String &p_suffix = String()); EditorPropertyInteger(); }; diff --git a/editor/editor_properties_array_dict.cpp b/editor/editor_properties_array_dict.cpp index b3a1f35218..f47c6e298b 100644 --- a/editor/editor_properties_array_dict.cpp +++ b/editor/editor_properties_array_dict.cpp @@ -217,11 +217,11 @@ void EditorPropertyArray::update_property() { if (array.get_type() == Variant::NIL) { edit->set_text(vformat(TTR("(Nil) %s"), array_type_name)); edit->set_pressed(false); - if (vbox) { + if (container) { set_bottom_editor(nullptr); - memdelete(vbox); + memdelete(container); button_add_item = nullptr; - vbox = nullptr; + container = nullptr; } return; } @@ -241,10 +241,14 @@ void EditorPropertyArray::update_property() { if (unfolded) { updating = true; - if (!vbox) { - vbox = memnew(VBoxContainer); - add_child(vbox); - set_bottom_editor(vbox); + if (!container) { + container = memnew(MarginContainer); + container->set_theme_type_variation("MarginContainer4px"); + add_child(container); + set_bottom_editor(container); + + VBoxContainer *vbox = memnew(VBoxContainer); + container->add_child(vbox); HBoxContainer *hbox = memnew(HBoxContainer); vbox->add_child(hbox); @@ -372,11 +376,11 @@ void EditorPropertyArray::update_property() { updating = false; } else { - if (vbox) { + if (container) { set_bottom_editor(nullptr); - memdelete(vbox); + memdelete(container); button_add_item = nullptr; - vbox = nullptr; + container = nullptr; } } } @@ -687,7 +691,7 @@ EditorPropertyArray::EditorPropertyArray() { add_child(edit); add_focusable(edit); - vbox = nullptr; + container = nullptr; property_vbox = nullptr; size_slider = nullptr; button_add_item = nullptr; @@ -791,11 +795,11 @@ void EditorPropertyDictionary::update_property() { if (updated_val.get_type() == Variant::NIL) { edit->set_text(TTR("Dictionary (Nil)")); // This provides symmetry with the array property. edit->set_pressed(false); - if (vbox) { + if (container) { set_bottom_editor(nullptr); - memdelete(vbox); + memdelete(container); button_add_item = nullptr; - vbox = nullptr; + container = nullptr; } return; } @@ -812,10 +816,14 @@ void EditorPropertyDictionary::update_property() { if (unfolded) { updating = true; - if (!vbox) { - vbox = memnew(VBoxContainer); - add_child(vbox); - set_bottom_editor(vbox); + if (!container) { + container = memnew(MarginContainer); + container->set_theme_type_variation("MarginContainer4px"); + add_child(container); + set_bottom_editor(container); + + VBoxContainer *vbox = memnew(VBoxContainer); + container->add_child(vbox); property_vbox = memnew(VBoxContainer); property_vbox->set_h_size_flags(SIZE_EXPAND_FILL); @@ -1116,11 +1124,11 @@ void EditorPropertyDictionary::update_property() { updating = false; } else { - if (vbox) { + if (container) { set_bottom_editor(nullptr); - memdelete(vbox); + memdelete(container); button_add_item = nullptr; - vbox = nullptr; + container = nullptr; } } } @@ -1188,7 +1196,7 @@ EditorPropertyDictionary::EditorPropertyDictionary() { add_child(edit); add_focusable(edit); - vbox = nullptr; + container = nullptr; button_add_item = nullptr; paginator = nullptr; change_type = memnew(PopupMenu); @@ -1250,11 +1258,11 @@ void EditorPropertyLocalizableString::update_property() { if (updated_val.get_type() == Variant::NIL) { edit->set_text(TTR("Localizable String (Nil)")); // This provides symmetry with the array property. edit->set_pressed(false); - if (vbox) { + if (container) { set_bottom_editor(nullptr); - memdelete(vbox); + memdelete(container); button_add_item = nullptr; - vbox = nullptr; + container = nullptr; } return; } @@ -1271,10 +1279,14 @@ void EditorPropertyLocalizableString::update_property() { if (unfolded) { updating = true; - if (!vbox) { - vbox = memnew(VBoxContainer); - add_child(vbox); - set_bottom_editor(vbox); + if (!container) { + container = memnew(MarginContainer); + container->set_theme_type_variation("MarginContainer4px"); + add_child(container); + set_bottom_editor(container); + + VBoxContainer *vbox = memnew(VBoxContainer); + container->add_child(vbox); property_vbox = memnew(VBoxContainer); property_vbox->set_h_size_flags(SIZE_EXPAND_FILL); @@ -1351,11 +1363,11 @@ void EditorPropertyLocalizableString::update_property() { updating = false; } else { - if (vbox) { + if (container) { set_bottom_editor(nullptr); - memdelete(vbox); + memdelete(container); button_add_item = nullptr; - vbox = nullptr; + container = nullptr; } } } @@ -1410,7 +1422,7 @@ EditorPropertyLocalizableString::EditorPropertyLocalizableString() { add_child(edit); add_focusable(edit); - vbox = nullptr; + container = nullptr; button_add_item = nullptr; paginator = nullptr; updating = false; diff --git a/editor/editor_properties_array_dict.h b/editor/editor_properties_array_dict.h index 070353c538..44623149d0 100644 --- a/editor/editor_properties_array_dict.h +++ b/editor/editor_properties_array_dict.h @@ -89,7 +89,7 @@ class EditorPropertyArray : public EditorProperty { int page_index = 0; int changing_type_index; Button *edit = nullptr; - VBoxContainer *vbox = nullptr; + MarginContainer *container = nullptr; VBoxContainer *property_vbox = nullptr; EditorSpinSlider *size_slider = nullptr; Button *button_add_item = nullptr; @@ -146,9 +146,9 @@ class EditorPropertyDictionary : public EditorProperty { int page_index = 0; int changing_type_index; Button *edit = nullptr; - VBoxContainer *vbox = nullptr; + MarginContainer *container = nullptr; VBoxContainer *property_vbox = nullptr; - EditorSpinSlider *size_slider = nullptr; + EditorSpinSlider *size_sliderv; Button *button_add_item = nullptr; EditorPaginator *paginator = nullptr; @@ -181,7 +181,7 @@ class EditorPropertyLocalizableString : public EditorProperty { int page_length = 20; int page_index = 0; Button *edit = nullptr; - VBoxContainer *vbox = nullptr; + MarginContainer *container = nullptr; VBoxContainer *property_vbox = nullptr; EditorSpinSlider *size_slider = nullptr; Button *button_add_item = nullptr; diff --git a/editor/editor_property_name_processor.cpp b/editor/editor_property_name_processor.cpp index 1e7638bf72..397afc0653 100644 --- a/editor/editor_property_name_processor.cpp +++ b/editor/editor_property_name_processor.cpp @@ -213,6 +213,7 @@ EditorPropertyNameProcessor::EditorPropertyNameProcessor() { capitalize_string_remaps["stdout"] = "stdout"; capitalize_string_remaps["sv"] = "SV"; capitalize_string_remaps["svg"] = "SVG"; + capitalize_string_remaps["taa"] = "TAA"; capitalize_string_remaps["tcp"] = "TCP"; capitalize_string_remaps["ui"] = "UI"; capitalize_string_remaps["url"] = "URL"; diff --git a/editor/editor_resource_picker.cpp b/editor/editor_resource_picker.cpp index 34aa7217fa..4d53ddb344 100644 --- a/editor/editor_resource_picker.cpp +++ b/editor/editor_resource_picker.cpp @@ -903,6 +903,8 @@ EditorResourcePicker::EditorResourcePicker() { edit_button->connect("pressed", callable_mp(this, &EditorResourcePicker::_update_menu)); add_child(edit_button); edit_button->connect("gui_input", callable_mp(this, &EditorResourcePicker::_button_input)); + + add_theme_constant_override("separation", 0); } // EditorScriptPicker diff --git a/editor/editor_run_native.cpp b/editor/editor_run_native.cpp index 5db7b8673f..6ce9e5fa6f 100644 --- a/editor/editor_run_native.cpp +++ b/editor/editor_run_native.cpp @@ -151,7 +151,13 @@ Error EditorRunNative::run_native(int p_idx, int p_platform) { flags |= EditorExportPlatform::DEBUG_FLAG_VIEW_NAVIGATION; } - return eep->run(preset, p_idx, flags); + eep->clear_messages(); + Error err = eep->run(preset, p_idx, flags); + result_dialog_log->clear(); + if (eep->fill_log_messages(result_dialog_log, err)) { + result_dialog->popup_centered_ratio(0.5); + } + return err; } void EditorRunNative::resume_run_native() { @@ -167,6 +173,15 @@ bool EditorRunNative::is_deploy_debug_remote_enabled() const { } EditorRunNative::EditorRunNative() { + result_dialog = memnew(AcceptDialog); + result_dialog->set_title(TTR("Project Run")); + result_dialog_log = memnew(RichTextLabel); + result_dialog_log->set_custom_minimum_size(Size2(300, 80) * EDSCALE); + result_dialog->add_child(result_dialog_log); + + add_child(result_dialog); + result_dialog->hide(); + set_process(true); resume_idx = 0; resume_platform = 0; diff --git a/editor/editor_run_native.h b/editor/editor_run_native.h index 798a0371a4..66d9b0402a 100644 --- a/editor/editor_run_native.h +++ b/editor/editor_run_native.h @@ -32,11 +32,16 @@ #define EDITOR_RUN_NATIVE_H #include "scene/gui/box_container.h" +#include "scene/gui/dialogs.h" #include "scene/gui/menu_button.h" +#include "scene/gui/rich_text_label.h" class EditorRunNative : public HBoxContainer { GDCLASS(EditorRunNative, HBoxContainer); + RichTextLabel *result_dialog_log = nullptr; + AcceptDialog *result_dialog = nullptr; + HashMap<int, MenuButton *> menus; bool first = true; diff --git a/editor/editor_spin_slider.cpp b/editor/editor_spin_slider.cpp index 83944cc553..a0c818ba84 100644 --- a/editor/editor_spin_slider.cpp +++ b/editor/editor_spin_slider.cpp @@ -303,11 +303,11 @@ void EditorSpinSlider::_draw_spin_slider() { Color lc = get_theme_color(is_read_only() ? SNAME("read_only_label_color") : SNAME("label_color")); if (flat && !label.is_empty()) { - Color label_bg_color = get_theme_color(SNAME("dark_color_3"), SNAME("Editor")); + Ref<StyleBox> label_bg = get_theme_stylebox(SNAME("label_bg"), SNAME("EditorSpinSlider")); if (rtl) { - draw_rect(Rect2(Vector2(size.width - (sb->get_offset().x * 2 + label_width), 0), Vector2(sb->get_offset().x * 2 + label_width, size.height)), label_bg_color); + draw_style_box(label_bg, Rect2(Vector2(size.width - (sb->get_offset().x * 2 + label_width), 0), Vector2(sb->get_offset().x * 2 + label_width, size.height))); } else { - draw_rect(Rect2(Vector2(), Vector2(sb->get_offset().x * 2 + label_width, size.height)), label_bg_color); + draw_style_box(label_bg, Rect2(Vector2(), Vector2(sb->get_offset().x * 2 + label_width, size.height))); } } diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp index fa106979be..7a80cf36a8 100644 --- a/editor/editor_themes.cpp +++ b/editor/editor_themes.cpp @@ -72,11 +72,13 @@ static Ref<StyleBoxFlat> make_flat_stylebox(Color p_color, float p_margin_left = style->set_bg_color(p_color); // Adjust level of detail based on the corners' effective sizes. style->set_corner_detail(Math::ceil(1.5 * p_corner_width * EDSCALE)); - style->set_corner_radius_all(p_corner_width); + style->set_corner_radius_all(p_corner_width * EDSCALE); style->set_default_margin(SIDE_LEFT, p_margin_left * EDSCALE); style->set_default_margin(SIDE_RIGHT, p_margin_right * EDSCALE); style->set_default_margin(SIDE_BOTTOM, p_margin_bottom * EDSCALE); style->set_default_margin(SIDE_TOP, p_margin_top * EDSCALE); + // Work around issue about antialiased edges being blurrier (GH-35279). + style->set_anti_aliased(false); return style; } @@ -564,8 +566,6 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { // Styleboxes // This is the most commonly used stylebox, variations should be made as duplicate of this Ref<StyleBoxFlat> style_default = make_flat_stylebox(base_color, default_margin_size, default_margin_size, default_margin_size, default_margin_size, corner_width); - // Work around issue about antialiased edges being blurrier (GH-35279). - style_default->set_anti_aliased(false); style_default->set_border_width_all(border_width); style_default->set_border_color(base_color); style_default->set_draw_center(true); @@ -692,6 +692,21 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { style_canvas_editor_info->set_expand_margin_size_all(4 * EDSCALE); theme->set_stylebox("CanvasItemInfoOverlay", "EditorStyles", style_canvas_editor_info); + // 2D and 3D contextual toolbar. + // Use a custom stylebox to make contextual menu items stand out from the rest. + // This helps with editor usability as contextual menu items change when selecting nodes, + // even though it may not be immediately obvious at first. + Ref<StyleBoxFlat> toolbar_stylebox = memnew(StyleBoxFlat); + toolbar_stylebox->set_bg_color(accent_color * Color(1, 1, 1, 0.1)); + toolbar_stylebox->set_corner_radius(CORNER_TOP_LEFT, corner_radius * EDSCALE); + toolbar_stylebox->set_corner_radius(CORNER_TOP_RIGHT, corner_radius * EDSCALE); + toolbar_stylebox->set_anti_aliased(false); + // Add an underline to the StyleBox, but prevent its minimum vertical size from changing. + toolbar_stylebox->set_border_color(accent_color); + toolbar_stylebox->set_border_width(SIDE_BOTTOM, Math::round(2 * EDSCALE)); + toolbar_stylebox->set_default_margin(SIDE_BOTTOM, 0); + theme->set_stylebox("ContextualToolbar", "EditorStyles", toolbar_stylebox); + // Script Editor theme->set_stylebox("ScriptEditorPanel", "EditorStyles", make_empty_stylebox(default_margin_size, 0, default_margin_size, default_margin_size)); theme->set_stylebox("ScriptEditor", "EditorStyles", make_empty_stylebox(0, 0, 0, 0)); @@ -910,6 +925,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_constant("item_start_padding", "PopupMenu", popup_menu_margin_size * EDSCALE); theme->set_constant("item_end_padding", "PopupMenu", popup_menu_margin_size * EDSCALE); + // Sub-inspectors for (int i = 0; i < 16; i++) { Color si_base_color = accent_color; @@ -917,51 +933,53 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { si_base_color.set_hsv(Math::fmod(float(si_base_color.get_h() + hue_rotate), float(1.0)), si_base_color.get_s(), si_base_color.get_v()); si_base_color = accent_color.lerp(si_base_color, float(EDITOR_GET("docks/property_editor/subresource_hue_tint"))); - Ref<StyleBoxFlat> sub_inspector_bg; - - sub_inspector_bg = make_flat_stylebox(dark_color_1.lerp(si_base_color, 0.08), 2, 0, 2, 2); - - sub_inspector_bg->set_border_width(SIDE_LEFT, 2); - sub_inspector_bg->set_border_width(SIDE_RIGHT, 2); - sub_inspector_bg->set_border_width(SIDE_BOTTOM, 2); - sub_inspector_bg->set_border_width(SIDE_TOP, 2); - sub_inspector_bg->set_default_margin(SIDE_LEFT, 3); - sub_inspector_bg->set_default_margin(SIDE_RIGHT, 3); - sub_inspector_bg->set_default_margin(SIDE_BOTTOM, 10); - sub_inspector_bg->set_default_margin(SIDE_TOP, 5); + // Sub-inspector background. + Ref<StyleBoxFlat> sub_inspector_bg = style_default->duplicate(); + sub_inspector_bg->set_bg_color(dark_color_1.lerp(si_base_color, 0.08)); + sub_inspector_bg->set_border_width_all(2 * EDSCALE); sub_inspector_bg->set_border_color(si_base_color * Color(0.7, 0.7, 0.7, 0.8)); - sub_inspector_bg->set_draw_center(true); + sub_inspector_bg->set_default_margin(SIDE_LEFT, 4 * EDSCALE); + sub_inspector_bg->set_default_margin(SIDE_RIGHT, 4 * EDSCALE); + sub_inspector_bg->set_default_margin(SIDE_BOTTOM, 4 * EDSCALE); + sub_inspector_bg->set_default_margin(SIDE_TOP, 4 * EDSCALE); + sub_inspector_bg->set_corner_radius(CORNER_TOP_LEFT, 0); + sub_inspector_bg->set_corner_radius(CORNER_TOP_RIGHT, 0); theme->set_stylebox("sub_inspector_bg" + itos(i), "Editor", sub_inspector_bg); - Ref<StyleBoxFlat> bg_color; - bg_color.instantiate(); - bg_color->set_bg_color(si_base_color * Color(0.7, 0.7, 0.7, 0.8)); - bg_color->set_border_width_all(0); - - Ref<StyleBoxFlat> bg_color_selected; - bg_color_selected.instantiate(); - bg_color_selected->set_border_width_all(0); - bg_color_selected->set_bg_color(si_base_color * Color(0.8, 0.8, 0.8, 0.8)); + // EditorProperty background while it has a sub-inspector open. + Ref<StyleBoxFlat> bg_color = make_flat_stylebox(si_base_color * Color(0.7, 0.7, 0.7, 0.8), 0, 0, 0, 0, corner_radius); + bg_color->set_anti_aliased(false); + bg_color->set_corner_radius(CORNER_BOTTOM_LEFT, 0); + bg_color->set_corner_radius(CORNER_BOTTOM_RIGHT, 0); theme->set_stylebox("sub_inspector_property_bg" + itos(i), "Editor", bg_color); - theme->set_stylebox("sub_inspector_property_bg_selected" + itos(i), "Editor", bg_color_selected); } theme->set_color("sub_inspector_property_color", "Editor", dark_theme ? Color(1, 1, 1, 1) : Color(0, 0, 0, 1)); - theme->set_constant("sub_inspector_font_offset", "Editor", 4 * EDSCALE); // EditorSpinSlider. theme->set_color("label_color", "EditorSpinSlider", font_color); theme->set_color("read_only_label_color", "EditorSpinSlider", font_readonly_color); + Ref<StyleBoxFlat> editor_spin_label_bg = style_default->duplicate(); + editor_spin_label_bg->set_bg_color(dark_color_3); + editor_spin_label_bg->set_border_width_all(0); + theme->set_stylebox("label_bg", "EditorSpinSlider", editor_spin_label_bg); + + // EditorProperty Ref<StyleBoxFlat> style_property_bg = style_default->duplicate(); style_property_bg->set_bg_color(highlight_color); style_property_bg->set_border_width_all(0); + Ref<StyleBoxFlat> style_property_child_bg = style_default->duplicate(); + style_property_child_bg->set_bg_color(dark_color_2); + style_property_child_bg->set_border_width_all(0); + theme->set_constant("font_offset", "EditorProperty", 8 * EDSCALE); theme->set_stylebox("bg_selected", "EditorProperty", style_property_bg); theme->set_stylebox("bg", "EditorProperty", Ref<StyleBoxEmpty>(memnew(StyleBoxEmpty))); + theme->set_stylebox("child_bg", "EditorProperty", style_property_child_bg); theme->set_constant("v_separation", "EditorProperty", (extra_spacing + default_margin_size) * EDSCALE); theme->set_color("warning_color", "EditorProperty", warning_color); theme->set_color("property_color", "EditorProperty", property_color); @@ -974,6 +992,7 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { style_property_group_note->set_bg_color(property_group_note_color); theme->set_stylebox("bg_group_note", "EditorProperty", style_property_group_note); + // EditorInspectorSection Color inspector_section_color = font_color.lerp(Color(0.5, 0.5, 0.5), 0.35); theme->set_color("font_color", "EditorInspectorSection", inspector_section_color); @@ -1076,11 +1095,11 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_color("prop_subsection", "Editor", prop_subsection_color); theme->set_color("drop_position_color", "Tree", accent_color); + // EditorInspectorCategory Ref<StyleBoxFlat> category_bg = style_default->duplicate(); - // Make Trees easier to distinguish from other controls by using a darker background color. category_bg->set_bg_color(prop_category_color); category_bg->set_border_color(prop_category_color); - theme->set_stylebox("prop_category_style", "Editor", category_bg); + theme->set_stylebox("bg", "EditorInspectorCategory", category_bg); // ItemList Ref<StyleBoxFlat> style_itemlist_bg = style_default->duplicate(); @@ -1241,20 +1260,6 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_color("selection_color", "TextEdit", selection_color); theme->set_constant("line_spacing", "TextEdit", 4 * EDSCALE); - // CodeEdit - theme->set_font("font", "CodeEdit", theme->get_font(SNAME("source"), SNAME("EditorFonts"))); - theme->set_font_size("font_size", "CodeEdit", theme->get_font_size(SNAME("source_size"), SNAME("EditorFonts"))); - theme->set_stylebox("normal", "CodeEdit", style_widget); - theme->set_stylebox("focus", "CodeEdit", style_widget_hover); - theme->set_stylebox("read_only", "CodeEdit", style_widget_disabled); - theme->set_icon("tab", "CodeEdit", theme->get_icon(SNAME("GuiTab"), SNAME("EditorIcons"))); - theme->set_icon("space", "CodeEdit", theme->get_icon(SNAME("GuiSpace"), SNAME("EditorIcons"))); - theme->set_icon("folded", "CodeEdit", theme->get_icon(SNAME("GuiTreeArrowRight"), SNAME("EditorIcons"))); - theme->set_icon("can_fold", "CodeEdit", theme->get_icon(SNAME("GuiTreeArrowDown"), SNAME("EditorIcons"))); - theme->set_icon("executing_line", "CodeEdit", theme->get_icon(SNAME("MainPlay"), SNAME("EditorIcons"))); - theme->set_icon("breakpoint", "CodeEdit", theme->get_icon(SNAME("Breakpoint"), SNAME("EditorIcons"))); - theme->set_constant("line_spacing", "CodeEdit", EDITOR_GET("text_editor/appearance/whitespace/line_spacing")); - theme->set_icon("grabber", "VSplitContainer", theme->get_icon(SNAME("GuiVsplitter"), SNAME("EditorIcons"))); theme->set_icon("grabber", "HSplitContainer", theme->get_icon(SNAME("GuiHsplitter"), SNAME("EditorIcons"))); @@ -1278,6 +1283,13 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_constant("h_separation", "VFlowContainer", default_margin_size * EDSCALE); theme->set_constant("v_separation", "VFlowContainer", default_margin_size * EDSCALE); + // Custom theme type for MarginContainer with 4px margins. + theme->set_type_variation("MarginContainer4px", "MarginContainer"); + theme->set_constant("margin_left", "MarginContainer4px", 4 * EDSCALE); + theme->set_constant("margin_top", "MarginContainer4px", 4 * EDSCALE); + theme->set_constant("margin_right", "MarginContainer4px", 4 * EDSCALE); + theme->set_constant("margin_bottom", "MarginContainer4px", 4 * EDSCALE); + // Window // Prevent corner artifacts between window title and body. @@ -1405,7 +1417,9 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_color("font_pressed_color", "LinkButton", accent_color); theme->set_color("font_disabled_color", "LinkButton", font_disabled_color); - // TooltipPanel + // TooltipPanel + TooltipLabel + // TooltipPanel is also used for custom tooltips, while TooltipLabel + // is only relevant for default tooltips. Ref<StyleBoxFlat> style_tooltip = style_popup->duplicate(); style_tooltip->set_shadow_size(0); style_tooltip->set_default_margin(SIDE_LEFT, default_margin_size * EDSCALE * 0.5); @@ -1589,7 +1603,6 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { // ColorPresetButton Ref<StyleBoxFlat> preset_sb = make_flat_stylebox(Color(1, 1, 1), 2, 2, 2, 2, 2); - preset_sb->set_anti_aliased(false); theme->set_stylebox("preset_fg", "ColorPresetButton", preset_sb); theme->set_icon("preset_bg", "ColorPresetButton", theme->get_icon(SNAME("GuiMiniCheckerboard"), SNAME("EditorIcons"))); theme->set_icon("overbright_indicator", "ColorPresetButton", theme->get_icon(SNAME("OverbrightIndicator"), SNAME("EditorIcons"))); @@ -1620,7 +1633,11 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { theme->set_stylebox("preview_picker_label", "ThemeEditor", theme_preview_picker_label_sb); // Dictionary editor add item. - theme->set_stylebox("DictionaryAddItem", "EditorStyles", make_flat_stylebox(prop_subsection_color, 4, 4, 4, 4, corner_radius)); + // Expand to the left and right by 4px to compensate for the dictionary editor margins. + Ref<StyleBoxFlat> style_dictionary_add_item = make_flat_stylebox(prop_subsection_color, 0, 4, 0, 4, corner_radius); + style_dictionary_add_item->set_expand_margin_size(SIDE_LEFT, 4 * EDSCALE); + style_dictionary_add_item->set_expand_margin_size(SIDE_RIGHT, 4 * EDSCALE); + theme->set_stylebox("DictionaryAddItem", "EditorStyles", style_dictionary_add_item); // adaptive script theme constants // for comments and elements with lower relevance @@ -1715,7 +1732,20 @@ Ref<Theme> create_editor_theme(const Ref<Theme> p_theme) { } // Now theme is loaded, apply it to CodeEdit. - theme->set_color("background_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/background_color")); + theme->set_font("font", "CodeEdit", theme->get_font(SNAME("source"), SNAME("EditorFonts"))); + theme->set_font_size("font_size", "CodeEdit", theme->get_font_size(SNAME("source_size"), SNAME("EditorFonts"))); + Ref<StyleBoxFlat> code_edit_stylebox = make_flat_stylebox(EDITOR_GET("text_editor/theme/highlighting/background_color"), widget_default_margin.x, widget_default_margin.y, widget_default_margin.x, widget_default_margin.y, corner_radius); + theme->set_stylebox("normal", "CodeEdit", code_edit_stylebox); + theme->set_stylebox("read_only", "CodeEdit", code_edit_stylebox); + theme->set_stylebox("focus", "CodeEdit", Ref<StyleBoxEmpty>(memnew(StyleBoxEmpty))); + theme->set_icon("tab", "CodeEdit", theme->get_icon(SNAME("GuiTab"), SNAME("EditorIcons"))); + theme->set_icon("space", "CodeEdit", theme->get_icon(SNAME("GuiSpace"), SNAME("EditorIcons"))); + theme->set_icon("folded", "CodeEdit", theme->get_icon(SNAME("GuiTreeArrowRight"), SNAME("EditorIcons"))); + theme->set_icon("can_fold", "CodeEdit", theme->get_icon(SNAME("GuiTreeArrowDown"), SNAME("EditorIcons"))); + theme->set_icon("executing_line", "CodeEdit", theme->get_icon(SNAME("MainPlay"), SNAME("EditorIcons"))); + theme->set_icon("breakpoint", "CodeEdit", theme->get_icon(SNAME("Breakpoint"), SNAME("EditorIcons"))); + theme->set_constant("line_spacing", "CodeEdit", EDITOR_GET("text_editor/appearance/whitespace/line_spacing")); + theme->set_color("background_color", "CodeEdit", Color(0, 0, 0, 0)); theme->set_color("completion_background_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/completion_background_color")); theme->set_color("completion_selected_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/completion_selected_color")); theme->set_color("completion_existing_color", "CodeEdit", EDITOR_GET("text_editor/theme/highlighting/completion_existing_color")); diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp index 80230bc316..f2975b1d7a 100644 --- a/editor/import/resource_importer_scene.cpp +++ b/editor/import/resource_importer_scene.cpp @@ -658,6 +658,44 @@ Node *ResourceImporterScene::_pre_fix_node(Node *p_node, Node *p_root, HashMap<R } } } + } else if (_teststr(name, "vehicle")) { + if (isroot) { + return p_node; + } + + Node *owner = p_node->get_owner(); + Node3D *s = Object::cast_to<Node3D>(p_node); + VehicleBody3D *bv = memnew(VehicleBody3D); + String n = _fixstr(p_node->get_name(), "vehicle"); + bv->set_name(n); + p_node->replace_by(bv); + p_node->set_name(n); + bv->add_child(p_node); + bv->set_owner(owner); + p_node->set_owner(owner); + bv->set_transform(s->get_transform()); + s->set_transform(Transform3D()); + + p_node = bv; + } else if (_teststr(name, "wheel")) { + if (isroot) { + return p_node; + } + + Node *owner = p_node->get_owner(); + Node3D *s = Object::cast_to<Node3D>(p_node); + VehicleWheel3D *bv = memnew(VehicleWheel3D); + String n = _fixstr(p_node->get_name(), "wheel"); + bv->set_name(n); + p_node->replace_by(bv); + p_node->set_name(n); + bv->add_child(p_node); + bv->set_owner(owner); + p_node->set_owner(owner); + bv->set_transform(s->get_transform()); + s->set_transform(Transform3D()); + + p_node = bv; } else if (Object::cast_to<ImporterMeshInstance3D>(p_node)) { //last attempt, maybe collision inside the mesh data diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp index 32c7a5db4d..98ccc1fdbe 100644 --- a/editor/plugins/animation_player_editor_plugin.cpp +++ b/editor/plugins/animation_player_editor_plugin.cpp @@ -1573,7 +1573,7 @@ AnimationPlayerEditor::AnimationPlayerEditor(AnimationPlayerEditorPlugin *p_plug frame = memnew(SpinBox); hb->add_child(frame); - frame->set_custom_minimum_size(Size2(60, 0)); + frame->set_custom_minimum_size(Size2(80, 0) * EDSCALE); frame->set_stretch_ratio(2); frame->set_step(0.0001); frame->set_tooltip(TTR("Animation position (in seconds).")); diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 40894cdb8b..bfe9e202d6 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -3779,7 +3779,7 @@ void CanvasItemEditor::_update_editor_settings() { key_auto_insert_button->add_theme_color_override("icon_pressed_color", key_auto_color.lerp(Color(1, 0, 0), 0.55)); animation_menu->set_icon(get_theme_icon(SNAME("GuiTabMenuHl"), SNAME("EditorIcons"))); - _update_context_menu_stylebox(); + context_menu_container->add_theme_style_override("panel", get_theme_stylebox(SNAME("ContextualToolbar"), SNAME("EditorStyles"))); panner->setup((ViewPanner::ControlScheme)EDITOR_GET("editors/panning/2d_editor_panning_scheme").operator int(), ED_GET_SHORTCUT("canvas_item_editor/pan_view"), bool(EditorSettings::get_singleton()->get("editors/panning/simple_panning"))); pan_speed = int(EditorSettings::get_singleton()->get("editors/panning/2d_editor_pan_speed")); @@ -3915,18 +3915,6 @@ void CanvasItemEditor::edit(CanvasItem *p_canvas_item) { } } -void CanvasItemEditor::_update_context_menu_stylebox() { - // This must be called when the theme changes to follow the new accent color. - Ref<StyleBoxFlat> context_menu_stylebox = memnew(StyleBoxFlat); - const Color accent_color = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("accent_color"), SNAME("Editor")); - context_menu_stylebox->set_bg_color(accent_color * Color(1, 1, 1, 0.1)); - // Add an underline to the StyleBox, but prevent its minimum vertical size from changing. - context_menu_stylebox->set_border_color(accent_color); - context_menu_stylebox->set_border_width(SIDE_BOTTOM, Math::round(2 * EDSCALE)); - context_menu_stylebox->set_default_margin(SIDE_BOTTOM, 0); - context_menu_container->add_theme_style_override("panel", context_menu_stylebox); -} - void CanvasItemEditor::_update_scrollbars() { updating_scroll = true; @@ -5213,11 +5201,7 @@ CanvasItemEditor::CanvasItemEditor() { context_menu_container = memnew(PanelContainer); hbc_context_menu = memnew(HBoxContainer); context_menu_container->add_child(hbc_context_menu); - // Use a custom stylebox to make contextual menu items stand out from the rest. - // This helps with editor usability as contextual menu items change when selecting nodes, - // even though it may not be immediately obvious at first. hb->add_child(context_menu_container); - _update_context_menu_stylebox(); // Animation controls. animation_hb = memnew(HBoxContainer); diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h index a4099079f3..c20a054800 100644 --- a/editor/plugins/canvas_item_editor_plugin.h +++ b/editor/plugins/canvas_item_editor_plugin.h @@ -492,8 +492,6 @@ private: HSplitContainer *right_panel_split = nullptr; VSplitContainer *bottom_split = nullptr; - void _update_context_menu_stylebox(); - void _set_owner_for_node_and_children(Node *p_node, Node *p_owner); friend class CanvasItemEditorPlugin; diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index ef31e132b3..9f4842a5a1 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -6362,18 +6362,6 @@ void fragment() { _generate_selection_boxes(); } -void Node3DEditor::_update_context_menu_stylebox() { - // This must be called when the theme changes to follow the new accent color. - Ref<StyleBoxFlat> context_menu_stylebox = memnew(StyleBoxFlat); - const Color accent_color = EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("accent_color"), SNAME("Editor")); - context_menu_stylebox->set_bg_color(accent_color * Color(1, 1, 1, 0.1)); - // Add an underline to the StyleBox, but prevent its minimum vertical size from changing. - context_menu_stylebox->set_border_color(accent_color); - context_menu_stylebox->set_border_width(SIDE_BOTTOM, Math::round(2 * EDSCALE)); - context_menu_stylebox->set_default_margin(SIDE_BOTTOM, 0); - context_menu_container->add_theme_style_override("panel", context_menu_stylebox); -} - void Node3DEditor::_update_gizmos_menu() { gizmos_menu->clear(); @@ -6965,6 +6953,8 @@ void Node3DEditor::_update_theme() { sun_color->set_custom_minimum_size(Size2(0, get_theme_constant(SNAME("color_picker_button_height"), SNAME("Editor")))); environ_sky_color->set_custom_minimum_size(Size2(0, get_theme_constant(SNAME("color_picker_button_height"), SNAME("Editor")))); environ_ground_color->set_custom_minimum_size(Size2(0, get_theme_constant(SNAME("color_picker_button_height"), SNAME("Editor")))); + + context_menu_container->add_theme_style_override("panel", get_theme_stylebox(SNAME("ContextualToolbar"), SNAME("EditorStyles"))); } void Node3DEditor::_notification(int p_what) { @@ -7003,7 +6993,6 @@ void Node3DEditor::_notification(int p_what) { case NOTIFICATION_THEME_CHANGED: { _update_theme(); _update_gizmos_menu_theme(); - _update_context_menu_stylebox(); sun_title->add_theme_font_override("font", get_theme_font(SNAME("title_font"), SNAME("Window"))); environ_title->add_theme_font_override("font", get_theme_font(SNAME("title_font"), SNAME("Window"))); } break; @@ -7724,11 +7713,7 @@ Node3DEditor::Node3DEditor() { context_menu_container = memnew(PanelContainer); hbc_context_menu = memnew(HBoxContainer); context_menu_container->add_child(hbc_context_menu); - // Use a custom stylebox to make contextual menu items stand out from the rest. - // This helps with editor usability as contextual menu items change when selecting nodes, - // even though it may not be immediately obvious at first. hbc_menu->add_child(context_menu_container); - _update_context_menu_stylebox(); // Get the view menu popup and have it stay open when a checkable item is selected p = view_menu->get_popup(); diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h index 894ec9a119..8a602be08b 100644 --- a/editor/plugins/node_3d_editor_plugin.h +++ b/editor/plugins/node_3d_editor_plugin.h @@ -676,7 +676,6 @@ private: int camera_override_viewport_id; void _init_indicators(); - void _update_context_menu_stylebox(); void _update_gizmos_menu(); void _update_gizmos_menu_theme(); void _init_grid(); diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index fe418b72a5..ecf1bea6bb 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -5523,9 +5523,9 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("InverseSqrt", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the inverse of the square root of the parameter."), { VisualShaderNodeVectorFunc::FUNC_INVERSE_SQRT, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); add_options.push_back(AddOption("InverseSqrt", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the inverse of the square root of the parameter."), { VisualShaderNodeVectorFunc::FUNC_INVERSE_SQRT, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("InverseSqrt", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Returns the inverse of the square root of the parameter."), { VisualShaderNodeVectorFunc::FUNC_INVERSE_SQRT, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_4D }, VisualShaderNode::PORT_TYPE_VECTOR_4D)); - add_options.push_back(AddOption("Length", "Vector", "Functions", "VisualShaderNodeVectorLen", TTR("Calculates the length of a vector."), { VisualShaderNodeVectorLen::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("Length", "Vector", "Functions", "VisualShaderNodeVectorLen", TTR("Calculates the length of a vector."), { VisualShaderNodeVectorLen::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_SCALAR)); - add_options.push_back(AddOption("Length", "Vector", "Functions", "VisualShaderNodeVectorLen", TTR("Calculates the length of a vector."), { VisualShaderNodeVectorLen::OP_TYPE_VECTOR_4D }, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("Length2D", "Vector", "Functions", "VisualShaderNodeVectorLen", TTR("Calculates the length of a vector."), { VisualShaderNodeVectorLen::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("Length3D", "Vector", "Functions", "VisualShaderNodeVectorLen", TTR("Calculates the length of a vector."), { VisualShaderNodeVectorLen::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("Length4D", "Vector", "Functions", "VisualShaderNodeVectorLen", TTR("Calculates the length of a vector."), { VisualShaderNodeVectorLen::OP_TYPE_VECTOR_4D }, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("Log", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Natural logarithm."), { VisualShaderNodeVectorFunc::FUNC_LOG, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_2D }, VisualShaderNode::PORT_TYPE_VECTOR_2D)); add_options.push_back(AddOption("Log", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Natural logarithm."), { VisualShaderNodeVectorFunc::FUNC_LOG, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D)); add_options.push_back(AddOption("Log", "Vector", "Functions", "VisualShaderNodeVectorFunc", TTR("Natural logarithm."), { VisualShaderNodeVectorFunc::FUNC_LOG, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_4D }, VisualShaderNode::PORT_TYPE_VECTOR_4D)); diff --git a/editor/project_export.cpp b/editor/project_export.cpp index 70627d5e82..030337a4bc 100644 --- a/editor/project_export.cpp +++ b/editor/project_export.cpp @@ -928,17 +928,13 @@ void ProjectExportDialog::_export_project_to_path(const String &p_path) { ERR_FAIL_COND(platform.is_null()); current->set_export_path(p_path); + platform->clear_messages(); Error err = platform->export_project(current, export_debug->is_pressed(), p_path, 0); - if (err != OK && err != ERR_SKIP) { - if (err == ERR_FILE_NOT_FOUND) { - error_dialog->set_text(vformat(TTR("Failed to export the project for platform '%s'.\nExport templates seem to be missing or invalid."), platform->get_name())); - } else { // Assume misconfiguration. FIXME: Improve error handling and preset config validation. - error_dialog->set_text(vformat(TTR("Failed to export the project for platform '%s'.\nThis might be due to a configuration issue in the export preset or your export settings."), platform->get_name())); + result_dialog_log->clear(); + if (err != ERR_SKIP) { + if (platform->fill_log_messages(result_dialog_log, err)) { + result_dialog->popup_centered_ratio(0.5); } - - ERR_PRINT(vformat("Failed to export the project for platform '%s'.", platform->get_name())); - error_dialog->show(); - error_dialog->popup_centered(Size2(300, 80)); } } @@ -957,6 +953,8 @@ void ProjectExportDialog::_export_all(bool p_debug) { String mode = p_debug ? TTR("Debug") : TTR("Release"); EditorProgress ep("exportall", TTR("Exporting All") + " " + mode, EditorExport::get_singleton()->get_export_preset_count(), true); + bool show_dialog = false; + result_dialog_log->clear(); for (int i = 0; i < EditorExport::get_singleton()->get_export_preset_count(); i++) { Ref<EditorExportPreset> preset = EditorExport::get_singleton()->get_export_preset(i); ERR_FAIL_COND(preset.is_null()); @@ -965,17 +963,16 @@ void ProjectExportDialog::_export_all(bool p_debug) { ep.step(preset->get_name(), i); + platform->clear_messages(); Error err = platform->export_project(preset, p_debug, preset->get_export_path(), 0); - if (err != OK && err != ERR_SKIP) { - if (err == ERR_FILE_BAD_PATH) { - error_dialog->set_text(TTR("The given export path doesn't exist:") + "\n" + preset->get_export_path().get_base_dir()); - } else { - error_dialog->set_text(TTR("Export templates for this platform are missing/corrupted:") + " " + platform->get_name()); - } - error_dialog->show(); - error_dialog->popup_centered(Size2(300, 80)); - ERR_PRINT("Failed to export project"); + if (err == ERR_SKIP) { + return; } + bool has_messages = platform->fill_log_messages(result_dialog_log, err); + show_dialog = show_dialog || has_messages; + } + if (show_dialog) { + result_dialog->popup_centered_ratio(0.5); } } @@ -1030,10 +1027,12 @@ ProjectExportDialog::ProjectExportDialog() { mc->add_child(presets); presets->connect("item_selected", callable_mp(this, &ProjectExportDialog::_edit_preset)); duplicate_preset = memnew(Button); + duplicate_preset->set_tooltip(TTR("Duplicate")); duplicate_preset->set_flat(true); preset_hb->add_child(duplicate_preset); duplicate_preset->connect("pressed", callable_mp(this, &ProjectExportDialog::_duplicate_preset)); delete_preset = memnew(Button); + delete_preset->set_tooltip(TTR("Delete")); delete_preset->set_flat(true); preset_hb->add_child(delete_preset); delete_preset->connect("pressed", callable_mp(this, &ProjectExportDialog::_delete_preset)); @@ -1248,11 +1247,14 @@ ProjectExportDialog::ProjectExportDialog() { export_error2->add_theme_color_override("font_color", EditorNode::get_singleton()->get_gui_base()->get_theme_color(SNAME("error_color"), SNAME("Editor"))); export_error2->set_text(String::utf8("• ") + TTR("Export templates for this platform are missing:") + " "); - error_dialog = memnew(AcceptDialog); - error_dialog->set_title(TTR("Error")); - error_dialog->set_text(TTR("Export templates for this platform are missing/corrupted:") + " "); - main_vb->add_child(error_dialog); - error_dialog->hide(); + result_dialog = memnew(AcceptDialog); + result_dialog->set_title(TTR("Project Export")); + result_dialog_log = memnew(RichTextLabel); + result_dialog_log->set_custom_minimum_size(Size2(300, 80) * EDSCALE); + result_dialog->add_child(result_dialog_log); + + main_vb->add_child(result_dialog); + result_dialog->hide(); LinkButton *download_templates = memnew(LinkButton); download_templates->set_text(TTR("Manage Export Templates")); diff --git a/editor/project_export.h b/editor/project_export.h index 4d1719d6eb..6b10642495 100644 --- a/editor/project_export.h +++ b/editor/project_export.h @@ -73,7 +73,8 @@ private: Button *button_export = nullptr; bool updating = false; - AcceptDialog *error_dialog = nullptr; + RichTextLabel *result_dialog_log = nullptr; + AcceptDialog *result_dialog = nullptr; ConfirmationDialog *delete_confirm = nullptr; OptionButton *export_filter = nullptr; diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index 1ddefeba77..9646462ead 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -71,9 +71,17 @@ void SceneTreeDock::input(const Ref<InputEvent> &p_event) { Ref<InputEventMouseButton> mb = p_event; - if (pending_click_select && mb.is_valid() && !mb->is_pressed() && (mb->get_button_index() == MouseButton::LEFT || mb->get_button_index() == MouseButton::RIGHT)) { - _push_item(pending_click_select); - pending_click_select = nullptr; + if (mb.is_valid() && (mb->get_button_index() == MouseButton::LEFT || mb->get_button_index() == MouseButton::RIGHT)) { + if (mb->is_pressed() && scene_tree->get_rect().has_point(mb->get_position())) { + tree_clicked = true; + } else if (!mb->is_pressed()) { + tree_clicked = false; + } + + if (!mb->is_pressed() && pending_click_select) { + _push_item(pending_click_select); + pending_click_select = nullptr; + } } } @@ -1371,10 +1379,10 @@ void SceneTreeDock::_push_item(Object *p_object) { } void SceneTreeDock::_handle_select(Node *p_node) { - if ((Input::get_singleton()->get_mouse_button_mask() & (MouseButton::MASK_LEFT | MouseButton::MASK_RIGHT)) != MouseButton::NONE) { + if (tree_clicked) { pending_click_select = p_node; } else { - EditorNode::get_singleton()->push_item(p_node); + _push_item(p_node); } } diff --git a/editor/scene_tree_dock.h b/editor/scene_tree_dock.h index 54e6108d84..dc7f3476ee 100644 --- a/editor/scene_tree_dock.h +++ b/editor/scene_tree_dock.h @@ -172,6 +172,7 @@ class SceneTreeDock : public VBoxContainer { Node *scene_root = nullptr; Node *edited_scene = nullptr; Node *pending_click_select = nullptr; + bool tree_clicked = false; VBoxContainer *create_root_dialog = nullptr; String selected_favorite_root; |