diff options
23 files changed, 187 insertions, 134 deletions
diff --git a/core/io/file_access_pack.cpp b/core/io/file_access_pack.cpp index a4821e0ce8..54ef753b7c 100644 --- a/core/io/file_access_pack.cpp +++ b/core/io/file_access_pack.cpp @@ -36,11 +36,11 @@ #define PACK_VERSION 1 -Error PackedData::add_pack(const String &p_path) { +Error PackedData::add_pack(const String &p_path, bool p_replace_files) { for (int i = 0; i < sources.size(); i++) { - if (sources[i]->try_open_pack(p_path)) { + if (sources[i]->try_open_pack(p_path, p_replace_files)) { return OK; }; @@ -49,7 +49,7 @@ Error PackedData::add_pack(const String &p_path) { return ERR_FILE_UNRECOGNIZED; }; -void PackedData::add_path(const String &pkg_path, const String &path, uint64_t ofs, uint64_t size, const uint8_t *p_md5, PackSource *p_src) { +void PackedData::add_path(const String &pkg_path, const String &path, uint64_t ofs, uint64_t size, const uint8_t *p_md5, PackSource *p_src, bool p_replace_files) { PathMD5 pmd5(path.md5_buffer()); //printf("adding path %ls, %lli, %lli\n", path.c_str(), pmd5.a, pmd5.b); @@ -64,7 +64,8 @@ void PackedData::add_path(const String &pkg_path, const String &path, uint64_t o pf.md5[i] = p_md5[i]; pf.src = p_src; - files[pmd5] = pf; + if (!exists || p_replace_files) + files[pmd5] = pf; if (!exists) { //search for dir @@ -133,7 +134,7 @@ PackedData::~PackedData() { ////////////////////////////////////////////////////////////////// -bool PackedSourcePCK::try_open_pack(const String &p_path) { +bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files) { FileAccess *f = FileAccess::open(p_path, FileAccess::READ); if (!f) @@ -196,7 +197,7 @@ bool PackedSourcePCK::try_open_pack(const String &p_path) { uint64_t size = f->get_64(); uint8_t md5[16]; f->get_buffer(md5, 16); - PackedData::get_singleton()->add_path(p_path, path, ofs, size, md5, this); + PackedData::get_singleton()->add_path(p_path, path, ofs, size, md5, this, p_replace_files); }; return true; diff --git a/core/io/file_access_pack.h b/core/io/file_access_pack.h index a21dd7d22d..8c34069f3a 100644 --- a/core/io/file_access_pack.h +++ b/core/io/file_access_pack.h @@ -102,13 +102,13 @@ private: public: void add_pack_source(PackSource *p_source); - void add_path(const String &pkg_path, const String &path, uint64_t ofs, uint64_t size, const uint8_t *p_md5, PackSource *p_src); // for PackSource + void add_path(const String &pkg_path, const String &path, uint64_t ofs, uint64_t size, const uint8_t *p_md5, PackSource *p_src, bool p_replace_files); // for PackSource void set_disabled(bool p_disabled) { disabled = p_disabled; } _FORCE_INLINE_ bool is_disabled() const { return disabled; } static PackedData *get_singleton() { return singleton; } - Error add_pack(const String &p_path); + Error add_pack(const String &p_path, bool p_replace_files); _FORCE_INLINE_ FileAccess *try_open_path(const String &p_path); _FORCE_INLINE_ bool has_path(const String &p_path); @@ -120,7 +120,7 @@ public: class PackSource { public: - virtual bool try_open_pack(const String &p_path) = 0; + virtual bool try_open_pack(const String &p_path, bool p_replace_files) = 0; virtual FileAccess *get_file(const String &p_path, PackedData::PackedFile *p_file) = 0; virtual ~PackSource() {} }; @@ -128,7 +128,7 @@ public: class PackedSourcePCK : public PackSource { public: - virtual bool try_open_pack(const String &p_path); + virtual bool try_open_pack(const String &p_path, bool p_replace_files); virtual FileAccess *get_file(const String &p_path, PackedData::PackedFile *p_file); }; diff --git a/core/io/file_access_zip.cpp b/core/io/file_access_zip.cpp index 81568b2aae..3187f3bab6 100644 --- a/core/io/file_access_zip.cpp +++ b/core/io/file_access_zip.cpp @@ -160,7 +160,7 @@ unzFile ZipArchive::get_file_handle(String p_file) const { return pkg; } -bool ZipArchive::try_open_pack(const String &p_path) { +bool ZipArchive::try_open_pack(const String &p_path, bool p_replace_files) { //printf("opening zip pack %ls, %i, %i\n", p_name.c_str(), p_name.extension().nocasecmp_to("zip"), p_name.extension().nocasecmp_to("pcz")); if (p_path.get_extension().nocasecmp_to("zip") != 0 && p_path.get_extension().nocasecmp_to("pcz") != 0) @@ -210,7 +210,7 @@ bool ZipArchive::try_open_pack(const String &p_path) { files[fname] = f; uint8_t md5[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - PackedData::get_singleton()->add_path(p_path, fname, 1, 0, md5, this); + PackedData::get_singleton()->add_path(p_path, fname, 1, 0, md5, this, p_replace_files); //printf("packed data add path %ls, %ls\n", p_name.c_str(), fname.c_str()); if ((i + 1) < gi.number_entry) { diff --git a/core/io/file_access_zip.h b/core/io/file_access_zip.h index 217176c0af..cdd50f9eb3 100644 --- a/core/io/file_access_zip.h +++ b/core/io/file_access_zip.h @@ -74,7 +74,7 @@ public: bool file_exists(String p_name) const; - virtual bool try_open_pack(const String &p_path); + virtual bool try_open_pack(const String &p_path, bool p_replace_files); FileAccess *get_file(const String &p_path, PackedData::PackedFile *p_file); static ZipArchive *get_singleton(); diff --git a/core/io/stream_peer_tcp.cpp b/core/io/stream_peer_tcp.cpp index 310bb12bc0..b9c5896b24 100644 --- a/core/io/stream_peer_tcp.cpp +++ b/core/io/stream_peer_tcp.cpp @@ -248,16 +248,7 @@ void StreamPeerTCP::set_no_delay(bool p_enabled) { bool StreamPeerTCP::is_connected_to_host() const { - if (status == STATUS_NONE || status == STATUS_ERROR) { - - return false; - } - - if (status != STATUS_CONNECTED) { - return true; - } - - return _sock.is_valid() && _sock->is_open(); + return _sock.is_valid() && _sock->is_open() && (status == STATUS_CONNECTED || status == STATUS_CONNECTING); } StreamPeerTCP::Status StreamPeerTCP::get_status() { diff --git a/core/project_settings.cpp b/core/project_settings.cpp index 9e3b9bd1e4..c2241ed926 100644 --- a/core/project_settings.cpp +++ b/core/project_settings.cpp @@ -264,12 +264,12 @@ void ProjectSettings::_get_property_list(List<PropertyInfo> *p_list) const { } } -bool ProjectSettings::_load_resource_pack(const String &p_pack) { +bool ProjectSettings::_load_resource_pack(const String &p_pack, bool p_replace_files) { if (PackedData::get_singleton()->is_disabled()) return false; - bool ok = PackedData::get_singleton()->add_pack(p_pack) == OK; + bool ok = PackedData::get_singleton()->add_pack(p_pack, p_replace_files) == OK; if (!ok) return false; @@ -979,7 +979,7 @@ void ProjectSettings::_bind_methods() { ClassDB::bind_method(D_METHOD("localize_path", "path"), &ProjectSettings::localize_path); ClassDB::bind_method(D_METHOD("globalize_path", "path"), &ProjectSettings::globalize_path); ClassDB::bind_method(D_METHOD("save"), &ProjectSettings::save); - ClassDB::bind_method(D_METHOD("load_resource_pack", "pack"), &ProjectSettings::_load_resource_pack); + ClassDB::bind_method(D_METHOD("load_resource_pack", "pack", "replace_files"), &ProjectSettings::_load_resource_pack, DEFVAL(true)); ClassDB::bind_method(D_METHOD("property_can_revert", "name"), &ProjectSettings::property_can_revert); ClassDB::bind_method(D_METHOD("property_get_revert", "name"), &ProjectSettings::property_get_revert); diff --git a/core/project_settings.h b/core/project_settings.h index a8deab028c..b32470361b 100644 --- a/core/project_settings.h +++ b/core/project_settings.h @@ -104,7 +104,7 @@ protected: void _convert_to_last_version(int p_from_version); - bool _load_resource_pack(const String &p_pack); + bool _load_resource_pack(const String &p_pack, bool p_replace_files = true); void _add_property_info_bind(const Dictionary &p_info); diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index 3da403c681..abf7c4d4e0 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -80,9 +80,11 @@ </return> <argument index="0" name="pack" type="String"> </argument> + <argument index="1" name="replace_files" type="bool" default="true"> + </argument> <description> Loads the contents of the .pck or .zip file specified by [code]pack[/code] into the resource filesystem ([code]res://[/code]). Returns [code]true[/code] on success. - [b]Note:[/b] If a file from [code]pack[/code] shares the same path as a file already in the resource filesystem, any attempts to load that file will use the file from [code]pack[/code]. + [b]Note:[/b] If a file from [code]pack[/code] shares the same path as a file already in the resource filesystem, any attempts to load that file will use the file from [code]pack[/code] unless [code]replace_files[/code] is set to [code]false[/code]. </description> </method> <method name="localize_path" qualifiers="const"> diff --git a/editor/animation_bezier_editor.cpp b/editor/animation_bezier_editor.cpp index 9194da654c..1283956ae6 100644 --- a/editor/animation_bezier_editor.cpp +++ b/editor/animation_bezier_editor.cpp @@ -546,7 +546,7 @@ void AnimationBezierTrackEdit::set_timeline(AnimationTimelineEdit *p_timeline) { } void AnimationBezierTrackEdit::set_editor(AnimationTrackEditor *p_editor) { editor = p_editor; - connect("clear_selection", editor, "_clear_selection"); + connect("clear_selection", editor, "_clear_selection", varray(false)); } void AnimationBezierTrackEdit::_play_position_draw() { diff --git a/editor/animation_track_editor.cpp b/editor/animation_track_editor.cpp index fa773b17c2..74e8df60f9 100644 --- a/editor/animation_track_editor.cpp +++ b/editor/animation_track_editor.cpp @@ -3080,7 +3080,6 @@ void AnimationTrackEdit::_bind_methods() { ADD_SIGNAL(MethodInfo("insert_key", PropertyInfo(Variant::REAL, "ofs"))); ADD_SIGNAL(MethodInfo("select_key", PropertyInfo(Variant::INT, "index"), PropertyInfo(Variant::BOOL, "single"))); ADD_SIGNAL(MethodInfo("deselect_key", PropertyInfo(Variant::INT, "index"))); - ADD_SIGNAL(MethodInfo("clear_selection")); ADD_SIGNAL(MethodInfo("bezier_edit")); ADD_SIGNAL(MethodInfo("move_selection_begin")); @@ -4265,7 +4264,6 @@ void AnimationTrackEditor::_update_tracks() { track_edit->connect("select_key", this, "_key_selected", varray(i), CONNECT_DEFERRED); track_edit->connect("deselect_key", this, "_key_deselected", varray(i), CONNECT_DEFERRED); track_edit->connect("bezier_edit", this, "_bezier_edit", varray(i), CONNECT_DEFERRED); - track_edit->connect("clear_selection", this, "_clear_selection"); track_edit->connect("move_selection_begin", this, "_move_selection_begin"); track_edit->connect("move_selection", this, "_move_selection"); track_edit->connect("move_selection_commit", this, "_move_selection_commit"); diff --git a/editor/connections_dialog.cpp b/editor/connections_dialog.cpp index cfc2ec11cf..1e5eabc24e 100644 --- a/editor/connections_dialog.cpp +++ b/editor/connections_dialog.cpp @@ -108,8 +108,8 @@ public: }; /* -Signal automatically called by parent dialog. -*/ + * Signal automatically called by parent dialog. + */ void ConnectDialog::ok_pressed() { if (dst_method->get_text() == "") { @@ -134,8 +134,8 @@ void ConnectDialog::_cancel_pressed() { } /* -Called each time a target node is selected within the target node tree. -*/ + * Called each time a target node is selected within the target node tree. + */ void ConnectDialog::_tree_node_selected() { Node *current = tree->get_selected(); @@ -148,8 +148,8 @@ void ConnectDialog::_tree_node_selected() { } /* -Adds a new parameter bind to connection. -*/ + * Adds a new parameter bind to connection. + */ void ConnectDialog::_add_bind() { if (cdbinds->params.size() >= VARIANT_ARG_MAX) @@ -184,8 +184,8 @@ void ConnectDialog::_add_bind() { } /* -Remove parameter bind from connection. -*/ + * Remove parameter bind from connection. + */ void ConnectDialog::_remove_bind() { String st = bind_editor->get_selected_path(); @@ -265,18 +265,18 @@ bool ConnectDialog::get_oneshot() const { } /* -Returns true if ConnectDialog is being used to edit an existing connection. -*/ + * Returns true if ConnectDialog is being used to edit an existing connection. + */ bool ConnectDialog::is_editing() const { return bEditMode; } /* -Initialize ConnectDialog and populate fields with expected data. -If creating a connection from scratch, sensible defaults are used. -If editing an existing connection, previous data is retained. -*/ + * Initialize ConnectDialog and populate fields with expected data. + * If creating a connection from scratch, sensible defaults are used. + * If editing an existing connection, previous data is retained. + */ void ConnectDialog::init(Connection c, bool bEdit) { source = static_cast<Node *>(c.source); @@ -482,9 +482,9 @@ struct _ConnectionsDockMethodInfoSort { }; /* -Post-ConnectDialog callback for creating/editing connections. -Creates or edits connections based on state of the ConnectDialog when "Connect" is pressed. -*/ + * Post-ConnectDialog callback for creating/editing connections. + * Creates or edits connections based on state of the ConnectDialog when "Connect" is pressed. + */ void ConnectionsDock::_make_or_edit_connection() { TreeItem *it = tree->get_selected(); @@ -552,8 +552,8 @@ void ConnectionsDock::_make_or_edit_connection() { } /* -Creates single connection w/ undo-redo functionality. -*/ + * Creates single connection w/ undo-redo functionality. + */ void ConnectionsDock::_connect(Connection cToMake) { Node *source = static_cast<Node *>(cToMake.source); @@ -575,8 +575,8 @@ void ConnectionsDock::_connect(Connection cToMake) { } /* -Break single connection w/ undo-redo functionality. -*/ + * Break single connection w/ undo-redo functionality. + */ void ConnectionsDock::_disconnect(TreeItem &item) { Connection c = item.get_metadata(0); @@ -595,9 +595,9 @@ void ConnectionsDock::_disconnect(TreeItem &item) { } /* -Break all connections of currently selected signal. -Can undo-redo as a single action. -*/ + * Break all connections of currently selected signal. + * Can undo-redo as a single action. + */ void ConnectionsDock::_disconnect_all() { TreeItem *item = tree->get_selected(); @@ -659,8 +659,8 @@ bool ConnectionsDock::_is_item_signal(TreeItem &item) { } /* -Open connection dialog with TreeItem data to CREATE a brand-new connection. -*/ + * Open connection dialog with TreeItem data to CREATE a brand-new connection. + */ void ConnectionsDock::_open_connection_dialog(TreeItem &item) { String signal = item.get_metadata(0).operator Dictionary()["name"]; @@ -700,8 +700,8 @@ void ConnectionsDock::_open_connection_dialog(TreeItem &item) { } /* -Open connection dialog with Connection data to EDIT an existing connection. -*/ + * Open connection dialog with Connection data to EDIT an existing connection. + */ void ConnectionsDock::_open_connection_dialog(Connection cToEdit) { Node *src = static_cast<Node *>(cToEdit.source); @@ -715,8 +715,8 @@ void ConnectionsDock::_open_connection_dialog(Connection cToEdit) { } /* -Open slot method location in script editor. -*/ + * Open slot method location in script editor. + */ void ConnectionsDock::_go_to_script(TreeItem &item) { if (_is_item_signal(item)) @@ -914,7 +914,6 @@ void ConnectionsDock::update_tree() { String signaldesc = "("; PoolStringArray argnames; if (mi.arguments.size()) { - signaldesc += " "; for (int i = 0; i < mi.arguments.size(); i++) { PropertyInfo &pi = mi.arguments[i]; @@ -927,10 +926,9 @@ void ConnectionsDock::update_tree() { } else if (pi.type != Variant::NIL) { tname = Variant::get_type_name(pi.type); } - signaldesc += tname + " " + (pi.name == "" ? String("arg " + itos(i)) : pi.name); + signaldesc += (pi.name == "" ? String("arg " + itos(i)) : pi.name) + ": " + tname; argnames.push_back(pi.name + ":" + tname); } - signaldesc += " "; } signaldesc += ")"; @@ -1000,14 +998,14 @@ void ConnectionsDock::update_tree() { path += " (oneshot)"; if (c.binds.size()) { - path += " binds( "; + path += " binds("; for (int i = 0; i < c.binds.size(); i++) { if (i > 0) path += ", "; path += c.binds[i].operator String(); } - path += " )"; + path += ")"; } TreeItem *item2 = tree->create_item(item); diff --git a/editor/editor_audio_buses.cpp b/editor/editor_audio_buses.cpp index 31095b1100..b331a39535 100644 --- a/editor/editor_audio_buses.cpp +++ b/editor/editor_audio_buses.cpp @@ -88,7 +88,7 @@ void EditorAudioBus::_notification(int p_what) { bypass->set_icon(get_icon("AudioBusBypass", "EditorIcons")); bypass->add_color_override("icon_color_pressed", bypass_color); - bus_options->set_icon(get_icon("GuiMiniTabMenu", "EditorIcons")); + bus_options->set_icon(get_icon("GuiTabMenu", "EditorIcons")); update_bus(); set_process(true); @@ -180,7 +180,7 @@ void EditorAudioBus::_notification(int p_what) { mute->set_icon(get_icon("AudioBusMute", "EditorIcons")); bypass->set_icon(get_icon("AudioBusBypass", "EditorIcons")); - bus_options->set_icon(get_icon("GuiMiniTabMenu", "EditorIcons")); + bus_options->set_icon(get_icon("GuiTabMenu", "EditorIcons")); } break; case NOTIFICATION_MOUSE_EXIT: case NOTIFICATION_DRAG_END: { diff --git a/editor/icons/icon_GUI_tab_menu.svg b/editor/icons/icon_GUI_tab_menu.svg index 55e98143a6..8bf5ef2f7d 100644 --- a/editor/icons/icon_GUI_tab_menu.svg +++ b/editor/icons/icon_GUI_tab_menu.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 0a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm0 6a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm0 6a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2z" fill="#fff" fill-opacity=".39216"/></svg>
\ No newline at end of file +<svg height="16" viewBox="0 0 6 16" width="6" xmlns="http://www.w3.org/2000/svg"><path d="m3 0a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm0 6a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm0 6a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2z" fill="#fff" fill-opacity=".39216"/></svg>
\ No newline at end of file diff --git a/editor/icons/icon_GUI_tab_menu_hl.svg b/editor/icons/icon_GUI_tab_menu_hl.svg index e4c5b7bf1e..42d58a5abf 100644 --- a/editor/icons/icon_GUI_tab_menu_hl.svg +++ b/editor/icons/icon_GUI_tab_menu_hl.svg @@ -1 +1 @@ -<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 0a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm0 6a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm0 6a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2z" fill="#e0e0e0"/></svg>
\ No newline at end of file +<svg height="16" viewBox="0 0 6 16" width="6" xmlns="http://www.w3.org/2000/svg"><path d="m3 0a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm0 6a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2zm0 6a2 2 0 0 0 -2 2 2 2 0 0 0 2 2 2 2 0 0 0 2-2 2 2 0 0 0 -2-2z" fill="#e0e0e0"/></svg>
\ No newline at end of file diff --git a/editor/import/editor_scene_importer_gltf.cpp b/editor/import/editor_scene_importer_gltf.cpp index df5511f540..49091dc812 100644 --- a/editor/import/editor_scene_importer_gltf.cpp +++ b/editor/import/editor_scene_importer_gltf.cpp @@ -156,7 +156,7 @@ static Transform _arr_to_xform(const Array &p_array) { } String EditorSceneImporterGLTF::_sanitize_scene_name(const String &name) { - RegEx regex("([^a-zA-Z0-9_ ]+)"); + RegEx regex("([^a-zA-Z0-9_ -]+)"); String p_name = regex.sub(name, "", true); return p_name; } diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp index 831b1434f3..2d00324c84 100644 --- a/editor/plugins/animation_player_editor_plugin.cpp +++ b/editor/plugins/animation_player_editor_plugin.cpp @@ -122,7 +122,7 @@ void AnimationPlayerEditor::_notification(int p_what) { stop->set_icon(get_icon("Stop", "EditorIcons")); onion_toggle->set_icon(get_icon("Onion", "EditorIcons")); - onion_skinning->set_icon(get_icon("GuiMiniTabMenu", "EditorIcons")); + onion_skinning->set_icon(get_icon("GuiTabMenu", "EditorIcons")); pin->set_icon(get_icon("Pin", "EditorIcons")); diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 78873e739b..a11c35e5f2 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -1749,6 +1749,9 @@ bool CanvasItemEditor::_gui_input_resize(const Ref<InputEvent> &p_event) { if (key_auto_insert_button->is_pressed()) { _insert_animation_keys(false, false, true, true); } + + snap_target[0] = SNAP_TARGET_NONE; + snap_target[1] = SNAP_TARGET_NONE; drag_type = DRAG_NONE; viewport->update(); return true; @@ -1757,6 +1760,8 @@ bool CanvasItemEditor::_gui_input_resize(const Ref<InputEvent> &p_event) { // Cancel a drag if (b.is_valid() && b->get_button_index() == BUTTON_RIGHT && b->is_pressed()) { _restore_canvas_item_state(drag_selection); + snap_target[0] = SNAP_TARGET_NONE; + snap_target[1] = SNAP_TARGET_NONE; drag_type = DRAG_NONE; viewport->update(); return true; @@ -3662,7 +3667,7 @@ void CanvasItemEditor::_notification(int p_what) { scale_button->set_icon(get_icon("ToolScale", "EditorIcons")); rotate_button->set_icon(get_icon("ToolRotate", "EditorIcons")); snap_button->set_icon(get_icon("Snap", "EditorIcons")); - snap_config_menu->set_icon(get_icon("GuiMiniTabMenu", "EditorIcons")); + snap_config_menu->set_icon(get_icon("GuiTabMenu", "EditorIcons")); skeleton_menu->set_icon(get_icon("Bone", "EditorIcons")); pan_button->set_icon(get_icon("ToolPan", "EditorIcons")); ruler_button->set_icon(get_icon("Ruler", "EditorIcons")); diff --git a/editor/plugins/curve_editor_plugin.cpp b/editor/plugins/curve_editor_plugin.cpp index 98db911799..9160920c50 100644 --- a/editor/plugins/curve_editor_plugin.cpp +++ b/editor/plugins/curve_editor_plugin.cpp @@ -456,6 +456,9 @@ void CurveEditor::remove_point(int index) { if (index == _selected_point) set_selected_point(-1); + if (index == _hover_point) + set_hover_point_index(-1); + ur.commit_action(); } diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp index 136ec17ddb..ba40fc5612 100644 --- a/editor/plugins/spatial_editor_plugin.cpp +++ b/editor/plugins/spatial_editor_plugin.cpp @@ -2304,7 +2304,7 @@ void SpatialEditorViewport::_notification(int p_what) { if (p_what == NOTIFICATION_THEME_CHANGED) { - view_menu->set_icon(get_icon("GuiMiniTabMenu", "EditorIcons")); + view_menu->set_icon(get_icon("GuiTabMenu", "EditorIcons")); preview_camera->set_icon(get_icon("Camera", "EditorIcons")); view_menu->add_style_override("normal", editor->get_gui_base()->get_stylebox("Information3dViewport", "EditorStyles")); diff --git a/editor/script_editor_debugger.cpp b/editor/script_editor_debugger.cpp index 6ba507fb9c..6a9dbb103a 100644 --- a/editor/script_editor_debugger.cpp +++ b/editor/script_editor_debugger.cpp @@ -804,60 +804,102 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da } else if (p_msg == "error") { - Array err = p_data[0]; - - Array vals; - vals.push_back(err[0]); - vals.push_back(err[1]); - vals.push_back(err[2]); - vals.push_back(err[3]); + // Should have at least two elements, error array and stack items count. + ERR_FAIL_COND_MSG(p_data.size() < 2, "Malformed error message from script debugger."); - bool warning = err[9]; + // Error or warning data. + Array err = p_data[0]; + ERR_FAIL_COND_MSG(err.size() < 10, "Malformed error message from script debugger."); + + // Format time. + Array time_vals; + time_vals.push_back(err[0]); + time_vals.push_back(err[1]); + time_vals.push_back(err[2]); + time_vals.push_back(err[3]); bool e; - String time = String("%d:%02d:%02d:%04d").sprintf(vals, &e); - String txt = err[8].is_zero() ? String(err[7]) : String(err[8]); + String time = String("%d:%02d:%02d:%04d").sprintf(time_vals, &e); + // Rest of the error data. + String method = err[4]; + String source_file = err[5]; + String source_line = err[6]; + String error_cond = err[7]; + String error_msg = err[8]; + bool is_warning = err[9]; + bool has_method = !method.empty(); + bool has_error_msg = !error_msg.empty(); + bool source_is_project_file = source_file.begins_with("res://"); + + // Metadata to highlight error line in scripts. + Array source_meta; + source_meta.push_back(source_file); + source_meta.push_back(source_line); + + // Create error tree to display above error or warning details. TreeItem *r = error_tree->get_root(); if (!r) { r = error_tree->create_item(); } + // Also provide the relevant details as tooltip to quickly check without + // uncollapsing the tree. + String tooltip = is_warning ? TTR("Warning:") : TTR("Error:"); + TreeItem *error = error_tree->create_item(r); error->set_collapsed(true); - error->set_icon(0, get_icon(warning ? "Warning" : "Error", "EditorIcons")); + error->set_icon(0, get_icon(is_warning ? "Warning" : "Error", "EditorIcons")); error->set_text(0, time); error->set_text_align(0, TreeItem::ALIGN_LEFT); - error->set_text(1, txt); - - String source(err[5]); - bool source_is_project_file = source.begins_with("res://"); - if (source_is_project_file) - txt = source.get_file() + ":" + String(err[6]); - else - txt = source + ":" + String(err[6]); + String error_title; + // Include method name, when given, in error title. + if (has_method) + error_title += method + ": "; + // If we have a (custom) error message, use it as title, and add a C++ Error + // item with the original error condition. + error_title += error_msg.empty() ? error_cond : error_msg; + error->set_text(1, error_title); + tooltip += " " + error_title + "\n"; + + if (has_error_msg) { + // Add item for C++ error condition. + TreeItem *cpp_cond = error_tree->create_item(error); + cpp_cond->set_text(0, "<" + TTR("C++ Error") + ">"); + cpp_cond->set_text(1, error_cond); + cpp_cond->set_text_align(0, TreeItem::ALIGN_LEFT); + tooltip += TTR("C++ Error:") + " " + error_cond + "\n"; + if (source_is_project_file) + cpp_cond->set_metadata(0, source_meta); + } - String method = err[4]; - if (method.length() > 0) - txt += " @ " + method + "()"; + // Source of the error. + String source_txt = (source_is_project_file ? source_file.get_file() : source_file) + ":" + source_line; + if (has_method) + source_txt += " @ " + method + "()"; - TreeItem *c_info = error_tree->create_item(error); - c_info->set_text(0, "<" + TTR(source_is_project_file ? "Source" : "C Source") + ">"); - c_info->set_text(1, txt); - c_info->set_text_align(0, TreeItem::ALIGN_LEFT); + TreeItem *cpp_source = error_tree->create_item(error); + cpp_source->set_text(0, "<" + (source_is_project_file ? TTR("Source") : TTR("C++ Source")) + ">"); + cpp_source->set_text(1, source_txt); + cpp_source->set_text_align(0, TreeItem::ALIGN_LEFT); + tooltip += (source_is_project_file ? TTR("Source:") : TTR("C++ Source:")) + " " + source_txt + "\n"; + // Set metadata to highlight error line in scripts. if (source_is_project_file) { - Array meta; - meta.push_back(source); - meta.push_back(err[6]); - error->set_metadata(0, meta); - c_info->set_metadata(0, meta); + error->set_metadata(0, source_meta); + cpp_source->set_metadata(0, source_meta); } - int scc = p_data[1]; + error->set_tooltip(0, tooltip); + error->set_tooltip(1, tooltip); + + // Format stack trace. + // stack_items_count is the number of elements to parse, with 3 items per frame + // of the stack trace (script, method, line). + int stack_items_count = p_data[1]; - for (int i = 0; i < scc; i += 3) { + for (int i = 0; i < stack_items_count; i += 3) { String script = p_data[2 + i]; String method2 = p_data[3 + i]; int line = p_data[4 + i]; @@ -876,7 +918,7 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da stack_trace->set_text(1, script.get_file() + ":" + itos(line) + " @ " + method2 + "()"); } - if (warning) + if (is_warning) warning_count++; else error_count++; diff --git a/editor/spatial_editor_gizmos.cpp b/editor/spatial_editor_gizmos.cpp index 5d1250aac2..489049c543 100644 --- a/editor/spatial_editor_gizmos.cpp +++ b/editor/spatial_editor_gizmos.cpp @@ -729,7 +729,7 @@ void EditorSpatialGizmo::set_plugin(EditorSpatialGizmoPlugin *p_plugin) { void EditorSpatialGizmo::_bind_methods() { ClassDB::bind_method(D_METHOD("add_lines", "lines", "material", "billboard"), &EditorSpatialGizmo::add_lines, DEFVAL(false)); - ClassDB::bind_method(D_METHOD("add_mesh", "mesh", "billboard", "skeleton", "material"), &EditorSpatialGizmo::add_mesh, DEFVAL(false), DEFVAL(Variant()), DEFVAL(Variant())); + ClassDB::bind_method(D_METHOD("add_mesh", "mesh", "billboard", "skeleton", "material"), &EditorSpatialGizmo::add_mesh, DEFVAL(false), DEFVAL(Ref<SkinReference>()), DEFVAL(Variant())); ClassDB::bind_method(D_METHOD("add_collision_segments", "segments"), &EditorSpatialGizmo::add_collision_segments); ClassDB::bind_method(D_METHOD("add_collision_triangles", "triangles"), &EditorSpatialGizmo::add_collision_triangles); ClassDB::bind_method(D_METHOD("add_unscaled_billboard", "material", "default_scale"), &EditorSpatialGizmo::add_unscaled_billboard, DEFVAL(1)); diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp index 915a01af7e..b2e1deca01 100644 --- a/modules/mono/mono_gd/gd_mono.cpp +++ b/modules/mono/mono_gd/gd_mono.cpp @@ -119,26 +119,29 @@ void gdmono_debug_init() { mono_debug_init(MONO_DEBUG_FORMAT_MONO); + CharString da_args = OS::get_singleton()->get_environment("GODOT_MONO_DEBUGGER_AGENT").utf8(); + +#ifdef TOOLS_ENABLED int da_port = GLOBAL_DEF("mono/debugger_agent/port", 23685); bool da_suspend = GLOBAL_DEF("mono/debugger_agent/wait_for_debugger", false); int da_timeout = GLOBAL_DEF("mono/debugger_agent/wait_timeout", 3000); - CharString da_args = OS::get_singleton()->get_environment("GODOT_MONO_DEBUGGER_AGENT").utf8(); - -#ifdef TOOLS_ENABLED if (Engine::get_singleton()->is_editor_hint() || ProjectSettings::get_singleton()->get_resource_path().empty() || Main::is_project_manager()) { if (da_args.size() == 0) return; } -#endif if (da_args.length() == 0) { da_args = String("--debugger-agent=transport=dt_socket,address=127.0.0.1:" + itos(da_port) + ",embedding=1,server=y,suspend=" + (da_suspend ? "y,timeout=" + itos(da_timeout) : "n")) .utf8(); } +#else + if (da_args.length() == 0) + return; // Exported games don't use the project settings to setup the debugger agent +#endif // --debugger-agent=help const char *options[] = { @@ -761,7 +764,9 @@ bool GDMono::_try_load_api_assemblies() { void GDMono::_load_api_assemblies() { - if (!_try_load_api_assemblies()) { + bool api_assemblies_loaded = _try_load_api_assemblies(); + + if (!api_assemblies_loaded) { #ifdef TOOLS_ENABLED // The API assemblies are out of sync. Fine, try one more time, but this time // update them from the prebuilt assemblies directory before trying to load them. @@ -782,28 +787,30 @@ void GDMono::_load_api_assemblies() { CRASH_COND_MSG(domain_load_err != OK, "Mono: Failed to load scripts domain."); // 4. Try loading the updated assemblies - if (!_try_load_api_assemblies()) { - // welp... too bad - - if (_are_api_assemblies_out_of_sync()) { - if (core_api_assembly_out_of_sync) { - ERR_PRINT("The assembly '" CORE_API_ASSEMBLY_NAME "' is out of sync."); - } else if (!GDMonoUtils::mono_cache.godot_api_cache_updated) { - ERR_PRINT("The loaded assembly '" CORE_API_ASSEMBLY_NAME "' is in sync, but the cache update failed."); - } - - if (editor_api_assembly_out_of_sync) { - ERR_PRINT("The assembly '" EDITOR_API_ASSEMBLY_NAME "' is out of sync."); - } - - CRASH_NOW(); - } else { - CRASH_NOW_MSG("Failed to load one of the API assemblies."); + api_assemblies_loaded = _try_load_api_assemblies(); +#endif + } + + if (!api_assemblies_loaded) { + // welp... too bad + + if (_are_api_assemblies_out_of_sync()) { + if (core_api_assembly_out_of_sync) { + ERR_PRINT("The assembly '" CORE_API_ASSEMBLY_NAME "' is out of sync."); + } else if (!GDMonoUtils::mono_cache.godot_api_cache_updated) { + ERR_PRINT("The loaded assembly '" CORE_API_ASSEMBLY_NAME "' is in sync, but the cache update failed."); + } + +#ifdef TOOLS_ENABLED + if (editor_api_assembly_out_of_sync) { + ERR_PRINT("The assembly '" EDITOR_API_ASSEMBLY_NAME "' is out of sync."); } - } -#else - CRASH_NOW_MSG("Failed to load one of the API assemblies."); #endif + + CRASH_NOW(); + } else { + CRASH_NOW_MSG("Failed to load one of the API assemblies."); + } } } diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 04278b2902..39c5759871 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -1742,6 +1742,12 @@ void Viewport::_gui_input_event(Ref<InputEvent> p_event) { return; // no one gets the event if exclusive NO ONE } + if (mb->get_button_index() == BUTTON_WHEEL_UP || mb->get_button_index() == BUTTON_WHEEL_DOWN || mb->get_button_index() == BUTTON_WHEEL_LEFT || mb->get_button_index() == BUTTON_WHEEL_RIGHT) { + //cancel scroll wheel events, only clicks should trigger focus changes. + set_input_as_handled(); + return; + } + top->notification(Control::NOTIFICATION_MODAL_CLOSE); top->_modal_stack_remove(); top->hide(); |