summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/classes/@GlobalScope.xml2
-rw-r--r--doc/classes/String.xml4
-rw-r--r--doc/classes/StringName.xml8
-rw-r--r--drivers/metal/rendering_context_driver_metal.h2
-rw-r--r--drivers/metal/rendering_context_driver_metal.mm2
-rw-r--r--drivers/metal/rendering_device_driver_metal.h1
-rw-r--r--drivers/metal/rendering_device_driver_metal.mm6
-rw-r--r--editor/editor_help_search.cpp4
-rw-r--r--editor/editor_node.cpp12
-rw-r--r--editor/export/editor_export_platform_pc.cpp4
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp298
-rw-r--r--editor/plugins/script_editor_plugin.cpp16
-rw-r--r--editor/project_manager.cpp19
-rw-r--r--modules/gridmap/editor/grid_map_editor_plugin.cpp4
-rw-r--r--pyproject.toml98
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="&quot;{_}&quot;" />
<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="&quot;{_}&quot;" />
<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",
+]