diff options
| -rw-r--r-- | doc/classes/@GlobalScope.xml | 2 | ||||
| -rw-r--r-- | doc/classes/String.xml | 4 | ||||
| -rw-r--r-- | doc/classes/StringName.xml | 8 | ||||
| -rw-r--r-- | drivers/metal/rendering_context_driver_metal.h | 2 | ||||
| -rw-r--r-- | drivers/metal/rendering_context_driver_metal.mm | 2 | ||||
| -rw-r--r-- | drivers/metal/rendering_device_driver_metal.h | 1 | ||||
| -rw-r--r-- | drivers/metal/rendering_device_driver_metal.mm | 6 | ||||
| -rw-r--r-- | editor/editor_help_search.cpp | 4 | ||||
| -rw-r--r-- | editor/editor_node.cpp | 12 | ||||
| -rw-r--r-- | editor/export/editor_export_platform_pc.cpp | 4 | ||||
| -rw-r--r-- | editor/plugins/canvas_item_editor_plugin.cpp | 298 | ||||
| -rw-r--r-- | editor/plugins/script_editor_plugin.cpp | 16 | ||||
| -rw-r--r-- | editor/project_manager.cpp | 19 | ||||
| -rw-r--r-- | modules/gridmap/editor/grid_map_editor_plugin.cpp | 4 | ||||
| -rw-r--r-- | pyproject.toml | 98 |
15 files changed, 268 insertions, 212 deletions
diff --git a/doc/classes/@GlobalScope.xml b/doc/classes/@GlobalScope.xml index ce64bcc17c..1721134d08 100644 --- a/doc/classes/@GlobalScope.xml +++ b/doc/classes/@GlobalScope.xml @@ -2981,7 +2981,7 @@ Editing the property prompts the user for restarting the editor. </constant> <constant name="PROPERTY_USAGE_SCRIPT_VARIABLE" value="4096" enum="PropertyUsageFlags" is_bitfield="true"> - The property is a script variable which should be serialized and saved in the scene file. + The property is a script variable. [constant PROPERTY_USAGE_SCRIPT_VARIABLE] can be used to distinguish between exported script variables from built-in variables (which don't have this usage flag). By default, [constant PROPERTY_USAGE_SCRIPT_VARIABLE] is [b]not[/b] applied to variables that are created by overriding [method Object._get_property_list] in a script. </constant> <constant name="PROPERTY_USAGE_STORE_IF_NULL" value="8192" enum="PropertyUsageFlags" is_bitfield="true"> The property value of type [Object] will be stored even if its value is [code]null[/code]. diff --git a/doc/classes/String.xml b/doc/classes/String.xml index e59734cf03..d0512b8e1c 100644 --- a/doc/classes/String.xml +++ b/doc/classes/String.xml @@ -248,7 +248,7 @@ <param index="1" name="placeholder" type="String" default=""{_}"" /> <description> Formats the string by replacing all occurrences of [param placeholder] with the elements of [param values]. - [param values] can be a [Dictionary], an [Array] or an [Object]. Any underscores in [param placeholder] will be replaced with the corresponding keys in advance. Array elements use their index as keys. + [param values] can be a [Dictionary], an [Array], or an [Object]. Any underscores in [param placeholder] will be replaced with the corresponding keys in advance. Array elements use their index as keys. [codeblock] # Prints "Waiting for Godot is a play by Samuel Beckett, and Godot Engine is named after it." var use_array_values = "Waiting for {0} is a play by {1}, and {0} Engine is named after it." @@ -265,7 +265,7 @@ [/codeblock] When passing an [Object], the property names from [method Object.get_property_list] are used as keys. [codeblock] - # Prints: Visible true, position (0, 0). + # Prints "Visible true, position (0, 0)" var node = Node2D.new() print("Visible {visible}, position {position}".format(node)) [/codeblock] diff --git a/doc/classes/StringName.xml b/doc/classes/StringName.xml index 4982bc36a8..e561ef54fa 100644 --- a/doc/classes/StringName.xml +++ b/doc/classes/StringName.xml @@ -231,7 +231,7 @@ <param index="1" name="placeholder" type="String" default=""{_}"" /> <description> Formats the string by replacing all occurrences of [param placeholder] with the elements of [param values]. - [param values] can be a [Dictionary] or an [Array]. Any underscores in [param placeholder] will be replaced with the corresponding keys in advance. Array elements use their index as keys. + [param values] can be a [Dictionary], an [Array], or an [Object]. Any underscores in [param placeholder] will be replaced with the corresponding keys in advance. Array elements use their index as keys. [codeblock] # Prints "Waiting for Godot is a play by Samuel Beckett, and Godot Engine is named after it." var use_array_values = "Waiting for {0} is a play by {1}, and {0} Engine is named after it." @@ -246,6 +246,12 @@ print("User {} is {}.".format([42, "Godot"], "{}")) print("User {id} is {name}.".format([["id", 42], ["name", "Godot"]])) [/codeblock] + When passing an [Object], the property names from [method Object.get_property_list] are used as keys. + [codeblock] + # Prints "Visible true, position (0, 0)" + var node = Node2D.new() + print("Visible {visible}, position {position}".format(node)) + [/codeblock] See also the [url=$DOCS_URL/tutorials/scripting/gdscript/gdscript_format_string.html]GDScript format string[/url] tutorial. [b]Note:[/b] Each replacement is done sequentially for each element of [param values], [b]not[/b] all at once. This means that if any element is inserted and it contains another placeholder, it may be changed by the next replacement. While this can be very useful, it often causes unexpected results. If not necessary, make sure [param values]'s elements do not contain placeholders. [codeblock] diff --git a/drivers/metal/rendering_context_driver_metal.h b/drivers/metal/rendering_context_driver_metal.h index 7e0b09186d..1fdc255f93 100644 --- a/drivers/metal/rendering_context_driver_metal.h +++ b/drivers/metal/rendering_context_driver_metal.h @@ -107,6 +107,7 @@ public: uint32_t height = 0; DisplayServer::VSyncMode vsync_mode = DisplayServer::VSYNC_ENABLED; bool needs_resize = false; + double present_minimum_duration = 0.0; Surface( #ifdef __OBJC__ @@ -123,6 +124,7 @@ public: virtual Error resize(uint32_t p_desired_framebuffer_count) = 0; virtual RDD::FramebufferID acquire_next_frame_buffer() = 0; virtual void present(MDCommandBuffer *p_cmd_buffer) = 0; + void set_max_fps(int p_max_fps) { present_minimum_duration = p_max_fps ? 1.0 / p_max_fps : 0.0; } }; #ifdef __OBJC__ diff --git a/drivers/metal/rendering_context_driver_metal.mm b/drivers/metal/rendering_context_driver_metal.mm index cf8c7e1c83..199ec25d79 100644 --- a/drivers/metal/rendering_context_driver_metal.mm +++ b/drivers/metal/rendering_context_driver_metal.mm @@ -172,7 +172,7 @@ public: count--; front = (front + 1) % frame_buffers.size(); - [p_cmd_buffer->get_command_buffer() presentDrawable:drawable]; + [p_cmd_buffer->get_command_buffer() presentDrawable:drawable afterMinimumDuration:present_minimum_duration]; } }; diff --git a/drivers/metal/rendering_device_driver_metal.h b/drivers/metal/rendering_device_driver_metal.h index e238de958e..09ab7601e9 100644 --- a/drivers/metal/rendering_device_driver_metal.h +++ b/drivers/metal/rendering_device_driver_metal.h @@ -220,6 +220,7 @@ public: virtual FramebufferID swap_chain_acquire_framebuffer(CommandQueueID p_cmd_queue, SwapChainID p_swap_chain, bool &r_resize_required) override final; virtual RenderPassID swap_chain_get_render_pass(SwapChainID p_swap_chain) override final; virtual DataFormat swap_chain_get_format(SwapChainID p_swap_chain) override final; + virtual void swap_chain_set_max_fps(SwapChainID p_swap_chain, int p_max_fps) override final; virtual void swap_chain_free(SwapChainID p_swap_chain) override final; #pragma mark - Frame Buffer diff --git a/drivers/metal/rendering_device_driver_metal.mm b/drivers/metal/rendering_device_driver_metal.mm index d90f528a14..1dec02699e 100644 --- a/drivers/metal/rendering_device_driver_metal.mm +++ b/drivers/metal/rendering_device_driver_metal.mm @@ -982,6 +982,12 @@ RDD::DataFormat RenderingDeviceDriverMetal::swap_chain_get_format(SwapChainID p_ return swap_chain->data_format; } +void RenderingDeviceDriverMetal::swap_chain_set_max_fps(SwapChainID p_swap_chain, int p_max_fps) { + SwapChain *swap_chain = (SwapChain *)(p_swap_chain.id); + RenderingContextDriverMetal::Surface *metal_surface = (RenderingContextDriverMetal::Surface *)(swap_chain->surface); + metal_surface->set_max_fps(p_max_fps); +} + void RenderingDeviceDriverMetal::swap_chain_free(SwapChainID p_swap_chain) { SwapChain *swap_chain = (SwapChain *)(p_swap_chain.id); _swap_chain_release(swap_chain); diff --git a/editor/editor_help_search.cpp b/editor/editor_help_search.cpp index b0c06475f8..0fc7052a2b 100644 --- a/editor/editor_help_search.cpp +++ b/editor/editor_help_search.cpp @@ -1166,7 +1166,7 @@ TreeItem *EditorHelpSearch::Runner::_create_class_item(TreeItem *p_parent, const if (p_matching_keyword.is_empty()) { item->set_text(0, p_doc->name); } else { - item->set_text(0, p_doc->name + " - " + TTR(vformat("Matches the \"%s\" keyword.", p_matching_keyword))); + item->set_text(0, p_doc->name + " - " + vformat(TTR("Matches the \"%s\" keyword."), p_matching_keyword)); } if (!term.is_empty()) { @@ -1272,7 +1272,7 @@ TreeItem *EditorHelpSearch::Runner::_create_member_item(TreeItem *p_parent, cons text = p_class_name + "." + p_text; } if (!p_matching_keyword.is_empty()) { - text += " - " + TTR(vformat("Matches the \"%s\" keyword.", p_matching_keyword)); + text += " - " + vformat(TTR("Matches the \"%s\" keyword."), p_matching_keyword); } item->set_text(0, text); diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 0df062c508..87f1f1b8a0 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -7706,24 +7706,28 @@ EditorNode::EditorNode() { disk_changed = memnew(ConfirmationDialog); { - disk_changed->set_title(TTR("Files have been modified on disk")); + disk_changed->set_title(TTR("Files have been modified outside Godot")); VBoxContainer *vbc = memnew(VBoxContainer); disk_changed->add_child(vbc); Label *dl = memnew(Label); - dl->set_text(TTR("The following files are newer on disk.\nWhat action should be taken?")); + dl->set_text(TTR("The following files are newer on disk:")); vbc->add_child(dl); disk_changed_list = memnew(Tree); vbc->add_child(disk_changed_list); disk_changed_list->set_v_size_flags(Control::SIZE_EXPAND_FILL); + Label *what_action_label = memnew(Label); + what_action_label->set_text(TTR("What action should be taken?")); + vbc->add_child(what_action_label); + disk_changed->connect(SceneStringName(confirmed), callable_mp(this, &EditorNode::_reload_modified_scenes)); disk_changed->connect(SceneStringName(confirmed), callable_mp(this, &EditorNode::_reload_project_settings)); - disk_changed->set_ok_button_text(TTR("Discard local changes and reload")); + disk_changed->set_ok_button_text(TTR("Reload from disk")); - disk_changed->add_button(TTR("Keep local changes and overwrite"), !DisplayServer::get_singleton()->get_swap_cancel_ok(), "resave"); + disk_changed->add_button(TTR("Ignore external changes"), !DisplayServer::get_singleton()->get_swap_cancel_ok(), "resave"); disk_changed->connect("custom_action", callable_mp(this, &EditorNode::_resave_scenes)); } diff --git a/editor/export/editor_export_platform_pc.cpp b/editor/export/editor_export_platform_pc.cpp index 4eff096840..15d684cac5 100644 --- a/editor/export/editor_export_platform_pc.cpp +++ b/editor/export/editor_export_platform_pc.cpp @@ -223,13 +223,13 @@ Error EditorExportPlatformPC::export_project_data(const Ref<EditorExportPreset> if (err == OK) { err = da->copy_dir(src_path, target_path, -1, true); if (err != OK) { - add_message(EXPORT_MESSAGE_ERROR, TTR("GDExtension"), TTR(vformat("Failed to copy shared object \"%s\".", src_path))); + add_message(EXPORT_MESSAGE_ERROR, TTR("GDExtension"), vformat(TTR("Failed to copy shared object \"%s\"."), src_path)); } } } else { err = da->copy(src_path, target_path); if (err != OK) { - add_message(EXPORT_MESSAGE_ERROR, TTR("GDExtension"), TTR(vformat("Failed to copy shared object \"%s\".", src_path))); + add_message(EXPORT_MESSAGE_ERROR, TTR("GDExtension"), vformat(TTR("Failed to copy shared object \"%s\"."), src_path)); } if (err == OK) { err = sign_shared_object(p_preset, p_debug, target_path); diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index 62793fbcb5..f91a052a24 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -1930,37 +1930,50 @@ bool CanvasItemEditor::_gui_input_scale(const Ref<InputEvent> &p_event) { // Drag resize handles if (drag_type == DRAG_NONE) { - if (b.is_valid() && b->get_button_index() == MouseButton::LEFT && b->is_pressed() && ((b->is_alt_pressed() && b->is_command_or_control_pressed()) || tool == TOOL_SCALE)) { + if (b.is_valid() && b->get_button_index() == MouseButton::LEFT && b->is_pressed() && + ((tool == TOOL_SELECT && b->is_alt_pressed() && b->is_command_or_control_pressed()) || tool == TOOL_SCALE)) { bool has_locked_items = false; List<CanvasItem *> selection = _get_edited_canvas_items(false, true, &has_locked_items); - if (selection.size() == 1) { + + // Remove non-movable nodes. + for (CanvasItem *ci : selection) { + if (!_is_node_movable(ci, true)) { + selection.erase(ci); + } + } + + if (!selection.is_empty()) { CanvasItem *ci = selection.front()->get(); - if (_is_node_movable(ci)) { - Transform2D xform = transform * ci->get_global_transform_with_canvas(); - Transform2D unscaled_transform = (xform * ci->get_transform().affine_inverse() * ci->_edit_get_transform()).orthonormalized(); - Transform2D simple_xform = viewport->get_transform() * unscaled_transform; + Transform2D edit_transform; + if (!Math::is_inf(temp_pivot.x) || !Math::is_inf(temp_pivot.y)) { + edit_transform = Transform2D(ci->_edit_get_rotation(), temp_pivot); + } else { + edit_transform = ci->_edit_get_transform(); + } - drag_type = DRAG_SCALE_BOTH; + Transform2D xform = transform * ci->get_global_transform_with_canvas(); + Transform2D unscaled_transform = (xform * ci->get_transform().affine_inverse() * edit_transform).orthonormalized(); + Transform2D simple_xform = viewport->get_transform() * unscaled_transform; - if (show_transformation_gizmos) { - Size2 scale_factor = Size2(SCALE_HANDLE_DISTANCE, SCALE_HANDLE_DISTANCE); - Rect2 x_handle_rect = Rect2(scale_factor.x * EDSCALE, -5 * EDSCALE, 10 * EDSCALE, 10 * EDSCALE); - if (x_handle_rect.has_point(simple_xform.affine_inverse().xform(b->get_position()))) { - drag_type = DRAG_SCALE_X; - } - Rect2 y_handle_rect = Rect2(-5 * EDSCALE, scale_factor.y * EDSCALE, 10 * EDSCALE, 10 * EDSCALE); - if (y_handle_rect.has_point(simple_xform.affine_inverse().xform(b->get_position()))) { - drag_type = DRAG_SCALE_Y; - } - } + drag_type = DRAG_SCALE_BOTH; - drag_from = transform.affine_inverse().xform(b->get_position()); - drag_selection = List<CanvasItem *>(); - drag_selection.push_back(ci); - _save_canvas_item_state(drag_selection); - return true; + if (show_transformation_gizmos) { + Size2 scale_factor = Size2(SCALE_HANDLE_DISTANCE, SCALE_HANDLE_DISTANCE); + Rect2 x_handle_rect = Rect2(scale_factor.x * EDSCALE, -5 * EDSCALE, 10 * EDSCALE, 10 * EDSCALE); + if (x_handle_rect.has_point(simple_xform.affine_inverse().xform(b->get_position()))) { + drag_type = DRAG_SCALE_X; + } + Rect2 y_handle_rect = Rect2(-5 * EDSCALE, scale_factor.y * EDSCALE, 10 * EDSCALE, 10 * EDSCALE); + if (y_handle_rect.has_point(simple_xform.affine_inverse().xform(b->get_position()))) { + drag_type = DRAG_SCALE_Y; + } } + + drag_from = transform.affine_inverse().xform(b->get_position()); + drag_selection = selection; + _save_canvas_item_state(drag_selection); + return true; } else { if (has_locked_items) { EditorToaster::get_singleton()->popup_str(TTR(locked_transform_warning), EditorToaster::SEVERITY_WARNING); @@ -1968,66 +1981,87 @@ bool CanvasItemEditor::_gui_input_scale(const Ref<InputEvent> &p_event) { return has_locked_items; } } - } - - if (drag_type == DRAG_SCALE_BOTH || drag_type == DRAG_SCALE_X || drag_type == DRAG_SCALE_Y) { + } else if (drag_type == DRAG_SCALE_BOTH || drag_type == DRAG_SCALE_X || drag_type == DRAG_SCALE_Y) { // Resize the node if (m.is_valid()) { _restore_canvas_item_state(drag_selection); - CanvasItem *ci = drag_selection.front()->get(); drag_to = transform.affine_inverse().xform(m->get_position()); - Transform2D parent_xform = ci->get_global_transform_with_canvas() * ci->get_transform().affine_inverse(); - Transform2D unscaled_transform = (transform * parent_xform * ci->_edit_get_transform()).orthonormalized(); - Transform2D simple_xform = (viewport->get_transform() * unscaled_transform).affine_inverse() * transform; - - bool uniform = m->is_shift_pressed(); - bool is_ctrl = m->is_command_or_control_pressed(); - - Point2 drag_from_local = simple_xform.xform(drag_from); - Point2 drag_to_local = simple_xform.xform(drag_to); - Point2 offset = drag_to_local - drag_from_local; + Size2 scale_max; + if (drag_type != DRAG_SCALE_BOTH) { + for (CanvasItem *ci : drag_selection) { + scale_max = scale_max.max(ci->_edit_get_scale()); + } + } - Size2 scale = ci->_edit_get_scale(); - Size2 original_scale = scale; - real_t ratio = scale.y / scale.x; - if (drag_type == DRAG_SCALE_BOTH) { - Size2 scale_factor = drag_to_local / drag_from_local; - if (uniform) { - scale *= (scale_factor.x + scale_factor.y) / 2.0; + for (CanvasItem *ci : drag_selection) { + Transform2D edit_transform; + bool using_temp_pivot = !Math::is_inf(temp_pivot.x) || !Math::is_inf(temp_pivot.y); + if (using_temp_pivot) { + edit_transform = Transform2D(ci->_edit_get_rotation(), temp_pivot); } else { - scale *= scale_factor; + edit_transform = ci->_edit_get_transform(); } - } else { - Size2 scale_factor = Vector2(offset.x, -offset.y) / SCALE_HANDLE_DISTANCE; - Size2 parent_scale = parent_xform.get_scale(); - scale_factor *= Vector2(1.0 / parent_scale.x, 1.0 / parent_scale.y); - if (drag_type == DRAG_SCALE_X) { - scale.x += scale_factor.x; + Transform2D parent_xform = ci->get_global_transform_with_canvas() * ci->get_transform().affine_inverse(); + Transform2D unscaled_transform = (transform * parent_xform * edit_transform).orthonormalized(); + Transform2D simple_xform = (viewport->get_transform() * unscaled_transform).affine_inverse() * transform; + + bool uniform = m->is_shift_pressed(); + bool is_ctrl = m->is_command_or_control_pressed(); + + Point2 drag_from_local = simple_xform.xform(drag_from); + Point2 drag_to_local = simple_xform.xform(drag_to); + Point2 offset = drag_to_local - drag_from_local; + + Size2 scale = ci->_edit_get_scale(); + Size2 original_scale = scale; + real_t ratio = scale.y / scale.x; + if (drag_type == DRAG_SCALE_BOTH) { + Size2 scale_factor = drag_to_local / drag_from_local; if (uniform) { - scale.y = scale.x * ratio; + scale *= (scale_factor.x + scale_factor.y) / 2.0; + } else { + scale *= scale_factor; } - } else if (drag_type == DRAG_SCALE_Y) { - scale.y -= scale_factor.y; - if (uniform) { - scale.x = scale.y / ratio; + } else { + Size2 scale_factor = Vector2(offset.x, -offset.y) / SCALE_HANDLE_DISTANCE; + Size2 parent_scale = parent_xform.get_scale(); + // Take into account the biggest scale, so all nodes are scaled uniformly. + scale_factor *= Vector2(1.0 / parent_scale.x, 1.0 / parent_scale.y) / (scale_max / original_scale); + + if (drag_type == DRAG_SCALE_X) { + scale.x += scale_factor.x; + if (uniform) { + scale.y = scale.x * ratio; + } + } else if (drag_type == DRAG_SCALE_Y) { + scale.y -= scale_factor.y; + if (uniform) { + scale.x = scale.y / ratio; + } } } - } - if (snap_scale && !is_ctrl) { - if (snap_relative) { - scale.x = original_scale.x * (roundf((scale.x / original_scale.x) / snap_scale_step) * snap_scale_step); - scale.y = original_scale.y * (roundf((scale.y / original_scale.y) / snap_scale_step) * snap_scale_step); - } else { - scale.x = roundf(scale.x / snap_scale_step) * snap_scale_step; - scale.y = roundf(scale.y / snap_scale_step) * snap_scale_step; + if (snap_scale && !is_ctrl) { + if (snap_relative) { + scale.x = original_scale.x * (Math::round((scale.x / original_scale.x) / snap_scale_step) * snap_scale_step); + scale.y = original_scale.y * (Math::round((scale.y / original_scale.y) / snap_scale_step) * snap_scale_step); + } else { + scale.x = Math::round(scale.x / snap_scale_step) * snap_scale_step; + scale.y = Math::round(scale.y / snap_scale_step) * snap_scale_step; + } + } + + ci->_edit_set_scale(scale); + + if (using_temp_pivot) { + Point2 ci_origin = ci->_edit_get_transform().get_origin(); + ci->_edit_set_position(ci_origin + (ci_origin - temp_pivot) * ((scale - original_scale) / original_scale)); } } - ci->_edit_set_scale(scale); return true; } @@ -2075,7 +2109,7 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) { if (drag_type == DRAG_NONE) { //Start moving the nodes if (b.is_valid() && b->get_button_index() == MouseButton::LEFT && b->is_pressed()) { - if ((b->is_alt_pressed() && !b->is_command_or_control_pressed()) || tool == TOOL_MOVE) { + if ((tool == TOOL_SELECT && b->is_alt_pressed() && !b->is_command_or_control_pressed()) || tool == TOOL_MOVE) { bool has_locked_items = false; List<CanvasItem *> selection = _get_edited_canvas_items(false, true, &has_locked_items); @@ -2135,7 +2169,7 @@ bool CanvasItemEditor::_gui_input_move(const Ref<InputEvent> &p_event) { } Point2 drag_delta = drag_to - drag_from; - if (drag_selection.size() == 1 && (drag_type == DRAG_MOVE_X || drag_type == DRAG_MOVE_Y)) { + if (drag_type == DRAG_MOVE_X || drag_type == DRAG_MOVE_Y) { const CanvasItem *selected = drag_selection.front()->get(); Transform2D parent_xform = selected->get_global_transform_with_canvas() * selected->get_transform().affine_inverse(); Transform2D unscaled_transform = (transform * parent_xform * selected->_edit_get_transform()).orthonormalized(); @@ -3468,16 +3502,14 @@ void CanvasItemEditor::_draw_selection() { Ref<Texture2D> previous_position_icon = get_editor_theme_icon(SNAME("EditorPositionPrevious")); RID vp_ci = viewport->get_canvas_item(); - List<CanvasItem *> selection = _get_edited_canvas_items(true, false); - bool single = selection.size() == 1; + bool transform_tool = tool == TOOL_SELECT || tool == TOOL_MOVE || tool == TOOL_SCALE || tool == TOOL_ROTATE || tool == TOOL_EDIT_PIVOT; + for (CanvasItem *E : selection) { CanvasItem *ci = Object::cast_to<CanvasItem>(E); CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(ci); - bool item_locked = ci->has_meta("_edit_lock_"); - // Draw the previous position if we are dragging the node if (show_helpers && (drag_type == DRAG_MOVE || drag_type == DRAG_ROTATE || @@ -3502,6 +3534,7 @@ void CanvasItemEditor::_draw_selection() { } } + bool item_locked = ci->has_meta("_edit_lock_"); Transform2D xform = transform * ci->get_global_transform_with_canvas(); // Draw the selected items position / surrounding boxes @@ -3531,7 +3564,7 @@ void CanvasItemEditor::_draw_selection() { viewport->draw_set_transform_matrix(viewport->get_transform()); } - if (single && !item_locked && (tool == TOOL_SELECT || tool == TOOL_MOVE || tool == TOOL_SCALE || tool == TOOL_ROTATE || tool == TOOL_EDIT_PIVOT)) { //kind of sucks + if (single && !item_locked && transform_tool) { // Draw the pivot if (ci->_edit_use_pivot()) { // Draw the node's pivot @@ -3574,73 +3607,88 @@ void CanvasItemEditor::_draw_selection() { select_handle->draw(vp_ci, (ofs - (select_handle->get_size() / 2)).floor()); } } + } + } - // Draw the move handles - bool is_ctrl = Input::get_singleton()->is_key_pressed(Key::CMD_OR_CTRL); - bool is_alt = Input::get_singleton()->is_key_pressed(Key::ALT); - if (tool == TOOL_MOVE && show_transformation_gizmos) { - if (_is_node_movable(ci)) { - Transform2D unscaled_transform = (xform * ci->get_transform().affine_inverse() * ci->_edit_get_transform()).orthonormalized(); - Transform2D simple_xform = viewport->get_transform() * unscaled_transform; + // Remove non-movable nodes. + for (CanvasItem *ci : selection) { + if (!_is_node_movable(ci, true)) { + selection.erase(ci); + } + } - Size2 move_factor = Size2(MOVE_HANDLE_DISTANCE, MOVE_HANDLE_DISTANCE); - viewport->draw_set_transform_matrix(simple_xform); + if (!selection.is_empty() && transform_tool && show_transformation_gizmos) { + CanvasItem *ci = selection.front()->get(); - Vector<Point2> points = { - Vector2(move_factor.x * EDSCALE, 5 * EDSCALE), - Vector2(move_factor.x * EDSCALE, -5 * EDSCALE), - Vector2((move_factor.x + 10) * EDSCALE, 0) - }; + Transform2D xform = transform * ci->get_global_transform_with_canvas(); + bool is_ctrl = Input::get_singleton()->is_key_pressed(Key::CMD_OR_CTRL); + bool is_alt = Input::get_singleton()->is_key_pressed(Key::ALT); - viewport->draw_colored_polygon(points, get_theme_color(SNAME("axis_x_color"), EditorStringName(Editor))); - viewport->draw_line(Point2(), Point2(move_factor.x * EDSCALE, 0), get_theme_color(SNAME("axis_x_color"), EditorStringName(Editor)), Math::round(EDSCALE)); + // Draw the move handles. + if ((tool == TOOL_SELECT && is_alt && !is_ctrl) || tool == TOOL_MOVE) { + Transform2D unscaled_transform = (xform * ci->get_transform().affine_inverse() * ci->_edit_get_transform()).orthonormalized(); + Transform2D simple_xform = viewport->get_transform() * unscaled_transform; - points.clear(); - points.push_back(Vector2(5 * EDSCALE, move_factor.y * EDSCALE)); - points.push_back(Vector2(-5 * EDSCALE, move_factor.y * EDSCALE)); - points.push_back(Vector2(0, (move_factor.y + 10) * EDSCALE)); + Size2 move_factor = Size2(MOVE_HANDLE_DISTANCE, MOVE_HANDLE_DISTANCE); + viewport->draw_set_transform_matrix(simple_xform); - viewport->draw_colored_polygon(points, get_theme_color(SNAME("axis_y_color"), EditorStringName(Editor))); - viewport->draw_line(Point2(), Point2(0, move_factor.y * EDSCALE), get_theme_color(SNAME("axis_y_color"), EditorStringName(Editor)), Math::round(EDSCALE)); + Vector<Point2> points = { + Vector2(move_factor.x * EDSCALE, 5 * EDSCALE), + Vector2(move_factor.x * EDSCALE, -5 * EDSCALE), + Vector2((move_factor.x + 10) * EDSCALE, 0) + }; - viewport->draw_set_transform_matrix(viewport->get_transform()); - } - } + viewport->draw_colored_polygon(points, get_theme_color(SNAME("axis_x_color"), EditorStringName(Editor))); + viewport->draw_line(Point2(), Point2(move_factor.x * EDSCALE, 0), get_theme_color(SNAME("axis_x_color"), EditorStringName(Editor)), Math::round(EDSCALE)); - // Draw the rescale handles - if (show_transformation_gizmos && ((is_alt && is_ctrl) || tool == TOOL_SCALE || drag_type == DRAG_SCALE_X || drag_type == DRAG_SCALE_Y)) { - if (_is_node_movable(ci)) { - Transform2D unscaled_transform = (xform * ci->get_transform().affine_inverse() * ci->_edit_get_transform()).orthonormalized(); - Transform2D simple_xform = viewport->get_transform() * unscaled_transform; + points.clear(); + points.push_back(Vector2(5 * EDSCALE, move_factor.y * EDSCALE)); + points.push_back(Vector2(-5 * EDSCALE, move_factor.y * EDSCALE)); + points.push_back(Vector2(0, (move_factor.y + 10) * EDSCALE)); - Size2 scale_factor = Size2(SCALE_HANDLE_DISTANCE, SCALE_HANDLE_DISTANCE); - bool uniform = Input::get_singleton()->is_key_pressed(Key::SHIFT); - Point2 offset = (simple_xform.affine_inverse().xform(drag_to) - simple_xform.affine_inverse().xform(drag_from)) * zoom; + viewport->draw_colored_polygon(points, get_theme_color(SNAME("axis_y_color"), EditorStringName(Editor))); + viewport->draw_line(Point2(), Point2(0, move_factor.y * EDSCALE), get_theme_color(SNAME("axis_y_color"), EditorStringName(Editor)), Math::round(EDSCALE)); - if (drag_type == DRAG_SCALE_X) { - scale_factor.x += offset.x; - if (uniform) { - scale_factor.y += offset.x; - } - } else if (drag_type == DRAG_SCALE_Y) { - scale_factor.y += offset.y; - if (uniform) { - scale_factor.x += offset.y; - } - } + viewport->draw_set_transform_matrix(viewport->get_transform()); + } - viewport->draw_set_transform_matrix(simple_xform); - Rect2 x_handle_rect = Rect2(scale_factor.x * EDSCALE, -5 * EDSCALE, 10 * EDSCALE, 10 * EDSCALE); - viewport->draw_rect(x_handle_rect, get_theme_color(SNAME("axis_x_color"), EditorStringName(Editor))); - viewport->draw_line(Point2(), Point2(scale_factor.x * EDSCALE, 0), get_theme_color(SNAME("axis_x_color"), EditorStringName(Editor)), Math::round(EDSCALE)); + // Draw the rescale handles. + if ((tool == TOOL_SELECT && is_alt && is_ctrl) || tool == TOOL_SCALE || drag_type == DRAG_SCALE_X || drag_type == DRAG_SCALE_Y) { + Transform2D edit_transform; + if (!Math::is_inf(temp_pivot.x) || !Math::is_inf(temp_pivot.y)) { + edit_transform = Transform2D(ci->_edit_get_rotation(), temp_pivot); + } else { + edit_transform = ci->_edit_get_transform(); + } + Transform2D unscaled_transform = (xform * ci->get_transform().affine_inverse() * edit_transform).orthonormalized(); + Transform2D simple_xform = viewport->get_transform() * unscaled_transform; - Rect2 y_handle_rect = Rect2(-5 * EDSCALE, scale_factor.y * EDSCALE, 10 * EDSCALE, 10 * EDSCALE); - viewport->draw_rect(y_handle_rect, get_theme_color(SNAME("axis_y_color"), EditorStringName(Editor))); - viewport->draw_line(Point2(), Point2(0, scale_factor.y * EDSCALE), get_theme_color(SNAME("axis_y_color"), EditorStringName(Editor)), Math::round(EDSCALE)); + Size2 scale_factor = Size2(SCALE_HANDLE_DISTANCE, SCALE_HANDLE_DISTANCE); + bool uniform = Input::get_singleton()->is_key_pressed(Key::SHIFT); + Point2 offset = (simple_xform.affine_inverse().xform(drag_to) - simple_xform.affine_inverse().xform(drag_from)) * zoom; - viewport->draw_set_transform_matrix(viewport->get_transform()); + if (drag_type == DRAG_SCALE_X) { + scale_factor.x += offset.x; + if (uniform) { + scale_factor.y += offset.x; + } + } else if (drag_type == DRAG_SCALE_Y) { + scale_factor.y += offset.y; + if (uniform) { + scale_factor.x += offset.y; } } + + viewport->draw_set_transform_matrix(simple_xform); + Rect2 x_handle_rect = Rect2(scale_factor.x * EDSCALE, -5 * EDSCALE, 10 * EDSCALE, 10 * EDSCALE); + viewport->draw_rect(x_handle_rect, get_theme_color(SNAME("axis_x_color"), EditorStringName(Editor))); + viewport->draw_line(Point2(), Point2(scale_factor.x * EDSCALE, 0), get_theme_color(SNAME("axis_x_color"), EditorStringName(Editor)), Math::round(EDSCALE)); + + Rect2 y_handle_rect = Rect2(-5 * EDSCALE, scale_factor.y * EDSCALE, 10 * EDSCALE, 10 * EDSCALE); + viewport->draw_rect(y_handle_rect, get_theme_color(SNAME("axis_y_color"), EditorStringName(Editor))); + viewport->draw_line(Point2(), Point2(0, scale_factor.y * EDSCALE), get_theme_color(SNAME("axis_y_color"), EditorStringName(Editor)), Math::round(EDSCALE)); + + viewport->draw_set_transform_matrix(viewport->get_transform()); } } @@ -5356,7 +5404,7 @@ CanvasItemEditor::CanvasItemEditor() { main_menu_hbox->add_child(pivot_button); pivot_button->set_toggle_mode(true); pivot_button->connect(SceneStringName(pressed), callable_mp(this, &CanvasItemEditor::_button_tool_select).bind(TOOL_EDIT_PIVOT)); - pivot_button->set_tooltip_text(TTR("Click to change object's rotation pivot.") + "\n" + TTR("Shift: Set temporary rotation pivot.") + "\n" + TTR("Click this button while holding Shift to put the temporary rotation pivot in the center of the selected nodes.")); + pivot_button->set_tooltip_text(TTR("Click to change object's pivot.") + "\n" + TTR("Shift: Set temporary pivot.") + "\n" + TTR("Click this button while holding Shift to put the temporary pivot in the center of the selected nodes.")); pan_button = memnew(Button); pan_button->set_theme_type_variation("FlatButton"); diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index 8c3979918d..49ecbac751 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -4391,28 +4391,28 @@ ScriptEditor::ScriptEditor(WindowWrapper *p_wrapper) { disk_changed = memnew(ConfirmationDialog); { - disk_changed->set_title(TTR("Files have been modified on disk")); + disk_changed->set_title(TTR("Files have been modified outside Godot")); VBoxContainer *vbc = memnew(VBoxContainer); disk_changed->add_child(vbc); Label *files_are_newer_label = memnew(Label); - files_are_newer_label->set_text(TTR("The following files are newer on disk.")); + files_are_newer_label->set_text(TTR("The following files are newer on disk:")); vbc->add_child(files_are_newer_label); - Label *what_action_label = memnew(Label); - what_action_label->set_text(TTR("What action should be taken?:")); - vbc->add_child(what_action_label); - disk_changed_list = memnew(Tree); vbc->add_child(disk_changed_list); disk_changed_list->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED); disk_changed_list->set_v_size_flags(SIZE_EXPAND_FILL); + Label *what_action_label = memnew(Label); + what_action_label->set_text(TTR("What action should be taken?")); + vbc->add_child(what_action_label); + disk_changed->connect(SceneStringName(confirmed), callable_mp(this, &ScriptEditor::reload_scripts).bind(false)); - disk_changed->set_ok_button_text(TTR("Discard local changes and reload")); + disk_changed->set_ok_button_text(TTR("Reload from disk")); - disk_changed->add_button(TTR("Keep local changes and overwrite"), !DisplayServer::get_singleton()->get_swap_cancel_ok(), "resave"); + disk_changed->add_button(TTR("Ignore external changes"), !DisplayServer::get_singleton()->get_swap_cancel_ok(), "resave"); disk_changed->connect("custom_action", callable_mp(this, &ScriptEditor::_resave_scripts)); } diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp index 30cf2030bc..eb5e8d2a72 100644 --- a/editor/project_manager.cpp +++ b/editor/project_manager.cpp @@ -34,8 +34,6 @@ #include "core/io/config_file.h" #include "core/io/dir_access.h" #include "core/io/file_access.h" -#include "core/io/resource_saver.h" -#include "core/io/stream_peer_tls.h" #include "core/os/keyboard.h" #include "core/os/os.h" #include "core/version.h" @@ -51,12 +49,9 @@ #include "editor/project_manager/project_list.h" #include "editor/project_manager/project_tag.h" #include "editor/project_manager/quick_settings_dialog.h" -#include "editor/themes/editor_icons.h" #include "editor/themes/editor_scale.h" #include "editor/themes/editor_theme_manager.h" #include "main/main.h" -#include "scene/gui/check_box.h" -#include "scene/gui/color_rect.h" #include "scene/gui/flow_container.h" #include "scene/gui/line_edit.h" #include "scene/gui/margin_container.h" @@ -64,7 +59,6 @@ #include "scene/gui/panel_container.h" #include "scene/gui/rich_text_label.h" #include "scene/gui/separator.h" -#include "scene/gui/texture_rect.h" #include "scene/main/window.h" #include "scene/theme/theme_db.h" #include "servers/display_server.h" @@ -1300,15 +1294,10 @@ ProjectManager::ProjectManager() { filter_option->connect(SceneStringName(item_selected), callable_mp(this, &ProjectManager::_on_order_option_changed)); hb->add_child(filter_option); - Vector<String> sort_filter_titles; - sort_filter_titles.push_back(TTR("Last Edited")); - sort_filter_titles.push_back(TTR("Name")); - sort_filter_titles.push_back(TTR("Path")); - sort_filter_titles.push_back(TTR("Tags")); - - for (int i = 0; i < sort_filter_titles.size(); i++) { - filter_option->add_item(sort_filter_titles[i]); - } + filter_option->add_item(TTR("Last Edited")); + filter_option->add_item(TTR("Name")); + filter_option->add_item(TTR("Path")); + filter_option->add_item(TTR("Tags")); } // Project list and its sidebar. diff --git a/modules/gridmap/editor/grid_map_editor_plugin.cpp b/modules/gridmap/editor/grid_map_editor_plugin.cpp index 432ce5ffa3..99e3b02dea 100644 --- a/modules/gridmap/editor/grid_map_editor_plugin.cpp +++ b/modules/gridmap/editor/grid_map_editor_plugin.cpp @@ -1462,9 +1462,9 @@ GridMapEditor::GridMapEditor() { floor->set_max(32767); floor->set_step(1); floor->set_tooltip_text( - TTR(vformat("Change Grid Floor:\nPrevious Plane (%s)\nNext Plane (%s)", + vformat(TTR("Change Grid Floor:\nPrevious Plane (%s)\nNext Plane (%s)"), ED_GET_SHORTCUT("grid_map/previous_floor")->get_as_text(), - ED_GET_SHORTCUT("grid_map/next_floor")->get_as_text()))); + ED_GET_SHORTCUT("grid_map/next_floor")->get_as_text())); toolbar->add_child(floor); floor->get_line_edit()->add_theme_constant_override("minimum_character_width", 2); floor->get_line_edit()->set_context_menu_enabled(false); diff --git a/pyproject.toml b/pyproject.toml index c4fbe4a459..403d9fd675 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,14 +1,14 @@ [tool.mypy] -ignore_missing_imports = true disallow_any_generics = true +explicit_package_bases = true +ignore_missing_imports = true +namespace_packages = true no_implicit_optional = true pretty = true show_column_numbers = true warn_redundant_casts = true warn_return_any = true warn_unreachable = true -namespace_packages = true -explicit_package_bases = true exclude = ["thirdparty/"] python_version = "3.8" @@ -42,50 +42,50 @@ section-order = [ ] [tool.codespell] -enable-colors = "" -write-changes = "" -check-hidden = "" +enable-colors = true +write-changes = true +check-hidden = true quiet-level = 3 -builtin = "clear,rare,en-GB_to_en-US" -skip = """\ - .mailmap, - *.desktop, - *.gitignore, - *.po, - *.pot, - *.rc, - AUTHORS.md, - COPYRIGHT.txt, - core/input/gamecontrollerdb.txt, - core/string/locales.h, - DONORS.md, - editor/project_converter_3_to_4.cpp, - platform/android/java/lib/src/com/*, - platform/web/package-lock.json -""" -ignore-words-list = """\ - breaked, - cancelled, - checkin, - colour, - curvelinear, - doubleclick, - expct, - findn, - gird, - hel, - inout, - labelin, - lod, - mis, - nd, - numer, - ot, - outin, - parm, - requestor, - te, - textin, - thirdparty, - vai -""" +builtin = ["clear", "rare", "en-GB_to_en-US"] +skip = [ + ".mailmap", + "*.desktop", + "*.gitignore", + "*.po", + "*.pot", + "*.rc", + "AUTHORS.md", + "COPYRIGHT.txt", + "core/input/gamecontrollerdb.txt", + "core/string/locales.h", + "DONORS.md", + "editor/project_converter_3_to_4.cpp", + "platform/android/java/lib/src/com/*", + "platform/web/package-lock.json", +] +ignore-words-list = [ + "breaked", + "cancelled", + "checkin", + "colour", + "curvelinear", + "doubleclick", + "expct", + "findn", + "gird", + "hel", + "inout", + "labelin", + "lod", + "mis", + "nd", + "numer", + "ot", + "outin", + "parm", + "requestor", + "te", + "textin", + "thirdparty", + "vai", +] |
