summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/classes/AnimationNodeBlendTree.xml3
-rw-r--r--doc/classes/MultiplayerPeerExtension.xml18
-rw-r--r--editor/editor_about.cpp4
-rw-r--r--editor/editor_node.cpp5
-rw-r--r--editor/editor_property_name_processor.cpp20
-rw-r--r--editor/editor_settings.cpp14
-rw-r--r--editor/export_template_manager.cpp4
-rw-r--r--editor/plugins/control_editor_plugin.cpp53
-rw-r--r--editor/plugins/control_editor_plugin.h2
-rw-r--r--editor/plugins/skeleton_3d_editor_plugin.cpp8
-rwxr-xr-xeditor/translations/extract.py25
11 files changed, 91 insertions, 65 deletions
diff --git a/doc/classes/AnimationNodeBlendTree.xml b/doc/classes/AnimationNodeBlendTree.xml
index 20eb349363..fcdd09f144 100644
--- a/doc/classes/AnimationNodeBlendTree.xml
+++ b/doc/classes/AnimationNodeBlendTree.xml
@@ -4,7 +4,8 @@
[AnimationTree] node resource that contains many blend type nodes.
</brief_description>
<description>
- This node may contain a sub-tree of any other blend type nodes, such as mix, blend2, blend3, one shot, etc. This is one of the most commonly used roots.
+ This node may contain a sub-tree of any other blend type nodes, such as [AnimationNodeTransition], [AnimationNodeBlend2], [AnimationNodeBlend3], [AnimationNodeOneShot], etc. This is one of the most commonly used roots.
+ An [AnimationNodeOutput] node named [code]output[/code] is created by default.
</description>
<tutorials>
<link title="AnimationTree">$DOCS_URL/tutorials/animation/animation_tree.html</link>
diff --git a/doc/classes/MultiplayerPeerExtension.xml b/doc/classes/MultiplayerPeerExtension.xml
index c5fe04cb32..bd11c76039 100644
--- a/doc/classes/MultiplayerPeerExtension.xml
+++ b/doc/classes/MultiplayerPeerExtension.xml
@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8" ?>
<class name="MultiplayerPeerExtension" inherits="MultiplayerPeer" version="4.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
<brief_description>
+ Class that can be inherited to implement custom multiplayer API networking layers via GDExtension.
</brief_description>
<description>
+ This class is designed to be inherited from a GDExtension plugin to implement custom networking layers for the multiplayer API (such as WebRTC). All the methods below [b]must[/b] be implemented to have a working custom multiplayer implementation. See also [MultiplayerAPI].
</description>
<tutorials>
</tutorials>
@@ -10,16 +12,19 @@
<method name="_get_available_packet_count" qualifiers="virtual const">
<return type="int" />
<description>
+ Called when the available packet count is internally requested by the [MultiplayerAPI].
</description>
</method>
<method name="_get_connection_status" qualifiers="virtual const">
<return type="int" />
<description>
+ Called when the connection status is requested on the [MultiplayerPeer] (see [method MultiplayerPeer.get_connection_status]).
</description>
</method>
<method name="_get_max_packet_size" qualifiers="virtual const">
<return type="int" />
<description>
+ Called when the maximum allowed packet size (in bytes) is requested by the [MultiplayerAPI].
</description>
</method>
<method name="_get_packet" qualifiers="virtual">
@@ -27,41 +32,49 @@
<argument index="0" name="r_buffer" type="const uint8_t **" />
<argument index="1" name="r_buffer_size" type="int32_t*" />
<description>
+ Called when a packet needs to be received by the [MultiplayerAPI], with [code]p_buffer_size[/code] being the size of the binary [code]p_buffer[/code] in bytes.
</description>
</method>
<method name="_get_packet_peer" qualifiers="virtual const">
<return type="int" />
<description>
+ Called when the ID of the [MultiplayerPeer] who sent the most recent packet is requested (see [method MultiplayerPeer.get_packet_peer]).
</description>
</method>
<method name="_get_transfer_channel" qualifiers="virtual const">
<return type="int" />
<description>
+ Called when the transfer channel to use is read on this [MultiplayerPeer] (see [member MultiplayerPeer.transfer_channel]).
</description>
</method>
<method name="_get_transfer_mode" qualifiers="virtual const">
<return type="int" />
<description>
+ Called when the transfer mode to use is read on this [MultiplayerPeer] (see [member MultiplayerPeer.transfer_mode]).
</description>
</method>
<method name="_get_unique_id" qualifiers="virtual const">
<return type="int" />
<description>
+ Called when the unique ID of this [MultiplayerPeer] is requested (see [method MultiplayerPeer.get_unique_id]).
</description>
</method>
<method name="_is_refusing_new_connections" qualifiers="virtual const">
<return type="bool" />
<description>
+ Called when the "refuse new connections" status is requested on this [MultiplayerPeer] (see [member MultiplayerPeer.refuse_new_connections]).
</description>
</method>
<method name="_is_server" qualifiers="virtual const">
<return type="bool" />
<description>
+ Called when the "is server" status is requested on the [MultiplayerAPI]. See [method MultiplayerAPI.is_server].
</description>
</method>
<method name="_poll" qualifiers="virtual">
<return type="int" />
<description>
+ Called when the [MultiplayerAPI] is polled. See [method MultiplayerAPI.poll].
</description>
</method>
<method name="_put_packet" qualifiers="virtual">
@@ -69,30 +82,35 @@
<argument index="0" name="p_buffer" type="const uint8_t*" />
<argument index="1" name="p_buffer_size" type="int" />
<description>
+ Called when a packet needs to be sent by the [MultiplayerAPI], with [code]p_buffer_size[/code] being the size of the binary [code]p_buffer[/code] in bytes.
</description>
</method>
<method name="_set_refuse_new_connections" qualifiers="virtual">
<return type="void" />
<argument index="0" name="p_enable" type="bool" />
<description>
+ Called when the "refuse new connections" status is set on this [MultiplayerPeer] (see [member MultiplayerPeer.refuse_new_connections]).
</description>
</method>
<method name="_set_target_peer" qualifiers="virtual">
<return type="void" />
<argument index="0" name="p_peer" type="int" />
<description>
+ Called when the target peer to use is set for this [MultiplayerPeer] (see [method MultiplayerPeer.set_target_peer]).
</description>
</method>
<method name="_set_transfer_channel" qualifiers="virtual">
<return type="void" />
<argument index="0" name="p_channel" type="int" />
<description>
+ Called when the channel to use is set for this [MultiplayerPeer] (see [member MultiplayerPeer.transfer_channel]).
</description>
</method>
<method name="_set_transfer_mode" qualifiers="virtual">
<return type="void" />
<argument index="0" name="p_mode" type="int" />
<description>
+ Called when the transfer mode is set on this [MultiplayerPeer] (see [member MultiplayerPeer.transfer_mode]).
</description>
</method>
</methods>
diff --git a/editor/editor_about.cpp b/editor/editor_about.cpp
index 9b6e2698b6..5beda7d907 100644
--- a/editor/editor_about.cpp
+++ b/editor/editor_about.cpp
@@ -43,10 +43,10 @@ void EditorAbout::_theme_changed() {
const int font_size = get_theme_font_size(SNAME("source_size"), SNAME("EditorFonts"));
_tpl_text->add_theme_font_override("normal_font", font);
_tpl_text->add_theme_font_size_override("normal_font_size", font_size);
- _tpl_text->add_theme_constant_override("line_separation", 6 * EDSCALE);
+ _tpl_text->add_theme_constant_override("line_separation", 4 * EDSCALE);
_license_text->add_theme_font_override("normal_font", font);
_license_text->add_theme_font_size_override("normal_font_size", font_size);
- _license_text->add_theme_constant_override("line_separation", 6 * EDSCALE);
+ _license_text->add_theme_constant_override("line_separation", 4 * EDSCALE);
_logo->set_texture(get_theme_icon(SNAME("Logo"), SNAME("EditorIcons")));
}
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index d01dfb5361..bf118b8e16 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -707,7 +707,10 @@ void EditorNode::_notification(int p_what) {
bool theme_changed =
EditorSettings::get_singleton()->check_changed_settings_in_group("interface/theme") ||
- EditorSettings::get_singleton()->check_changed_settings_in_group("text_editor/theme");
+ EditorSettings::get_singleton()->check_changed_settings_in_group("text_editor/theme") ||
+ EditorSettings::get_singleton()->check_changed_settings_in_group("interface/editor/font") ||
+ EditorSettings::get_singleton()->check_changed_settings_in_group("interface/editor/main_font") ||
+ EditorSettings::get_singleton()->check_changed_settings_in_group("interface/editor/code_font");
if (theme_changed) {
theme = create_custom_theme(theme_base->get_theme());
diff --git a/editor/editor_property_name_processor.cpp b/editor/editor_property_name_processor.cpp
index 49f2f21095..f55b2b61c8 100644
--- a/editor/editor_property_name_processor.cpp
+++ b/editor/editor_property_name_processor.cpp
@@ -83,6 +83,7 @@ EditorPropertyNameProcessor::EditorPropertyNameProcessor() {
capitalize_string_remaps["aabb"] = "AABB";
capitalize_string_remaps["adb"] = "ADB";
capitalize_string_remaps["ao"] = "AO";
+ capitalize_string_remaps["apk"] = "APK";
capitalize_string_remaps["arvr"] = "ARVR";
capitalize_string_remaps["bg"] = "BG";
capitalize_string_remaps["bp"] = "BP";
@@ -119,15 +120,21 @@ EditorPropertyNameProcessor::EditorPropertyNameProcessor() {
capitalize_string_remaps["hsv"] = "HSV";
capitalize_string_remaps["http"] = "HTTP";
capitalize_string_remaps["id"] = "ID";
- capitalize_string_remaps["ik"] = "IK";
capitalize_string_remaps["igd"] = "IGD";
+ capitalize_string_remaps["ik"] = "IK";
+ capitalize_string_remaps["image@2x"] = "Image @2x";
+ capitalize_string_remaps["image@3x"] = "Image @3x";
capitalize_string_remaps["ios"] = "iOS";
capitalize_string_remaps["iod"] = "IOD";
capitalize_string_remaps["ip"] = "IP";
+ capitalize_string_remaps["ipad"] = "iPad";
+ capitalize_string_remaps["iphone"] = "iPhone";
capitalize_string_remaps["ipv6"] = "IPv6";
+ capitalize_string_remaps["jit"] = "JIT";
capitalize_string_remaps["k1"] = "K1";
capitalize_string_remaps["k2"] = "K2";
capitalize_string_remaps["kb"] = "(KB)"; // Unit.
+ capitalize_string_remaps["ldr"] = "LDR";
capitalize_string_remaps["lod"] = "LOD";
capitalize_string_remaps["lowpass"] = "Low-pass";
capitalize_string_remaps["macos"] = "macOS";
@@ -137,13 +144,16 @@ EditorPropertyNameProcessor::EditorPropertyNameProcessor() {
//capitalize_string_remaps["msec"] = "(msec)"; // Unit.
capitalize_string_remaps["msaa"] = "MSAA";
capitalize_string_remaps["normalmap"] = "Normal Map";
+ capitalize_string_remaps["ok"] = "OK";
capitalize_string_remaps["opengl"] = "OpenGL";
capitalize_string_remaps["opentype"] = "OpenType";
capitalize_string_remaps["openxr"] = "OpenXR";
+ capitalize_string_remaps["pck"] = "PCK";
capitalize_string_remaps["png"] = "PNG";
capitalize_string_remaps["po2"] = "(Power of 2)"; // Unit.
capitalize_string_remaps["pvs"] = "PVS";
capitalize_string_remaps["pvrtc"] = "PVRTC";
+ capitalize_string_remaps["rgb"] = "RGB";
capitalize_string_remaps["rid"] = "RID";
capitalize_string_remaps["rmb"] = "RMB";
capitalize_string_remaps["rpc"] = "RPC";
@@ -152,18 +162,21 @@ EditorPropertyNameProcessor::EditorPropertyNameProcessor() {
capitalize_string_remaps["sdfgi"] = "SDFGI";
capitalize_string_remaps["sdk"] = "SDK";
capitalize_string_remaps["sec"] = "(sec)"; // Unit.
+ capitalize_string_remaps["srgb"] = "sRGB";
capitalize_string_remaps["ssao"] = "SSAO";
capitalize_string_remaps["ssh"] = "SSH";
capitalize_string_remaps["ssil"] = "SSIL";
capitalize_string_remaps["ssl"] = "SSL";
capitalize_string_remaps["stderr"] = "stderr";
capitalize_string_remaps["stdout"] = "stdout";
+ capitalize_string_remaps["svg"] = "SVG";
capitalize_string_remaps["tcp"] = "TCP";
capitalize_string_remaps["ui"] = "UI";
capitalize_string_remaps["url"] = "URL";
capitalize_string_remaps["urls"] = "URLs";
- capitalize_string_remaps["us"] = "(µs)"; // Unit.
- capitalize_string_remaps["usec"] = "(µsec)"; // Unit.
+ capitalize_string_remaps["us"] = String::utf8("(µs)"); // Unit.
+ capitalize_string_remaps["usec"] = String::utf8("(µsec)"); // Unit.
+ capitalize_string_remaps["uuid"] = "UUID";
capitalize_string_remaps["uv"] = "UV";
capitalize_string_remaps["uv1"] = "UV1";
capitalize_string_remaps["uv2"] = "UV2";
@@ -174,6 +187,7 @@ EditorPropertyNameProcessor::EditorPropertyNameProcessor() {
capitalize_string_remaps["webp"] = "WebP";
capitalize_string_remaps["webrtc"] = "WebRTC";
capitalize_string_remaps["websocket"] = "WebSocket";
+ capitalize_string_remaps["wifi"] = "Wi-Fi";
capitalize_string_remaps["xr"] = "XR";
capitalize_string_remaps["xy"] = "XY";
capitalize_string_remaps["xz"] = "XZ";
diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp
index 2d80fe85f8..08cc957ec7 100644
--- a/editor/editor_settings.cpp
+++ b/editor/editor_settings.cpp
@@ -404,12 +404,12 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
const String display_scale_hint_string = vformat("Auto (%d%%),75%%,100%%,125%%,150%%,175%%,200%%,Custom", Math::round(get_auto_display_scale() * 100));
EDITOR_SETTING_USAGE(Variant::INT, PROPERTY_HINT_ENUM, "interface/editor/display_scale", 0, display_scale_hint_string, PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED)
- _initial_set("interface/editor/enable_debugging_pseudolocalization", false);
- set_restart_if_changed("interface/editor/enable_debugging_pseudolocalization", true);
+ _initial_set("interface/editor/debug/enable_pseudolocalization", false);
+ set_restart_if_changed("interface/editor/debug/enable_pseudolocalization", true);
// Use pseudolocalization in editor.
EDITOR_SETTING_USAGE(Variant::FLOAT, PROPERTY_HINT_RANGE, "interface/editor/custom_display_scale", 1.0, "0.5,3,0.01", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED)
- EDITOR_SETTING_USAGE(Variant::INT, PROPERTY_HINT_RANGE, "interface/editor/main_font_size", 14, "8,48,1", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED)
+ EDITOR_SETTING(Variant::INT, PROPERTY_HINT_RANGE, "interface/editor/main_font_size", 14, "8,48,1")
EDITOR_SETTING(Variant::INT, PROPERTY_HINT_RANGE, "interface/editor/code_font_size", 14, "8,48,1")
EDITOR_SETTING(Variant::INT, PROPERTY_HINT_ENUM, "interface/editor/code_font_contextual_ligatures", 0, "Default,Disable Contextual Alternates (Coding Ligatures),Use Custom OpenType Feature Set")
_initial_set("interface/editor/code_font_custom_opentype_features", "");
@@ -535,7 +535,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
// Appearance: Whitespace
_initial_set("text_editor/appearance/whitespace/draw_tabs", true);
_initial_set("text_editor/appearance/whitespace/draw_spaces", false);
- EDITOR_SETTING(Variant::INT, PROPERTY_HINT_RANGE, "text_editor/appearance/whitespace/line_spacing", 6, "0,50,1")
+ EDITOR_SETTING(Variant::INT, PROPERTY_HINT_RANGE, "text_editor/appearance/whitespace/line_spacing", 4, "0,50,1")
// Behavior
// Behavior: Navigation
@@ -716,6 +716,10 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
// Profiler
_initial_set("debugger/profiler_frame_history_size", 600);
+ // HTTP Proxy
+ _initial_set("network/http_proxy/host", "");
+ EDITOR_SETTING(Variant::INT, PROPERTY_HINT_RANGE, "network/http_proxy/port", 8080, "1,65535,1")
+
/* Extra config */
EDITOR_SETTING(Variant::INT, PROPERTY_HINT_ENUM, "project_manager/sorting_order", 0, "Name,Path,Last Edited")
@@ -887,7 +891,7 @@ fail:
}
void EditorSettings::setup_language() {
- TranslationServer::get_singleton()->set_editor_pseudolocalization(get("interface/editor/enable_debugging_pseudolocalization"));
+ TranslationServer::get_singleton()->set_editor_pseudolocalization(get("interface/editor/debug/enable_pseudolocalization"));
String lang = get("interface/editor/editor_language");
if (lang == "en") {
return; // Default, nothing to do.
diff --git a/editor/export_template_manager.cpp b/editor/export_template_manager.cpp
index df3e73267e..7320f957c9 100644
--- a/editor/export_template_manager.cpp
+++ b/editor/export_template_manager.cpp
@@ -147,8 +147,8 @@ void ExportTemplateManager::_download_template(const String &p_url, bool p_skip_
download_templates->set_download_file(EditorPaths::get_singleton()->get_cache_dir().plus_file("tmp_templates.tpz"));
download_templates->set_use_threads(true);
- const String proxy_host = EDITOR_DEF("network/http_proxy/host", "");
- const int proxy_port = EDITOR_DEF("network/http_proxy/port", -1);
+ const String proxy_host = EDITOR_GET("network/http_proxy/host");
+ const int proxy_port = EDITOR_GET("network/http_proxy/port");
download_templates->set_http_proxy(proxy_host, proxy_port);
download_templates->set_https_proxy(proxy_host, proxy_port);
diff --git a/editor/plugins/control_editor_plugin.cpp b/editor/plugins/control_editor_plugin.cpp
index 7b85fea1e9..5ca8216d4d 100644
--- a/editor/plugins/control_editor_plugin.cpp
+++ b/editor/plugins/control_editor_plugin.cpp
@@ -818,7 +818,7 @@ void ControlEditorToolbar::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE:
case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
- anchor_layouts_icon->set_texture(get_theme_icon(SNAME("ControlLayout"), SNAME("EditorIcons")));
+ anchor_presets_menu->set_icon(get_theme_icon(SNAME("ControlLayout"), SNAME("EditorIcons")));
PopupMenu *p = anchor_presets_menu->get_popup();
p->clear();
@@ -871,7 +871,8 @@ void ControlEditorToolbar::_notification(int p_what) {
anchor_mode_button->set_icon(get_theme_icon(SNAME("Anchor"), SNAME("EditorIcons")));
- container_layouts_icon->set_texture(get_theme_icon(SNAME("Container"), SNAME("EditorIcons")));
+ container_h_presets_menu->set_icon(get_theme_icon(SNAME("Container"), SNAME("EditorIcons")));
+ container_v_presets_menu->set_icon(get_theme_icon(SNAME("Container"), SNAME("EditorIcons")));
p = container_h_presets_menu->get_popup();
p->clear();
@@ -925,27 +926,19 @@ void ControlEditorToolbar::_notification(int p_what) {
}
if (enable_anchors) {
- anchor_presets_menu->set_disabled(false);
- anchor_presets_menu->set_tooltip(TTR("Presets for the anchor and offset values of a Control node."));
- anchor_mode_button->set_disabled(false);
- anchor_mode_button->set_tooltip(TTR("When active, moving Control nodes changes their anchors instead of their offsets."));
+ anchor_presets_menu->set_visible(true);
+ anchor_mode_button->set_visible(true);
} else {
- anchor_presets_menu->set_disabled(true);
- anchor_presets_menu->set_tooltip(TTR("Children of containers have their anchors and offsets values controlled by their parent."));
- anchor_mode_button->set_disabled(true);
- anchor_mode_button->set_tooltip(TTR("Children of containers have their anchors and offsets values controlled by their parent."));
+ anchor_presets_menu->set_visible(false);
+ anchor_mode_button->set_visible(false);
}
if (enable_containers) {
- container_h_presets_menu->set_disabled(false);
- container_h_presets_menu->set_tooltip(TTR("Horizontal sizing setting for children of a Container node."));
- container_v_presets_menu->set_disabled(false);
- container_v_presets_menu->set_tooltip(TTR("Vertical sizing setting for children of a Container node."));
+ container_h_presets_menu->set_visible(true);
+ container_v_presets_menu->set_visible(true);
} else {
- container_h_presets_menu->set_disabled(true);
- container_h_presets_menu->set_tooltip(TTR("Children of regular controls are controlled by their anchors and offsets."));
- container_v_presets_menu->set_disabled(true);
- container_v_presets_menu->set_tooltip(TTR("Children of regular controls are controlled by their anchors and offsets."));
+ container_h_presets_menu->set_visible(false);
+ container_v_presets_menu->set_visible(false);
}
} else {
set_visible(false);
@@ -955,18 +948,10 @@ void ControlEditorToolbar::_notification(int p_what) {
}
ControlEditorToolbar::ControlEditorToolbar() {
- anchor_layouts_icon = memnew(TextureRect);
- anchor_layouts_icon->set_stretch_mode(TextureRect::StretchMode::STRETCH_KEEP_CENTERED);
- add_child(anchor_layouts_icon);
-
- Label *l = memnew(Label);
- l->set_text(TTR("Anchors"));
- l->set_vertical_alignment(VerticalAlignment::VERTICAL_ALIGNMENT_CENTER);
- add_child(l);
-
anchor_presets_menu = memnew(MenuButton);
anchor_presets_menu->set_shortcut_context(this);
- anchor_presets_menu->set_text(TTR("Preset"));
+ anchor_presets_menu->set_text(TTR("Anchors"));
+ anchor_presets_menu->set_tooltip(TTR("Presets for the anchor and offset values of a Control node."));
add_child(anchor_presets_menu);
anchor_presets_menu->set_switch_on_hover(true);
@@ -981,23 +966,16 @@ ControlEditorToolbar::ControlEditorToolbar() {
anchor_mode_button = memnew(Button);
anchor_mode_button->set_flat(true);
anchor_mode_button->set_toggle_mode(true);
+ anchor_mode_button->set_tooltip(TTR("When active, moving Control nodes changes their anchors instead of their offsets."));
add_child(anchor_mode_button);
anchor_mode_button->connect("toggled", callable_mp(this, &ControlEditorToolbar::_button_toggle_anchor_mode));
add_child(memnew(VSeparator));
- container_layouts_icon = memnew(TextureRect);
- container_layouts_icon->set_stretch_mode(TextureRect::StretchMode::STRETCH_KEEP_CENTERED);
- add_child(container_layouts_icon);
-
- l = memnew(Label);
- l->set_text(TTR("Containers"));
- l->set_vertical_alignment(VerticalAlignment::VERTICAL_ALIGNMENT_CENTER);
- add_child(l);
-
container_h_presets_menu = memnew(MenuButton);
container_h_presets_menu->set_shortcut_context(this);
container_h_presets_menu->set_text(TTR("Horizontal"));
+ container_h_presets_menu->set_tooltip(TTR("Horizontal sizing setting for children of a Container node."));
add_child(container_h_presets_menu);
container_h_presets_menu->set_switch_on_hover(true);
@@ -1007,6 +985,7 @@ ControlEditorToolbar::ControlEditorToolbar() {
container_v_presets_menu = memnew(MenuButton);
container_v_presets_menu->set_shortcut_context(this);
container_v_presets_menu->set_text(TTR("Vertical"));
+ container_v_presets_menu->set_tooltip(TTR("Vertical sizing setting for children of a Container node."));
add_child(container_v_presets_menu);
container_v_presets_menu->set_switch_on_hover(true);
diff --git a/editor/plugins/control_editor_plugin.h b/editor/plugins/control_editor_plugin.h
index bbbada2b3f..37d218abb9 100644
--- a/editor/plugins/control_editor_plugin.h
+++ b/editor/plugins/control_editor_plugin.h
@@ -198,10 +198,8 @@ class ControlEditorToolbar : public HBoxContainer {
CONTAINERS_V_PRESET_SHRINK_END,
};
- TextureRect *anchor_layouts_icon;
MenuButton *anchor_presets_menu;
PopupMenu *anchors_popup;
- TextureRect *container_layouts_icon;
MenuButton *container_h_presets_menu;
MenuButton *container_v_presets_menu;
diff --git a/editor/plugins/skeleton_3d_editor_plugin.cpp b/editor/plugins/skeleton_3d_editor_plugin.cpp
index ef171e9115..065683d632 100644
--- a/editor/plugins/skeleton_3d_editor_plugin.cpp
+++ b/editor/plugins/skeleton_3d_editor_plugin.cpp
@@ -419,8 +419,14 @@ PhysicalBone3D *Skeleton3DEditor::create_physical_bone(int bone_id, int bone_chi
capsule_transform.basis = Basis(Vector3(1, 0, 0), Vector3(0, 0, 1), Vector3(0, -1, 0));
bone_shape->set_transform(capsule_transform);
+ /// Get an up vector not collinear with child rest origin
+ Vector3 up = Vector3(0, 1, 0);
+ if (up.cross(child_rest.origin).is_equal_approx(Vector3())) {
+ up = Vector3(0, 0, 1);
+ }
+
Transform3D body_transform;
- body_transform.basis = Basis::looking_at(child_rest.origin);
+ body_transform.basis = Basis::looking_at(child_rest.origin, up);
body_transform.origin = body_transform.basis.xform(Vector3(0, 0, -half_height));
Transform3D joint_transform;
diff --git a/editor/translations/extract.py b/editor/translations/extract.py
index dd86bd1c1f..8737eb5204 100755
--- a/editor/translations/extract.py
+++ b/editor/translations/extract.py
@@ -34,12 +34,12 @@ matches.sort()
remaps = {}
-remap_re = re.compile(r'capitalize_string_remaps\["(.+)"\] = "(.+)";')
+remap_re = re.compile(r'^\t*capitalize_string_remaps\["(?P<from>.+)"\] = (String::utf8\()?"(?P<to>.+)"')
with open("editor/editor_property_name_processor.cpp") as f:
for line in f:
m = remap_re.search(line)
if m:
- remaps[m.group(1)] = m.group(2)
+ remaps[m.group("from")] = m.group("to")
unique_str = []
@@ -70,22 +70,25 @@ class ExtractType(enum.IntEnum):
GROUP = 3
-# Regex "(?P<name>(?:[^"\\]|\\.)*)" creates a group named `name` that matches a string.
+# Regex "(?P<name>([^"\\]|\\.)*)" creates a group named `name` that matches a string.
message_patterns = {
- re.compile(r'RTR\("(?P<message>(?:[^"\\]|\\.)*)"(?:, "(?P<context>(?:[^"\\]|\\.)*)")?\)'): ExtractType.TEXT,
- re.compile(r'TTR\("(?P<message>(?:[^"\\]|\\.)*)"(?:, "(?P<context>(?:[^"\\]|\\.)*)")?\)'): ExtractType.TEXT,
- re.compile(r'TTRC\("(?P<message>(?:[^"\\]|\\.)*)"\)'): ExtractType.TEXT,
+ re.compile(r'RTR\("(?P<message>([^"\\]|\\.)*)"(, "(?P<context>([^"\\]|\\.)*)")?\)'): ExtractType.TEXT,
+ re.compile(r'TTR\("(?P<message>([^"\\]|\\.)*)"(, "(?P<context>([^"\\]|\\.)*)")?\)'): ExtractType.TEXT,
+ re.compile(r'TTRC\("(?P<message>([^"\\]|\\.)*)"\)'): ExtractType.TEXT,
re.compile(
- r'TTRN\("(?P<message>(?:[^"\\]|\\.)*)", "(?P<plural_message>(?:[^"\\]|\\.)*)",[^,)]+?(?:, "(?P<context>(?:[^"\\]|\\.)*)")?\)'
+ r'TTRN\("(?P<message>([^"\\]|\\.)*)", "(?P<plural_message>([^"\\]|\\.)*)",[^,)]+?(, "(?P<context>([^"\\]|\\.)*)")?\)'
): ExtractType.TEXT,
re.compile(
- r'RTRN\("(?P<message>(?:[^"\\]|\\.)*)", "(?P<plural_message>(?:[^"\\]|\\.)*)",[^,)]+?(?:, "(?P<context>(?:[^"\\]|\\.)*)")?\)'
+ r'RTRN\("(?P<message>([^"\\]|\\.)*)", "(?P<plural_message>([^"\\]|\\.)*)",[^,)]+?(, "(?P<context>([^"\\]|\\.)*)")?\)'
): ExtractType.TEXT,
re.compile(r'_initial_set\("(?P<message>[^"]+?)",'): ExtractType.PROPERTY_PATH,
- re.compile(r'GLOBAL_DEF(?:_RST)?\("(?P<message>[^".]+?)",'): ExtractType.PROPERTY_PATH,
- re.compile(r'EDITOR_DEF(?:_RST)?\("(?P<message>[^"]+?)",'): ExtractType.PROPERTY_PATH,
+ re.compile(r'GLOBAL_DEF(_RST)?(_NOVAL)?\("(?P<message>[^".]+?)",'): ExtractType.PROPERTY_PATH,
+ re.compile(r'EDITOR_DEF(_RST)?\("(?P<message>[^"]+?)",'): ExtractType.PROPERTY_PATH,
re.compile(
- r'ADD_PROPERTY\(PropertyInfo\(Variant::[_A-Z0-9]+, "(?P<message>[^"]+?)"[,)]'
+ r'(ADD_PROPERTYI?|ImportOption|ExportOption)\(PropertyInfo\(Variant::[_A-Z0-9]+, "(?P<message>[^"]+?)"[,)]'
+ ): ExtractType.PROPERTY_PATH,
+ re.compile(
+ r"(?!#define )LIMPL_PROPERTY(_RANGE)?\(Variant::[_A-Z0-9]+, (?P<message>[^,]+?),"
): ExtractType.PROPERTY_PATH,
re.compile(r'ADD_GROUP\("(?P<message>[^"]+?)", "(?P<prefix>[^"]*?)"\)'): ExtractType.GROUP,
}