diff options
-rw-r--r-- | DONORS.md | 76 | ||||
-rw-r--r-- | core/list.h | 3 | ||||
-rw-r--r-- | doc/classes/@GDScript.xml | 10 | ||||
-rw-r--r-- | doc/classes/InputEventKey.xml | 2 | ||||
-rw-r--r-- | doc/classes/OS.xml | 9 | ||||
-rw-r--r-- | doc/classes/Particles.xml | 3 | ||||
-rw-r--r-- | editor/editor_data.cpp | 1 | ||||
-rw-r--r-- | editor/editor_node.cpp | 42 | ||||
-rw-r--r-- | editor/editor_node.h | 11 | ||||
-rw-r--r-- | editor/filesystem_dock.cpp | 31 | ||||
-rw-r--r-- | editor/filesystem_dock.h | 1 | ||||
-rw-r--r-- | editor/plugins/tile_map_editor_plugin.cpp | 65 | ||||
-rw-r--r-- | editor/script_editor_debugger.cpp | 7 | ||||
-rw-r--r-- | modules/mono/SCsub | 5 | ||||
-rw-r--r-- | modules/mono/build_scripts/mono_configure.py | 8 | ||||
-rw-r--r-- | modules/mono/config.py | 10 | ||||
-rw-r--r-- | platform/osx/os_osx.h | 1 | ||||
-rw-r--r-- | platform/osx/os_osx.mm | 128 | ||||
-rw-r--r-- | scene/gui/graph_node.cpp | 4 | ||||
-rw-r--r-- | scene/gui/line_edit.cpp | 2 | ||||
-rw-r--r-- | scene/gui/text_edit.cpp | 2 | ||||
-rw-r--r-- | scene/gui/tree.cpp | 6 | ||||
-rw-r--r-- | scene/resources/default_theme/default_theme.cpp | 12 |
23 files changed, 290 insertions, 149 deletions
@@ -17,25 +17,24 @@ generous deed immortalized in the next stable release of Godot Engine. ## Gold sponsors Gamblify <https://www.gamblify.com> - Image Campus <https://www.imagecampus.edu.ar> ## Mini sponsors Alan Beauchamp + Aleksandar Kordic Anandarup Mallik Andrew Dunai Brandon Lamb + Christian Chipont Christian Uldall Pedersen Christoph Woinke - Connor Hill Denis Malyavin Edward Flick GameDev.net GameDev.tv Hein-Pieter van Braam Jacob McKenney - Javary Games - Jay Sistar + Javary Co. Justin Arnold Kyle Szklenski Leonard Meagher @@ -44,15 +43,13 @@ generous deed immortalized in the next stable release of Godot Engine. Mike King Neal Gompa (Conan Kudo) Patrick Aarstad - "Rainway " Slobodan Milnovic - StarFlare Software Stephan Lanfermann Stephen Telford Steve - TigerJ VilliHaukka Xananax + Y8.com Zashi ## Gold donors @@ -77,12 +74,14 @@ generous deed immortalized in the next stable release of Godot Engine. Andreas Schüle Asher Glick Austen McRae + Brian van der Stel + Carlo Cabanilla Daniel James David Giardi - David Graham Edward E Florian Breisch Gero + Javier Roman Jay Horton Jon Smith Jon Woodward @@ -107,12 +106,12 @@ generous deed immortalized in the next stable release of Godot Engine. William Wold Wyatt Goodin + Alex Khayrullin Chris Goddard Chris Serino Christian Padilla Conrad Curry Craig Smith - Daniel Egger Dean Harmon Ian Richard Kunert Ivan Trombley @@ -135,17 +134,18 @@ generous deed immortalized in the next stable release of Godot Engine. Wojciech Chojnacki Xavier PATRICELLI + Adam Neumann Alessandra Pereyra + Alexander J Maynard Alexey Dyadchenko Andrew Bowen Asdf - Benjamin W Flint + Ben Botwin Carlos de Sousa Marques Chris Petrich Christian Leth Jeppesen Christoph Schröder Cody Parker - ComicSads D Daniel Daniel Eichler @@ -163,6 +163,8 @@ generous deed immortalized in the next stable release of Godot Engine. Guilherme Felipe de C. G. da Silva Heath Hayes Hysteria + Idzard Kwadijk + Jared White Jose Malheiro Joshua Flores Juan T Chen @@ -173,7 +175,6 @@ generous deed immortalized in the next stable release of Godot Engine. Leandro Voltolino Maarten Elings Malcolm Peralty - Marius Kamm Markus Fehr Markus Wiesner Martin Eigel @@ -184,6 +185,7 @@ generous deed immortalized in the next stable release of Godot Engine. M H Nick Nikitin Oliver Dick + Paolo Munoz Paul Hocker Paul Von Zimmerman Pete Goodwin @@ -197,7 +199,6 @@ generous deed immortalized in the next stable release of Godot Engine. Urho WytRabbit Xavier Fumado Beltran - yuanzhe zhou ## Silver donors @@ -208,6 +209,7 @@ generous deed immortalized in the next stable release of Godot Engine. Adam Nakonieczny Adam Smeltzer Adisibio + Agustinus Arya Aidan O'Flannagain Alder Stefano Alessandro Senese @@ -231,21 +233,23 @@ generous deed immortalized in the next stable release of Godot Engine. Benedikt Ben Phelan Ben Vercammen + Ben Woodley + Berbank Bernd Jänichen Black Block Blair Allen Bobby CC Wong Boyquotes - Branwen Zak + Branwyn Tylwyth Bryan Stevenson - Carl Winder Carwyn Edwards Chris Brown Chris Chapin + Chris Gonzales Christian Baune Christian Winter Christoffer Sundbom - Christopher Fisher + Christopher Schmitt Chris Wilson Clay Heaton Cobaltum @@ -262,7 +266,6 @@ generous deed immortalized in the next stable release of Godot Engine. Dominik Wetzel Duobix Edward Herbert - E.G. Egon Elbre Ellen Marie Dash Elmeri '- Duy Kevin Nguyen @@ -271,30 +274,33 @@ generous deed immortalized in the next stable release of Godot Engine. Eric Martini Eric McCarthy Eric Williams - Fabian Lökes + Evan Rose Felix Kollmann fengjiongmax - Foomf + Flaredown G3Dev sàrl Gary Hulst Gerrit Großkopf gmmath Grant Clarke Greg Olson - Greg Pennefather + Greg P Guldoman Heribert Hirth Hiroshi Naruo HMan Hunter Jones + Hylpher ialex32x Igor Buzatovic Iiari + IndustrialRobot Isaac Morton Jaime Ruiz-Borau Vizárraga Jako Danar James A F Manley Jax + Jed Jeff Hungerford Jeff Nyte Jeremy Kahn @@ -302,6 +308,7 @@ generous deed immortalized in the next stable release of Godot Engine. Joe Alden Joel Fivat Joel Setterberg + Johannes Eichler Johannes Wuensch Jonas Rudlang Jonas Yamazaki @@ -316,6 +323,7 @@ generous deed immortalized in the next stable release of Godot Engine. Juan Negrier Judd Julian Murgia + Kasier Bald0 KC Chan kickmaniac Kiyohiro Kawamura (kyorohiro) @@ -324,22 +332,24 @@ generous deed immortalized in the next stable release of Godot Engine. KsyTek Games Kuan Cheang kycho + Lavik1988 Levi Lindsey Linus Lind Lundgren Lionel Gaillard Luis Moraes + LunaticInAHat + Lurkars Macil - magodev Major Haul Malcolm Malik Ahmed + Malik Nejer + Marcus Richter Markus Michael Egger Martin Holas Matthew Little Maxwell medecau - Menno Finlay-Smits - Mertcan Mermerkaya mhilbrunner Michael Dürwald Michael Gringauz @@ -347,9 +357,9 @@ generous deed immortalized in the next stable release of Godot Engine. Mikael Olsson Mikayla Hutchinson Mike Cunningham + mlevin cantu MoM Moritz Laass - Moritz Weissenberger MuffinManKen Natrim nee @@ -360,6 +370,7 @@ generous deed immortalized in the next stable release of Godot Engine. Nicolas SAN AGUSTIN Nithin Jino NZ + Omar Delarosa Oscar Norlander Pan Ip Patrick Forringer @@ -370,30 +381,30 @@ generous deed immortalized in the next stable release of Godot Engine. Philip O. Staiger Pierre-Igor Berthet Pietro Vertechi - Piotr Kaczmarski Pitsanu Tongprasin Poryg + Rafa Laguna + Rafal Wyszomirski Raphael Leroux - Red Hara Rémi Verschelde Ricardo Alcantara - Rob Crowle Robert Farr (Larington) Robert Hernandez Rodrigo Loli - Roger Burgess Roger Smith Roland Rząsa Roman Tinkov Ryan Groom Ryan Hentz Saad Khoudmi - Samdze + Samuele Zolfanelli + Sanka.X Sasori Olkof Scott D. Yelich Sebastian Michailidis Shane Sicienski Shane Spoor + Simon Ledam Simon Wenner SK Sootstone @@ -408,13 +419,18 @@ generous deed immortalized in the next stable release of Godot Engine. Tim Drumheller Tim Gudex Timo Schmidt + Timothy B. MacDonald + Tobbun Tom Larrow Torsten Crass Travis O'Brien + Trent Skinner Tryggve Sollid - Tyler Strafos + Turgut Temucin + Tyler Stafos UltyX Vaiktorg + Valeria Viana Gusmao Veodok Victor Vigilant Watch diff --git a/core/list.h b/core/list.h index 103a82a31d..d1b528562d 100644 --- a/core/list.h +++ b/core/list.h @@ -602,9 +602,6 @@ public: Element *next = current->next_ptr; - //disconnect - current->next_ptr = NULL; - if (from != current) { current->prev_ptr = NULL; diff --git a/doc/classes/@GDScript.xml b/doc/classes/@GDScript.xml index 553fd4d629..b6de5dbf62 100644 --- a/doc/classes/@GDScript.xml +++ b/doc/classes/@GDScript.xml @@ -92,13 +92,13 @@ <argument index="0" name="condition" type="bool"> </argument> <description> - Assert that the [code]condition[/code] is [code]true[/code] . If the [code]condition[/code] is [code]false[/code] a fatal error is generated and the program is halted. Useful for debugging to make sure a value is always [code]true[/code]. + Asserts that the [code]condition[/code] is [code]true[/code] . If the [code]condition[/code] is [code]false[/code], an error is generated and the program is halted until you resume it. Only executes in debug builds, or when running the game from the editor. Use it for debugging purposes, to make sure a statement is [code]true[/code] during development. [codeblock] - # Speed should always be between 0 and 20 + # Imagine we always want speed to be between 0 and 20 speed = -10 - assert(speed < 20) # Is true and program continues - assert(speed >= 0) # Is false and program stops - assert(speed >= 0 && speed < 20) # Or combined + assert(speed < 20) # True, the program will continue + assert(speed >= 0) # False, the program will stop + assert(speed >= 0 && speed < 20) # You can also combine the two conditional statements in one check [/codeblock] </description> </method> diff --git a/doc/classes/InputEventKey.xml b/doc/classes/InputEventKey.xml index 86a1362230..53b1f74bd4 100644 --- a/doc/classes/InputEventKey.xml +++ b/doc/classes/InputEventKey.xml @@ -29,7 +29,7 @@ Key scancode, one of the [enum KeyList] constants. </member> <member name="unicode" type="int" setter="set_unicode" getter="get_unicode"> - Key unicode identifier when relevant. + Key unicode identifier when relevant. Unicode identifiers for the composite characters and complex scripts may not be available unless IME input mode is active. See [method OS.set_ime_active] for more information. </member> </members> <constants> diff --git a/doc/classes/OS.xml b/doc/classes/OS.xml index dd0fcd63e7..f7cd6c3e83 100644 --- a/doc/classes/OS.xml +++ b/doc/classes/OS.xml @@ -221,14 +221,16 @@ <return type="Vector2"> </return> <description> - Returns IME selection range. + Returns IME cursor position (currently edited portion of the string) relative to the characters in the composition string. + [code]NOTIFICATION_OS_IME_UPDATE[/code] is sent to the application to notify it of changes to the IME cursor position. </description> </method> <method name="get_ime_text" qualifiers="const"> <return type="String"> </return> <description> - Returns IME intermediate text. + Returns IME intermediate composition string. + [code]NOTIFICATION_OS_IME_UPDATE[/code] is sent to the application to notify it of changes to the IME composition string. </description> </method> <method name="get_latin_keyboard_variant" qualifiers="const"> @@ -710,6 +712,9 @@ </argument> <description> Sets whether IME input mode should be enabled. + If active IME handles key events before the application and creates an composition string and suggestion list. + Application can retrieve the composition status by using [method get_ime_selection] and [method get_ime_text] functions. + Completed composition string is committed when input is finished. </description> </method> <method name="set_ime_position"> diff --git a/doc/classes/Particles.xml b/doc/classes/Particles.xml index 0023fce97d..7820c63ad7 100644 --- a/doc/classes/Particles.xml +++ b/doc/classes/Particles.xml @@ -15,13 +15,14 @@ <return type="AABB"> </return> <description> + Returns the bounding box that contains all the particles that are active in the current frame. </description> </method> <method name="restart"> <return type="void"> </return> <description> - Restarts the particle emmission, clearing existing particles. + Restarts the particle emission, clearing existing particles. </description> </method> </methods> diff --git a/editor/editor_data.cpp b/editor/editor_data.cpp index f61a831015..38f30df169 100644 --- a/editor/editor_data.cpp +++ b/editor/editor_data.cpp @@ -560,6 +560,7 @@ void EditorData::move_edited_scene_index(int p_idx, int p_to_idx) { ERR_FAIL_INDEX(p_to_idx, edited_scene.size()); SWAP(edited_scene.write[p_idx], edited_scene.write[p_to_idx]); } + void EditorData::remove_scene(int p_idx) { ERR_FAIL_INDEX(p_idx, edited_scene.size()); if (edited_scene[p_idx].root) { diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 43c8ef60aa..969e1affd7 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -523,6 +523,7 @@ void EditorNode::_fs_changed() { void EditorNode::_resources_reimported(const Vector<String> &p_resources) { List<String> scenes; //will load later + int current_tab = scene_tabs->get_current_tab(); for (int i = 0; i < p_resources.size(); i++) { String file_type = ResourceLoader::get_resource_type(p_resources[i]); @@ -545,6 +546,8 @@ void EditorNode::_resources_reimported(const Vector<String> &p_resources) { for (List<String>::Element *E = scenes.front(); E; E = E->next()) { reload_scene(E->get()); } + + scene_tabs->set_current_tab(current_tab); } void EditorNode::_sources_changed(bool p_exist) { @@ -1214,6 +1217,17 @@ void EditorNode::save_all_scenes() { _save_all_scenes(); } +void EditorNode::save_scene_list(Vector<String> p_scene_filenames) { + + for (int i = 0; i < editor_data.get_edited_scene_count(); i++) { + Node *scene = editor_data.get_edited_scene_root(i); + + if (scene && (p_scene_filenames.find(scene->get_filename()) >= 0)) { + _save_scene(scene->get_filename(), i); + } + } +} + void EditorNode::restart_editor() { exiting = true; @@ -2859,7 +2873,7 @@ bool EditorNode::is_addon_plugin_enabled(const String &p_addon) const { return plugin_addons.has(p_addon); } -void EditorNode::_remove_edited_scene() { +void EditorNode::_remove_edited_scene(bool p_change_tab) { int new_index = editor_data.get_edited_scene(); int old_index = new_index; @@ -2875,18 +2889,19 @@ void EditorNode::_remove_edited_scene() { if (editor_data.get_scene_path(old_index) != String()) { ScriptEditor::get_singleton()->close_builtin_scripts_from_scene(editor_data.get_scene_path(old_index)); } - _scene_tab_changed(new_index); + + if (p_change_tab) _scene_tab_changed(new_index); editor_data.remove_scene(old_index); editor_data.get_undo_redo().clear_history(false); _update_title(); _update_scene_tabs(); } -void EditorNode::_remove_scene(int index) { +void EditorNode::_remove_scene(int index, bool p_change_tab) { if (editor_data.get_edited_scene() == index) { //Scene to remove is current scene - _remove_edited_scene(); + _remove_edited_scene(p_change_tab); } else { //Scene to remove is not active scene editor_data.remove_scene(index); @@ -4182,6 +4197,14 @@ bool EditorNode::ensure_main_scene(bool p_from_native) { return true; } +int EditorNode::get_current_tab() { + return scene_tabs->get_current_tab(); +} + +void EditorNode::set_current_tab(int p_tab) { + scene_tabs->set_current_tab(p_tab); +} + void EditorNode::_update_layouts_menu() { editor_layouts->clear(); @@ -4809,8 +4832,7 @@ void EditorNode::reload_scene(const String &p_path) { if (scene_idx == -1) { if (get_edited_scene()) { - //scene is not open, so at it might be instanced, just refresh, set tab to itself and it will reload - set_current_scene(current_tab); + //scene is not open, so at it might be instanced. We'll refresh the whole scene later. editor_data.get_undo_redo().clear_history(); } return; @@ -4820,17 +4842,19 @@ void EditorNode::reload_scene(const String &p_path) { editor_data.apply_changes_in_editors(); _set_scene_metadata(p_path); } + //remove scene - _remove_scene(scene_idx); - //reload scene + _remove_scene(scene_idx, false); + //reload scene load_scene(p_path, true, false, true, true); + //adjust index so tab is back a the previous position editor_data.move_edited_scene_to_index(scene_idx); get_undo_redo()->clear_history(); + //recover the tab scene_tabs->set_current_tab(current_tab); - _scene_tab_changed(current_tab); } int EditorNode::plugin_init_callback_count = 0; diff --git a/editor/editor_node.h b/editor/editor_node.h index ea988cb134..f3bc95c409 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -525,8 +525,8 @@ private: static void _editor_file_dialog_unregister(EditorFileDialog *p_dialog); void _cleanup_scene(); - void _remove_edited_scene(); - void _remove_scene(int index); + void _remove_edited_scene(bool p_change_tab = true); + void _remove_scene(int index, bool p_change_tab = true); bool _find_and_save_resource(RES p_res, Map<RES, bool> &processed, int32_t flags); bool _find_and_save_edited_subresources(Object *obj, Map<RES, bool> &processed, int32_t flags); void _save_edited_subresources(Node *scene, Map<RES, bool> &processed, int32_t flags); @@ -644,6 +644,12 @@ protected: void _notification(int p_what); static void _bind_methods(); +protected: + friend class FileSystemDock; + + int get_current_tab(); + void set_current_tab(int p_tab); + public: bool call_build(); @@ -815,6 +821,7 @@ public: void remove_tool_menu_item(const String &p_name); void save_all_scenes(); + void save_scene_list(Vector<String> p_scene_filenames); void restart_editor(); void dim_editor(bool p_dimming); diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp index 6a4d9fea0c..ee88b558c8 100644 --- a/editor/filesystem_dock.cpp +++ b/editor/filesystem_dock.cpp @@ -1203,6 +1203,21 @@ void FileSystemDock::_update_favorites_list_after_move(const Map<String, String> EditorSettings::get_singleton()->set_favorites(new_favorites); } +void FileSystemDock::_save_scenes_after_move(const Map<String, String> &p_renames) const { + Vector<String> remaps; + _find_remaps(EditorFileSystem::get_singleton()->get_filesystem(), p_renames, remaps); + Vector<String> new_filenames; + + for (int i = 0; i < remaps.size(); ++i) { + String file = p_renames.has(remaps[i]) ? p_renames[remaps[i]] : remaps[i]; + if (ResourceLoader::get_resource_type(file) == "PackedScene") { + new_filenames.push_back(file); + } + } + + editor->save_scene_list(new_filenames); +} + void FileSystemDock::_make_dir_confirm() { String dir_name = make_dir_dialog_text->get_text().strip_edges(); @@ -1281,14 +1296,21 @@ void FileSystemDock::_rename_operation_confirm() { Map<String, String> file_renames; Map<String, String> folder_renames; _try_move_item(to_rename, new_path, file_renames, folder_renames); + + int current_tab = editor->get_current_tab(); + _update_dependencies_after_move(file_renames); _update_resource_paths_after_move(file_renames); _update_project_settings_after_move(file_renames); _update_favorites_list_after_move(file_renames, folder_renames); - //Rescan everything + editor->set_current_tab(current_tab); + print_verbose("FileSystem: calling rescan."); _rescan(); + + print_verbose("FileSystem: saving moved scenes."); + _save_scenes_after_move(file_renames); } void FileSystemDock::_duplicate_operation_confirm() { @@ -1384,13 +1406,20 @@ void FileSystemDock::_move_operation_confirm(const String &p_to_path, bool overw } if (is_moved) { + int current_tab = editor->get_current_tab(); + _update_dependencies_after_move(file_renames); _update_resource_paths_after_move(file_renames); _update_project_settings_after_move(file_renames); _update_favorites_list_after_move(file_renames, folder_renames); + editor->set_current_tab(current_tab); + print_verbose("FileSystem: calling rescan."); _rescan(); + + print_verbose("FileSystem: saving moved scenes."); + _save_scenes_after_move(file_renames); } } diff --git a/editor/filesystem_dock.h b/editor/filesystem_dock.h index 978235b328..46eaf71a8a 100644 --- a/editor/filesystem_dock.h +++ b/editor/filesystem_dock.h @@ -202,6 +202,7 @@ private: void _try_duplicate_item(const FileOrFolder &p_item, const String &p_new_path) const; void _update_dependencies_after_move(const Map<String, String> &p_renames) const; void _update_resource_paths_after_move(const Map<String, String> &p_renames) const; + void _save_scenes_after_move(const Map<String, String> &p_renames) const; void _update_favorites_list_after_move(const Map<String, String> &p_files_renames, const Map<String, String> &p_folders_renames) const; void _update_project_settings_after_move(const Map<String, String> &p_folders_renames) const; diff --git a/editor/plugins/tile_map_editor_plugin.cpp b/editor/plugins/tile_map_editor_plugin.cpp index 4ef2d17128..3f513de30f 100644 --- a/editor/plugins/tile_map_editor_plugin.cpp +++ b/editor/plugins/tile_map_editor_plugin.cpp @@ -299,9 +299,13 @@ void TileMapEditor::_set_cell(const Point2i &p_pos, Vector<int> p_values, bool p Vector2 position; int current = manual_palette->get_current(); if (current != -1) { - position = manual_palette->get_item_metadata(current); + if (tool != TOOL_PASTING) { + position = manual_palette->get_item_metadata(current); + } else { + position = p_autotile_coord; + } } else { - // if there is no manual tile selected, that either means that + // If there is no manual tile selected, that either means that // autotiling is enabled, or the given tile is not autotiling. Either // way, the coordinate of the tile does not matter, so assigning it to // the coordinate of the existing tile works fine. @@ -309,7 +313,7 @@ void TileMapEditor::_set_cell(const Point2i &p_pos, Vector<int> p_values, bool p } if (p_value == prev_val && p_flip_h == prev_flip_h && p_flip_v == prev_flip_v && p_transpose == prev_transpose && prev_position == position) - return; //check that it's actually different + return; // Check that it's actually different. for (int y = p_pos.y - 1; y <= p_pos.y + 1; y++) { for (int x = p_pos.x - 1; x <= p_pos.x + 1; x++) { @@ -322,21 +326,19 @@ void TileMapEditor::_set_cell(const Point2i &p_pos, Vector<int> p_values, bool p node->_set_celld(p_pos, _create_cell_dictionary(p_value, p_flip_h, p_flip_v, p_transpose, p_autotile_coord)); + if (tool == TOOL_PASTING) + return; + if (manual_autotile || (p_value != -1 && node->get_tileset()->tile_get_tile_mode(p_value) == TileSet::ATLAS_TILE)) { if (current != -1) { node->set_cell_autotile_coord(p_pos.x, p_pos.y, position); - - } else if (tool != TOOL_PASTING && node->get_tileset()->tile_get_tile_mode(p_value) == TileSet::ATLAS_TILE && priority_atlastile) { - - // BIND_CENTER is used to indicate that bitmask should not update for this tile cell + } else if (node->get_tileset()->tile_get_tile_mode(p_value) == TileSet::ATLAS_TILE && priority_atlastile) { + // BIND_CENTER is used to indicate that bitmask should not update for this tile cell. node->get_tileset()->autotile_set_bitmask(p_value, Vector2(p_pos.x, p_pos.y), TileSet::BIND_CENTER); node->update_cell_bitmask(p_pos.x, p_pos.y); } } else { - // manually placing tiles should not update bitmasks - if (tool != TOOL_PASTING) { - node->update_bitmask_area(Point2(p_pos)); - } + node->update_bitmask_area(Point2(p_pos)); } } @@ -396,6 +398,8 @@ void TileMapEditor::_update_palette() { // Update the palette Vector<int> selected = get_selected_tiles(); + int selected_single = palette->get_current(); + int selected_manual = manual_palette->get_current(); palette->clear(); manual_palette->clear(); manual_palette->hide(); @@ -503,7 +507,7 @@ void TileMapEditor::_update_palette() { if (selected.get(0) != TileMap::INVALID_CELL) { set_selected_tiles(selected); sel_tile = selected.get(Math::rand() % selected.size()); - } else { + } else if (palette->get_item_count() > 0) { palette->select(0); } @@ -545,9 +549,10 @@ void TileMapEditor::_update_palette() { if (manual_palette->get_item_count() > 0) { // Only show the manual palette if at least tile exists in it - int selected2 = manual_palette->get_current(); - if (selected2 == -1) selected2 = 0; - manual_palette->set_current(selected2); + if (selected_manual == -1 || selected_single != palette->get_current()) + selected_manual = 0; + if (selected_manual < manual_palette->get_item_count()) + manual_palette->set_current(selected_manual); manual_palette->show(); } @@ -759,15 +764,15 @@ void TileMapEditor::_draw_cell(Control *p_viewport, int p_cell, const Point2i &p Rect2 r = node->get_tileset()->tile_get_region(p_cell); if (node->get_tileset()->tile_get_tile_mode(p_cell) == TileSet::AUTO_TILE || node->get_tileset()->tile_get_tile_mode(p_cell) == TileSet::ATLAS_TILE) { Vector2 offset; - int selected = manual_palette->get_current(); - if ((manual_autotile || (node->get_tileset()->tile_get_tile_mode(p_cell) == TileSet::ATLAS_TILE && !priority_atlastile)) && selected != -1) { - offset = manual_palette->get_item_metadata(selected); - } else { - if (tool != TOOL_PASTING) { - offset = node->get_tileset()->autotile_get_icon_coordinate(p_cell); + if (tool != TOOL_PASTING) { + int selected = manual_palette->get_current(); + if ((manual_autotile || (node->get_tileset()->tile_get_tile_mode(p_cell) == TileSet::ATLAS_TILE && !priority_atlastile)) && selected != -1) { + offset = manual_palette->get_item_metadata(selected); } else { - offset = p_autotile_coord; + offset = node->get_tileset()->autotile_get_icon_coordinate(p_cell); } + } else { + offset = p_autotile_coord; } int spacing = node->get_tileset()->autotile_get_spacing(p_cell); @@ -810,10 +815,11 @@ void TileMapEditor::_draw_cell(Control *p_viewport, int p_cell, const Point2i &p Color modulate = node->get_tileset()->tile_get_modulate(p_cell); modulate.a = 0.5; - if (r.has_no_area()) + if (r.has_no_area()) { p_viewport->draw_texture_rect(t, rect, false, modulate, p_transpose); - else + } else { p_viewport->draw_texture_rect_region(t, rect, r, modulate, p_transpose); + } } void TileMapEditor::_draw_fill_preview(Control *p_viewport, int p_cell, const Point2i &p_point, bool p_flip_h, bool p_flip_v, bool p_transpose, const Point2i p_autotile_coord, const Transform2D &p_xform) { @@ -848,7 +854,6 @@ void TileMapEditor::_update_copydata() { TileData tcd; tcd.cell = node->get_cell(j, i); - if (tcd.cell != TileMap::INVALID_CELL) { tcd.pos = Point2i(j, i); tcd.flip_h = node->is_cell_x_flipped(j, i); @@ -1980,31 +1985,31 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) { p->connect("id_pressed", this, "_menu_option"); rotate_left_button = memnew(ToolButton); - rotate_left_button->set_tooltip(TTR("Rotate left")); + rotate_left_button->set_tooltip(TTR("Rotate Left")); rotate_left_button->set_focus_mode(FOCUS_NONE); rotate_left_button->connect("pressed", this, "_rotate", varray(-1)); tool_hb->add_child(rotate_left_button); rotate_right_button = memnew(ToolButton); - rotate_right_button->set_tooltip(TTR("Rotate right")); + rotate_right_button->set_tooltip(TTR("Rotate Right")); rotate_right_button->set_focus_mode(FOCUS_NONE); rotate_right_button->connect("pressed", this, "_rotate", varray(1)); tool_hb->add_child(rotate_right_button); flip_horizontal_button = memnew(ToolButton); - flip_horizontal_button->set_tooltip(TTR("Flip horizontally")); + flip_horizontal_button->set_tooltip(TTR("Flip Horizontally")); flip_horizontal_button->set_focus_mode(FOCUS_NONE); flip_horizontal_button->connect("pressed", this, "_flip_horizontal"); tool_hb->add_child(flip_horizontal_button); flip_vertical_button = memnew(ToolButton); - flip_vertical_button->set_tooltip(TTR("Flip vertically")); + flip_vertical_button->set_tooltip(TTR("Flip Vertically")); flip_vertical_button->set_focus_mode(FOCUS_NONE); flip_vertical_button->connect("pressed", this, "_flip_vertical"); tool_hb->add_child(flip_vertical_button); clear_transform_button = memnew(ToolButton); - clear_transform_button->set_tooltip(TTR("Clear transform")); + clear_transform_button->set_tooltip(TTR("Clear Transform")); clear_transform_button->set_focus_mode(FOCUS_NONE); clear_transform_button->connect("pressed", this, "_clear_transform"); tool_hb->add_child(clear_transform_button); diff --git a/editor/script_editor_debugger.cpp b/editor/script_editor_debugger.cpp index 621ab039f4..c3b62810f1 100644 --- a/editor/script_editor_debugger.cpp +++ b/editor/script_editor_debugger.cpp @@ -1025,7 +1025,9 @@ void ScriptEditorDebugger::_performance_draw() { int pi = which[i]; Color c = get_color("accent_color", "Editor"); float h = (float)which[i] / (float)(perf_items.size()); - c.set_hsv(Math::fmod(h + 0.4, 0.9), c.get_s() * 0.9, c.get_v() * 1.4); + // Use a darker color on light backgrounds for better visibility + float value_multiplier = EditorSettings::get_singleton()->is_dark_theme() ? 1.4 : 0.55; + c.set_hsv(Math::fmod(h + 0.4, 0.9), c.get_s() * 0.9, c.get_v() * value_multiplier); c.a = 0.6; perf_draw->draw_string(graph_font, r.position + Point2(0, graph_font->get_ascent()), perf_items[pi]->get_text(0), c, r.size.x); @@ -1045,9 +1047,8 @@ void ScriptEditorDebugger::_performance_draw() { float h2 = E->get()[pi] / m; h2 = (1.0 - h2) * r.size.y; - c.a = 0.7; if (E != perf_history.front()) - perf_draw->draw_line(r.position + Point2(from, h2), r.position + Point2(from + spacing, prev), c, 2.0); + perf_draw->draw_line(r.position + Point2(from, h2), r.position + Point2(from + spacing, prev), c, Math::round(EDSCALE), true); prev = h2; E = E->next(); from -= spacing; diff --git a/modules/mono/SCsub b/modules/mono/SCsub index 341d57f3e4..6c3ecee272 100644 --- a/modules/mono/SCsub +++ b/modules/mono/SCsub @@ -20,11 +20,6 @@ if env['tools']: 'glue/cs_glue_version.gen.h' ) -vars = Variables() -vars.Add(BoolVariable('mono_glue', 'Build with the mono glue sources', True)) -vars.Add(BoolVariable('xbuild_fallback', 'If MSBuild is not found, fallback to xbuild', False)) -vars.Update(env_mono) - # Glue sources if env_mono['mono_glue']: env_mono.Append(CPPDEFINES=['MONO_GLUE_ENABLED']) diff --git a/modules/mono/build_scripts/mono_configure.py b/modules/mono/build_scripts/mono_configure.py index 2bce3ed376..c549640d61 100644 --- a/modules/mono/build_scripts/mono_configure.py +++ b/modules/mono/build_scripts/mono_configure.py @@ -47,14 +47,6 @@ def copy_file(src_dir, dst_dir, name): def configure(env, env_mono): - from SCons.Script import BoolVariable, PathVariable, Variables - - envvars = Variables() - envvars.Add(PathVariable('mono_prefix', 'Path to the mono installation directory for the target platform and architecture', '', PathVariable.PathAccept)) - envvars.Add(BoolVariable('mono_static', 'Statically link mono', False)) - envvars.Add(BoolVariable('copy_mono_root', 'Make a copy of the mono installation directory to bundle with the editor', False)) - envvars.Update(env) - bits = env['bits'] is_android = env['platform'] == 'android' diff --git a/modules/mono/config.py b/modules/mono/config.py index 3b2e96765e..9adf4ee6e5 100644 --- a/modules/mono/config.py +++ b/modules/mono/config.py @@ -8,6 +8,16 @@ def configure(env): env.use_ptrcall = True env.add_module_version_string('mono') + from SCons.Script import BoolVariable, PathVariable, Variables + + envvars = Variables() + envvars.Add(PathVariable('mono_prefix', 'Path to the mono installation directory for the target platform and architecture', '', PathVariable.PathAccept)) + envvars.Add(BoolVariable('mono_static', 'Statically link mono', False)) + envvars.Add(BoolVariable('mono_glue', 'Build with the mono glue sources', True)) + envvars.Add(BoolVariable('copy_mono_root', 'Make a copy of the mono installation directory to bundle with the editor', False)) + envvars.Add(BoolVariable('xbuild_fallback', 'If MSBuild is not found, fallback to xbuild', False)) + envvars.Update(env) + def get_doc_classes(): return [ diff --git a/platform/osx/os_osx.h b/platform/osx/os_osx.h index 212966af11..eed230ba89 100644 --- a/platform/osx/os_osx.h +++ b/platform/osx/os_osx.h @@ -60,6 +60,7 @@ public: unsigned int osx_state; bool pressed; bool echo; + bool raw; uint32_t scancode; uint32_t unicode; }; diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm index 113c6636f0..567d24de3e 100644 --- a/platform/osx/os_osx.mm +++ b/platform/osx/os_osx.mm @@ -392,7 +392,7 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt @interface GodotContentView : NSView <NSTextInputClient> { NSTrackingArea *trackingArea; NSMutableAttributedString *markedText; - bool imeMode; + bool imeInputEventInProgress; } - (void)cancelComposition; - (BOOL)wantsUpdateLayer; @@ -418,7 +418,7 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt - (id)init { self = [super init]; trackingArea = nil; - imeMode = false; + imeInputEventInProgress = false; [self updateTrackingAreas]; [self registerForDraggedTypes:[NSArray arrayWithObject:NSFilenamesPboardType]]; markedText = [[NSMutableAttributedString alloc] init]; @@ -452,7 +452,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; [markedText initWithString:aString]; } if (OS_OSX::singleton->im_active) { - imeMode = true; + imeInputEventInProgress = true; OS_OSX::singleton->im_text.parse_utf8([[markedText mutableString] UTF8String]); OS_OSX::singleton->im_selection = Point2(selectedRange.location, selectedRange.length); @@ -467,7 +467,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; } - (void)unmarkText { - imeMode = false; + imeInputEventInProgress = false; [[markedText mutableString] setString:@""]; if (OS_OSX::singleton->im_active) { OS_OSX::singleton->im_text = String(); @@ -540,6 +540,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; ke.osx_state = [event modifierFlags]; ke.pressed = true; ke.echo = false; + ke.raw = false; // IME input event ke.scancode = 0; ke.unicode = codepoint; @@ -1045,29 +1046,52 @@ static int remapKey(unsigned int key) { - (void)keyDown:(NSEvent *)event { - //disable raw input in IME mode - if (!imeMode) { - OS_OSX::KeyEvent ke; + // Ignore all input if IME input is in progress + if (!imeInputEventInProgress) { + NSString *characters = [event characters]; + NSUInteger length = [characters length]; - ke.osx_state = [event modifierFlags]; - ke.pressed = true; - ke.echo = [event isARepeat]; - ke.scancode = remapKey([event keyCode]); - ke.unicode = 0; + if (!OS_OSX::singleton->im_active && length > 0 && keycode_has_unicode(remapKey([event keyCode]))) { + // Fallback unicode character handler used if IME is not active + for (NSUInteger i = 0; i < length; i++) { + OS_OSX::KeyEvent ke; - push_to_key_event_buffer(ke); + ke.osx_state = [event modifierFlags]; + ke.pressed = true; + ke.echo = [event isARepeat]; + ke.scancode = remapKey([event keyCode]); + ke.raw = true; + ke.unicode = [characters characterAtIndex:i]; + + push_to_key_event_buffer(ke); + } + } else { + OS_OSX::KeyEvent ke; + + ke.osx_state = [event modifierFlags]; + ke.pressed = true; + ke.echo = [event isARepeat]; + ke.scancode = remapKey([event keyCode]); + ke.raw = false; + ke.unicode = 0; + + push_to_key_event_buffer(ke); + } } - if (OS_OSX::singleton->im_active == true) + // Pass events to IME handler + if (OS_OSX::singleton->im_active) [self interpretKeyEvents:[NSArray arrayWithObject:event]]; } - (void)flagsChanged:(NSEvent *)event { - if (!imeMode) { + // Ignore all input if IME input is in progress + if (!imeInputEventInProgress) { OS_OSX::KeyEvent ke; ke.echo = false; + ke.raw = true; int key = [event keyCode]; int mod = [event modifierFlags]; @@ -1114,17 +1138,37 @@ static int remapKey(unsigned int key) { - (void)keyUp:(NSEvent *)event { - if (!imeMode) { + // Ignore all input if IME input is in progress + if (!imeInputEventInProgress) { + NSString *characters = [event characters]; + NSUInteger length = [characters length]; - OS_OSX::KeyEvent ke; + // Fallback unicode character handler used if IME is not active + if (!OS_OSX::singleton->im_active && length > 0 && keycode_has_unicode(remapKey([event keyCode]))) { + for (NSUInteger i = 0; i < length; i++) { + OS_OSX::KeyEvent ke; - ke.osx_state = [event modifierFlags]; - ke.pressed = false; - ke.echo = false; - ke.scancode = remapKey([event keyCode]); - ke.unicode = 0; + ke.osx_state = [event modifierFlags]; + ke.pressed = false; + ke.echo = [event isARepeat]; + ke.scancode = remapKey([event keyCode]); + ke.raw = true; + ke.unicode = [characters characterAtIndex:i]; - push_to_key_event_buffer(ke); + push_to_key_event_buffer(ke); + } + } else { + OS_OSX::KeyEvent ke; + + ke.osx_state = [event modifierFlags]; + ke.pressed = false; + ke.echo = [event isARepeat]; + ke.scancode = remapKey([event keyCode]); + ke.raw = true; + ke.unicode = 0; + + push_to_key_event_buffer(ke); + } } } @@ -2612,30 +2656,44 @@ void OS_OSX::process_key_events() { const KeyEvent &ke = key_event_buffer[i]; - if ((i == 0 && ke.scancode == 0) || (i > 0 && key_event_buffer[i - 1].scancode == 0)) { + if (ke.raw) { + // Non IME input - no composite characters, pass events as is k.instance(); get_key_modifier_state(ke.osx_state, k); k->set_pressed(ke.pressed); k->set_echo(ke.echo); - k->set_scancode(0); + k->set_scancode(ke.scancode); k->set_unicode(ke.unicode); push_input(k); - } - if (ke.scancode != 0) { - k.instance(); + } else { + // IME input + if ((i == 0 && ke.scancode == 0) || (i > 0 && key_event_buffer[i - 1].scancode == 0)) { + k.instance(); - get_key_modifier_state(ke.osx_state, k); - k->set_pressed(ke.pressed); - k->set_echo(ke.echo); - k->set_scancode(ke.scancode); + get_key_modifier_state(ke.osx_state, k); + k->set_pressed(ke.pressed); + k->set_echo(ke.echo); + k->set_scancode(0); + k->set_unicode(ke.unicode); - if (i + 1 < key_event_pos && key_event_buffer[i + 1].scancode == 0) { - k->set_unicode(key_event_buffer[i + 1].unicode); + push_input(k); } + if (ke.scancode != 0) { + k.instance(); - push_input(k); + get_key_modifier_state(ke.osx_state, k); + k->set_pressed(ke.pressed); + k->set_echo(ke.echo); + k->set_scancode(ke.scancode); + + if (i + 1 < key_event_pos && key_event_buffer[i + 1].scancode == 0) { + k->set_unicode(key_event_buffer[i + 1].unicode); + } + + push_input(k); + } } } diff --git a/scene/gui/graph_node.cpp b/scene/gui/graph_node.cpp index e8692d56d2..6463ee5ad5 100644 --- a/scene/gui/graph_node.cpp +++ b/scene/gui/graph_node.cpp @@ -159,9 +159,7 @@ void GraphNode::_resort() { fit_child_in_rect(c, r); cache_y.push_back(vofs + size.y * 0.5); - if (vofs > 0) - vofs += sep; - vofs += size.y; + vofs += size.y + sep; } update(); diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index cc966efee9..58bdde1ffd 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -44,7 +44,7 @@ static bool _is_text_char(CharType c) { - return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_'; + return !is_symbol(c); } void LineEdit::_gui_input(Ref<InputEvent> p_event) { diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 3117d8c59f..6203b15992 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -50,7 +50,7 @@ inline bool _is_symbol(CharType c) { static bool _is_text_char(CharType c) { - return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_'; + return !is_symbol(c); } static bool _is_whitespace(CharType c) { diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index 474eb51860..2007ae2669 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -3532,14 +3532,14 @@ TreeItem *Tree::_search_item_text(TreeItem *p_at, const String &p_find, int *r_c TreeItem *Tree::search_item_text(const String &p_find, int *r_col, bool p_selectable) { - TreeItem *from = get_selected()->get_next_visible(); + TreeItem *from = get_selected(); - if (!root) + if (!from) from = root; if (!from) return NULL; - return _search_item_text(from, p_find, r_col, p_selectable); + return _search_item_text(from->get_next_visible(true), p_find, r_col, p_selectable); } void Tree::_do_incr_search(const String &p_add) { diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp index bdb6c78782..e8359e3dfe 100644 --- a/scene/resources/default_theme/default_theme.cpp +++ b/scene/resources/default_theme/default_theme.cpp @@ -582,14 +582,14 @@ void fill_default_theme(Ref<Theme> &theme, const Ref<Font> &default_font, const // GraphNode - Ref<StyleBoxTexture> graphsb = make_stylebox(graph_node_png, 6, 24, 6, 5, 16, 24, 16, 5); - Ref<StyleBoxTexture> graphsbcomment = make_stylebox(graph_node_comment_png, 6, 24, 6, 5, 16, 24, 16, 5); - Ref<StyleBoxTexture> graphsbcommentselected = make_stylebox(graph_node_comment_focus_png, 6, 24, 6, 5, 16, 24, 16, 5); - Ref<StyleBoxTexture> graphsbselected = make_stylebox(graph_node_selected_png, 6, 24, 6, 5, 16, 24, 16, 5); + Ref<StyleBoxTexture> graphsb = make_stylebox(graph_node_png, 6, 24, 6, 5, 16, 24, 16, 6); + Ref<StyleBoxTexture> graphsbcomment = make_stylebox(graph_node_comment_png, 6, 24, 6, 5, 16, 24, 16, 6); + Ref<StyleBoxTexture> graphsbcommentselected = make_stylebox(graph_node_comment_focus_png, 6, 24, 6, 5, 16, 24, 16, 6); + Ref<StyleBoxTexture> graphsbselected = make_stylebox(graph_node_selected_png, 6, 24, 6, 5, 16, 24, 16, 6); Ref<StyleBoxTexture> graphsbdefault = make_stylebox(graph_node_default_png, 4, 4, 4, 4, 6, 4, 4, 4); Ref<StyleBoxTexture> graphsbdeffocus = make_stylebox(graph_node_default_focus_png, 4, 4, 4, 4, 6, 4, 4, 4); - Ref<StyleBoxTexture> graph_bpoint = make_stylebox(graph_node_breakpoint_png, 6, 24, 6, 5, 16, 24, 16, 5); - Ref<StyleBoxTexture> graph_position = make_stylebox(graph_node_position_png, 6, 24, 6, 5, 16, 24, 16, 5); + Ref<StyleBoxTexture> graph_bpoint = make_stylebox(graph_node_breakpoint_png, 6, 24, 6, 5, 16, 24, 16, 6); + Ref<StyleBoxTexture> graph_position = make_stylebox(graph_node_position_png, 6, 24, 6, 5, 16, 24, 16, 6); //graphsb->set_expand_margin_size(MARGIN_LEFT,10); //graphsb->set_expand_margin_size(MARGIN_RIGHT,10); |