diff options
-rw-r--r-- | SConstruct | 29 | ||||
-rw-r--r-- | core/SCsub | 1 | ||||
-rw-r--r-- | core/config/engine.cpp | 5 | ||||
-rw-r--r-- | core/version.h | 3 | ||||
-rw-r--r-- | doc/classes/Tree.xml | 7 | ||||
-rw-r--r-- | doc/classes/TreeItem.xml | 20 | ||||
-rw-r--r-- | doc/classes/Window.xml | 2 | ||||
-rw-r--r-- | editor/debugger/script_editor_debugger.cpp | 18 | ||||
-rw-r--r-- | editor/editor_about.cpp | 3 | ||||
-rw-r--r-- | editor/editor_node.cpp | 1 | ||||
-rw-r--r-- | editor/plugins/node_3d_editor_plugin.cpp | 103 | ||||
-rw-r--r-- | editor/plugins/node_3d_editor_plugin.h | 79 | ||||
-rw-r--r-- | editor/project_manager.cpp | 1 | ||||
-rw-r--r-- | main/main.cpp | 3 | ||||
-rw-r--r-- | methods.py | 8 | ||||
-rw-r--r-- | modules/gltf/gltf_document.cpp | 5 | ||||
-rw-r--r-- | platform/iphone/godot_view.h | 5 | ||||
-rw-r--r-- | platform/iphone/godot_view.mm | 8 | ||||
-rw-r--r-- | platform/iphone/godot_view_gesture_recognizer.mm | 31 | ||||
-rw-r--r-- | platform/linuxbsd/crash_handler_linuxbsd.cpp | 7 | ||||
-rw-r--r-- | platform/osx/crash_handler_osx.mm | 7 | ||||
-rw-r--r-- | platform/windows/crash_handler_windows.cpp | 7 | ||||
-rw-r--r-- | scene/gui/popup_menu.cpp | 21 | ||||
-rw-r--r-- | scene/gui/tree.cpp | 11 | ||||
-rw-r--r-- | scene/gui/tree.h | 1 |
25 files changed, 162 insertions, 224 deletions
diff --git a/SConstruct b/SConstruct index b8063589c6..a27e5490a5 100644 --- a/SConstruct +++ b/SConstruct @@ -179,9 +179,11 @@ opts.Add(BoolVariable("use_volk", "Use the volk library to load the Vulkan loade # Advanced options opts.Add(BoolVariable("dev", "If yes, alias for verbose=yes warnings=extra werror=yes", False)) -opts.Add(BoolVariable("progress", "Show a progress indicator during compilation", True)) opts.Add(BoolVariable("tests", "Build the unit tests", False)) +opts.Add(BoolVariable("fast_unsafe", "Enable unsafe options for faster rebuilds", False)) +opts.Add(BoolVariable("compiledb", "Generate compilation DB (`compile_commands.json`) for external tools", False)) opts.Add(BoolVariable("verbose", "Enable verbose output for the compilation", False)) +opts.Add(BoolVariable("progress", "Show a progress indicator during compilation", True)) opts.Add(EnumVariable("warnings", "Level of compilation warnings", "all", ("extra", "all", "moderate", "no"))) opts.Add(BoolVariable("werror", "Treat compiler warnings as errors", False)) opts.Add("extra_suffix", "Custom extra suffix added to the base filename of all generated binary files", "") @@ -360,6 +362,17 @@ if env_base["target"] == "debug": # working on the engine itself. env_base.Append(CPPDEFINES=["DEV_ENABLED"]) +# SCons speed optimization controlled by the `fast_unsafe` option, which provide +# more than 10 s speed up for incremental rebuilds. +# Unsafe as they reduce the certainty of rebuilding all changed files, so it's +# enabled by default for `debug` builds, and can be overridden from command line. +# Ref: https://github.com/SCons/scons/wiki/GoFastButton +if methods.get_cmdline_bool("fast_unsafe", env_base["target"] == "debug"): + # Renamed to `content-timestamp` in SCons >= 4.2, keeping MD5 for compat. + env_base.Decider("MD5-timestamp") + env_base.SetOption("implicit_cache", 1) + env_base.SetOption("max_drift", 60) + if env_base["use_precise_math_checks"]: env_base.Append(CPPDEFINES=["PRECISE_MATH_CHECKS"]) @@ -385,14 +398,15 @@ if selected_platform in platform_list: else: env = env_base.Clone() - # Generating the compilation DB (`compile_commands.json`) requires SCons 4.0.0 or later. - from SCons import __version__ as scons_raw_version + if env["compiledb"]: + # Generating the compilation DB (`compile_commands.json`) requires SCons 4.0.0 or later. + from SCons import __version__ as scons_raw_version - scons_ver = env._get_major_minor_revision(scons_raw_version) + scons_ver = env._get_major_minor_revision(scons_raw_version) - if scons_ver >= (4, 0, 0): - env.Tool("compilation_db") - env.Alias("compiledb", env.CompilationDatabase()) + if scons_ver >= (4, 0, 0): + env.Tool("compilation_db") + env.Alias("compiledb", env.CompilationDatabase()) # 'dev' and 'production' are aliases to set default options if they haven't been set # manually by the user. @@ -817,6 +831,7 @@ elif selected_platform != "": # The following only makes sense when the 'env' is defined, and assumes it is. if "env" in locals(): + # FIXME: This method mixes both cosmetic progress stuff and cache handling... methods.show_progress(env) # TODO: replace this with `env.Dump(format="json")` # once we start requiring SCons 4.0 as min version. diff --git a/core/SCsub b/core/SCsub index c12dd4e60e..1379e9df9b 100644 --- a/core/SCsub +++ b/core/SCsub @@ -147,6 +147,7 @@ env.core_sources += thirdparty_obj env.add_source_files(env.core_sources, "*.cpp") env.add_source_files(env.core_sources, "script_encryption_key.gen.cpp") +env.add_source_files(env.core_sources, "version_hash.gen.cpp") # Certificates env.Depends( diff --git a/core/config/engine.cpp b/core/config/engine.cpp index d9abf5e5e9..ff8a8d283f 100644 --- a/core/config/engine.cpp +++ b/core/config/engine.cpp @@ -35,7 +35,6 @@ #include "core/donors.gen.h" #include "core/license.gen.h" #include "core/version.h" -#include "core/version_hash.gen.h" void Engine::set_physics_ticks_per_second(int p_ips) { ERR_FAIL_COND_MSG(p_ips <= 0, "Engine iterations per second must be greater than 0."); @@ -95,8 +94,8 @@ Dictionary Engine::get_version_info() const { dict["build"] = VERSION_BUILD; dict["year"] = VERSION_YEAR; - String hash = VERSION_HASH; - dict["hash"] = hash.length() == 0 ? String("unknown") : hash; + String hash = String(VERSION_HASH); + dict["hash"] = hash.is_empty() ? String("unknown") : hash; String stringver = String(dict["major"]) + "." + String(dict["minor"]); if ((int)dict["patch"] != 0) { diff --git a/core/version.h b/core/version.h index c718d0f4d7..e22922fa66 100644 --- a/core/version.h +++ b/core/version.h @@ -68,4 +68,7 @@ // Example: "Godot v3.1.4.stable.official.mono" #define VERSION_FULL_NAME "" VERSION_NAME " v" VERSION_FULL_BUILD +// Git commit hash, generated at build time in `core/version_hash.gen.cpp`. +extern const char *const VERSION_HASH; + #endif // VERSION_H diff --git a/doc/classes/Tree.xml b/doc/classes/Tree.xml index 4b051c4938..35a70ae53f 100644 --- a/doc/classes/Tree.xml +++ b/doc/classes/Tree.xml @@ -72,6 +72,13 @@ [b]Note:[/b] Despite the name of this method, the focus cursor itself is only visible in [constant SELECT_MULTI] mode. </description> </method> + <method name="get_button_id_at_position" qualifiers="const"> + <return type="int" /> + <argument index="0" name="position" type="Vector2" /> + <description> + Returns the button id at [code]position[/code], or -1 if no button is there. + </description> + </method> <method name="get_column_at_position" qualifiers="const"> <return type="int" /> <argument index="0" name="position" type="Vector2" /> diff --git a/doc/classes/TreeItem.xml b/doc/classes/TreeItem.xml index 12c91cdd10..675c534e7b 100644 --- a/doc/classes/TreeItem.xml +++ b/doc/classes/TreeItem.xml @@ -14,11 +14,11 @@ <return type="void" /> <argument index="0" name="column" type="int" /> <argument index="1" name="button" type="Texture2D" /> - <argument index="2" name="button_idx" type="int" default="-1" /> + <argument index="2" name="id" type="int" default="-1" /> <argument index="3" name="disabled" type="bool" default="false" /> <argument index="4" name="tooltip" type="String" default="""" /> <description> - Adds a button with [Texture2D] [code]button[/code] at column [code]column[/code]. The [code]button_idx[/code] index is used to identify the button when calling other methods. If not specified, the next available index is used, which may be retrieved by calling [method get_button_count] immediately after this method. Optionally, the button can be [code]disabled[/code] and have a [code]tooltip[/code]. + Adds a button with [Texture2D] [code]button[/code] at column [code]column[/code]. The [code]id[/code] is used to identify the button. If not specified, the next available index is used, which may be retrieved by calling [method get_button_count] immediately after this method. Optionally, the button can be [code]disabled[/code] and have a [code]tooltip[/code]. </description> </method> <method name="call_recursive" qualifiers="vararg"> @@ -80,6 +80,14 @@ Returns the [Texture2D] of the button at index [code]button_idx[/code] in column [code]column[/code]. </description> </method> + <method name="get_button_by_id" qualifiers="const"> + <return type="int" /> + <argument index="0" name="column" type="int" /> + <argument index="1" name="id" type="int" /> + <description> + Returns the button index if there is a button with id [code]id[/code] in column [code]column[/code], otherwise returns -1. + </description> + </method> <method name="get_button_count" qualifiers="const"> <return type="int" /> <argument index="0" name="column" type="int" /> @@ -87,6 +95,14 @@ Returns the number of buttons in column [code]column[/code]. May be used to get the most recently added button's index, if no index was specified. </description> </method> + <method name="get_button_id" qualifiers="const"> + <return type="int" /> + <argument index="0" name="column" type="int" /> + <argument index="1" name="button_idx" type="int" /> + <description> + Returns the id for the button at index [code]button_idx[/code] in column [code]column[/code]. + </description> + </method> <method name="get_button_tooltip" qualifiers="const"> <return type="String" /> <argument index="0" name="column" type="int" /> diff --git a/doc/classes/Window.xml b/doc/classes/Window.xml index ab8f51ced5..82bb74683f 100644 --- a/doc/classes/Window.xml +++ b/doc/classes/Window.xml @@ -435,7 +435,7 @@ <constant name="CONTENT_SCALE_ASPECT_EXPAND" value="4" enum="ContentScaleAspect"> </constant> <constant name="LAYOUT_DIRECTION_INHERITED" value="0" enum="LayoutDirection"> - Automatic layout direction, determined from the parent control layout direction. + Automatic layout direction, determined from the parent window layout direction. </constant> <constant name="LAYOUT_DIRECTION_LOCALE" value="1" enum="LayoutDirection"> Automatic layout direction, determined from the current locale. diff --git a/editor/debugger/script_editor_debugger.cpp b/editor/debugger/script_editor_debugger.cpp index 6aedfa6ccb..6a2cb8ee4a 100644 --- a/editor/debugger/script_editor_debugger.cpp +++ b/editor/debugger/script_editor_debugger.cpp @@ -36,7 +36,6 @@ #include "core/io/marshalls.h" #include "core/string/ustring.h" #include "core/version.h" -#include "core/version_hash.gen.h" #include "editor/debugger/debug_adapter/debug_adapter_protocol.h" #include "editor/debugger/editor_network_profiler.h" #include "editor/debugger/editor_performance_profiler.h" @@ -1543,19 +1542,10 @@ void ScriptEditorDebugger::_item_menu_id_pressed(int p_option) { const int line_number = file_line_number[1].to_int(); // Construct a GitHub repository URL and open it in the user's default web browser. - if (String(VERSION_HASH).length() >= 1) { - // Git commit hash information available; use it for greater accuracy, including for development versions. - OS::get_singleton()->shell_open(vformat("https://github.com/godotengine/godot/blob/%s/%s#L%d", - VERSION_HASH, - file, - line_number)); - } else { - // Git commit hash information unavailable; fall back to tagged releases. - OS::get_singleton()->shell_open(vformat("https://github.com/godotengine/godot/blob/%s-stable/%s#L%d", - VERSION_NUMBER, - file, - line_number)); - } + // If the commit hash is available, use it for greater accuracy. Otherwise fall back to tagged release. + String git_ref = String(VERSION_HASH).is_empty() ? String(VERSION_NUMBER) + "-stable" : String(VERSION_HASH); + OS::get_singleton()->shell_open(vformat("https://github.com/godotengine/godot/blob/%s/%s#L%d", + git_ref, file, line_number)); } break; case ACTION_DELETE_BREAKPOINT: { const TreeItem *selected = breakpoints_tree->get_selected(); diff --git a/editor/editor_about.cpp b/editor/editor_about.cpp index 54377971c6..4309f55a2b 100644 --- a/editor/editor_about.cpp +++ b/editor/editor_about.cpp @@ -29,13 +29,12 @@ /*************************************************************************/ #include "editor_about.h" -#include "editor_node.h" #include "core/authors.gen.h" #include "core/donors.gen.h" #include "core/license.gen.h" #include "core/version.h" -#include "core/version_hash.gen.h" +#include "editor_node.h" // The metadata key used to store and retrieve the version text to copy to the clipboard. static const String META_TEXT_TO_COPY = "text_to_copy"; diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 10ce7228e0..4b2f1c5104 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -47,7 +47,6 @@ #include "core/string/print_string.h" #include "core/string/translation.h" #include "core/version.h" -#include "core/version_hash.gen.h" #include "main/main.h" #include "scene/3d/importer_mesh_instance_3d.h" #include "scene/gui/center_container.h" diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index f79b5027cb..2e8ae1a286 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -886,15 +886,13 @@ void Node3DEditorViewport::_update_name() { view_menu->reset_size(); } -void Node3DEditorViewport::_compute_edit(const Point2 &p_point, const bool p_auto_center) { +void Node3DEditorViewport::_compute_edit(const Point2 &p_point) { _edit.original_local = spatial_editor->are_local_coords_enabled(); _edit.click_ray = _get_ray(p_point); _edit.click_ray_pos = _get_ray_pos(p_point); _edit.plane = TRANSFORM_VIEW; - if (p_auto_center) { - _edit.center = spatial_editor->get_gizmo_transform().origin; - } spatial_editor->update_transform_gizmo(); + _edit.center = spatial_editor->get_gizmo_transform().origin; Node3D *selected = spatial_editor->get_single_selected_node(); Node3DEditorSelectedItem *se = selected ? editor_selection->get_node_editor_data<Node3DEditorSelectedItem>(selected) : nullptr; @@ -1366,7 +1364,6 @@ void Node3DEditorViewport::_sinput(const Ref<InputEvent> &p_event) { } } - _edit.center = spatial_editor->get_gizmo_target_center(); Ref<InputEventMouseButton> b = p_event; if (b.is_valid()) { @@ -3367,7 +3364,7 @@ void Node3DEditorViewport::update_transform_gizmo_view() { Transform3D xform = spatial_editor->get_gizmo_transform(); - const Transform3D camera_xform = camera->get_transform(); + Transform3D camera_xform = camera->get_transform(); if (xform.origin.is_equal_approx(camera_xform.origin)) { for (int i = 0; i < 3; i++) { @@ -3386,63 +3383,11 @@ void Node3DEditorViewport::update_transform_gizmo_view() { const Vector3 camz = -camera_xform.get_basis().get_axis(2).normalized(); const Vector3 camy = -camera_xform.get_basis().get_axis(1).normalized(); const Plane p = Plane(camz, camera_xform.origin); - const real_t gizmo_d = CLAMP(Math::abs(p.distance_to(xform.origin)), camera->get_near() * 2, camera->get_far() / 2); + const real_t gizmo_d = MAX(Math::abs(p.distance_to(xform.origin)), CMP_EPSILON); const real_t d0 = camera->unproject_position(camera_xform.origin + camz * gizmo_d).y; const real_t d1 = camera->unproject_position(camera_xform.origin + camz * gizmo_d + camy).y; const real_t dd = MAX(Math::abs(d0 - d1), CMP_EPSILON); - // This code ensures the gizmo stays on the screen. This includes if - // the gizmo would otherwise be behind the camera, to the sides of - // the camera, too close to the edge of the screen, too close to - // the camera, or too far away from the camera. First we calculate - // where the gizmo would go on screen, then we put it there. - const Vector3 object_position = spatial_editor->get_gizmo_target_center(); - Vector2 gizmo_screen_position = camera->unproject_position(object_position); - const Vector2 viewport_size = viewport->get_size(); - // We would use "camera.is_position_behind(parent_translation)" instead of dot, - // except that it also accounts for the near clip plane, which we don't want. - const bool is_in_front = camera_xform.basis.get_column(2).dot(object_position - camera_xform.origin) < 0; - const bool is_in_viewport = is_in_front && Rect2(Vector2(0, 0), viewport_size).has_point(gizmo_screen_position); - if (spatial_editor->is_keep_gizmo_onscreen_enabled()) { - if (!spatial_editor->is_gizmo_visible() || is_in_viewport) { - // In this case, the gizmo is either not visible, or in the viewport - // already, so we should hide the offscreen line. - gizmo_offscreen_line->hide(); - } else { - // In this case, the point is not "normally" on screen, and - // it should be placed in the center. - const Vector2 half_viewport_size = viewport_size / 2; - gizmo_screen_position = half_viewport_size; - // The rest of this is for drawing the offscreen line. - // One point goes in the center of the viewport. - // Calculate where to put the other point of the line. - Vector2 unprojected_position = camera->unproject_position(object_position); - if (!is_in_front) { - // When the object is behind, we need to flip and grow the line. - unprojected_position -= half_viewport_size; - unprojected_position = unprojected_position.normalized() * -half_viewport_size.length_squared(); - unprojected_position += half_viewport_size; - } - gizmo_offscreen_line->point1 = half_viewport_size; - gizmo_offscreen_line->point2 = unprojected_position; - gizmo_offscreen_line->update(); - gizmo_offscreen_line->show(); - } - // Update the gizmo's position using what we calculated. - xform.origin = camera->project_position(gizmo_screen_position, gizmo_d); - } else { - // In this case, the user does not want the gizmo to be - // kept on screen, so we should hide the offscreen line, - // and just use the gizmo's unmodified position. - gizmo_offscreen_line->hide(); - if (is_in_viewport) { - xform.origin = camera->project_position(gizmo_screen_position, gizmo_d); - } else { - xform.origin = object_position; - } - } - spatial_editor->set_gizmo_transform(xform); - const real_t gizmo_size = EditorSettings::get_singleton()->get("editors/3d/manipulator_gizmo_size"); // At low viewport heights, multiply the gizmo scale based on the viewport height. // This prevents the gizmo from growing very large and going outside the viewport. @@ -3451,6 +3396,7 @@ void Node3DEditorViewport::update_transform_gizmo_view() { (gizmo_size / Math::abs(dd)) * MAX(1, EDSCALE) * MIN(viewport_base_height, subviewport_container->get_size().height) / viewport_base_height / subviewport_container->get_stretch_shrink(); + Vector3 scale = Vector3(1, 1, 1) * gizmo_scale; // if the determinant is zero, we should disable the gizmo from being rendered // this prevents supplying bad values to the renderer and then having to filter it out again @@ -3472,7 +3418,7 @@ void Node3DEditorViewport::update_transform_gizmo_view() { if (xform.basis.get_axis(i).normalized().dot(xform.basis.get_axis((i + 1) % 3).normalized()) < 1.0) { axis_angle = axis_angle.looking_at(xform.basis.get_axis(i).normalized(), xform.basis.get_axis((i + 1) % 3).normalized()); } - axis_angle.basis *= gizmo_scale; + axis_angle.basis.scale(scale); axis_angle.origin = xform.origin; RenderingServer::get_singleton()->instance_set_transform(move_gizmo_instance[i], axis_angle); RenderingServer::get_singleton()->instance_set_visible(move_gizmo_instance[i], spatial_editor->is_gizmo_visible() && (spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SELECT || spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_MOVE)); @@ -3495,7 +3441,7 @@ void Node3DEditorViewport::update_transform_gizmo_view() { // Rotation white outline xform.orthonormalize(); - xform.basis *= gizmo_scale; + xform.basis.scale(scale); RenderingServer::get_singleton()->instance_set_transform(rotate_gizmo_instance[3], xform); RenderingServer::get_singleton()->instance_set_visible(rotate_gizmo_instance[3], spatial_editor->is_gizmo_visible() && (spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_SELECT || spatial_editor->get_tool_mode() == Node3DEditor::TOOL_MODE_ROTATE)); } @@ -4077,7 +4023,7 @@ void Node3DEditorViewport::drop_data_fw(const Point2 &p_point, const Variant &p_ void Node3DEditorViewport::begin_transform(TransformMode p_mode, bool instant) { if (get_selected_count() > 0) { _edit.mode = p_mode; - _compute_edit(_edit.mouse_pos, false); + _compute_edit(_edit.mouse_pos); _edit.instant = instant; _edit.snap = spatial_editor->is_snap_enabled(); } @@ -4480,14 +4426,15 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, Edito zoom_indicator_delay = 0.0; spatial_editor = p_spatial_editor; - subviewport_container = memnew(SubViewportContainer); - subviewport_container->set_stretch(true); - add_child(subviewport_container); - subviewport_container->set_anchors_and_offsets_preset(Control::PRESET_WIDE); + SubViewportContainer *c = memnew(SubViewportContainer); + subviewport_container = c; + c->set_stretch(true); + add_child(c); + c->set_anchors_and_offsets_preset(Control::PRESET_WIDE); viewport = memnew(SubViewport); viewport->set_disable_input(true); - subviewport_container->add_child(viewport); + c->add_child(viewport); surface = memnew(Control); surface->set_drag_forwarding(this); add_child(surface); @@ -4500,9 +4447,6 @@ Node3DEditorViewport::Node3DEditorViewport(Node3DEditor *p_spatial_editor, Edito camera->make_current(); surface->set_focus_mode(FOCUS_ALL); - gizmo_offscreen_line = memnew(GizmoOffScreenLine); - subviewport_container->add_child(gizmo_offscreen_line); - VBoxContainer *vbox = memnew(VBoxContainer); surface->add_child(vbox); vbox->set_offset(SIDE_LEFT, 10 * EDSCALE); @@ -5127,7 +5071,6 @@ void Node3DEditor::update_transform_gizmo() { gizmo.visible = count > 0; gizmo.transform.origin = (count > 0) ? gizmo_center / count : Vector3(); gizmo.transform.basis = (count == 1) ? gizmo_basis : Basis(); - gizmo.target_center = gizmo_center / count; for (uint32_t i = 0; i < VIEWPORTS_COUNT; i++) { viewports[i]->update_transform_gizmo_view(); @@ -5280,7 +5223,6 @@ Dictionary Node3DEditor::get_state() const { d["show_grid"] = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_GRID)); d["show_origin"] = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_ORIGIN)); - d["keep_gizmo_onscreen"] = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(MENU_KEEP_GIZMO_ONSCREEN)); d["fov"] = get_fov(); d["znear"] = get_znear(); d["zfar"] = get_zfar(); @@ -5405,13 +5347,6 @@ void Node3DEditor::set_state(const Dictionary &p_state) { RenderingServer::get_singleton()->instance_set_visible(origin_instance, use); } } - if (d.has("keep_gizmo_onscreen")) { - bool use = d["keep_gizmo_onscreen"]; - - if (use != view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(MENU_KEEP_GIZMO_ONSCREEN))) { - _menu_item_pressed(MENU_KEEP_GIZMO_ONSCREEN); - } - } if (d.has("gizmos_status")) { Dictionary gizmos_status = d["gizmos_status"]; @@ -5765,13 +5700,7 @@ void Node3DEditor::_menu_item_pressed(int p_option) { _init_grid(); view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(p_option), grid_enabled); - } break; - case MENU_KEEP_GIZMO_ONSCREEN: { - keep_gizmo_onscreen = !view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(p_option)); - for (uint32_t i = 0; i < VIEWPORTS_COUNT; i++) { - get_editor_viewport(i)->update_transform_gizmo_view(); - } - view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(p_option), keep_gizmo_onscreen); + } break; case MENU_VIEW_CAMERA_SETTINGS: { settings_dialog->popup_centered(settings_vbc->get_combined_minimum_size() + Size2(50, 50)); @@ -7756,14 +7685,12 @@ Node3DEditor::Node3DEditor(EditorNode *p_editor) { p->add_separator(); p->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_origin", TTR("View Origin")), MENU_VIEW_ORIGIN); p->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_grid", TTR("View Grid"), Key::NUMBERSIGN), MENU_VIEW_GRID); - p->add_check_shortcut(ED_SHORTCUT("spatial_editor/keep_gizmo_onscreen", TTR("Keep Gizmo On Screen"), KeyModifierMask::CMD + KeyModifierMask::ALT + Key::G), MENU_KEEP_GIZMO_ONSCREEN); p->add_separator(); p->add_shortcut(ED_SHORTCUT("spatial_editor/settings", TTR("Settings...")), MENU_VIEW_CAMERA_SETTINGS); p->set_item_checked(p->get_item_index(MENU_VIEW_ORIGIN), true); p->set_item_checked(p->get_item_index(MENU_VIEW_GRID), true); - p->set_item_checked(p->get_item_index(MENU_KEEP_GIZMO_ONSCREEN), true); p->connect("id_pressed", callable_mp(this, &Node3DEditor::_menu_item_pressed)); diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h index f14f8b90b9..bbe5615570 100644 --- a/editor/plugins/node_3d_editor_plugin.h +++ b/editor/plugins/node_3d_editor_plugin.h @@ -87,19 +87,6 @@ public: void set_viewport(Node3DEditorViewport *p_viewport); }; -class GizmoOffScreenLine : public Control { - GDCLASS(GizmoOffScreenLine, Control); - -public: - Vector2 point1; - Vector2 point2; - void _notification(int p_what) { - if (p_what == NOTIFICATION_DRAW && is_visible()) { - draw_line(point1, point2, Color(0.0f, 0.75f, 0.75f), 2); - } - } -}; - class Node3DEditorViewport : public Control { GDCLASS(Node3DEditorViewport, Control); friend class Node3DEditor; @@ -214,7 +201,6 @@ private: CheckBox *preview_camera; SubViewportContainer *subviewport_container; - GizmoOffScreenLine *gizmo_offscreen_line; MenuButton *view_menu; PopupMenu *display_submenu; @@ -251,7 +237,7 @@ private: }; void _update_name(); - void _compute_edit(const Point2 &p_point, const bool p_auto_center = true); + void _compute_edit(const Point2 &p_point); void _clear_selected(); void _select_clicked(bool p_allow_locked); ObjectID _select_ray(const Point2 &p_pos); @@ -521,35 +507,6 @@ class Node3DEditor : public VBoxContainer { public: static const unsigned int VIEWPORTS_COUNT = 4; - enum MenuOption { - MENU_GROUP_SELECTED, - MENU_KEEP_GIZMO_ONSCREEN, - MENU_LOCK_SELECTED, - MENU_SNAP_TO_FLOOR, - MENU_TOOL_LIST_SELECT, - MENU_TOOL_LOCAL_COORDS, - MENU_TOOL_MOVE, - MENU_TOOL_OVERRIDE_CAMERA, - MENU_TOOL_ROTATE, - MENU_TOOL_SCALE, - MENU_TOOL_SELECT, - MENU_TOOL_USE_SNAP, - MENU_TRANSFORM_CONFIGURE_SNAP, - MENU_TRANSFORM_DIALOG, - MENU_UNGROUP_SELECTED, - MENU_UNLOCK_SELECTED, - MENU_VIEW_CAMERA_SETTINGS, - MENU_VIEW_GIZMOS_3D_ICONS, - MENU_VIEW_GRID, - MENU_VIEW_ORIGIN, - MENU_VIEW_USE_1_VIEWPORT, - MENU_VIEW_USE_2_VIEWPORTS, - MENU_VIEW_USE_2_VIEWPORTS_ALT, - MENU_VIEW_USE_3_VIEWPORTS, - MENU_VIEW_USE_3_VIEWPORTS_ALT, - MENU_VIEW_USE_4_VIEWPORTS, - }; - enum ToolMode { TOOL_MODE_SELECT, TOOL_MODE_MOVE, @@ -568,6 +525,7 @@ public: TOOL_OPT_USE_SNAP, TOOL_OPT_OVERRIDE_CAMERA, TOOL_OPT_MAX + }; private: @@ -596,7 +554,6 @@ private: Camera3D::Projection grid_camera_last_update_perspective = Camera3D::PROJECTION_PERSPECTIVE; Vector3 grid_camera_last_update_position = Vector3(); - bool keep_gizmo_onscreen = true; Ref<ArrayMesh> move_gizmo[3], move_plane_gizmo[3], rotate_gizmo[4], scale_gizmo[3], scale_plane_gizmo[3], axis_gizmo[3]; Ref<StandardMaterial3D> gizmo_color[3]; Ref<StandardMaterial3D> plane_gizmo_color[3]; @@ -630,10 +587,37 @@ private: struct Gizmo { bool visible = false; real_t scale = 0; - Vector3 target_center; Transform3D transform; } gizmo; + enum MenuOption { + MENU_TOOL_SELECT, + MENU_TOOL_MOVE, + MENU_TOOL_ROTATE, + MENU_TOOL_SCALE, + MENU_TOOL_LIST_SELECT, + MENU_TOOL_LOCAL_COORDS, + MENU_TOOL_USE_SNAP, + MENU_TOOL_OVERRIDE_CAMERA, + MENU_TRANSFORM_CONFIGURE_SNAP, + MENU_TRANSFORM_DIALOG, + MENU_VIEW_USE_1_VIEWPORT, + MENU_VIEW_USE_2_VIEWPORTS, + MENU_VIEW_USE_2_VIEWPORTS_ALT, + MENU_VIEW_USE_3_VIEWPORTS, + MENU_VIEW_USE_3_VIEWPORTS_ALT, + MENU_VIEW_USE_4_VIEWPORTS, + MENU_VIEW_ORIGIN, + MENU_VIEW_GRID, + MENU_VIEW_GIZMOS_3D_ICONS, + MENU_VIEW_CAMERA_SETTINGS, + MENU_LOCK_SELECTED, + MENU_UNLOCK_SELECTED, + MENU_GROUP_SELECTED, + MENU_UNGROUP_SELECTED, + MENU_SNAP_TO_FLOOR + }; + Button *tool_button[TOOL_MAX]; Button *tool_option_button[TOOL_OPT_MAX]; @@ -792,10 +776,7 @@ public: float get_zfar() const { return settings_zfar->get_value(); } float get_fov() const { return settings_fov->get_value(); } - Vector3 get_gizmo_target_center() const { return gizmo.target_center; } Transform3D get_gizmo_transform() const { return gizmo.transform; } - void set_gizmo_transform(const Transform3D &p_transform) { gizmo.transform = p_transform; } - bool is_keep_gizmo_onscreen_enabled() const { return keep_gizmo_onscreen; } bool is_gizmo_visible() const; ToolMode get_tool_mode() const { return tool_mode; } diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp index cfb42c0741..57e47a15fd 100644 --- a/editor/project_manager.cpp +++ b/editor/project_manager.cpp @@ -40,7 +40,6 @@ #include "core/os/os.h" #include "core/string/translation.h" #include "core/version.h" -#include "core/version_hash.gen.h" #include "editor/editor_vcs_interface.h" #include "editor_scale.h" #include "editor_settings.h" diff --git a/main/main.cpp b/main/main.cpp index 216d0a446a..0bca5bef0c 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -50,7 +50,6 @@ #include "core/register_core_types.h" #include "core/string/translation.h" #include "core/version.h" -#include "core/version_hash.gen.h" #include "drivers/register_driver_types.h" #include "main/app_icon.gen.h" #include "main/main_timer_sync.h" @@ -200,7 +199,7 @@ static String unescape_cmdline(const String &p_str) { static String get_full_version_string() { String hash = String(VERSION_HASH); - if (hash.length() != 0) { + if (!hash.is_empty()) { hash = "." + hash.left(9); } return String(VERSION_FULL_BUILD) + hash; diff --git a/methods.py b/methods.py index fbd304ddde..fe84641e9d 100644 --- a/methods.py +++ b/methods.py @@ -111,10 +111,9 @@ def update_version(module_version_string=""): f.close() # NOTE: It is safe to generate this file here, since this is still executed serially - fhash = open("core/version_hash.gen.h", "w") + fhash = open("core/version_hash.gen.cpp", "w") fhash.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n") - fhash.write("#ifndef VERSION_HASH_GEN_H\n") - fhash.write("#define VERSION_HASH_GEN_H\n") + fhash.write('#include "core/version.h"\n') githash = "" gitfolder = ".git" @@ -132,8 +131,7 @@ def update_version(module_version_string=""): else: githash = head - fhash.write('#define VERSION_HASH "' + githash + '"\n') - fhash.write("#endif // VERSION_HASH_GEN_H\n") + fhash.write('const char *const VERSION_HASH = "' + githash + '";\n') fhash.close() diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp index baa39a3b80..0056fee7a4 100644 --- a/modules/gltf/gltf_document.cpp +++ b/modules/gltf/gltf_document.cpp @@ -57,7 +57,6 @@ #include "core/variant/typed_array.h" #include "core/variant/variant.h" #include "core/version.h" -#include "core/version_hash.gen.h" #include "drivers/png/png_driver_common.h" #include "editor/import/resource_importer_scene.h" #include "scene/2d/node_2d.h" @@ -6655,8 +6654,8 @@ Error GLTFDocument::_serialize_version(Ref<GLTFState> state) { Dictionary asset; asset["version"] = version; - String hash = VERSION_HASH; - asset["generator"] = String(VERSION_FULL_NAME) + String("@") + (hash.length() == 0 ? String("unknown") : hash); + String hash = String(VERSION_HASH); + asset["generator"] = String(VERSION_FULL_NAME) + String("@") + (hash.is_empty() ? String("unknown") : hash); state->json["asset"] = asset; ERR_FAIL_COND_V(!asset.has("version"), Error::FAILED); ERR_FAIL_COND_V(!state->json.has("asset"), Error::FAILED); diff --git a/platform/iphone/godot_view.h b/platform/iphone/godot_view.h index 1c72a26b4a..fcb97fa63a 100644 --- a/platform/iphone/godot_view.h +++ b/platform/iphone/godot_view.h @@ -59,4 +59,9 @@ class String; - (void)stopRendering; - (void)startRendering; +- (void)godotTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event; +- (void)godotTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event; +- (void)godotTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event; +- (void)godotTouchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event; + @end diff --git a/platform/iphone/godot_view.mm b/platform/iphone/godot_view.mm index b90c10fa84..ae92f32851 100644 --- a/platform/iphone/godot_view.mm +++ b/platform/iphone/godot_view.mm @@ -336,7 +336,7 @@ static const float earth_gravity = 9.80665; } } -- (void)touchesBegan:(NSSet *)touchesSet withEvent:(UIEvent *)event { +- (void)godotTouchesBegan:(NSSet *)touchesSet withEvent:(UIEvent *)event { NSArray *tlist = [event.allTouches allObjects]; for (unsigned int i = 0; i < [tlist count]; i++) { if ([touchesSet containsObject:[tlist objectAtIndex:i]]) { @@ -349,7 +349,7 @@ static const float earth_gravity = 9.80665; } } -- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { +- (void)godotTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { NSArray *tlist = [event.allTouches allObjects]; for (unsigned int i = 0; i < [tlist count]; i++) { if ([touches containsObject:[tlist objectAtIndex:i]]) { @@ -363,7 +363,7 @@ static const float earth_gravity = 9.80665; } } -- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { +- (void)godotTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { NSArray *tlist = [event.allTouches allObjects]; for (unsigned int i = 0; i < [tlist count]; i++) { if ([touches containsObject:[tlist objectAtIndex:i]]) { @@ -377,7 +377,7 @@ static const float earth_gravity = 9.80665; } } -- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { +- (void)godotTouchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { NSArray *tlist = [event.allTouches allObjects]; for (unsigned int i = 0; i < [tlist count]; i++) { if ([touches containsObject:[tlist objectAtIndex:i]]) { diff --git a/platform/iphone/godot_view_gesture_recognizer.mm b/platform/iphone/godot_view_gesture_recognizer.mm index b50ba5f942..a46c42765a 100644 --- a/platform/iphone/godot_view_gesture_recognizer.mm +++ b/platform/iphone/godot_view_gesture_recognizer.mm @@ -29,6 +29,7 @@ /*************************************************************************/ #import "godot_view_gesture_recognizer.h" +#import "godot_view.h" #include "core/config/project_settings.h" @@ -58,6 +59,10 @@ const CGFloat kGLGestureMovementDistance = 0.5; @implementation GodotViewGestureRecognizer +- (GodotView *)godotView { + return (GodotView *)self.view; +} + - (instancetype)init { self = [super init]; @@ -104,7 +109,7 @@ const CGFloat kGLGestureMovementDistance = 0.5; self.delayTimer = nil; if (self.delayedTouches) { - [self.view touchesBegan:self.delayedTouches withEvent:self.delayedEvent]; + [self.godotView godotTouchesBegan:self.delayedTouches withEvent:self.delayedEvent]; } self.delayedTouches = nil; @@ -114,6 +119,8 @@ const CGFloat kGLGestureMovementDistance = 0.5; - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { NSSet *cleared = [self copyClearedTouches:touches phase:UITouchPhaseBegan]; [self delayTouches:cleared andEvent:event]; + + [super touchesBegan:touches withEvent:event]; } - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { @@ -123,8 +130,8 @@ const CGFloat kGLGestureMovementDistance = 0.5; // We should check if movement was significant enough to fire an event // for dragging to work correctly. for (UITouch *touch in cleared) { - CGPoint from = [touch locationInView:self.view]; - CGPoint to = [touch previousLocationInView:self.view]; + CGPoint from = [touch locationInView:self.godotView]; + CGPoint to = [touch previousLocationInView:self.godotView]; CGFloat xDistance = from.x - to.x; CGFloat yDistance = from.y - to.y; @@ -133,7 +140,7 @@ const CGFloat kGLGestureMovementDistance = 0.5; // Early exit, since one of touches has moved enough to fire a drag event. if (distance > kGLGestureMovementDistance) { [self.delayTimer fire]; - [self.view touchesMoved:cleared withEvent:event]; + [self.godotView godotTouchesMoved:cleared withEvent:event]; return; } } @@ -141,26 +148,32 @@ const CGFloat kGLGestureMovementDistance = 0.5; return; } - [self.view touchesMoved:cleared withEvent:event]; + [self.godotView touchesMoved:cleared withEvent:event]; + + [super touchesMoved:touches withEvent:event]; } - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { [self.delayTimer fire]; NSSet *cleared = [self copyClearedTouches:touches phase:UITouchPhaseEnded]; - [self.view touchesEnded:cleared withEvent:event]; + [self.godotView godotTouchesEnded:cleared withEvent:event]; + + [super touchesEnded:touches withEvent:event]; } - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { [self.delayTimer fire]; - [self.view touchesCancelled:touches withEvent:event]; -}; + [self.godotView godotTouchesCancelled:touches withEvent:event]; + + [super touchesCancelled:touches withEvent:event]; +} - (NSSet *)copyClearedTouches:(NSSet *)touches phase:(UITouchPhase)phaseToSave { NSMutableSet *cleared = [touches mutableCopy]; for (UITouch *touch in touches) { - if (touch.phase != phaseToSave) { + if (touch.view != self.view || touch.phase != phaseToSave) { [cleared removeObject:touch]; } } diff --git a/platform/linuxbsd/crash_handler_linuxbsd.cpp b/platform/linuxbsd/crash_handler_linuxbsd.cpp index e9369fefdd..b4ec7924f6 100644 --- a/platform/linuxbsd/crash_handler_linuxbsd.cpp +++ b/platform/linuxbsd/crash_handler_linuxbsd.cpp @@ -33,7 +33,6 @@ #include "core/config/project_settings.h" #include "core/os/os.h" #include "core/version.h" -#include "core/version_hash.gen.h" #include "main/main.h" #ifdef DEBUG_ENABLED @@ -71,10 +70,10 @@ static void handle_crash(int sig) { } // Print the engine version just before, so that people are reminded to include the version in backtrace reports. - if (String(VERSION_HASH).length() != 0) { - fprintf(stderr, "Engine version: " VERSION_FULL_NAME " (" VERSION_HASH ")\n"); + if (String(VERSION_HASH).is_empty()) { + fprintf(stderr, "Engine version: %s\n", VERSION_FULL_NAME); } else { - fprintf(stderr, "Engine version: " VERSION_FULL_NAME "\n"); + fprintf(stderr, "Engine version: %s (%s)\n", VERSION_FULL_NAME, VERSION_HASH); } fprintf(stderr, "Dumping the backtrace. %s\n", msg.utf8().get_data()); char **strings = backtrace_symbols(bt_buffer, size); diff --git a/platform/osx/crash_handler_osx.mm b/platform/osx/crash_handler_osx.mm index 16be941308..3e640b3bf3 100644 --- a/platform/osx/crash_handler_osx.mm +++ b/platform/osx/crash_handler_osx.mm @@ -33,7 +33,6 @@ #include "core/config/project_settings.h" #include "core/os/os.h" #include "core/version.h" -#include "core/version_hash.gen.h" #include "main/main.h" #include <string.h> @@ -94,10 +93,10 @@ static void handle_crash(int sig) { OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_CRASH); // Print the engine version just before, so that people are reminded to include the version in backtrace reports. - if (String(VERSION_HASH).length() != 0) { - fprintf(stderr, "Engine version: " VERSION_FULL_NAME " (" VERSION_HASH ")\n"); + if (String(VERSION_HASH).is_empty()) { + fprintf(stderr, "Engine version: %s\n", VERSION_FULL_NAME); } else { - fprintf(stderr, "Engine version: " VERSION_FULL_NAME "\n"); + fprintf(stderr, "Engine version: %s (%s)\n", VERSION_FULL_NAME, VERSION_HASH); } fprintf(stderr, "Dumping the backtrace. %s\n", msg.utf8().get_data()); char **strings = backtrace_symbols(bt_buffer, size); diff --git a/platform/windows/crash_handler_windows.cpp b/platform/windows/crash_handler_windows.cpp index 71e9d9acbd..5064f6b97f 100644 --- a/platform/windows/crash_handler_windows.cpp +++ b/platform/windows/crash_handler_windows.cpp @@ -33,7 +33,6 @@ #include "core/config/project_settings.h" #include "core/os/os.h" #include "core/version.h" -#include "core/version_hash.gen.h" #include "main/main.h" #ifdef CRASH_HANDLER_EXCEPTION @@ -179,10 +178,10 @@ DWORD CrashHandlerException(EXCEPTION_POINTERS *ep) { } // Print the engine version just before, so that people are reminded to include the version in backtrace reports. - if (String(VERSION_HASH).length() != 0) { - fprintf(stderr, "Engine version: " VERSION_FULL_NAME " (" VERSION_HASH ")\n"); + if (String(VERSION_HASH).is_empty()) { + fprintf(stderr, "Engine version: %s\n", VERSION_FULL_NAME); } else { - fprintf(stderr, "Engine version: " VERSION_FULL_NAME "\n"); + fprintf(stderr, "Engine version: %s (%s)\n", VERSION_FULL_NAME, VERSION_HASH); } fprintf(stderr, "Dumping the backtrace. %s\n", msg.utf8().get_data()); diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index b26b9d1225..61a5fb999c 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -736,26 +736,7 @@ void PopupMenu::_notification(int p_what) { } } break; case NOTIFICATION_THEME_CHANGED: - case Control::NOTIFICATION_LAYOUT_DIRECTION_CHANGED: { - // Pass the layout direction to all submenus. - for (int i = 0; i < items.size(); i++) { - if (items[i].submenu.is_empty()) { - continue; - } - - Node *n = get_node(items[i].submenu); - if (!n) { - continue; - } - - PopupMenu *pm = Object::cast_to<PopupMenu>(n); - if (pm) { - pm->set_layout_direction(get_layout_direction()); - } - } - - [[fallthrough]]; - } + case Control::NOTIFICATION_LAYOUT_DIRECTION_CHANGED: case NOTIFICATION_TRANSLATION_CHANGED: { for (int i = 0; i < items.size(); i++) { items.write[i].xl_text = atr(items[i].text); diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index 9a6c87276f..a36eaaa0ee 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -905,6 +905,12 @@ String TreeItem::get_button_tooltip(int p_column, int p_idx) const { return cells[p_column].buttons[p_idx].tooltip; } +int TreeItem::get_button_id(int p_column, int p_idx) const { + ERR_FAIL_INDEX_V(p_column, cells.size(), -1); + ERR_FAIL_INDEX_V(p_idx, cells[p_column].buttons.size(), -1); + return cells[p_column].buttons[p_idx].id; +} + void TreeItem::erase_button(int p_column, int p_idx) { ERR_FAIL_INDEX(p_column, cells.size()); ERR_FAIL_INDEX(p_idx, cells[p_column].buttons.size()); @@ -1283,9 +1289,11 @@ void TreeItem::_bind_methods() { ClassDB::bind_method(D_METHOD("set_custom_as_button", "column", "enable"), &TreeItem::set_custom_as_button); ClassDB::bind_method(D_METHOD("is_custom_set_as_button", "column"), &TreeItem::is_custom_set_as_button); - ClassDB::bind_method(D_METHOD("add_button", "column", "button", "button_idx", "disabled", "tooltip"), &TreeItem::add_button, DEFVAL(-1), DEFVAL(false), DEFVAL("")); + ClassDB::bind_method(D_METHOD("add_button", "column", "button", "id", "disabled", "tooltip"), &TreeItem::add_button, DEFVAL(-1), DEFVAL(false), DEFVAL("")); ClassDB::bind_method(D_METHOD("get_button_count", "column"), &TreeItem::get_button_count); ClassDB::bind_method(D_METHOD("get_button_tooltip", "column", "button_idx"), &TreeItem::get_button_tooltip); + ClassDB::bind_method(D_METHOD("get_button_id", "column", "button_idx"), &TreeItem::get_button_id); + ClassDB::bind_method(D_METHOD("get_button_by_id", "column", "id"), &TreeItem::get_button_by_id); ClassDB::bind_method(D_METHOD("get_button", "column", "button_idx"), &TreeItem::get_button); ClassDB::bind_method(D_METHOD("set_button", "column", "button_idx", "button"), &TreeItem::set_button); ClassDB::bind_method(D_METHOD("erase_button", "column", "button_idx"), &TreeItem::erase_button); @@ -4856,6 +4864,7 @@ void Tree::_bind_methods() { ClassDB::bind_method(D_METHOD("get_item_at_position", "position"), &Tree::get_item_at_position); ClassDB::bind_method(D_METHOD("get_column_at_position", "position"), &Tree::get_column_at_position); ClassDB::bind_method(D_METHOD("get_drop_section_at_position", "position"), &Tree::get_drop_section_at_position); + ClassDB::bind_method(D_METHOD("get_button_id_at_position", "position"), &Tree::get_button_id_at_position); ClassDB::bind_method(D_METHOD("ensure_cursor_is_visible"), &Tree::ensure_cursor_is_visible); diff --git a/scene/gui/tree.h b/scene/gui/tree.h index 255a4f0576..dc786de6dc 100644 --- a/scene/gui/tree.h +++ b/scene/gui/tree.h @@ -248,6 +248,7 @@ public: int get_button_count(int p_column) const; String get_button_tooltip(int p_column, int p_idx) const; Ref<Texture2D> get_button(int p_column, int p_idx) const; + int get_button_id(int p_column, int p_idx) const; void erase_button(int p_column, int p_idx); int get_button_by_id(int p_column, int p_id) const; void set_button(int p_column, int p_idx, const Ref<Texture2D> &p_button); |