diff options
Diffstat (limited to 'editor')
28 files changed, 289 insertions, 166 deletions
diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp index 6fce55f8e3..f36a2099d5 100644 --- a/editor/animation_track_editor.cpp +++ b/editor/animation_track_editor.cpp @@ -39,6 +39,7 @@ #include "editor_scale.h" #include "scene/animation/animation_player.h" #include "scene/main/window.h" +#include "scene/scene_string_names.h" #include "servers/audio/audio_stream.h" class AnimationTrackKeyEdit : public Object { @@ -3505,7 +3506,7 @@ void AnimationTrackEditor::make_insert_queue() { void AnimationTrackEditor::commit_insert_queue() { bool reset_allowed = true; AnimationPlayer *player = AnimationPlayerEditor::get_singleton()->get_player(); - if (player->has_animation("RESET") && player->get_animation("RESET") == animation) { + if (player->has_animation(SceneStringNames::get_singleton()->RESET) && player->get_animation(SceneStringNames::get_singleton()->RESET) == animation) { // Avoid messing with the reset animation itself. reset_allowed = false; } else { @@ -3925,15 +3926,15 @@ void AnimationTrackEditor::insert_value_key(const String &p_property, const Vari Ref<Animation> AnimationTrackEditor::_create_and_get_reset_animation() { AnimationPlayer *player = AnimationPlayerEditor::get_singleton()->get_player(); - if (player->has_animation("RESET")) { - return player->get_animation("RESET"); + if (player->has_animation(SceneStringNames::get_singleton()->RESET)) { + return player->get_animation(SceneStringNames::get_singleton()->RESET); } else { Ref<Animation> reset_anim; reset_anim.instantiate(); reset_anim->set_length(ANIM_MIN_LENGTH); - undo_redo->add_do_method(player, "add_animation", "RESET", reset_anim); + undo_redo->add_do_method(player, "add_animation", SceneStringNames::get_singleton()->RESET, reset_anim); undo_redo->add_do_method(AnimationPlayerEditor::get_singleton(), "_animation_player_changed", player); - undo_redo->add_undo_method(player, "remove_animation", "RESET"); + undo_redo->add_undo_method(player, "remove_animation", SceneStringNames::get_singleton()->RESET); undo_redo->add_undo_method(AnimationPlayerEditor::get_singleton(), "_animation_player_changed", player); return reset_anim; } diff --git a/editor/debugger/editor_debugger_node.cpp b/editor/debugger/editor_debugger_node.cpp index 391839d639..85cf1558fe 100644 --- a/editor/debugger/editor_debugger_node.cpp +++ b/editor/debugger/editor_debugger_node.cpp @@ -183,6 +183,11 @@ ScriptEditorDebugger *EditorDebuggerNode::get_default_debugger() const { return Object::cast_to<ScriptEditorDebugger>(tabs->get_tab_control(0)); } +String EditorDebuggerNode::get_server_uri() const { + ERR_FAIL_COND_V(server.is_null(), ""); + return server->get_uri(); +} + Error EditorDebuggerNode::start(const String &p_uri) { stop(); ERR_FAIL_COND_V(p_uri.find("://") < 0, ERR_INVALID_PARAMETER); diff --git a/editor/debugger/editor_debugger_node.h b/editor/debugger/editor_debugger_node.h index 4d9e846834..135122db68 100644 --- a/editor/debugger/editor_debugger_node.h +++ b/editor/debugger/editor_debugger_node.h @@ -188,8 +188,9 @@ public: void set_camera_override(CameraOverride p_override); CameraOverride get_camera_override(); - Error start(const String &p_uri = "tcp://"); + String get_server_uri() const; + Error start(const String &p_uri = "tcp://"); void stop(); void add_debugger_plugin(const Ref<Script> &p_script); diff --git a/editor/debugger/editor_debugger_server.cpp b/editor/debugger/editor_debugger_server.cpp index 8c3833af50..34904d55aa 100644 --- a/editor/debugger/editor_debugger_server.cpp +++ b/editor/debugger/editor_debugger_server.cpp @@ -41,15 +41,18 @@ class EditorDebuggerServerTCP : public EditorDebuggerServer { private: Ref<TCPServer> server; + String endpoint; public: static EditorDebuggerServer *create(const String &p_protocol); - virtual void poll() {} - virtual Error start(const String &p_uri); - virtual void stop(); - virtual bool is_active() const; - virtual bool is_connection_available() const; - virtual Ref<RemoteDebuggerPeer> take_connection(); + + virtual void poll() override {} + virtual String get_uri() const override; + virtual Error start(const String &p_uri) override; + virtual void stop() override; + virtual bool is_active() const override; + virtual bool is_connection_available() const override; + virtual Ref<RemoteDebuggerPeer> take_connection() override; EditorDebuggerServerTCP(); }; @@ -63,21 +66,42 @@ EditorDebuggerServerTCP::EditorDebuggerServerTCP() { server.instantiate(); } +String EditorDebuggerServerTCP::get_uri() const { + return endpoint; +} + Error EditorDebuggerServerTCP::start(const String &p_uri) { - int bind_port = (int)EditorSettings::get_singleton()->get("network/debug/remote_port"); + // Default host and port String bind_host = (String)EditorSettings::get_singleton()->get("network/debug/remote_host"); + int bind_port = (int)EditorSettings::get_singleton()->get("network/debug/remote_port"); + + // Optionally override if (!p_uri.is_empty() && p_uri != "tcp://") { String scheme, path; Error err = p_uri.parse_url(scheme, bind_host, bind_port, path); ERR_FAIL_COND_V(err != OK, ERR_INVALID_PARAMETER); ERR_FAIL_COND_V(!bind_host.is_valid_ip_address() && bind_host != "*", ERR_INVALID_PARAMETER); } - const Error err = server->listen(bind_port, bind_host); - if (err != OK) { - EditorNode::get_log()->add_message(String("Error listening on port ") + itos(bind_port), EditorLog::MSG_TYPE_ERROR); - return err; + + // Try listening on ports + const int max_attempts = 5; + for (int attempt = 1;; ++attempt) { + const Error err = server->listen(bind_port, bind_host); + if (err == OK) { + break; + } + if (attempt >= max_attempts) { + EditorNode::get_log()->add_message(vformat("Cannot listen on port %d, remote debugging unavailable.", bind_port), EditorLog::MSG_TYPE_ERROR); + return err; + } + int last_port = bind_port++; + EditorNode::get_log()->add_message(vformat("Cannot listen on port %d, trying %d instead.", last_port, bind_port), EditorLog::MSG_TYPE_WARNING); } - return err; + + // Endpoint that the client should connect to + endpoint = vformat("tcp://%s:%d", bind_host, bind_port); + + return OK; } void EditorDebuggerServerTCP::stop() { diff --git a/editor/debugger/editor_debugger_server.h b/editor/debugger/editor_debugger_server.h index 844d1a9e5a..6a4ca895d1 100644 --- a/editor/debugger/editor_debugger_server.h +++ b/editor/debugger/editor_debugger_server.h @@ -47,8 +47,10 @@ public: static void register_protocol_handler(const String &p_protocol, CreateServerFunc p_func); static EditorDebuggerServer *create(const String &p_protocol); + + virtual String get_uri() const = 0; virtual void poll() = 0; - virtual Error start(const String &p_uri = "") = 0; + virtual Error start(const String &p_uri) = 0; virtual void stop() = 0; virtual bool is_active() const = 0; virtual bool is_connection_available() const = 0; diff --git a/editor/doc_tools.cpp b/editor/doc_tools.cpp index 5ce57e936a..f1d427648a 100644 --- a/editor/doc_tools.cpp +++ b/editor/doc_tools.cpp @@ -341,11 +341,17 @@ void DocTools::generate(bool p_basic_types) { } DocData::PropertyDoc prop; - prop.name = E.name; - prop.overridden = inherited; + if (inherited) { + String parent = ClassDB::get_parent_class(c.name); + while (!ClassDB::has_property(parent, prop.name, true)) { + parent = ClassDB::get_parent_class(parent); + } + prop.overrides = parent; + } + bool default_value_valid = false; Variant default_value; @@ -603,6 +609,8 @@ void DocTools::generate(bool p_basic_types) { tid.data_type = "style"; c.theme_properties.push_back(tid); } + + c.theme_properties.sort(); } classes.pop_front(); @@ -1355,7 +1363,7 @@ Error DocTools::save_classes(const String &p_default_path, const Map<String, Str const DocData::PropertyDoc &p = c.properties[i]; if (c.properties[i].overridden) { - _write_string(f, 2, "<member name=\"" + p.name + "\" type=\"" + p.type + "\" setter=\"" + p.setter + "\" getter=\"" + p.getter + "\" override=\"true\"" + additional_attributes + " />"); + _write_string(f, 2, "<member name=\"" + p.name + "\" type=\"" + p.type + "\" setter=\"" + p.setter + "\" getter=\"" + p.getter + "\" overrides=\"" + p.overrides + "\"" + additional_attributes + " />"); } else { _write_string(f, 2, "<member name=\"" + p.name + "\" type=\"" + p.type + "\" setter=\"" + p.setter + "\" getter=\"" + p.getter + "\"" + additional_attributes + ">"); _write_string(f, 3, p.description.strip_edges().xml_escape()); diff --git a/editor/editor_folding.cpp b/editor/editor_folding.cpp index 29e3236ac2..c98606730c 100644 --- a/editor/editor_folding.cpp +++ b/editor/editor_folding.cpp @@ -262,10 +262,6 @@ void EditorFolding::_do_object_unfolds(Object *p_object, Set<RES> &resources) { if (E.type == Variant::OBJECT) { RES res = p_object->get(E.name); - print_line("res: " + String(E.name) + " valid " + itos(res.is_valid())); - if (res.is_valid()) { - print_line("path " + res->get_path()); - } if (res.is_valid() && !resources.has(res) && res->get_path() != String() && !res->get_path().is_resource_file()) { resources.insert(res); _do_object_unfolds(res.ptr(), resources); diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp index f520877256..c95b1c753e 100644 --- a/editor/editor_help.cpp +++ b/editor/editor_help.cpp @@ -237,8 +237,7 @@ void EditorHelp::_add_method(const DocData::MethodDoc &p_method, bool p_overview class_desc->push_cell(); class_desc->push_paragraph(RichTextLabel::ALIGN_RIGHT, Control::TEXT_DIRECTION_AUTO, ""); } else { - static const char32_t prefix[3] = { 0x25CF /* filled circle */, ' ', 0 }; - class_desc->add_text(String(prefix)); + _add_bulletpoint(); } _add_type(p_method.return_type, p_method.return_enum); @@ -314,6 +313,11 @@ void EditorHelp::_add_method(const DocData::MethodDoc &p_method, bool p_overview } } +void EditorHelp::_add_bulletpoint() { + static const char32_t prefix[3] = { 0x25CF /* filled circle */, ' ', 0 }; + class_desc->add_text(String(prefix)); +} + Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) { if (!doc->class_list.has(p_class)) { return ERR_DOES_NOT_EXIST; @@ -669,7 +673,7 @@ void EditorHelp::_update_doc() { class_desc->add_newline(); class_desc->push_font(doc_code_font); class_desc->push_indent(1); - class_desc->push_table(2); + class_desc->push_table(4); class_desc->set_table_column_expand(1, true); for (int i = 0; i < cd.properties.size(); i++) { @@ -679,13 +683,14 @@ void EditorHelp::_update_doc() { } property_line[cd.properties[i].name] = class_desc->get_line_count() - 2; //gets overridden if description + // Property type. class_desc->push_cell(); class_desc->push_paragraph(RichTextLabel::ALIGN_RIGHT, Control::TEXT_DIRECTION_AUTO, ""); class_desc->push_font(doc_code_font); _add_type(cd.properties[i].type, cd.properties[i].enumeration); class_desc->pop(); class_desc->pop(); - class_desc->pop(); + class_desc->pop(); // cell bool describe = false; @@ -706,6 +711,7 @@ void EditorHelp::_update_doc() { describe = false; } + // Property name. class_desc->push_cell(); class_desc->push_font(doc_code_font); class_desc->push_color(headline_color); @@ -721,18 +727,43 @@ void EditorHelp::_update_doc() { property_descr = true; } + class_desc->pop(); + class_desc->pop(); + class_desc->pop(); // cell + + // Property value. + class_desc->push_cell(); + class_desc->push_font(doc_code_font); + if (cd.properties[i].default_value != "") { class_desc->push_color(symbol_color); - class_desc->add_text(cd.properties[i].overridden ? " [" + TTR("override:") + " " : " [" + TTR("default:") + " "); + if (cd.properties[i].overridden) { + class_desc->add_text(" ["); + class_desc->push_meta("@member " + cd.properties[i].overrides + "." + cd.properties[i].name); + _add_text(vformat(TTR("overrides %s:"), cd.properties[i].overrides)); + class_desc->pop(); + class_desc->add_text(" "); + } else { + class_desc->add_text(" [" + TTR("default:") + " "); + } class_desc->pop(); + class_desc->push_color(value_color); _add_text(_fix_constant(cd.properties[i].default_value)); class_desc->pop(); + class_desc->push_color(symbol_color); class_desc->add_text("]"); class_desc->pop(); } + class_desc->pop(); + class_desc->pop(); // cell + + // Property setters and getters. + class_desc->push_cell(); + class_desc->push_font(doc_code_font); + if (cd.is_script_doc && (cd.properties[i].setter != "" || cd.properties[i].getter != "")) { class_desc->push_color(symbol_color); class_desc->add_text(" [" + TTR("property:") + " "); @@ -760,12 +791,10 @@ void EditorHelp::_update_doc() { } class_desc->pop(); - class_desc->pop(); - - class_desc->pop(); + class_desc->pop(); // cell } - class_desc->pop(); //table + class_desc->pop(); // table class_desc->pop(); class_desc->pop(); // font class_desc->add_newline(); @@ -837,27 +866,54 @@ void EditorHelp::_update_doc() { class_desc->pop(); class_desc->pop(); + class_desc->add_newline(); + class_desc->add_newline(); + class_desc->push_indent(1); - class_desc->push_table(2); - class_desc->set_table_column_expand(1, true); + + String theme_data_type; + Map<String, String> data_type_names; + data_type_names["color"] = TTR("Colors"); + data_type_names["constant"] = TTR("Constants"); + data_type_names["font"] = TTR("Fonts"); + data_type_names["font_size"] = TTR("Font Sizes"); + data_type_names["icon"] = TTR("Icons"); + data_type_names["style"] = TTR("Styles"); for (int i = 0; i < cd.theme_properties.size(); i++) { theme_property_line[cd.theme_properties[i].name] = class_desc->get_line_count() - 2; //gets overridden if description - class_desc->push_cell(); - class_desc->push_paragraph(RichTextLabel::ALIGN_RIGHT, Control::TEXT_DIRECTION_AUTO, ""); + if (theme_data_type != cd.theme_properties[i].data_type) { + theme_data_type = cd.theme_properties[i].data_type; + + class_desc->push_color(title_color); + class_desc->push_font(doc_title_font); + if (data_type_names.has(theme_data_type)) { + class_desc->add_text(data_type_names[theme_data_type]); + } else { + class_desc->add_text(""); + } + class_desc->pop(); + class_desc->pop(); + + class_desc->add_newline(); + class_desc->add_newline(); + } + + // Theme item header. class_desc->push_font(doc_code_font); + _add_bulletpoint(); + + // Theme item object type. _add_type(cd.theme_properties[i].type); - class_desc->pop(); - class_desc->pop(); - class_desc->pop(); - class_desc->push_cell(); - class_desc->push_font(doc_code_font); + // Theme item name. class_desc->push_color(headline_color); + class_desc->add_text(" "); _add_text(cd.theme_properties[i].name); class_desc->pop(); + // Theme item default value. if (cd.theme_properties[i].default_value != "") { class_desc->push_color(symbol_color); class_desc->add_text(" [" + TTR("default:") + " "); @@ -870,23 +926,25 @@ void EditorHelp::_update_doc() { class_desc->pop(); } - class_desc->pop(); + class_desc->pop(); // monofont + // Theme item description. if (cd.theme_properties[i].description != "") { class_desc->push_font(doc_font); class_desc->push_color(comment_color); - class_desc->add_text(U" – "); + class_desc->push_indent(1); _add_text(DTR(cd.theme_properties[i].description)); - class_desc->pop(); - class_desc->pop(); + class_desc->pop(); // indent + class_desc->pop(); // color + class_desc->pop(); // font } - class_desc->pop(); // cell + + class_desc->add_newline(); + class_desc->add_newline(); } - class_desc->pop(); // table class_desc->pop(); class_desc->add_newline(); - class_desc->add_newline(); } // Signals @@ -909,10 +967,10 @@ void EditorHelp::_update_doc() { for (int i = 0; i < cd.signals.size(); i++) { signal_line[cd.signals[i].name] = class_desc->get_line_count() - 2; //gets overridden if description + class_desc->push_font(doc_code_font); // monofont class_desc->push_color(headline_color); - static const char32_t prefix[3] = { 0x25CF /* filled circle */, ' ', 0 }; - class_desc->add_text(String(prefix)); + _add_bulletpoint(); _add_text(cd.signals[i].name); class_desc->pop(); class_desc->push_color(symbol_color); @@ -1043,8 +1101,7 @@ void EditorHelp::_update_doc() { class_desc->push_font(doc_code_font); class_desc->push_color(headline_color); - static const char32_t prefix[3] = { 0x25CF /* filled circle */, ' ', 0 }; - class_desc->add_text(String(prefix)); + _add_bulletpoint(); _add_text(enum_list[i].name); class_desc->pop(); class_desc->push_color(symbol_color); @@ -1054,10 +1111,12 @@ void EditorHelp::_update_doc() { _add_text(_fix_constant(enum_list[i].value)); class_desc->pop(); class_desc->pop(); - if (enum_list[i].description != "") { + + class_desc->add_newline(); + + if (enum_list[i].description.strip_edges() != "") { class_desc->push_font(doc_font); class_desc->push_color(comment_color); - class_desc->add_text(U" – "); _add_text(DTR(enum_list[i].description)); class_desc->pop(); class_desc->pop(); @@ -1103,13 +1162,11 @@ void EditorHelp::_update_doc() { Vector<float> color = stripped.split_floats(","); if (color.size() >= 3) { class_desc->push_color(Color(color[0], color[1], color[2])); - static const char32_t prefix[3] = { 0x25CF /* filled circle */, ' ', 0 }; - class_desc->add_text(String(prefix)); + _add_bulletpoint(); class_desc->pop(); } } else { - static const char32_t prefix[3] = { 0x25CF /* filled circle */, ' ', 0 }; - class_desc->add_text(String(prefix)); + _add_bulletpoint(); } class_desc->push_color(headline_color); @@ -1123,10 +1180,12 @@ void EditorHelp::_update_doc() { class_desc->pop(); class_desc->pop(); + + class_desc->add_newline(); + if (constants[i].description != "") { class_desc->push_font(doc_font); class_desc->push_color(comment_color); - class_desc->add_text(U" – "); _add_text(DTR(constants[i].description)); class_desc->pop(); class_desc->pop(); @@ -1167,8 +1226,7 @@ void EditorHelp::_update_doc() { class_desc->push_cell(); class_desc->push_font(doc_code_font); - static const char32_t prefix[3] = { 0x25CF /* filled circle */, ' ', 0 }; - class_desc->add_text(String(prefix)); + _add_bulletpoint(); _add_type(cd.properties[i].type, cd.properties[i].enumeration); class_desc->add_text(" "); diff --git a/editor/editor_help.h b/editor/editor_help.h index c0f3f66505..393e4a940a 100644 --- a/editor/editor_help.h +++ b/editor/editor_help.h @@ -145,6 +145,8 @@ class EditorHelp : public VBoxContainer { void _add_type(const String &p_type, const String &p_enum = String()); void _add_method(const DocData::MethodDoc &p_method, bool p_overview = true); + void _add_bulletpoint(); + void _class_list_select(const String &p_select); void _class_desc_select(const String &p_select); void _class_desc_input(const Ref<InputEvent> &p_input); diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp index e1fae47057..a6cd07dab3 100644 --- a/editor/editor_inspector.cpp +++ b/editor/editor_inspector.cpp @@ -2194,10 +2194,7 @@ void EditorInspector::remove_inspector_plugin(const Ref<EditorInspectorPlugin> & for (int i = idx; i < inspector_plugin_count - 1; i++) { inspector_plugins[i] = inspector_plugins[i + 1]; } - - if (idx == inspector_plugin_count - 1) { - inspector_plugins[idx] = Ref<EditorInspectorPlugin>(); - } + inspector_plugins[inspector_plugin_count - 1] = Ref<EditorInspectorPlugin>(); inspector_plugin_count--; } diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 6aaf0b063f..2cf4a3395f 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -2315,8 +2315,6 @@ void EditorNode::_run(bool p_current, const String &p_custom) { play_custom_scene_button->set_icon(gui_base->get_theme_icon(SNAME("PlayCustom"), SNAME("EditorIcons"))); String run_filename; - String args; - bool skip_breakpoints; if (p_current || (editor_data.get_edited_scene_root() && p_custom != String() && p_custom == editor_data.get_edited_scene_root()->get_scene_file_path())) { Node *scene = editor_data.get_edited_scene_root(); @@ -2371,17 +2369,11 @@ void EditorNode::_run(bool p_current, const String &p_custom) { make_bottom_panel_item_visible(log); } - List<String> breakpoints; - editor_data.get_editor_breakpoints(&breakpoints); - - args = ProjectSettings::get_singleton()->get("editor/run/main_run_args"); - skip_breakpoints = EditorDebuggerNode::get_singleton()->is_skip_breakpoints(); - EditorDebuggerNode::get_singleton()->start(); - Error error = editor_run.run(run_filename, args, breakpoints, skip_breakpoints); + Error error = editor_run.run(run_filename); if (error != OK) { EditorDebuggerNode::get_singleton()->stop(); - show_accept(TTR("Could not start subprocess!"), TTR("OK")); + show_accept(TTR("Could not start subprocess(es)!"), TTR("OK")); return; } @@ -4244,7 +4236,6 @@ void EditorNode::_dock_make_float() { Size2 dock_size = dock->get_size() + borders * 2; // remember size Point2 dock_screen_pos = dock->get_global_position() + get_tree()->get_root()->get_position() - borders; - print_line("dock pos: " + dock->get_global_position() + " window pos: " + get_tree()->get_root()->get_position()); int dock_index = dock->get_index(); dock_slot[dock_popup_selected]->remove_child(dock); diff --git a/editor/editor_run.cpp b/editor/editor_run.cpp index 0a77a8b0bb..3f4418d5f2 100644 --- a/editor/editor_run.cpp +++ b/editor/editor_run.cpp @@ -31,6 +31,7 @@ #include "editor_run.h" #include "core/config/project_settings.h" +#include "editor/editor_node.h" #include "editor_settings.h" #include "servers/display_server.h" @@ -42,20 +43,17 @@ String EditorRun::get_running_scene() const { return running_scene; } -Error EditorRun::run(const String &p_scene, const String &p_custom_args, const List<String> &p_breakpoints, const bool &p_skip_breakpoints) { +Error EditorRun::run(const String &p_scene) { List<String> args; String resource_path = ProjectSettings::get_singleton()->get_resource_path(); - String remote_host = EditorSettings::get_singleton()->get("network/debug/remote_host"); - int remote_port = (int)EditorSettings::get_singleton()->get("network/debug/remote_port"); - - if (resource_path != "") { + if (!resource_path.is_empty()) { args.push_back("--path"); args.push_back(resource_path.replace(" ", "%20")); } args.push_back("--remote-debug"); - args.push_back("tcp://" + remote_host + ":" + String::num(remote_port)); + args.push_back(EditorDebuggerNode::get_singleton()->get_server_uri()); args.push_back("--allow_focus_steal_pid"); args.push_back(itos(OS::get_singleton()->get_process_id())); @@ -162,10 +160,13 @@ Error EditorRun::run(const String &p_scene, const String &p_custom_args, const L } break; } - if (p_breakpoints.size()) { + List<String> breakpoints; + EditorNode::get_editor_data().get_editor_breakpoints(&breakpoints); + + if (!breakpoints.is_empty()) { args.push_back("--breakpoints"); String bpoints; - for (const List<String>::Element *E = p_breakpoints.front(); E; E = E->next()) { + for (const List<String>::Element *E = breakpoints.front(); E; E = E->next()) { bpoints += E->get().replace(" ", "%20"); if (E->next()) { bpoints += ","; @@ -175,7 +176,7 @@ Error EditorRun::run(const String &p_scene, const String &p_custom_args, const L args.push_back(bpoints); } - if (p_skip_breakpoints) { + if (EditorDebuggerNode::get_singleton()->is_skip_breakpoints()) { args.push_back("--skip-breakpoints"); } @@ -185,20 +186,21 @@ Error EditorRun::run(const String &p_scene, const String &p_custom_args, const L String exec = OS::get_singleton()->get_executable_path(); - if (p_custom_args != "") { + const String raw_custom_args = ProjectSettings::get_singleton()->get("editor/run/main_run_args"); + if (!raw_custom_args.is_empty()) { // Allow the user to specify a command to run, similar to Steam's launch options. // In this case, Godot will no longer be run directly; it's up to the underlying command // to run it. For instance, this can be used on Linux to force a running project // to use Optimus using `prime-run` or similar. // Example: `prime-run %command% --time-scale 0.5` - const int placeholder_pos = p_custom_args.find("%command%"); + const int placeholder_pos = raw_custom_args.find("%command%"); Vector<String> custom_args; if (placeholder_pos != -1) { // Prepend executable-specific custom arguments. // If nothing is placed before `%command%`, behave as if no placeholder was specified. - Vector<String> exec_args = p_custom_args.substr(0, placeholder_pos).split(" ", false); + Vector<String> exec_args = raw_custom_args.substr(0, placeholder_pos).split(" ", false); if (exec_args.size() >= 1) { exec = exec_args[0]; exec_args.remove_at(0); @@ -214,13 +216,13 @@ Error EditorRun::run(const String &p_scene, const String &p_custom_args, const L } // Append Godot-specific custom arguments. - custom_args = p_custom_args.substr(placeholder_pos + String("%command%").size()).split(" ", false); + custom_args = raw_custom_args.substr(placeholder_pos + String("%command%").size()).split(" ", false); for (int i = 0; i < custom_args.size(); i++) { args.push_back(custom_args[i].replace(" ", "%20")); } } else { // Append Godot-specific custom arguments. - custom_args = p_custom_args.split(" ", false); + custom_args = raw_custom_args.split(" ", false); for (int i = 0; i < custom_args.size(); i++) { args.push_back(custom_args[i].replace(" ", "%20")); } diff --git a/editor/editor_run.h b/editor/editor_run.h index d6cf3fed71..3bfe28e1ad 100644 --- a/editor/editor_run.h +++ b/editor/editor_run.h @@ -50,7 +50,7 @@ private: public: Status get_status() const; String get_running_scene() const; - Error run(const String &p_scene, const String &p_custom_args, const List<String> &p_breakpoints, const bool &p_skip_breakpoints = false); + Error run(const String &p_scene); void run_native_notify() { status = STATUS_PLAY; } void stop(); diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index f40a048b75..abe20c693b 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -46,6 +46,7 @@ #include "scene/main/window.h" #include "scene/resources/packed_scene.h" #include "servers/display_server.h" +#include "shader_create_dialog.h" Ref<Texture2D> FileSystemDock::_get_tree_item_icon(bool p_is_valid, String p_file_type) { Ref<Texture2D> file_icon; @@ -1967,6 +1968,22 @@ void FileSystemDock::_file_option(int p_option, const Vector<String> &p_selected } void FileSystemDock::_resource_created() { + String fpath = path; + if (!fpath.ends_with("/")) { + fpath = fpath.get_base_dir(); + } + + String type_name = new_resource_dialog->get_selected_type(); + if (type_name == "Shader") { + make_shader_dialog->config(fpath.plus_file("new_shader"), false, false, 0); + make_shader_dialog->popup_centered(); + return; + } else if (type_name == "VisualShader") { + make_shader_dialog->config(fpath.plus_file("new_shader"), false, false, 1); + make_shader_dialog->popup_centered(); + return; + } + Variant c = new_resource_dialog->instance_selected(); ERR_FAIL_COND(!c); @@ -1982,12 +1999,6 @@ void FileSystemDock::_resource_created() { } editor->push_item(r); - - String fpath = path; - if (!fpath.ends_with("/")) { - fpath = fpath.get_base_dir(); - } - editor->save_resource_as(RES(r), fpath); } @@ -2997,6 +3008,9 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) { make_script_dialog->set_title(TTR("Create Script")); add_child(make_script_dialog); + make_shader_dialog = memnew(ShaderCreateDialog); + add_child(make_shader_dialog); + new_resource_dialog = memnew(CreateDialog); add_child(new_resource_dialog); new_resource_dialog->set_base_type("Resource"); diff --git a/editor/filesystem_dock.h b/editor/filesystem_dock.h index 7c3851b94f..34b445f1b3 100644 --- a/editor/filesystem_dock.h +++ b/editor/filesystem_dock.h @@ -54,6 +54,7 @@ #include "script_create_dialog.h" class EditorNode; +class ShaderCreateDialog; class FileSystemDock : public VBoxContainer { GDCLASS(FileSystemDock, VBoxContainer); @@ -158,6 +159,7 @@ private: LineEdit *make_scene_dialog_text; ConfirmationDialog *overwrite_dialog; ScriptCreateDialog *make_script_dialog; + ShaderCreateDialog *make_shader_dialog; CreateDialog *new_resource_dialog; bool always_show_folders; diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp index 226046f250..f936871bce 100644 --- a/editor/plugins/animation_player_editor_plugin.cpp +++ b/editor/plugins/animation_player_editor_plugin.cpp @@ -42,6 +42,7 @@ #include "editor/plugins/node_3d_editor_plugin.h" // For onion skinning. #include "scene/main/window.h" #include "scene/resources/animation.h" +#include "scene/scene_string_names.h" #include "servers/rendering_server.h" void AnimationPlayerEditor::_node_removed(Node *p_node) { @@ -836,12 +837,12 @@ void AnimationPlayerEditor::_update_player() { for (const StringName &E : animlist) { Ref<Texture2D> icon; if (E == player->get_autoplay()) { - if (E == "RESET") { + if (E == SceneStringNames::get_singleton()->RESET) { icon = autoplay_reset_icon; } else { icon = autoplay_icon; } - } else if (E == "RESET") { + } else if (E == SceneStringNames::get_singleton()->RESET) { icon = reset_icon; } animation->add_icon_item(icon, E); diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index d9ce7cfd94..aa46eef21f 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -2913,14 +2913,6 @@ void CanvasItemEditor::_draw_ruler_tool() { Point2 corner = Point2(begin.x, end.y); Vector2 length_vector = (begin - end).abs() / zoom; - bool draw_secondary_lines = !(Math::is_equal_approx(begin.y, corner.y) || Math::is_equal_approx(end.x, corner.x)); - - viewport->draw_line(begin, end, ruler_primary_color, Math::round(EDSCALE * 3)); - if (draw_secondary_lines) { - viewport->draw_line(begin, corner, ruler_secondary_color, Math::round(EDSCALE)); - viewport->draw_line(corner, end, ruler_secondary_color, Math::round(EDSCALE)); - } - Ref<Font> font = get_theme_font(SNAME("bold"), SNAME("EditorFonts")); int font_size = get_theme_font_size(SNAME("bold_size"), SNAME("EditorFonts")); Color font_color = get_theme_color(SNAME("font_color"), SNAME("Editor")); @@ -2936,8 +2928,24 @@ void CanvasItemEditor::_draw_ruler_tool() { Point2 text_pos = (begin + end) / 2 - Vector2(text_width / 2, text_height / 2); text_pos.x = CLAMP(text_pos.x, text_width / 2, viewport->get_rect().size.x - text_width * 1.5); text_pos.y = CLAMP(text_pos.y, text_height * 1.5, viewport->get_rect().size.y - text_height * 1.5); + + if (begin.is_equal_approx(end)) { + viewport->draw_string(font, text_pos, (String)ruler_tool_origin, HALIGN_LEFT, -1, font_size, font_color, outline_size, outline_color); + Ref<Texture2D> position_icon = get_theme_icon(SNAME("EditorPosition"), SNAME("EditorIcons")); + viewport->draw_texture(get_theme_icon(SNAME("EditorPosition"), SNAME("EditorIcons")), (ruler_tool_origin - view_offset) * zoom - position_icon->get_size() / 2); + return; + } + viewport->draw_string(font, text_pos, TS->format_number(vformat("%.1f px", length_vector.length())), HALIGN_LEFT, -1, font_size, font_color, outline_size, outline_color); + bool draw_secondary_lines = !(Math::is_equal_approx(begin.y, corner.y) || Math::is_equal_approx(end.x, corner.x)); + + viewport->draw_line(begin, end, ruler_primary_color, Math::round(EDSCALE * 3)); + if (draw_secondary_lines) { + viewport->draw_line(begin, corner, ruler_secondary_color, Math::round(EDSCALE)); + viewport->draw_line(corner, end, ruler_secondary_color, Math::round(EDSCALE)); + } + if (draw_secondary_lines) { const real_t horizontal_angle_rad = length_vector.angle(); const real_t vertical_angle_rad = Math_PI / 2.0 - horizontal_angle_rad; diff --git a/editor/plugins/gpu_particles_collision_sdf_editor_plugin.cpp b/editor/plugins/gpu_particles_collision_sdf_editor_plugin.cpp index 6df2e34ceb..57279c57e7 100644 --- a/editor/plugins/gpu_particles_collision_sdf_editor_plugin.cpp +++ b/editor/plugins/gpu_particles_collision_sdf_editor_plugin.cpp @@ -68,32 +68,36 @@ void GPUParticlesCollisionSDFEditorPlugin::_notification(int p_what) { return; } + // Set information tooltip on the Bake button. This information is useful + // to optimize performance (video RAM size) and reduce collision tunneling (individual cell size). + const Vector3i size = col_sdf->get_estimated_cell_size(); - String text = vformat(String::utf8("%d × %d × %d"), size.x, size.y, size.z); - int data_size = 2; - const double size_mb = size.x * size.y * size.z * data_size / (1024.0 * 1024.0); - text += " - " + vformat(TTR("VRAM Size: %s MB"), String::num(size_mb, 2)); + const Vector3 extents = col_sdf->get_extents(); - if (bake_info->get_text() == text) { - return; + int data_size = 2; + const double size_mb = size.x * size.y * size.z * data_size / (1024.0 * 1024.0); + // Add a qualitative measurement to help the user assess whether a GPUParticlesCollisionSDF node is using a lot of VRAM. + String size_quality; + if (size_mb < 8.0) { + size_quality = TTR("Low"); + } else if (size_mb < 32.0) { + size_quality = TTR("Moderate"); + } else { + size_quality = TTR("High"); } - // Color the label depending on the estimated performance level. - Color color; - if (size_mb <= 16.0 + CMP_EPSILON) { - // Fast. - color = bake_info->get_theme_color(SNAME("success_color"), SNAME("Editor")); - } else if (size_mb <= 64.0 + CMP_EPSILON) { - // Medium. - color = bake_info->get_theme_color(SNAME("warning_color"), SNAME("Editor")); - } else { - // Slow. - color = bake_info->get_theme_color(SNAME("error_color"), SNAME("Editor")); + String text; + text += vformat(TTR("Subdivisions: %s"), vformat(String::utf8("%d × %d × %d"), size.x, size.y, size.z)) + "\n"; + text += vformat(TTR("Cell size: %s"), vformat(String::utf8("%.3f × %.3f × %.3f"), extents.x / size.x, extents.y / size.y, extents.z / size.z)) + "\n"; + text += vformat(TTR("Video RAM size: %s MB (%s)"), String::num(size_mb, 2), size_quality); + + // Only update the tooltip when needed to avoid constant redrawing. + if (bake->get_tooltip(Point2()) == text) { + return; } - bake_info->add_theme_color_override("font_color", color); - bake_info->set_text(text); + bake->set_tooltip(text); } } @@ -178,10 +182,6 @@ GPUParticlesCollisionSDFEditorPlugin::GPUParticlesCollisionSDFEditorPlugin(Edito bake->set_text(TTR("Bake SDF")); bake->connect("pressed", callable_mp(this, &GPUParticlesCollisionSDFEditorPlugin::_bake)); bake_hb->add_child(bake); - bake_info = memnew(Label); - bake_info->set_h_size_flags(Control::SIZE_EXPAND_FILL); - bake_info->set_clip_text(true); - bake_hb->add_child(bake_info); add_control_to_container(CONTAINER_SPATIAL_EDITOR_MENU, bake_hb); col_sdf = nullptr; diff --git a/editor/plugins/gpu_particles_collision_sdf_editor_plugin.h b/editor/plugins/gpu_particles_collision_sdf_editor_plugin.h index 5a71fc44ef..26b8b352d6 100644 --- a/editor/plugins/gpu_particles_collision_sdf_editor_plugin.h +++ b/editor/plugins/gpu_particles_collision_sdf_editor_plugin.h @@ -42,7 +42,6 @@ class GPUParticlesCollisionSDFEditorPlugin : public EditorPlugin { GPUParticlesCollisionSDF *col_sdf; HBoxContainer *bake_hb; - Label *bake_info; Button *bake; EditorNode *editor; diff --git a/editor/plugins/node_3d_editor_gizmos.cpp b/editor/plugins/node_3d_editor_gizmos.cpp index 154f9bd6b7..1f5d68929a 100644 --- a/editor/plugins/node_3d_editor_gizmos.cpp +++ b/editor/plugins/node_3d_editor_gizmos.cpp @@ -244,8 +244,10 @@ void EditorNode3DGizmo::Instance::create_instance(Node3D *p_base, bool p_hidden) RS::get_singleton()->instance_geometry_set_flag(instance, RS::INSTANCE_FLAG_IGNORE_OCCLUSION_CULLING, true); } -void EditorNode3DGizmo::add_mesh(const Ref<ArrayMesh> &p_mesh, const Ref<Material> &p_material, const Transform3D &p_xform, const Ref<SkinReference> &p_skin_reference) { +void EditorNode3DGizmo::add_mesh(const Ref<Mesh> &p_mesh, const Ref<Material> &p_material, const Transform3D &p_xform, const Ref<SkinReference> &p_skin_reference) { ERR_FAIL_COND(!spatial_node); + ERR_FAIL_COND_MSG(!p_mesh.is_valid(), "EditorNode3DGizmo.add_mesh() requires a valid Mesh resource."); + Instance ins; ins.mesh = p_mesh; @@ -2869,7 +2871,6 @@ void GPUParticlesCollision3DGizmoPlugin::commit_handle(const EditorNode3DGizmo * void GPUParticlesCollision3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) { Node3D *cs = p_gizmo->get_spatial_node(); - print_line("redraw request " + itos(cs != nullptr)); p_gizmo->clear(); const Ref<Material> material = diff --git a/editor/plugins/node_3d_editor_gizmos.h b/editor/plugins/node_3d_editor_gizmos.h index 56e4ad5518..cf9a464b69 100644 --- a/editor/plugins/node_3d_editor_gizmos.h +++ b/editor/plugins/node_3d_editor_gizmos.h @@ -45,7 +45,7 @@ class EditorNode3DGizmo : public Node3DGizmo { struct Instance { RID instance; - Ref<ArrayMesh> mesh; + Ref<Mesh> mesh; Ref<Material> material; Ref<SkinReference> skin_reference; bool extra_margin = false; @@ -95,7 +95,7 @@ protected: public: void add_lines(const Vector<Vector3> &p_lines, const Ref<Material> &p_material, bool p_billboard = false, const Color &p_modulate = Color(1, 1, 1)); void add_vertices(const Vector<Vector3> &p_vertices, const Ref<Material> &p_material, Mesh::PrimitiveType p_primitive_type, bool p_billboard = false, const Color &p_modulate = Color(1, 1, 1)); - void add_mesh(const Ref<ArrayMesh> &p_mesh, const Ref<Material> &p_material = Ref<Material>(), const Transform3D &p_xform = Transform3D(), const Ref<SkinReference> &p_skin_reference = Ref<SkinReference>()); + void add_mesh(const Ref<Mesh> &p_mesh, const Ref<Material> &p_material = Ref<Material>(), const Transform3D &p_xform = Transform3D(), const Ref<SkinReference> &p_skin_reference = Ref<SkinReference>()); void add_collision_segments(const Vector<Vector3> &p_lines); void add_collision_triangles(const Ref<TriangleMesh> &p_tmesh); void add_unscaled_billboard(const Ref<Material> &p_material, real_t p_scale = 1, const Color &p_modulate = Color(1, 1, 1)); diff --git a/editor/plugins/theme_editor_plugin.cpp b/editor/plugins/theme_editor_plugin.cpp index f94439f344..f62dbfc2cc 100644 --- a/editor/plugins/theme_editor_plugin.cpp +++ b/editor/plugins/theme_editor_plugin.cpp @@ -2581,11 +2581,11 @@ void ThemeTypeEditor::_update_type_items() { } // Various type settings. - if (ClassDB::class_exists(edited_type)) { + if (edited_type.is_empty() || ClassDB::class_exists(edited_type)) { type_variation_edit->set_editable(false); type_variation_edit->set_text(""); type_variation_button->hide(); - type_variation_locked->show(); + type_variation_locked->set_visible(!edited_type.is_empty()); } else { type_variation_edit->set_editable(true); type_variation_edit->set_text(edited_theme->get_type_variation_base(edited_type)); diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index da73fc093c..44f2eaa2a1 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -4556,6 +4556,7 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("ATan", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the arc-tangent of the parameter."), VisualShaderNodeFloatFunc::FUNC_ATAN, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("ATan2", "Scalar", "Functions", "VisualShaderNodeFloatOp", TTR("Returns the arc-tangent of the parameters."), VisualShaderNodeFloatOp::OP_ATAN2, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("ATanH", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Returns the inverse hyperbolic tangent of the parameter."), VisualShaderNodeFloatFunc::FUNC_ATANH, VisualShaderNode::PORT_TYPE_SCALAR)); + add_options.push_back(AddOption("BitwiseNOT", "Scalar", "Functions", "VisualShaderNodeIntFunc", TTR("Returns the result of bitwise NOT (~a) operation on the integer."), VisualShaderNodeIntFunc::FUNC_BITWISE_NOT, VisualShaderNode::PORT_TYPE_SCALAR_INT)); add_options.push_back(AddOption("Ceil", "Scalar", "Functions", "VisualShaderNodeFloatFunc", TTR("Finds the nearest integer that is greater than or equal to the parameter."), VisualShaderNodeFloatFunc::FUNC_CEIL, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("Clamp", "Scalar", "Functions", "VisualShaderNodeClamp", TTR("Constrains a value to lie between two further values."), VisualShaderNodeClamp::OP_TYPE_FLOAT, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("Clamp", "Scalar", "Functions", "VisualShaderNodeClamp", TTR("Constrains a value to lie between two further values."), VisualShaderNodeClamp::OP_TYPE_INT, VisualShaderNode::PORT_TYPE_SCALAR_INT)); @@ -4595,6 +4596,11 @@ VisualShaderEditor::VisualShaderEditor() { add_options.push_back(AddOption("Add", "Scalar", "Operators", "VisualShaderNodeFloatOp", TTR("Sums two floating-point scalars."), VisualShaderNodeFloatOp::OP_ADD, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("Add", "Scalar", "Operators", "VisualShaderNodeIntOp", TTR("Sums two integer scalars."), VisualShaderNodeIntOp::OP_ADD, VisualShaderNode::PORT_TYPE_SCALAR_INT)); + add_options.push_back(AddOption("BitwiseAND", "Scalar", "Operators", "VisualShaderNodeIntOp", TTR("Returns the result of bitwise AND (a & b) operation for two integers."), VisualShaderNodeIntOp::OP_BITWISE_AND, VisualShaderNode::PORT_TYPE_SCALAR_INT)); + add_options.push_back(AddOption("BitwiseLeftShift", "Scalar", "Operators", "VisualShaderNodeIntOp", TTR("Returns the result of bitwise left shift (a << b) operation on the integer."), VisualShaderNodeIntOp::OP_BITWISE_LEFT_SHIFT, VisualShaderNode::PORT_TYPE_SCALAR_INT)); + add_options.push_back(AddOption("BitwiseOR", "Scalar", "Operators", "VisualShaderNodeIntOp", TTR("Returns the result of bitwise OR (a | b) operation for two integers."), VisualShaderNodeIntOp::OP_BITWISE_OR, VisualShaderNode::PORT_TYPE_SCALAR_INT)); + add_options.push_back(AddOption("BitwiseRightShift", "Scalar", "Operators", "VisualShaderNodeIntOp", TTR("Returns the result of bitwise right shift (a >> b) operation on the integer."), VisualShaderNodeIntOp::OP_BITWISE_RIGHT_SHIFT, VisualShaderNode::PORT_TYPE_SCALAR_INT)); + add_options.push_back(AddOption("BitwiseXOR", "Scalar", "Operators", "VisualShaderNodeIntOp", TTR("Returns the result of bitwise XOR (a ^ b) operation on the integer."), VisualShaderNodeIntOp::OP_BITWISE_XOR, VisualShaderNode::PORT_TYPE_SCALAR_INT)); add_options.push_back(AddOption("Divide", "Scalar", "Operators", "VisualShaderNodeFloatOp", TTR("Divides two floating-point scalars."), VisualShaderNodeFloatOp::OP_DIV, VisualShaderNode::PORT_TYPE_SCALAR)); add_options.push_back(AddOption("Divide", "Scalar", "Operators", "VisualShaderNodeIntOp", TTR("Divides two integer scalars."), VisualShaderNodeIntOp::OP_DIV, VisualShaderNode::PORT_TYPE_SCALAR_INT)); add_options.push_back(AddOption("Multiply", "Scalar", "Operators", "VisualShaderNodeFloatOp", TTR("Multiplies two floating-point scalars."), VisualShaderNodeFloatOp::OP_MUL, VisualShaderNode::PORT_TYPE_SCALAR)); diff --git a/editor/plugins/voxel_gi_editor_plugin.cpp b/editor/plugins/voxel_gi_editor_plugin.cpp index 9a44d40dcb..4f3cb9e189 100644 --- a/editor/plugins/voxel_gi_editor_plugin.cpp +++ b/editor/plugins/voxel_gi_editor_plugin.cpp @@ -67,31 +67,36 @@ void VoxelGIEditorPlugin::_notification(int p_what) { return; } + // Set information tooltip on the Bake button. This information is useful + // to optimize performance (video RAM size) and reduce light leaking (individual cell size). + const Vector3i size = voxel_gi->get_estimated_cell_size(); - String text = vformat(String::utf8("%d × %d × %d"), size.x, size.y, size.z); + + const Vector3 extents = voxel_gi->get_extents(); + const int data_size = 4; const double size_mb = size.x * size.y * size.z * data_size / (1024.0 * 1024.0); - text += " - " + vformat(TTR("VRAM Size: %s MB"), String::num(size_mb, 2)); - - if (bake_info->get_text() == text) { - return; + // Add a qualitative measurement to help the user assess whether a VoxelGI node is using a lot of VRAM. + String size_quality; + if (size_mb < 16.0) { + size_quality = TTR("Low"); + } else if (size_mb < 64.0) { + size_quality = TTR("Moderate"); + } else { + size_quality = TTR("High"); } - // Color the label depending on the estimated performance level. - Color color; - if (size_mb <= 16.0 + CMP_EPSILON) { - // Fast. - color = bake_info->get_theme_color(SNAME("success_color"), SNAME("Editor")); - } else if (size_mb <= 64.0 + CMP_EPSILON) { - // Medium. - color = bake_info->get_theme_color(SNAME("warning_color"), SNAME("Editor")); - } else { - // Slow. - color = bake_info->get_theme_color(SNAME("error_color"), SNAME("Editor")); + String text; + text += vformat(TTR("Subdivisions: %s"), vformat(String::utf8("%d × %d × %d"), size.x, size.y, size.z)) + "\n"; + text += vformat(TTR("Cell size: %s"), vformat(String::utf8("%.3f × %.3f × %.3f"), extents.x / size.x, extents.y / size.y, extents.z / size.z)) + "\n"; + text += vformat(TTR("Video RAM size: %s MB (%s)"), String::num(size_mb, 2), size_quality); + + // Only update the tooltip when needed to avoid constant redrawing. + if (bake->get_tooltip(Point2()) == text) { + return; } - bake_info->add_theme_color_override("font_color", color); - bake_info->set_text(text); + bake->set_tooltip(text); } } @@ -147,10 +152,6 @@ VoxelGIEditorPlugin::VoxelGIEditorPlugin(EditorNode *p_node) { bake->set_text(TTR("Bake GI Probe")); bake->connect("pressed", callable_mp(this, &VoxelGIEditorPlugin::_bake)); bake_hb->add_child(bake); - bake_info = memnew(Label); - bake_info->set_h_size_flags(Control::SIZE_EXPAND_FILL); - bake_info->set_clip_text(true); - bake_hb->add_child(bake_info); add_control_to_container(CONTAINER_SPATIAL_EDITOR_MENU, bake_hb); voxel_gi = nullptr; diff --git a/editor/plugins/voxel_gi_editor_plugin.h b/editor/plugins/voxel_gi_editor_plugin.h index 4d3cfe90f6..ed66728557 100644 --- a/editor/plugins/voxel_gi_editor_plugin.h +++ b/editor/plugins/voxel_gi_editor_plugin.h @@ -42,7 +42,6 @@ class VoxelGIEditorPlugin : public EditorPlugin { VoxelGI *voxel_gi; HBoxContainer *bake_hb; - Label *bake_info; Button *bake; EditorNode *editor; diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp index cf89120beb..b36275322a 100644 --- a/editor/scene_tree_dock.cpp +++ b/editor/scene_tree_dock.cpp @@ -2977,7 +2977,7 @@ void SceneTreeDock::attach_shader_to_selected(int p_preferred_mode) { shader_create_dialog->connect("shader_created", callable_mp(this, &SceneTreeDock::_shader_created)); shader_create_dialog->connect("confirmed", callable_mp(this, &SceneTreeDock::_shader_creation_closed)); shader_create_dialog->connect("cancelled", callable_mp(this, &SceneTreeDock::_shader_creation_closed)); - shader_create_dialog->config(path, true, true, p_preferred_mode); + shader_create_dialog->config(path, true, true, -1, p_preferred_mode); shader_create_dialog->popup_centered(); } diff --git a/editor/shader_create_dialog.cpp b/editor/shader_create_dialog.cpp index 23bdc06f95..1ddd79eea8 100644 --- a/editor/shader_create_dialog.cpp +++ b/editor/shader_create_dialog.cpp @@ -324,7 +324,7 @@ void ShaderCreateDialog::_path_submitted(const String &p_path) { ok_pressed(); } -void ShaderCreateDialog::config(const String &p_base_path, bool p_built_in_enabled, bool p_load_enabled, int p_preferred_mode) { +void ShaderCreateDialog::config(const String &p_base_path, bool p_built_in_enabled, bool p_load_enabled, int p_preferred_type, int p_preferred_mode) { if (p_base_path != "") { initial_base_path = p_base_path.get_basename(); file_path->set_text(initial_base_path + "." + language_data[language_menu->get_selected()].default_extension); @@ -338,6 +338,11 @@ void ShaderCreateDialog::config(const String &p_base_path, bool p_built_in_enabl built_in_enabled = p_built_in_enabled; load_enabled = p_load_enabled; + if (p_preferred_type > -1) { + language_menu->select(p_preferred_type); + _language_changed(p_preferred_type); + } + if (p_preferred_mode > -1) { mode_menu->select(p_preferred_mode); _mode_changed(p_preferred_mode); diff --git a/editor/shader_create_dialog.h b/editor/shader_create_dialog.h index be0a0cad06..cd20897ddb 100644 --- a/editor/shader_create_dialog.h +++ b/editor/shader_create_dialog.h @@ -108,7 +108,7 @@ protected: static void _bind_methods(); public: - void config(const String &p_base_path, bool p_built_in_enabled = true, bool p_load_enabled = true, int p_preferred_mode = -1); + void config(const String &p_base_path, bool p_built_in_enabled = true, bool p_load_enabled = true, int p_preferred_type = -1, int p_preferred_mode = -1); ShaderCreateDialog(); }; |