Merge pull request #69433 from timothyqiu/3.x-cherrypicks

Cherry-picks for the 3.x branch (future 3.6) - 7th batch
This commit is contained in:
Rémi Verschelde 2022-12-01 08:51:34 +01:00 committed by GitHub
commit b7ef58f221
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 160 additions and 76 deletions

View file

@ -75,5 +75,4 @@ for more information.
[![Actions Build Status](https://github.com/godotengine/godot/workflows/Godot/badge.svg?branch=master)](https://github.com/godotengine/godot/actions)
[![Code Triagers Badge](https://www.codetriage.com/godotengine/godot/badges/users.svg)](https://www.codetriage.com/godotengine/godot)
[![Translate on Weblate](https://hosted.weblate.org/widgets/godot-engine/-/godot/svg-badge.svg)](https://hosted.weblate.org/engage/godot-engine/?utm_source=widget)
[![Total alerts on LGTM](https://img.shields.io/lgtm/alerts/g/godotengine/godot.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/godotengine/godot/alerts)
[![TODOs](https://badgen.net/https/api.tickgit.com/badgen/github.com/godotengine/godot)](https://www.tickgit.com/browse?repo=github.com/godotengine/godot)

View file

@ -902,10 +902,10 @@
Group Switch key mask.
</constant>
<constant name="BUTTON_LEFT" value="1" enum="ButtonList">
Left mouse button.
Primary mouse button, usually the left button.
</constant>
<constant name="BUTTON_RIGHT" value="2" enum="ButtonList">
Right mouse button.
Secondary mouse button, usually the right button.
</constant>
<constant name="BUTTON_MIDDLE" value="3" enum="ButtonList">
Middle mouse button.
@ -929,10 +929,10 @@
Mouse wheel right button (only present on some mice).
</constant>
<constant name="BUTTON_MASK_LEFT" value="1" enum="ButtonList">
Left mouse button mask.
Primary mouse button mask, usually for the left button.
</constant>
<constant name="BUTTON_MASK_RIGHT" value="2" enum="ButtonList">
Right mouse button mask.
Secondary mouse button mask, usually for the right button.
</constant>
<constant name="BUTTON_MASK_MIDDLE" value="4" enum="ButtonList">
Middle mouse button mask.

View file

@ -301,7 +301,7 @@
<method name="get_global_transform" qualifiers="const">
<return type="Transform2D" />
<description>
Returns the global transform matrix of this item.
Returns the global transform matrix of this item, i.e. the combined transform up to the topmost [CanvasItem] node. The topmost item is a [CanvasItem] that either has no parent, has non-[CanvasItem] parent or it is top-level. See also [method set_as_toplevel].
</description>
</method>
<method name="get_global_transform_with_canvas" qualifiers="const">

View file

@ -411,6 +411,12 @@
If [code]true[/code], when saving a file, the editor will rename the old file to a different name, save a new file, then only remove the old file once the new file has been saved. This makes loss of data less likely to happen if the editor or operating system exits unexpectedly while saving (e.g. due to a crash or power outage).
[b]Note:[/b] On Windows, this feature can interact negatively with certain antivirus programs. In this case, you may have to set this to [code]false[/code] to prevent file locking issues.
</member>
<member name="interface/editor/accept_dialog_cancel_ok_buttons" type="int" setter="" getter="">
How to position the Cancel and OK buttons in the editor's [AcceptDialog]s. Different platforms have different standard behaviors for this, which can be overridden using this setting. This is useful if you use Godot both on Windows and macOS/Linux and your Godot muscle memory is stronger than your OS specific one.
- [b]Auto[/b] follows the platform convention: Cancel first on macOS and Linux, OK first on Windows.
- [b]Cancel First[/b] forces the ordering Cancel/OK.
- [b]OK First[/b] forces the ordering OK/Cancel.
</member>
<member name="interface/editor/automatically_open_screenshots" type="bool" setter="" getter="">
If [code]true[/code], automatically opens screenshots with the default program associated to [code].png[/code] files after a screenshot is taken using the [b]Editor &gt; Take Screenshot[/b] action.
</member>

View file

@ -359,7 +359,14 @@
<method name="is_displayed_folded" qualifiers="const">
<return type="bool" />
<description>
Returns [code]true[/code] if the node is folded (collapsed) in the Scene dock.
Returns [code]true[/code] if the node is folded (collapsed) in the Scene dock. This method is only intended for use with editor tooling.
</description>
</method>
<method name="is_editable_instance" qualifiers="const">
<return type="bool" />
<argument index="0" name="node" type="Node" />
<description>
Returns [code]true[/code] if [code]node[/code] has editable children enabled relative to this node. This method is only intended for use with editor tooling.
</description>
</method>
<method name="is_greater_than" qualifiers="const">
@ -649,7 +656,15 @@
<return type="void" />
<argument index="0" name="fold" type="bool" />
<description>
Sets the folded state of the node in the Scene dock.
Sets the folded state of the node in the Scene dock. This method is only intended for use with editor tooling.
</description>
</method>
<method name="set_editable_instance">
<return type="void" />
<argument index="0" name="node" type="Node" />
<argument index="1" name="is_editable" type="bool" />
<description>
Sets the editable children state of [code]node[/code] relative to this node. This method is only intended for use with editor tooling.
</description>
</method>
<method name="set_network_master">

View file

@ -94,6 +94,7 @@
[b]Note:[/b] This returns a copy of the [PoolVector2Array] rather than a reference.
</member>
<member name="polygons" type="Array" setter="set_polygons" getter="get_polygons" default="[ ]">
The list of polygons, in case more than one is being represented. Every individual polygon is stored as a [PoolIntArray] where each [int] is an index to a point in [member polygon]. If empty, this property will be ignored, and the resulting single polygon will be composed of all points in [member polygon], using the order they are stored in.
</member>
<member name="skeleton" type="NodePath" setter="set_skeleton" getter="get_skeleton" default="NodePath(&quot;&quot;)">
</member>

View file

@ -3471,7 +3471,7 @@ void AnimationTrackEditor::_query_insert(const InsertData &p_id) {
}
}
void AnimationTrackEditor::_insert_delay(bool p_create_reset, bool p_create_beziers) {
void AnimationTrackEditor::_insert_delay(bool p_reset_wanted, bool p_create_beziers) {
if (insert_query) {
//discard since it's entered into query mode
insert_queue = false;
@ -3481,7 +3481,7 @@ void AnimationTrackEditor::_insert_delay(bool p_create_reset, bool p_create_bezi
undo_redo->create_action(TTR("Anim Insert"));
Ref<Animation> reset_anim;
if (p_create_reset) {
if (p_reset_wanted) {
reset_anim = _create_and_get_reset_animation();
}
@ -3491,26 +3491,14 @@ void AnimationTrackEditor::_insert_delay(bool p_create_reset, bool p_create_bezi
if (insert_data.front()->get().advance) {
advance = true;
}
next_tracks = _confirm_insert(insert_data.front()->get(), next_tracks, p_create_reset, reset_anim, p_create_beziers);
next_tracks = _confirm_insert(insert_data.front()->get(), next_tracks, p_reset_wanted, reset_anim, p_create_beziers);
insert_data.pop_front();
}
undo_redo->commit_action();
if (advance) {
float step = animation->get_step();
if (step == 0) {
step = 1;
}
float pos = timeline->get_play_position();
pos = Math::stepify(pos + step, step);
if (pos > animation->get_length()) {
pos = animation->get_length();
}
set_anim_pos(pos);
emit_signal("timeline_changed", pos, true);
_edit_menu_pressed(EDIT_GOTO_NEXT_STEP_TIMELINE_ONLY);
}
insert_queue = false;
}
@ -3811,12 +3799,20 @@ void AnimationTrackEditor::_confirm_insert_list() {
}
TrackIndices next_tracks(animation.ptr(), reset_anim.ptr());
bool advance = false;
while (insert_data.size()) {
if (insert_data.front()->get().advance) {
advance = true;
}
next_tracks = _confirm_insert(insert_data.front()->get(), next_tracks, create_reset, reset_anim, insert_confirm_bezier->is_pressed());
insert_data.pop_front();
}
undo_redo->commit_action();
if (advance) {
_edit_menu_pressed(EDIT_GOTO_NEXT_STEP_TIMELINE_ONLY);
}
}
PropertyInfo AnimationTrackEditor::_find_hint_for_track(int p_idx, NodePath &r_base_path, Variant *r_current_val) {
@ -3931,9 +3927,42 @@ static Vector<String> _get_bezier_subindices_for_type(Variant::Type p_type, bool
return subindices;
}
AnimationTrackEditor::TrackIndices AnimationTrackEditor::_confirm_insert(InsertData p_id, TrackIndices p_next_tracks, bool p_create_reset, Ref<Animation> p_reset_anim, bool p_create_beziers) {
AnimationTrackEditor::TrackIndices AnimationTrackEditor::_confirm_insert(InsertData p_id, TrackIndices p_next_tracks, bool p_reset_wanted, Ref<Animation> p_reset_anim, bool p_create_beziers) {
bool created = false;
if (p_id.track_idx < 0) {
bool create_normal_track = p_id.track_idx < 0;
bool create_reset_track = p_reset_wanted && track_type_is_resettable(p_id.type);
Animation::UpdateMode update_mode = Animation::UPDATE_DISCRETE;
if (create_normal_track || create_reset_track) {
if (p_id.type == Animation::TYPE_VALUE || p_id.type == Animation::TYPE_BEZIER) {
// Hack.
NodePath np;
animation->add_track(p_id.type);
animation->track_set_path(animation->get_track_count() - 1, p_id.path);
PropertyInfo h = _find_hint_for_track(animation->get_track_count() - 1, np);
animation->remove_track(animation->get_track_count() - 1); // Hack.
if (h.type == Variant::REAL ||
h.type == Variant::VECTOR2 ||
h.type == Variant::RECT2 ||
h.type == Variant::VECTOR3 ||
h.type == Variant::AABB ||
h.type == Variant::QUAT ||
h.type == Variant::COLOR ||
h.type == Variant::PLANE ||
h.type == Variant::TRANSFORM2D ||
h.type == Variant::TRANSFORM) {
update_mode = Animation::UPDATE_CONTINUOUS;
}
if (h.usage & PROPERTY_USAGE_ANIMATE_AS_TRIGGER) {
update_mode = Animation::UPDATE_TRIGGER;
}
}
}
if (create_normal_track) {
if (p_create_beziers) {
bool valid;
Vector<String> subindices = _get_bezier_subindices_for_type(p_id.value.get_type(), &valid);
@ -3943,7 +3972,7 @@ AnimationTrackEditor::TrackIndices AnimationTrackEditor::_confirm_insert(InsertD
id.type = Animation::TYPE_BEZIER;
id.value = p_id.value.get(subindices[i].substr(1, subindices[i].length()));
id.path = String(p_id.path) + subindices[i];
p_next_tracks = _confirm_insert(id, p_next_tracks, p_create_reset, p_reset_anim, false);
p_next_tracks = _confirm_insert(id, p_next_tracks, p_reset_wanted, p_reset_anim, false);
}
return p_next_tracks;
@ -3951,37 +3980,6 @@ AnimationTrackEditor::TrackIndices AnimationTrackEditor::_confirm_insert(InsertD
}
created = true;
undo_redo->create_action(TTR("Anim Insert Track & Key"));
Animation::UpdateMode update_mode = Animation::UPDATE_DISCRETE;
if (p_id.type == Animation::TYPE_VALUE || p_id.type == Animation::TYPE_BEZIER) {
// Wants a new track.
{
// Hack.
NodePath np;
animation->add_track(p_id.type);
animation->track_set_path(animation->get_track_count() - 1, p_id.path);
PropertyInfo h = _find_hint_for_track(animation->get_track_count() - 1, np);
animation->remove_track(animation->get_track_count() - 1); //hack
if (h.type == Variant::REAL ||
h.type == Variant::VECTOR2 ||
h.type == Variant::RECT2 ||
h.type == Variant::VECTOR3 ||
h.type == Variant::AABB ||
h.type == Variant::QUAT ||
h.type == Variant::COLOR ||
h.type == Variant::PLANE ||
h.type == Variant::TRANSFORM2D ||
h.type == Variant::TRANSFORM) {
update_mode = Animation::UPDATE_CONTINUOUS;
}
if (h.usage & PROPERTY_USAGE_ANIMATE_AS_TRIGGER) {
update_mode = Animation::UPDATE_TRIGGER;
}
}
}
p_id.track_idx = p_next_tracks.normal;
@ -4046,8 +4044,7 @@ AnimationTrackEditor::TrackIndices AnimationTrackEditor::_confirm_insert(InsertD
}
}
if (p_create_reset && track_type_is_resettable(p_id.type)) {
bool create_reset_track = true;
if (create_reset_track) {
Animation *reset_anim = p_reset_anim.ptr();
for (int i = 0; i < reset_anim->get_track_count(); i++) {
if (reset_anim->track_get_path(i) == p_id.path) {
@ -4058,6 +4055,9 @@ AnimationTrackEditor::TrackIndices AnimationTrackEditor::_confirm_insert(InsertD
if (create_reset_track) {
undo_redo->add_do_method(reset_anim, "add_track", p_id.type);
undo_redo->add_do_method(reset_anim, "track_set_path", p_next_tracks.reset, p_id.path);
if (p_id.type == Animation::TYPE_VALUE) {
undo_redo->add_do_method(reset_anim, "value_track_set_update_mode", p_next_tracks.reset, update_mode);
}
undo_redo->add_do_method(reset_anim, "track_insert_key", p_next_tracks.reset, 0.0f, value);
undo_redo->add_undo_method(reset_anim, "remove_track", reset_anim->get_track_count());
p_next_tracks.reset++;
@ -5243,7 +5243,7 @@ void AnimationTrackEditor::goto_prev_step(bool p_from_mouse_event) {
emit_signal("timeline_changed", pos, true);
}
void AnimationTrackEditor::goto_next_step(bool p_from_mouse_event) {
void AnimationTrackEditor::goto_next_step(bool p_from_mouse_event, bool p_timeline_only) {
if (animation.is_null()) {
return;
}
@ -5267,7 +5267,7 @@ void AnimationTrackEditor::goto_next_step(bool p_from_mouse_event) {
}
set_anim_pos(pos);
emit_signal("timeline_changed", pos, true);
emit_signal("timeline_changed", pos, true, p_timeline_only);
}
void AnimationTrackEditor::_edit_menu_pressed(int p_option) {
@ -5607,8 +5607,9 @@ void AnimationTrackEditor::_edit_menu_pressed(int p_option) {
_update_key_edit();
}
} break;
case EDIT_GOTO_NEXT_STEP_TIMELINE_ONLY:
case EDIT_GOTO_NEXT_STEP: {
goto_next_step(false);
goto_next_step(false, p_option == EDIT_GOTO_NEXT_STEP_TIMELINE_ONLY);
} break;
case EDIT_GOTO_PREV_STEP: {
goto_prev_step(false);
@ -5820,7 +5821,7 @@ void AnimationTrackEditor::_bind_methods() {
ClassDB::bind_method("_pick_track_filter_text_changed", &AnimationTrackEditor::_pick_track_filter_text_changed);
ClassDB::bind_method("_pick_track_filter_input", &AnimationTrackEditor::_pick_track_filter_input);
ADD_SIGNAL(MethodInfo("timeline_changed", PropertyInfo(Variant::REAL, "position"), PropertyInfo(Variant::BOOL, "drag")));
ADD_SIGNAL(MethodInfo("timeline_changed", PropertyInfo(Variant::REAL, "position"), PropertyInfo(Variant::BOOL, "drag"), PropertyInfo(Variant::BOOL, "timeline_only")));
ADD_SIGNAL(MethodInfo("keying_changed"));
ADD_SIGNAL(MethodInfo("animation_len_changed", PropertyInfo(Variant::REAL, "len")));
ADD_SIGNAL(MethodInfo("animation_step_changed", PropertyInfo(Variant::REAL, "step")));

View file

@ -373,8 +373,8 @@ class AnimationTrackEditor : public VBoxContainer {
reset = p_reset_anim ? p_reset_anim->get_track_count() : 0;
}
};
TrackIndices _confirm_insert(InsertData p_id, TrackIndices p_next_tracks, bool p_create_reset, Ref<Animation> p_reset_anim, bool p_create_beziers);
void _insert_delay(bool p_create_reset, bool p_create_beziers);
TrackIndices _confirm_insert(InsertData p_id, TrackIndices p_next_tracks, bool p_reset_wanted, Ref<Animation> p_reset_anim, bool p_create_beziers);
void _insert_delay(bool p_reset_wanted, bool p_create_beziers);
void _root_removed();
@ -509,6 +509,7 @@ public:
EDIT_ADD_RESET_KEY,
EDIT_DELETE_SELECTION,
EDIT_GOTO_NEXT_STEP,
EDIT_GOTO_NEXT_STEP_TIMELINE_ONLY, // Next step without updating animation.
EDIT_GOTO_PREV_STEP,
EDIT_APPLY_RESET,
EDIT_OPTIMIZE_ANIMATION,
@ -551,7 +552,7 @@ public:
void goto_prev_step(bool p_from_mouse_event);
/** If `p_from_mouse_event` is `true`, handle Shift key presses for precise snapping. */
void goto_next_step(bool p_from_mouse_event);
void goto_next_step(bool p_from_mouse_event, bool p_timeline_only = false);
MenuButton *get_edit_menu();
AnimationTrackEditor();

View file

@ -5921,10 +5921,17 @@ EditorNode::EditorNode() {
// Define a minimum window size to prevent UI elements from overlapping or being cut off
OS::get_singleton()->set_min_window_size(Size2(1024, 600) * EDSCALE);
ResourceLoader::set_abort_on_missing_resources(false);
FileDialog::set_default_show_hidden_files(EditorSettings::get_singleton()->get("filesystem/file_dialog/show_hidden_files"));
EditorFileDialog::set_default_show_hidden_files(EditorSettings::get_singleton()->get("filesystem/file_dialog/show_hidden_files"));
EditorFileDialog::set_default_display_mode((EditorFileDialog::DisplayMode)EditorSettings::get_singleton()->get("filesystem/file_dialog/display_mode").operator int());
int swap_cancel_ok = EDITOR_GET("interface/editor/accept_dialog_cancel_ok_buttons");
if (swap_cancel_ok != 0) { // 0 is auto, set in register_scene based on OS.
// Swap on means OK first.
AcceptDialog::set_swap_ok_cancel(swap_cancel_ok == 2);
}
ResourceLoader::set_abort_on_missing_resources(false);
ResourceLoader::set_error_notify_func(this, _load_error_notify);
ResourceLoader::set_dependency_error_notify_func(this, _dependency_error_report);

View file

@ -64,6 +64,10 @@ String EditorPropertyNameProcessor::_capitalize_name(const String &p_name) const
Vector<String> parts = p_name.split("_", false);
for (int i = 0; i < parts.size(); i++) {
// Articles/conjunctions/prepositions which should only be capitalized when not at beginning and end.
if (i > 0 && i + 1 < parts.size() && stop_words.find(parts[i]) != -1) {
continue;
}
const Map<String, String>::Element *remap = capitalize_string_remaps.find(parts[i]);
if (remap) {
parts.write[i] = remap->get();
@ -143,6 +147,7 @@ EditorPropertyNameProcessor::EditorPropertyNameProcessor() {
capitalize_string_remaps["gdscript"] = "GDScript";
capitalize_string_remaps["ggx"] = "GGX";
capitalize_string_remaps["gi"] = "GI";
capitalize_string_remaps["gl"] = "GL";
capitalize_string_remaps["glb"] = "GLB";
capitalize_string_remaps["gles2"] = "GLES2";
capitalize_string_remaps["gles3"] = "GLES3";
@ -157,6 +162,7 @@ EditorPropertyNameProcessor::EditorPropertyNameProcessor() {
capitalize_string_remaps["html"] = "HTML";
capitalize_string_remaps["http"] = "HTTP";
capitalize_string_remaps["id"] = "ID";
capitalize_string_remaps["ids"] = "IDs";
capitalize_string_remaps["igd"] = "IGD";
capitalize_string_remaps["ik"] = "IK";
capitalize_string_remaps["image@2x"] = "Image @2x";
@ -222,6 +228,7 @@ EditorPropertyNameProcessor::EditorPropertyNameProcessor() {
capitalize_string_remaps["sv"] = "SV";
capitalize_string_remaps["svg"] = "SVG";
capitalize_string_remaps["tcp"] = "TCP";
capitalize_string_remaps["tls"] = "TLS";
capitalize_string_remaps["ui"] = "UI";
capitalize_string_remaps["url"] = "URL";
capitalize_string_remaps["urls"] = "URLs";
@ -248,9 +255,31 @@ EditorPropertyNameProcessor::EditorPropertyNameProcessor() {
capitalize_string_remaps["wifi"] = "Wi-Fi";
capitalize_string_remaps["x86"] = "x86";
capitalize_string_remaps["xr"] = "XR";
capitalize_string_remaps["xray"] = "X-Ray";
capitalize_string_remaps["xy"] = "XY";
capitalize_string_remaps["xz"] = "XZ";
capitalize_string_remaps["yz"] = "YZ";
// Articles, conjunctions, prepositions.
// The following initialization is parsed in `editor/translations/extract.py` with a regex.
// The word definition format should be kept synced with the regex.
stop_words.push_back("a");
stop_words.push_back("an");
stop_words.push_back("and");
stop_words.push_back("as");
stop_words.push_back("at");
stop_words.push_back("by");
stop_words.push_back("for");
stop_words.push_back("in");
stop_words.push_back("not");
stop_words.push_back("of");
stop_words.push_back("on");
stop_words.push_back("or");
stop_words.push_back("over");
stop_words.push_back("per");
stop_words.push_back("the");
stop_words.push_back("then");
stop_words.push_back("to");
}
EditorPropertyNameProcessor::~EditorPropertyNameProcessor() {

View file

@ -40,6 +40,7 @@ class EditorPropertyNameProcessor : public Node {
mutable Map<String, String> capitalize_string_cache;
Map<String, String> capitalize_string_remaps;
LocalVector<String> stop_words; // Exceptions that shouldn't be capitalized.
// Capitalizes property path segments.
String _capitalize_name(const String &p_name) const;

View file

@ -338,6 +338,8 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
_initial_set("interface/editor/automatically_open_screenshots", true);
_initial_set("interface/editor/save_each_scene_on_quit", true); // Regression
_initial_set("interface/editor/quit_confirmation", true);
_initial_set("interface/editor/accept_dialog_cancel_ok_buttons", 0);
hints["interface/editor/accept_dialog_cancel_ok_buttons"] = PropertyInfo(Variant::INT, "interface/editor/accept_dialog_cancel_ok_buttons", PROPERTY_HINT_ENUM, vformat("Auto (%s),Cancel First,OK First", OS::get_singleton()->get_swap_ok_cancel() ? "OK First" : "Cancel First"), PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
// Inspector
_initial_set("interface/inspector/max_array_dictionary_items_per_page", 20);

View file

@ -2440,6 +2440,13 @@ ProjectManager::ProjectManager() {
FileDialog::set_default_show_hidden_files(EditorSettings::get_singleton()->get("filesystem/file_dialog/show_hidden_files"));
set_anchors_and_margins_preset(Control::PRESET_WIDE);
int swap_cancel_ok = EDITOR_GET("interface/editor/accept_dialog_cancel_ok_buttons");
if (swap_cancel_ok != 0) { // 0 is auto, set in register_scene based on OS.
// Swap on means OK first.
AcceptDialog::set_swap_ok_cancel(swap_cancel_ok == 2);
}
set_theme(create_custom_theme());
gui_base = memnew(Control);

View file

@ -1450,6 +1450,7 @@ void CameraSpatialGizmoPlugin::redraw(EditorSpatialGizmo *p_gizmo) {
#undef ADD_QUAD
p_gizmo->add_lines(lines, material);
p_gizmo->add_collision_segments(lines);
p_gizmo->add_handles(handles, get_material("handles"));
ClippedCamera *clipcam = Object::cast_to<ClippedCamera>(camera);

View file

@ -62,11 +62,17 @@ matches.sort()
remaps = {}
remap_re = re.compile(r'^\t*capitalize_string_remaps\["(?P<from>.+)"\] = (String::utf8\()?"(?P<to>.+)"')
stop_words = set()
stop_words_re = re.compile(r'^\t*stop_words\.push_back\("(?P<word>.+)"\)')
with open("editor/editor_property_name_processor.cpp") as f:
for line in f:
m = remap_re.search(line)
if m:
remaps[m.group("from")] = m.group("to")
else:
m = stop_words_re.search(line)
if m:
stop_words.add(m.group("word"))
main_po = """
@ -126,9 +132,12 @@ capitalize_re = re.compile(r"(?<=\D)(?=\d)|(?<=\d)(?=\D([a-z]|\d))")
def _process_editor_string(name):
# See EditorPropertyNameProcessor::process_string().
capitalized_parts = []
for segment in name.split("_"):
if not segment:
parts = list(filter(bool, name.split("_"))) # Non-empty only.
for i, segment in enumerate(parts):
if i > 0 and i + 1 < len(parts) and segment in stop_words:
capitalized_parts.append(segment)
continue
remapped = remaps.get(segment)
if remapped:
capitalized_parts.append(remapped)

View file

@ -28,7 +28,9 @@ while IFS= read -rd '' f; do
continue
elif [[ "$f" == *"po" ]]; then
continue
elif [[ "$f" == "thirdparty"* ]]; then
elif [[ "$f" == "thirdparty/"* ]]; then
continue
elif [[ "$f" == *"/thirdparty/"* ]]; then
continue
elif [[ "$f" == "platform/android/java/lib/src/com/google"* ]]; then
continue

View file

@ -475,9 +475,6 @@ Transform2D CanvasItem::get_global_transform_with_canvas() const {
}
Transform2D CanvasItem::get_global_transform() const {
#ifdef DEBUG_ENABLED
ERR_FAIL_COND_V(!is_inside_tree(), get_transform());
#endif
if (global_invalid) {
const CanvasItem *pi = get_parent_item();
if (pi) {

View file

@ -529,8 +529,11 @@ void FileDialog::update_file_list() {
files.pop_front();
}
if (tree->get_root() && tree->get_root()->get_children() && tree->get_selected() == nullptr) {
tree->get_root()->get_children()->select(0);
if (mode != MODE_SAVE_FILE) {
// Select the first file from list if nothing is selected.
if (tree->get_root() && tree->get_root()->get_children() && tree->get_selected() == nullptr) {
tree->get_root()->get_children()->select(0);
}
}
}

View file

@ -36,6 +36,7 @@ void CanvasLayer::set_layer(int p_xform) {
layer = p_xform;
if (viewport.is_valid()) {
VisualServer::get_singleton()->viewport_set_canvas_stacking(viewport, canvas, layer, get_position_in_parent());
vp->_gui_set_root_order_dirty();
}
}

View file

@ -3078,6 +3078,8 @@ void Node::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_scene_instance_load_placeholder", "load_placeholder"), &Node::set_scene_instance_load_placeholder);
ClassDB::bind_method(D_METHOD("get_scene_instance_load_placeholder"), &Node::get_scene_instance_load_placeholder);
ClassDB::bind_method(D_METHOD("set_editable_instance", "node", "is_editable"), &Node::set_editable_instance);
ClassDB::bind_method(D_METHOD("is_editable_instance", "node"), &Node::is_editable_instance);
ClassDB::bind_method(D_METHOD("get_viewport"), &Node::get_viewport);