diff options
39 files changed, 189 insertions, 101 deletions
diff --git a/core/config/engine.cpp b/core/config/engine.cpp index d714ec42c2..9f4bff3779 100644 --- a/core/config/engine.cpp +++ b/core/config/engine.cpp @@ -266,6 +266,12 @@ void Engine::print_header(const String &p_string) const { } } +void Engine::print_header_rich(const String &p_string) const { + if (_print_header) { + print_line_rich(p_string); + } +} + void Engine::add_singleton(const Singleton &p_singleton) { ERR_FAIL_COND_MSG(singleton_ptrs.has(p_singleton.name), vformat("Can't register singleton '%s' because it already exists.", p_singleton.name)); singletons.push_back(p_singleton); diff --git a/core/config/engine.h b/core/config/engine.h index be7cd62f66..d1495b36c2 100644 --- a/core/config/engine.h +++ b/core/config/engine.h @@ -126,6 +126,7 @@ public: void set_print_error_messages(bool p_enabled); bool is_printing_error_messages() const; void print_header(const String &p_string) const; + void print_header_rich(const String &p_string) const; void set_frame_delay(uint32_t p_msec); uint32_t get_frame_delay() const; diff --git a/core/extension/gdextension.cpp b/core/extension/gdextension.cpp index 5d43dceece..0ed4c3380c 100644 --- a/core/extension/gdextension.cpp +++ b/core/extension/gdextension.cpp @@ -735,7 +735,7 @@ Error GDExtension::open_library(const String &p_path, const String &p_entry_symb bool library_copied = false; if (Engine::get_singleton()->is_editor_hint()) { if (!FileAccess::exists(abs_path)) { - ERR_PRINT("GDExtension library not found: " + library_path); + ERR_PRINT("GDExtension library not found: " + abs_path); return ERR_FILE_NOT_FOUND; } @@ -750,7 +750,7 @@ Error GDExtension::open_library(const String &p_path, const String &p_entry_symb Error copy_err = DirAccess::copy_absolute(abs_path, copy_path); if (copy_err) { - ERR_PRINT("Error copying GDExtension library: " + library_path); + ERR_PRINT("Error copying GDExtension library: " + abs_path); return ERR_CANT_CREATE; } FileAccess::set_hidden_attribute(copy_path, true); diff --git a/core/variant/type_info.h b/core/variant/type_info.h index 32c410463b..9c52db3345 100644 --- a/core/variant/type_info.h +++ b/core/variant/type_info.h @@ -296,6 +296,7 @@ public: _FORCE_INLINE_ constexpr BitField(T p_value) { value = (int64_t)p_value; } _FORCE_INLINE_ operator int64_t() const { return value; } _FORCE_INLINE_ operator Variant() const { return value; } + _FORCE_INLINE_ BitField<T> operator^(const BitField<T> &p_b) const { return BitField<T>(value ^ p_b.value); } }; #define TEMPL_MAKE_BITFIELD_TYPE_INFO(m_enum, m_impl) \ diff --git a/doc/classes/CollisionPolygon2D.xml b/doc/classes/CollisionPolygon2D.xml index 12f7024518..29535ffd64 100644 --- a/doc/classes/CollisionPolygon2D.xml +++ b/doc/classes/CollisionPolygon2D.xml @@ -4,7 +4,7 @@ A node that provides a polygon shape to a [CollisionObject2D] parent. </brief_description> <description> - A node that provides a thickened polygon shape (a prism) to a [CollisionObject2D] parent and allows to edit it. The polygon can be concave or convex. This can give a detection shape to an [Area2D] or turn [PhysicsBody2D] into a solid object. + A node that provides a polygon shape to a [CollisionObject2D] parent and allows to edit it. The polygon can be concave or convex. This can give a detection shape to an [Area2D], turn [PhysicsBody2D] into a solid object, or give a hollow shape to a [StaticBody2D]. [b]Warning:[/b] A non-uniformly scaled [CollisionShape2D] will likely not behave as expected. Make sure to keep its scale the same on all axes and adjust its shape resource instead. </description> <tutorials> diff --git a/doc/classes/Node.xml b/doc/classes/Node.xml index 1ddcdce439..e6fdd229bf 100644 --- a/doc/classes/Node.xml +++ b/doc/classes/Node.xml @@ -100,7 +100,7 @@ <return type="void" /> <param index="0" name="event" type="InputEvent" /> <description> - Called when an [InputEventKey] or [InputEventShortcut] hasn't been consumed by [method _input] or any GUI [Control] item. It is called before [method _unhandled_key_input] and [method _unhandled_input]. The input event propagates up through the node tree until a node consumes it. + Called when an [InputEventKey], [InputEventShortcut], or [InputEventJoypadButton] hasn't been consumed by [method _input] or any GUI [Control] item. It is called before [method _unhandled_key_input] and [method _unhandled_input]. The input event propagates up through the node tree until a node consumes it. It is only called if shortcut processing is enabled, which is done automatically if this method is overridden, and can be toggled with [method set_process_shortcut_input]. To consume the input event and stop it propagating further to other nodes, [method Viewport.set_input_as_handled] can be called. This method can be used to handle shortcuts. For generic GUI events, use [method _input] instead. Gameplay events should usually be handled with either [method _unhandled_input] or [method _unhandled_key_input]. diff --git a/editor/SCsub b/editor/SCsub index 442d0a3b75..f4d30b68b1 100644 --- a/editor/SCsub +++ b/editor/SCsub @@ -104,6 +104,7 @@ if env.editor_build: # Extractable translations tlist = glob.glob(env.Dir("#editor/translations/extractable").abspath + "/*.po") + tlist.extend(glob.glob(env.Dir("#editor/translations/extractable").abspath + "/extractable.pot")) env.Depends("#editor/extractable_translations.gen.h", tlist) env.CommandNoCache( "#editor/extractable_translations.gen.h", diff --git a/editor/debugger/editor_performance_profiler.cpp b/editor/debugger/editor_performance_profiler.cpp index ffff362a94..da75715b6d 100644 --- a/editor/debugger/editor_performance_profiler.cpp +++ b/editor/debugger/editor_performance_profiler.cpp @@ -84,7 +84,7 @@ String EditorPerformanceProfiler::_create_label(float p_value, Performance::Moni return String::humanize_size(p_value); } case Performance::MONITOR_TYPE_TIME: { - return TS->format_number(rtos(p_value * 1000).pad_decimals(2)) + " " + RTR("ms"); + return TS->format_number(rtos(p_value * 1000).pad_decimals(2)) + " " + TTR("ms"); } default: { return TS->format_number(rtos(p_value)); diff --git a/editor/debugger/editor_profiler.cpp b/editor/debugger/editor_profiler.cpp index c1500631fe..ce08d40634 100644 --- a/editor/debugger/editor_profiler.cpp +++ b/editor/debugger/editor_profiler.cpp @@ -125,12 +125,12 @@ String EditorProfiler::_get_time_as_text(const Metric &m, float p_time, int p_ca const int dmode = display_mode->get_selected(); if (dmode == DISPLAY_FRAME_TIME) { - return TS->format_number(rtos(p_time * 1000).pad_decimals(2)) + " " + RTR("ms"); + return TS->format_number(rtos(p_time * 1000).pad_decimals(2)) + " " + TTR("ms"); } else if (dmode == DISPLAY_AVERAGE_TIME) { if (p_calls == 0) { - return TS->format_number("0.00") + " " + RTR("ms"); + return TS->format_number("0.00") + " " + TTR("ms"); } else { - return TS->format_number(rtos((p_time / p_calls) * 1000).pad_decimals(2)) + " " + RTR("ms"); + return TS->format_number(rtos((p_time / p_calls) * 1000).pad_decimals(2)) + " " + TTR("ms"); } } else if (dmode == DISPLAY_FRAME_PERCENT) { return _get_percent_txt(p_time, m.frame_time); diff --git a/editor/debugger/editor_visual_profiler.cpp b/editor/debugger/editor_visual_profiler.cpp index 72f1060589..8a5c464c2f 100644 --- a/editor/debugger/editor_visual_profiler.cpp +++ b/editor/debugger/editor_visual_profiler.cpp @@ -116,7 +116,7 @@ String EditorVisualProfiler::_get_time_as_text(float p_time) { int dmode = display_mode->get_selected(); if (dmode == DISPLAY_FRAME_TIME) { - return TS->format_number(String::num(p_time, 2)) + " " + RTR("ms"); + return TS->format_number(String::num(p_time, 2)) + " " + TTR("ms"); } else if (dmode == DISPLAY_FRAME_PERCENT) { return TS->format_number(String::num(p_time * 100 / graph_limit, 2)) + " " + TS->percent_sign(); } diff --git a/editor/editor_builders.py b/editor/editor_builders.py index 68595047fe..a25f4949c4 100644 --- a/editor/editor_builders.py +++ b/editor/editor_builders.py @@ -61,7 +61,9 @@ def make_translations_header(target, source, env, category): xl_names = [] for i in range(len(sorted_paths)): - if msgfmt_available: + name = os.path.splitext(os.path.basename(sorted_paths[i]))[0] + # msgfmt erases non-translated messages, so avoid using it if exporting the POT. + if msgfmt_available and name != category: mo_path = os.path.join(tempfile.gettempdir(), uuid.uuid4().hex + ".mo") cmd = "msgfmt " + sorted_paths[i] + " --no-hash -o " + mo_path try: @@ -79,7 +81,7 @@ def make_translations_header(target, source, env, category): try: os.remove(mo_path) except OSError as e: - # Do not fail the entire build if it cannot delete a temporary file + # Do not fail the entire build if it cannot delete a temporary file. print( "WARNING: Could not delete temporary .mo file: path=%r; [%s] %s" % (mo_path, e.__class__.__name__, e) @@ -88,11 +90,13 @@ def make_translations_header(target, source, env, category): with open(sorted_paths[i], "rb") as f: buf = f.read() + if name == category: + name = "source" + decomp_size = len(buf) # Use maximum zlib compression level to further reduce file size # (at the cost of initial build times). buf = zlib.compress(buf, zlib.Z_BEST_COMPRESSION) - name = os.path.splitext(os.path.basename(sorted_paths[i]))[0] g.write("static const unsigned char _{}_translation_{}_compressed[] = {{\n".format(category, name)) for j in range(len(buf)): diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp index 0e3b408996..b7380c9fc2 100644 --- a/editor/editor_properties.cpp +++ b/editor/editor_properties.cpp @@ -2630,16 +2630,22 @@ void EditorPropertyColor::_set_read_only(bool p_read_only) { } void EditorPropertyColor::_color_changed(const Color &p_color) { + if (!live_changes_enabled) { + return; + } + // Cancel the color change if the current color is identical to the new one. - if (get_edited_property_value() == p_color) { + if (((Color)get_edited_property_value()).is_equal_approx(p_color)) { return; } - emit_changed(get_edited_property(), p_color, "", true); + // Preview color change, bypassing undo/redo. + get_edited_object()->set(get_edited_property(), p_color); } void EditorPropertyColor::_popup_closed() { - if (picker->get_pick_color() != last_color) { + get_edited_object()->set(get_edited_property(), last_color); + if (!picker->get_pick_color().is_equal_approx(last_color)) { emit_changed(get_edited_property(), picker->get_pick_color(), "", false); } } @@ -2682,6 +2688,10 @@ void EditorPropertyColor::setup(bool p_show_alpha) { picker->set_edit_alpha(p_show_alpha); } +void EditorPropertyColor::set_live_changes_enabled(bool p_enabled) { + live_changes_enabled = p_enabled; +} + EditorPropertyColor::EditorPropertyColor() { picker = memnew(ColorPickerButton); add_child(picker); diff --git a/editor/editor_properties.h b/editor/editor_properties.h index fa759d5d19..ce164733fe 100644 --- a/editor/editor_properties.h +++ b/editor/editor_properties.h @@ -621,10 +621,10 @@ class EditorPropertyColor : public EditorProperty { ColorPickerButton *picker = nullptr; void _color_changed(const Color &p_color); void _popup_closed(); - void _picker_created(); void _picker_opening(); Color last_color; + bool live_changes_enabled = true; protected: virtual void _set_read_only(bool p_read_only) override; @@ -633,6 +633,7 @@ protected: public: virtual void update_property() override; void setup(bool p_show_alpha); + void set_live_changes_enabled(bool p_enabled); EditorPropertyColor(); }; diff --git a/editor/editor_translation.cpp b/editor/editor_translation.cpp index 302a81669d..194d78326d 100644 --- a/editor/editor_translation.cpp +++ b/editor/editor_translation.cpp @@ -160,20 +160,22 @@ List<StringName> get_extractable_message_list() { ExtractableTranslationList *etl = _extractable_translations; List<StringName> msgids; while (etl->data) { - Vector<uint8_t> data; - data.resize(etl->uncomp_size); - int ret = Compression::decompress(data.ptrw(), etl->uncomp_size, etl->data, etl->comp_size, Compression::MODE_DEFLATE); - ERR_FAIL_COND_V_MSG(ret == -1, msgids, "Compressed file is corrupt."); + if (!strcmp(etl->lang, "source")) { + Vector<uint8_t> data; + data.resize(etl->uncomp_size); + int ret = Compression::decompress(data.ptrw(), etl->uncomp_size, etl->data, etl->comp_size, Compression::MODE_DEFLATE); + ERR_FAIL_COND_V_MSG(ret == -1, msgids, "Compressed file is corrupt."); - Ref<FileAccessMemory> fa; - fa.instantiate(); - fa->open_custom(data.ptr(), data.size()); + Ref<FileAccessMemory> fa; + fa.instantiate(); + fa->open_custom(data.ptr(), data.size()); - Ref<Translation> tr = TranslationLoaderPO::load_translation(fa); + Ref<Translation> tr = TranslationLoaderPO::load_translation(fa); - if (tr.is_valid()) { - tr->get_message_list(&msgids); - break; + if (tr.is_valid()) { + tr->get_message_list(&msgids); + break; + } } etl++; diff --git a/editor/plugins/font_config_plugin.cpp b/editor/plugins/font_config_plugin.cpp index 70911ea364..be7ff6ba3e 100644 --- a/editor/plugins/font_config_plugin.cpp +++ b/editor/plugins/font_config_plugin.cpp @@ -716,7 +716,7 @@ void EditorPropertyOTFeatures::update_property() { } for (int i = 0; i < FGRP_MAX; i++) { if (have_sub[i]) { - menu->add_submenu_node_item(RTR(group_names[i]), menu_sub[i]); + menu->add_submenu_node_item(TTRGET(group_names[i]), menu_sub[i]); } } @@ -848,15 +848,15 @@ EditorPropertyOTFeatures::EditorPropertyOTFeatures() { menu_sub[i]->connect("id_pressed", callable_mp(this, &EditorPropertyOTFeatures::_add_feature)); } - group_names[FGRP_STYLISTIC_SET] = "Stylistic Sets"; - group_names[FGRP_CHARACTER_VARIANT] = "Character Variants"; - group_names[FGRP_CAPITLS] = "Capitals"; - group_names[FGRP_LIGATURES] = "Ligatures"; - group_names[FGRP_ALTERNATES] = "Alternates"; - group_names[FGRP_EAL] = "East Asian Language"; - group_names[FGRP_EAW] = "East Asian Widths"; - group_names[FGRP_NUMAL] = "Numeral Alignment"; - group_names[FGRP_CUSTOM] = "Custom"; + group_names[FGRP_STYLISTIC_SET] = TTRC("Stylistic Sets"); + group_names[FGRP_CHARACTER_VARIANT] = TTRC("Character Variants"); + group_names[FGRP_CAPITLS] = TTRC("Capitals"); + group_names[FGRP_LIGATURES] = TTRC("Ligatures"); + group_names[FGRP_ALTERNATES] = TTRC("Alternates"); + group_names[FGRP_EAL] = TTRC("East Asian Language"); + group_names[FGRP_EAW] = TTRC("East Asian Widths"); + group_names[FGRP_NUMAL] = TTRC("Numeral Alignment"); + group_names[FGRP_CUSTOM] = TTRC("Custom"); } /*************************************************************************/ diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index 7a4a7ddaec..468d7fb051 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -691,11 +691,11 @@ Vector3 Node3DEditorViewport::_get_camera_position() const { return _get_camera_transform().origin; } -Point2 Node3DEditorViewport::_point_to_screen(const Vector3 &p_point) { +Point2 Node3DEditorViewport::point_to_screen(const Vector3 &p_point) { return camera->unproject_position(p_point) * subviewport_container->get_stretch_shrink(); } -Vector3 Node3DEditorViewport::_get_ray_pos(const Vector2 &p_pos) const { +Vector3 Node3DEditorViewport::get_ray_pos(const Vector2 &p_pos) const { return camera->project_ray_origin(p_pos / subviewport_container->get_stretch_shrink()); } @@ -703,7 +703,7 @@ Vector3 Node3DEditorViewport::_get_camera_normal() const { return -_get_camera_transform().basis.get_column(2); } -Vector3 Node3DEditorViewport::_get_ray(const Vector2 &p_pos) const { +Vector3 Node3DEditorViewport::get_ray(const Vector2 &p_pos) const { return camera->project_ray_normal(p_pos / subviewport_container->get_stretch_shrink()); } @@ -769,8 +769,8 @@ void Node3DEditorViewport::_select_clicked(bool p_allow_locked) { } ObjectID Node3DEditorViewport::_select_ray(const Point2 &p_pos) const { - Vector3 ray = _get_ray(p_pos); - Vector3 pos = _get_ray_pos(p_pos); + Vector3 ray = get_ray(p_pos); + Vector3 pos = get_ray_pos(p_pos); Vector2 shrinked_pos = p_pos / subviewport_container->get_stretch_shrink(); if (viewport->get_debug_draw() == Viewport::DEBUG_DRAW_SDFGI_PROBES) { @@ -837,8 +837,8 @@ ObjectID Node3DEditorViewport::_select_ray(const Point2 &p_pos) const { } void Node3DEditorViewport::_find_items_at_pos(const Point2 &p_pos, Vector<_RayResult> &r_results, bool p_include_locked_nodes) { - Vector3 ray = _get_ray(p_pos); - Vector3 pos = _get_ray_pos(p_pos); + Vector3 ray = get_ray(p_pos); + Vector3 pos = get_ray_pos(p_pos); Vector<ObjectID> instances = RenderingServer::get_singleton()->instances_cull_ray(pos, pos + ray * camera->get_far(), get_tree()->get_root()->get_world_3d()->get_scenario()); HashSet<Node3D *> found_nodes; @@ -1153,8 +1153,8 @@ void Node3DEditorViewport::_update_name() { 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.click_ray = get_ray(p_point); + _edit.click_ray_pos = get_ray_pos(p_point); _edit.plane = TRANSFORM_VIEW; spatial_editor->update_transform_gizmo(); _edit.center = spatial_editor->get_gizmo_transform().origin; @@ -1233,8 +1233,8 @@ bool Node3DEditorViewport::_transform_gizmo_select(const Vector2 &p_screenpos, b return false; } - Vector3 ray_pos = _get_ray_pos(p_screenpos); - Vector3 ray = _get_ray(p_screenpos); + Vector3 ray_pos = get_ray_pos(p_screenpos); + Vector3 ray = get_ray(p_screenpos); Transform3D gt = spatial_editor->get_gizmo_transform(); @@ -3115,7 +3115,7 @@ void Node3DEditorViewport::_draw() { } if (_edit.mode == TRANSFORM_ROTATE && _edit.show_rotation_line) { - Point2 center = _point_to_screen(_edit.center); + Point2 center = point_to_screen(_edit.center); Color handle_color; switch (_edit.plane) { @@ -4087,8 +4087,8 @@ Vector3 Node3DEditorViewport::_get_instance_position(const Point2 &p_pos) const const float MAX_DISTANCE = 50.0; const float FALLBACK_DISTANCE = 5.0; - Vector3 world_ray = _get_ray(p_pos); - Vector3 world_pos = _get_ray_pos(p_pos); + Vector3 world_ray = get_ray(p_pos); + Vector3 world_pos = get_ray_pos(p_pos); PhysicsDirectSpaceState3D *ss = get_tree()->get_root()->get_world_3d()->get_direct_space_state(); @@ -4250,8 +4250,8 @@ bool Node3DEditorViewport::_apply_preview_material(ObjectID p_target, const Poin Ref<Mesh> mesh = mesh_instance->get_mesh(); int surface_count = mesh->get_surface_count(); - Vector3 world_ray = _get_ray(p_point); - Vector3 world_pos = _get_ray_pos(p_point); + Vector3 world_ray = get_ray(p_point); + Vector3 world_pos = get_ray_pos(p_point); int closest_surface = -1; float closest_dist = 1e20; @@ -4698,8 +4698,8 @@ void Node3DEditorViewport::apply_transform(Vector3 p_motion, double p_snap) { // Update the current transform operation in response to an input. void Node3DEditorViewport::update_transform(bool p_shift) { - Vector3 ray_pos = _get_ray_pos(_edit.mouse_pos); - Vector3 ray = _get_ray(_edit.mouse_pos); + Vector3 ray_pos = get_ray_pos(_edit.mouse_pos); + Vector3 ray = get_ray(_edit.mouse_pos); double snap = EDITOR_GET("interface/inspector/default_float_step"); int snap_step_decimals = Math::range_step_decimals(snap); diff --git a/editor/plugins/node_3d_editor_plugin.h b/editor/plugins/node_3d_editor_plugin.h index 091432b35a..7ddbb74006 100644 --- a/editor/plugins/node_3d_editor_plugin.h +++ b/editor/plugins/node_3d_editor_plugin.h @@ -271,9 +271,7 @@ private: void _select_clicked(bool p_allow_locked); ObjectID _select_ray(const Point2 &p_pos) const; void _find_items_at_pos(const Point2 &p_pos, Vector<_RayResult> &r_results, bool p_include_locked); - Vector3 _get_ray_pos(const Vector2 &p_pos) const; - Vector3 _get_ray(const Vector2 &p_pos) const; - Point2 _point_to_screen(const Vector3 &p_point); + Transform3D _get_camera_transform() const; int get_selected_count() const; void cancel_transform(); @@ -481,6 +479,10 @@ public: void reset(); bool is_freelook_active() const { return freelook_active; } + Vector3 get_ray_pos(const Vector2 &p_pos) const; + Vector3 get_ray(const Vector2 &p_pos) const; + Point2 point_to_screen(const Vector3 &p_point); + void focus_selection(); void assign_pending_data_pointers( diff --git a/editor/plugins/packed_scene_translation_parser_plugin.cpp b/editor/plugins/packed_scene_translation_parser_plugin.cpp index 86df57c469..e266a3241b 100644 --- a/editor/plugins/packed_scene_translation_parser_plugin.cpp +++ b/editor/plugins/packed_scene_translation_parser_plugin.cpp @@ -136,6 +136,10 @@ Error PackedSceneEditorTranslationParserPlugin::parse_file(const String &p_path, if (property_name == "script" && property_value.get_type() == Variant::OBJECT && !property_value.is_null()) { // Parse built-in script. Ref<Script> s = Object::cast_to<Script>(property_value); + if (!s->is_built_in()) { + continue; + } + String extension = s->get_language()->get_extension(); if (EditorTranslationParser::get_singleton()->can_parse(extension)) { Vector<String> temp; diff --git a/editor/plugins/path_3d_editor_plugin.cpp b/editor/plugins/path_3d_editor_plugin.cpp index ffdc06ceee..e4522f5a03 100644 --- a/editor/plugins/path_3d_editor_plugin.cpp +++ b/editor/plugins/path_3d_editor_plugin.cpp @@ -473,6 +473,17 @@ EditorPlugin::AfterGUIInput Path3DEditorPlugin::forward_3d_gui_input(Camera3D *p if (mb.is_valid()) { Point2 mbpos(mb->get_position().x, mb->get_position().y); + Node3DEditorViewport *viewport = nullptr; + for (uint32_t i = 0; i < Node3DEditor::VIEWPORTS_COUNT; i++) { + Node3DEditorViewport *vp = Node3DEditor::get_singleton()->get_editor_viewport(i); + if (vp->get_camera_3d() == p_camera) { + viewport = vp; + break; + } + } + + ERR_FAIL_NULL_V(viewport, EditorPlugin::AFTER_GUI_INPUT_PASS); + if (!mb->is_pressed()) { set_handle_clicked(false); } @@ -489,14 +500,14 @@ EditorPlugin::AfterGUIInput Path3DEditorPlugin::forward_3d_gui_input(Camera3D *p const Vector3 *r = v3a.ptr(); float closest_d = 1e20; - if (p_camera->unproject_position(gt.xform(c->get_point_position(0))).distance_to(mbpos) < click_dist) { + if (viewport->point_to_screen(gt.xform(c->get_point_position(0))).distance_to(mbpos) < click_dist) { return EditorPlugin::AFTER_GUI_INPUT_PASS; //nope, existing } for (int i = 0; i < c->get_point_count() - 1; i++) { //find the offset and point index of the place to break up int j = idx; - if (p_camera->unproject_position(gt.xform(c->get_point_position(i + 1))).distance_to(mbpos) < click_dist) { + if (viewport->point_to_screen(gt.xform(c->get_point_position(i + 1))).distance_to(mbpos) < click_dist) { return EditorPlugin::AFTER_GUI_INPUT_PASS; //nope, existing } @@ -508,16 +519,16 @@ EditorPlugin::AfterGUIInput Path3DEditorPlugin::forward_3d_gui_input(Camera3D *p to = gt.xform(to); if (cdist > 0) { Vector2 s[2]; - s[0] = p_camera->unproject_position(from); - s[1] = p_camera->unproject_position(to); + s[0] = viewport->point_to_screen(from); + s[1] = viewport->point_to_screen(to); Vector2 inters = Geometry2D::get_closest_point_to_segment(mbpos, s); float d = inters.distance_to(mbpos); if (d < 10 && d < closest_d) { closest_d = d; closest_seg = i; - Vector3 ray_from = p_camera->project_ray_origin(mbpos); - Vector3 ray_dir = p_camera->project_ray_normal(mbpos); + Vector3 ray_from = viewport->get_ray_pos(mbpos); + Vector3 ray_dir = viewport->get_ray(mbpos); Vector3 ra, rb; Geometry3D::get_closest_points_between_segments(ray_from, ray_from + ray_dir * 4096, from, to, ra, rb); @@ -557,8 +568,8 @@ EditorPlugin::AfterGUIInput Path3DEditorPlugin::forward_3d_gui_input(Camera3D *p origin = gt.xform(c->get_point_position(c->get_point_count() - 1)); } Plane p(p_camera->get_transform().basis.get_column(2), origin); - Vector3 ray_from = p_camera->project_ray_origin(mbpos); - Vector3 ray_dir = p_camera->project_ray_normal(mbpos); + Vector3 ray_from = viewport->get_ray_pos(mbpos); + Vector3 ray_dir = viewport->get_ray(mbpos); Vector3 inters; if (p.intersects_ray(ray_from, ray_dir, &inters)) { @@ -574,10 +585,10 @@ EditorPlugin::AfterGUIInput Path3DEditorPlugin::forward_3d_gui_input(Camera3D *p } else if (mb->is_pressed() && ((mb->get_button_index() == MouseButton::LEFT && curve_del->is_pressed()) || (mb->get_button_index() == MouseButton::RIGHT && curve_edit->is_pressed()))) { for (int i = 0; i < c->get_point_count(); i++) { - real_t dist_to_p = p_camera->unproject_position(gt.xform(c->get_point_position(i))).distance_to(mbpos); - real_t dist_to_p_out = p_camera->unproject_position(gt.xform(c->get_point_position(i) + c->get_point_out(i))).distance_to(mbpos); - real_t dist_to_p_in = p_camera->unproject_position(gt.xform(c->get_point_position(i) + c->get_point_in(i))).distance_to(mbpos); - real_t dist_to_p_up = p_camera->unproject_position(gt.xform(c->get_point_position(i) + c->get_point_baked_posture(i, true).get_column(1) * disk_size)).distance_to(mbpos); + real_t dist_to_p = viewport->point_to_screen(gt.xform(c->get_point_position(i))).distance_to(mbpos); + real_t dist_to_p_out = viewport->point_to_screen(gt.xform(c->get_point_position(i) + c->get_point_out(i))).distance_to(mbpos); + real_t dist_to_p_in = viewport->point_to_screen(gt.xform(c->get_point_position(i) + c->get_point_in(i))).distance_to(mbpos); + real_t dist_to_p_up = viewport->point_to_screen(gt.xform(c->get_point_position(i) + c->get_point_baked_posture(i, true).get_column(1) * disk_size)).distance_to(mbpos); // Find the offset and point index of the place to break up. // Also check for the control points. diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp index c093f556ea..640c755ccf 100644 --- a/editor/plugins/script_text_editor.cpp +++ b/editor/plugins/script_text_editor.cpp @@ -1164,11 +1164,22 @@ void ScriptTextEditor::_update_connected_methods() { // Add override icons to methods. methods_found.clear(); for (int i = 0; i < functions.size(); i++) { - StringName name = StringName(functions[i].get_slice(":", 0)); + String raw_name = functions[i].get_slice(":", 0); + StringName name = StringName(raw_name); if (methods_found.has(name)) { continue; } + // Account for inner classes + if (raw_name.contains(".")) { + // Strip inner class name from the method, and start from the right since + // our inner class might be inside another inner class + int pos = raw_name.rfind("."); + if (pos != -1) { + name = raw_name.substr(pos + 1); + } + } + String found_base_class; StringName base_class = script->get_instance_base_type(); Ref<Script> inherited_script = script->get_base_script(); @@ -1217,7 +1228,7 @@ void ScriptTextEditor::_update_connected_methods() { text_edit->set_line_gutter_icon(line, connection_gutter, get_parent_control()->get_editor_theme_icon(SNAME("MethodOverrideAndSlot"))); } - methods_found.insert(name); + methods_found.insert(StringName(raw_name)); } } } diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp index 964558ee78..c83c47577d 100644 --- a/editor/plugins/visual_shader_editor_plugin.cpp +++ b/editor/plugins/visual_shader_editor_plugin.cpp @@ -6922,6 +6922,8 @@ Control *VisualShaderNodePluginDefault::create_editor(const Ref<Resource> &p_par } else if (Object::cast_to<EditorPropertyEnum>(prop)) { prop->set_custom_minimum_size(Size2(100 * EDSCALE, 0)); Object::cast_to<EditorPropertyEnum>(prop)->set_option_button_clip(false); + } else if (Object::cast_to<EditorPropertyColor>(prop)) { + Object::cast_to<EditorPropertyColor>(prop)->set_live_changes_enabled(false); } editors.push_back(prop); diff --git a/main/main.cpp b/main/main.cpp index 41f82177bc..cf40f764cf 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -398,15 +398,15 @@ void Main::print_header(bool p_rich) { if (VERSION_TIMESTAMP > 0) { // Version timestamp available. if (p_rich) { - print_line_rich("\u001b[38;5;39m" + String(VERSION_NAME) + "\u001b[0m v" + get_full_version_string() + " (" + Time::get_singleton()->get_datetime_string_from_unix_time(VERSION_TIMESTAMP, true) + " UTC) - \u001b[4m" + String(VERSION_WEBSITE)); + Engine::get_singleton()->print_header_rich("\u001b[38;5;39m" + String(VERSION_NAME) + "\u001b[0m v" + get_full_version_string() + " (" + Time::get_singleton()->get_datetime_string_from_unix_time(VERSION_TIMESTAMP, true) + " UTC) - \u001b[4m" + String(VERSION_WEBSITE)); } else { - print_line(String(VERSION_NAME) + " v" + get_full_version_string() + " (" + Time::get_singleton()->get_datetime_string_from_unix_time(VERSION_TIMESTAMP, true) + " UTC) - " + String(VERSION_WEBSITE)); + Engine::get_singleton()->print_header(String(VERSION_NAME) + " v" + get_full_version_string() + " (" + Time::get_singleton()->get_datetime_string_from_unix_time(VERSION_TIMESTAMP, true) + " UTC) - " + String(VERSION_WEBSITE)); } } else { if (p_rich) { - print_line_rich("\u001b[38;5;39m" + String(VERSION_NAME) + "\u001b[0m v" + get_full_version_string() + " - \u001b[4m" + String(VERSION_WEBSITE)); + Engine::get_singleton()->print_header_rich("\u001b[38;5;39m" + String(VERSION_NAME) + "\u001b[0m v" + get_full_version_string() + " - \u001b[4m" + String(VERSION_WEBSITE)); } else { - print_line(String(VERSION_NAME) + " v" + get_full_version_string() + " - " + String(VERSION_WEBSITE)); + Engine::get_singleton()->print_header(String(VERSION_NAME) + " v" + get_full_version_string() + " - " + String(VERSION_WEBSITE)); } } } diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs index 8d24582ba1..8679f32e1a 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Basis.cs @@ -212,7 +212,7 @@ namespace Godot private void Rotate(Quaternion quaternion) { - this *= new Basis(quaternion); + this = new Basis(quaternion) * this; } private void SetDiagonal(Vector3 diagonal) diff --git a/modules/multiplayer/editor/multiplayer_editor_plugin.cpp b/modules/multiplayer/editor/multiplayer_editor_plugin.cpp index 599926ec99..29ebc38edf 100644 --- a/modules/multiplayer/editor/multiplayer_editor_plugin.cpp +++ b/modules/multiplayer/editor/multiplayer_editor_plugin.cpp @@ -149,7 +149,7 @@ void MultiplayerEditorPlugin::_node_removed(Node *p_node) { } void MultiplayerEditorPlugin::_pinned() { - if (!repl_editor->get_pin()->is_pressed()) { + if (!repl_editor->get_pin()->is_pressed() && repl_editor->get_current() == nullptr) { if (repl_editor->is_visible_in_tree()) { EditorNode::get_bottom_panel()->hide_bottom_panel(); } diff --git a/modules/multiplayer/editor/replication_editor.cpp b/modules/multiplayer/editor/replication_editor.cpp index f6df212d35..58803124cf 100644 --- a/modules/multiplayer/editor/replication_editor.cpp +++ b/modules/multiplayer/editor/replication_editor.cpp @@ -270,6 +270,7 @@ ReplicationEditor::ReplicationEditor() { pin = memnew(Button); pin->set_theme_type_variation("FlatButton"); pin->set_toggle_mode(true); + pin->set_tooltip_text(TTR("Pin replication editor")); hb->add_child(pin); tree = memnew(Tree); diff --git a/platform/linuxbsd/wayland/wayland_thread.cpp b/platform/linuxbsd/wayland/wayland_thread.cpp index 4057587db7..7f9008e952 100644 --- a/platform/linuxbsd/wayland/wayland_thread.cpp +++ b/platform/linuxbsd/wayland/wayland_thread.cpp @@ -1563,7 +1563,7 @@ void WaylandThread::_wl_pointer_on_frame(void *data, struct wl_pointer *wl_point } if (old_pd.pressed_button_mask != pd.pressed_button_mask) { - BitField<MouseButtonMask> pressed_mask_delta = BitField<MouseButtonMask>((uint32_t)old_pd.pressed_button_mask ^ (uint32_t)pd.pressed_button_mask); + BitField<MouseButtonMask> pressed_mask_delta = old_pd.pressed_button_mask ^ pd.pressed_button_mask; const MouseButton buttons_to_test[] = { MouseButton::LEFT, diff --git a/platform/macos/native_menu_macos.h b/platform/macos/native_menu_macos.h index c00a510fd5..1d9feb64a7 100644 --- a/platform/macos/native_menu_macos.h +++ b/platform/macos/native_menu_macos.h @@ -33,7 +33,7 @@ #include "core/templates/hash_map.h" #include "core/templates/rid_owner.h" -#include "servers/native_menu.h" +#include "servers/display/native_menu.h" #import <AppKit/AppKit.h> #import <ApplicationServices/ApplicationServices.h> diff --git a/platform/windows/native_menu_windows.h b/platform/windows/native_menu_windows.h index 6eab56d8b6..74fd231903 100644 --- a/platform/windows/native_menu_windows.h +++ b/platform/windows/native_menu_windows.h @@ -33,7 +33,7 @@ #include "core/templates/hash_map.h" #include "core/templates/rid_owner.h" -#include "servers/native_menu.h" +#include "servers/display/native_menu.h" #define WIN32_LEAN_AND_MEAN #include <windows.h> diff --git a/scene/2d/physics/collision_polygon_2d.cpp b/scene/2d/physics/collision_polygon_2d.cpp index 96ef346d23..72ee4d52c5 100644 --- a/scene/2d/physics/collision_polygon_2d.cpp +++ b/scene/2d/physics/collision_polygon_2d.cpp @@ -132,17 +132,16 @@ void CollisionPolygon2D::_notification(int p_what) { } if (polygon.size() > 2) { -#define DEBUG_DECOMPOSE -#if defined(TOOLS_ENABLED) && defined(DEBUG_DECOMPOSE) - Vector<Vector<Vector2>> decomp = _decompose_in_convex(); - - Color c(0.4, 0.9, 0.1); - for (int i = 0; i < decomp.size(); i++) { - c.set_hsv(Math::fmod(c.get_h() + 0.738, 1), c.get_s(), c.get_v(), 0.5); - draw_colored_polygon(decomp[i], c); +#ifdef TOOLS_ENABLED + if (build_mode == BUILD_SOLIDS) { + Vector<Vector<Vector2>> decomp = _decompose_in_convex(); + + Color c(0.4, 0.9, 0.1); + for (int i = 0; i < decomp.size(); i++) { + c.set_hsv(Math::fmod(c.get_h() + 0.738, 1), c.get_s(), c.get_v(), 0.5); + draw_colored_polygon(decomp[i], c); + } } -#else - draw_colored_polygon(polygon, get_tree()->get_debug_collisions_color()); #endif const Color stroke_color = Color(0.9, 0.2, 0.0); diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp index ee2122f269..3b62f6c23d 100644 --- a/scene/gui/color_picker.cpp +++ b/scene/gui/color_picker.cpp @@ -714,6 +714,10 @@ Color ColorPicker::get_pick_color() const { return color; } +Color ColorPicker::get_old_color() const { + return old_color; +} + void ColorPicker::set_picker_shape(PickerShapeType p_shape) { ERR_FAIL_INDEX(p_shape, SHAPE_MAX); if (p_shape == current_shape) { @@ -1514,7 +1518,7 @@ void ColorPicker::_pick_finished() { return; } - if (Input::get_singleton()->is_key_pressed(Key::ESCAPE)) { + if (Input::get_singleton()->is_action_just_pressed(SNAME("ui_cancel"))) { set_pick_color(old_color); } else { emit_signal(SNAME("color_changed"), color); @@ -1627,7 +1631,12 @@ void ColorPicker::_html_focus_exit() { if (c_text->is_menu_visible()) { return; } - _html_submitted(c_text->get_text()); + + if (is_visible_in_tree()) { + _html_submitted(c_text->get_text()); + } else { + _update_text_value(); + } } void ColorPicker::set_can_add_swatches(bool p_enabled) { @@ -2026,6 +2035,15 @@ ColorPicker::~ColorPicker() { ///////////////// +void ColorPickerPopupPanel::_input_from_window(const Ref<InputEvent> &p_event) { + if (p_event->is_action_pressed(SNAME("ui_accept"), false, true)) { + _close_pressed(); + } + PopupPanel::_input_from_window(p_event); +} + +///////////////// + void ColorPickerButton::_about_to_popup() { set_pressed(true); if (picker) { @@ -2040,6 +2058,10 @@ void ColorPickerButton::_color_changed(const Color &p_color) { } void ColorPickerButton::_modal_closed() { + if (Input::get_singleton()->is_action_just_pressed(SNAME("ui_cancel"))) { + set_pick_color(picker->get_old_color()); + emit_signal(SNAME("color_changed"), color); + } emit_signal(SNAME("popup_closed")); set_pressed(false); } @@ -2137,7 +2159,7 @@ PopupPanel *ColorPickerButton::get_popup() { void ColorPickerButton::_update_picker() { if (!picker) { - popup = memnew(PopupPanel); + popup = memnew(ColorPickerPopupPanel); popup->set_wrap_controls(true); picker = memnew(ColorPicker); picker->set_anchors_and_offsets_preset(PRESET_FULL_RECT); diff --git a/scene/gui/color_picker.h b/scene/gui/color_picker.h index 282926d1ff..ad028584b1 100644 --- a/scene/gui/color_picker.h +++ b/scene/gui/color_picker.h @@ -317,12 +317,11 @@ public: void set_edit_alpha(bool p_show); bool is_editing_alpha() const; - int get_preset_size(); - void _set_pick_color(const Color &p_color, bool p_update_sliders); void set_pick_color(const Color &p_color); Color get_pick_color() const; void set_old_color(const Color &p_color); + Color get_old_color() const; void set_display_old_color(bool p_enabled); bool is_displaying_old_color() const; @@ -375,6 +374,10 @@ public: ~ColorPicker(); }; +class ColorPickerPopupPanel : public PopupPanel { + virtual void _input_from_window(const Ref<InputEvent> &p_event) override; +}; + class ColorPickerButton : public Button { GDCLASS(ColorPickerButton, Button); diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 29e4956588..a7cd18e1a8 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -1113,7 +1113,7 @@ void TextEdit::_notification(int p_what) { Vector<Vector2> sel = TS->shaped_text_get_selection(rid, sel_from, sel_to); // Show selection at the end of line. - if (line < get_selection_to_line(c)) { + if (line_wrap_index == line_wrap_amount && line < get_selection_to_line(c)) { if (rtl) { sel.push_back(Vector2(-char_w, 0)); } else { @@ -1123,7 +1123,7 @@ void TextEdit::_notification(int p_what) { } for (int j = 0; j < sel.size(); j++) { - Rect2 rect = Rect2(sel[j].x + char_margin + ofs_x, ofs_y, Math::ceil(sel[j].y - sel[j].x), row_height); + Rect2 rect = Rect2(sel[j].x + char_margin + ofs_x, ofs_y, Math::ceil(sel[j].y) - sel[j].x, row_height); if (rect.position.x + rect.size.x <= xmargin_beg || rect.position.x > xmargin_end) { continue; } diff --git a/servers/SCsub b/servers/SCsub index 2e4430f030..736bed68ec 100644 --- a/servers/SCsub +++ b/servers/SCsub @@ -7,7 +7,6 @@ env.servers_sources = [] env.add_source_files(env.servers_sources, "audio_server.cpp") env.add_source_files(env.servers_sources, "camera_server.cpp") env.add_source_files(env.servers_sources, "display_server.cpp") -env.add_source_files(env.servers_sources, "native_menu.cpp") env.add_source_files(env.servers_sources, "navigation_server_2d.cpp") env.add_source_files(env.servers_sources, "navigation_server_3d.cpp") env.add_source_files(env.servers_sources, "physics_server_2d.cpp") @@ -19,6 +18,7 @@ env.add_source_files(env.servers_sources, "text_server.cpp") SConscript("audio/SCsub") SConscript("camera/SCsub") SConscript("debugger/SCsub") +SConscript("display/SCsub") SConscript("extensions/SCsub") SConscript("movie_writer/SCsub") SConscript("navigation/SCsub") diff --git a/servers/display/SCsub b/servers/display/SCsub new file mode 100644 index 0000000000..86681f9c74 --- /dev/null +++ b/servers/display/SCsub @@ -0,0 +1,5 @@ +#!/usr/bin/env python + +Import("env") + +env.add_source_files(env.servers_sources, "*.cpp") diff --git a/servers/native_menu.cpp b/servers/display/native_menu.cpp index ca46560c7c..ca46560c7c 100644 --- a/servers/native_menu.cpp +++ b/servers/display/native_menu.cpp diff --git a/servers/native_menu.h b/servers/display/native_menu.h index 2bc061a216..2bc061a216 100644 --- a/servers/native_menu.h +++ b/servers/display/native_menu.h diff --git a/servers/display_server.h b/servers/display_server.h index 85b791ca69..39a80ae7c1 100644 --- a/servers/display_server.h +++ b/servers/display_server.h @@ -36,7 +36,7 @@ #include "core/os/os.h" #include "core/variant/callable.h" -#include "native_menu.h" +#include "display/native_menu.h" class Texture2D; class Image; diff --git a/servers/register_server_types.cpp b/servers/register_server_types.cpp index 223d8f44e3..c03c0b7a40 100644 --- a/servers/register_server_types.cpp +++ b/servers/register_server_types.cpp @@ -57,11 +57,11 @@ #include "camera/camera_feed.h" #include "camera_server.h" #include "debugger/servers_debugger.h" +#include "display/native_menu.h" #include "display_server.h" #include "movie_writer/movie_writer.h" #include "movie_writer/movie_writer_mjpeg.h" #include "movie_writer/movie_writer_pngwav.h" -#include "native_menu.h" #include "rendering/renderer_compositor.h" #include "rendering/renderer_rd/framebuffer_cache_rd.h" #include "rendering/renderer_rd/storage_rd/render_data_rd.h" diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp index 33bb5459f2..d78f3ba05b 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp @@ -546,6 +546,8 @@ void RenderForwardClustered::_render_list(RenderingDevice::DrawListID p_draw_lis VALID_FLAG_COMBINATION(COLOR_PASS_FLAG_MULTIVIEW); VALID_FLAG_COMBINATION(COLOR_PASS_FLAG_MULTIVIEW | COLOR_PASS_FLAG_MOTION_VECTORS); VALID_FLAG_COMBINATION(COLOR_PASS_FLAG_MOTION_VECTORS); + VALID_FLAG_COMBINATION(COLOR_PASS_FLAG_SEPARATE_SPECULAR | COLOR_PASS_FLAG_MULTIVIEW | COLOR_PASS_FLAG_MOTION_VECTORS); + VALID_FLAG_COMBINATION(COLOR_PASS_FLAG_TRANSPARENT | COLOR_PASS_FLAG_MULTIVIEW | COLOR_PASS_FLAG_MOTION_VECTORS); default: { ERR_FAIL_MSG("Invalid color pass flag combination " + itos(p_params->color_pass_flags)); } |