summaryrefslogtreecommitdiff
path: root/editor
diff options
context:
space:
mode:
Diffstat (limited to 'editor')
-rw-r--r--editor/debugger/editor_debugger_node.cpp72
-rw-r--r--editor/debugger/editor_debugger_node.h1
-rw-r--r--editor/debugger/script_editor_debugger.cpp2
-rw-r--r--editor/dependency_editor.cpp2
-rw-r--r--editor/editor_export.cpp114
-rw-r--r--editor/editor_export.h59
-rw-r--r--editor/editor_inspector.cpp22
-rw-r--r--editor/editor_node.cpp17
-rw-r--r--editor/editor_properties.cpp11
-rw-r--r--editor/editor_properties.h2
-rw-r--r--editor/editor_properties_array_dict.cpp78
-rw-r--r--editor/editor_properties_array_dict.h8
-rw-r--r--editor/editor_property_name_processor.cpp1
-rw-r--r--editor/editor_resource_picker.cpp2
-rw-r--r--editor/editor_run_native.cpp17
-rw-r--r--editor/editor_run_native.h5
-rw-r--r--editor/editor_spin_slider.cpp6
-rw-r--r--editor/editor_themes.cpp124
-rw-r--r--editor/import/resource_importer_scene.cpp38
-rw-r--r--editor/plugins/animation_player_editor_plugin.cpp2
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp18
-rw-r--r--editor/plugins/canvas_item_editor_plugin.h2
-rw-r--r--editor/plugins/node_3d_editor_plugin.cpp19
-rw-r--r--editor/plugins/node_3d_editor_plugin.h1
-rw-r--r--editor/plugins/visual_shader_editor_plugin.cpp6
-rw-r--r--editor/project_export.cpp48
-rw-r--r--editor/project_export.h3
-rw-r--r--editor/scene_tree_dock.cpp18
-rw-r--r--editor/scene_tree_dock.h1
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;