Merge pull request #87530 from YeldhamDev/atr_inheritance

Rework the auto translation system
This commit is contained in:
Rémi Verschelde 2024-02-17 15:54:31 +01:00
commit 2c5fa95aea
No known key found for this signature in database
GPG key ID: C3336907360768E1
51 changed files with 284 additions and 136 deletions

View file

@ -937,9 +937,8 @@
<member name="anchor_top" type="float" setter="_set_anchor" getter="get_anchor" default="0.0">
Anchors the top edge of the node to the origin, the center or the end of its parent control. It changes how the top offset updates when the node moves or changes size. You can use one of the [enum Anchor] constants for convenience.
</member>
<member name="auto_translate" type="bool" setter="set_auto_translate" getter="is_auto_translating" default="true">
<member name="auto_translate" type="bool" setter="set_auto_translate" getter="is_auto_translating" default="true" deprecated="Use [member Node.auto_translate_mode] instead.">
Toggles if any text should automatically change to its translated version depending on the current locale.
Also decides if the node's strings should be parsed for POT generation.
</member>
<member name="clip_contents" type="bool" setter="set_clip_contents" getter="is_clipping_contents" default="false">
Enables whether rendering of [CanvasItem] based children should be clipped to this control's rectangle. If [code]true[/code], parts of a child which would be visibly outside of this control's rectangle will not be rendered and won't receive input.

View file

@ -186,6 +186,32 @@
[b]Note:[/b] [SceneTree]'s group methods will [i]not[/i] work on this node if not inside the tree (see [method is_inside_tree]).
</description>
</method>
<method name="atr" qualifiers="const">
<return type="String" />
<param index="0" name="message" type="String" />
<param index="1" name="context" type="StringName" default="&quot;&quot;" />
<description>
Translates a [param message], using the translation catalogs configured in the Project Settings. Further [param context] can be specified to help with the translation.
This method works the same as [method Object.tr], with the addition of respecting the [member auto_translate_mode] state.
If [method Object.can_translate_messages] is [code]false[/code], or no translation is available, this method returns the [param message] without changes. See [method Object.set_message_translation].
For detailed examples, see [url=$DOCS_URL/tutorials/i18n/internationalizing_games.html]Internationalizing games[/url].
</description>
</method>
<method name="atr_n" qualifiers="const">
<return type="String" />
<param index="0" name="message" type="String" />
<param index="1" name="plural_message" type="StringName" />
<param index="2" name="n" type="int" />
<param index="3" name="context" type="StringName" default="&quot;&quot;" />
<description>
Translates a [param message] or [param plural_message], using the translation catalogs configured in the Project Settings. Further [param context] can be specified to help with the translation.
This method works the same as [method Object.tr_n], with the addition of respecting the [member auto_translate_mode] state.
If [method Object.can_translate_messages] is [code]false[/code], or no translation is available, this method returns [param message] or [param plural_message], without changes. See [method Object.set_message_translation].
The [param n] is the number, or amount, of the message's subject. It is used by the translation system to fetch the correct plural form for the current language.
For detailed examples, see [url=$DOCS_URL/tutorials/i18n/localization_using_gettext.html]Localization using gettext[/url].
[b]Note:[/b] Negative and [float] numbers may not properly apply to some countable subjects. It's recommended to handle these cases with [method atr].
</description>
</method>
<method name="call_deferred_thread_group" qualifiers="vararg">
<return type="Variant" />
<param index="0" name="method" type="StringName" />
@ -203,7 +229,7 @@
<method name="can_process" qualifiers="const">
<return type="bool" />
<description>
Returns [code]true[/code] if the node can receive processing notifications and input callbacks ([constant NOTIFICATION_PROCESS], [method _input], etc) from the [SceneTree] and [Viewport]. The returned value depends on [member process_mode]:
Returns [code]true[/code] if the node can receive processing notifications and input callbacks ([constant NOTIFICATION_PROCESS], [method _input], etc.) from the [SceneTree] and [Viewport]. The returned value depends on [member process_mode]:
- If set to [constant PROCESS_MODE_PAUSABLE], returns [code]true[/code] when the game is processing, i.e. [member SceneTree.paused] is [code]false[/code];
- If set to [constant PROCESS_MODE_WHEN_PAUSED], returns [code]true[/code] when the game is paused, i.e. [member SceneTree.paused] is [code]true[/code];
- If set to [constant PROCESS_MODE_ALWAYS], always returns [code]true[/code];
@ -923,6 +949,10 @@
</method>
</methods>
<members>
<member name="auto_translate_mode" type="int" setter="set_auto_translate_mode" getter="get_auto_translate_mode" enum="Node.AutoTranslateMode" default="0">
Defines if any text should automatically change to its translated version depending on the current locale (for nodes such as [Label], [RichTextLabel], [Window], etc.). See [enum AutoTranslateMode].
Also decides if the node's strings should be parsed for POT generation.
</member>
<member name="editor_description" type="String" setter="set_editor_description" getter="get_editor_description" default="&quot;&quot;">
An optional description to the node. It will be displayed as a tooltip when hovering over the node in the editor's Scene dock.
</member>
@ -1180,10 +1210,10 @@
Notification received when the [TextServer] is changed.
</constant>
<constant name="PROCESS_MODE_INHERIT" value="0" enum="ProcessMode">
Inherits [member process_mode] from the node's parent. For the root node, it is equivalent to [constant PROCESS_MODE_PAUSABLE]. This is the default for any newly created node.
Inherits [member process_mode] from the node's parent. This is the default for any newly created node.
</constant>
<constant name="PROCESS_MODE_PAUSABLE" value="1" enum="ProcessMode">
Stops processing when [member SceneTree.paused] is [code]true[/code]. This is the inverse of [constant PROCESS_MODE_WHEN_PAUSED].
Stops processing when [member SceneTree.paused] is [code]true[/code]. This is the inverse of [constant PROCESS_MODE_WHEN_PAUSED], and the default for the root node.
</constant>
<constant name="PROCESS_MODE_WHEN_PAUSED" value="2" enum="ProcessMode">
Process [b]only[/b] when [member SceneTree.paused] is [code]true[/code]. This is the inverse of [constant PROCESS_MODE_PAUSABLE].
@ -1233,5 +1263,15 @@
<constant name="INTERNAL_MODE_BACK" value="2" enum="InternalMode">
The node will be placed at the end of the parent's children list, after any non-internal sibling.
</constant>
<constant name="AUTO_TRANSLATE_MODE_INHERIT" value="0" enum="AutoTranslateMode">
Inherits [member auto_translate_mode] from the node's parent. This is the default for any newly created node.
</constant>
<constant name="AUTO_TRANSLATE_MODE_ALWAYS" value="1" enum="AutoTranslateMode">
Always automatically translate. This is the inverse of [constant AUTO_TRANSLATE_MODE_DISABLED], and the default for the root node.
</constant>
<constant name="AUTO_TRANSLATE_MODE_DISABLED" value="2" enum="AutoTranslateMode">
Never automatically translate. This is the inverse of [constant AUTO_TRANSLATE_MODE_ALWAYS].
String parsing for POT generation will be skipped for this node and children that are set to [constant AUTO_TRANSLATE_MODE_INHERIT].
</constant>
</constants>
</class>

View file

@ -1032,7 +1032,7 @@
If [method can_translate_messages] is [code]false[/code], or no translation is available, this method returns [param message] or [param plural_message], without changes. See [method set_message_translation].
The [param n] is the number, or amount, of the message's subject. It is used by the translation system to fetch the correct plural form for the current language.
For detailed examples, see [url=$DOCS_URL/tutorials/i18n/localization_using_gettext.html]Localization using gettext[/url].
[b]Note:[/b] Negative and [float] numbers may not properly apply to some countable subjects. It's recommended handling these cases with [method tr].
[b]Note:[/b] Negative and [float] numbers may not properly apply to some countable subjects. It's recommended to handle these cases with [method tr].
</description>
</method>
</methods>

View file

@ -557,7 +557,7 @@
<member name="always_on_top" type="bool" setter="set_flag" getter="get_flag" default="false">
If [code]true[/code], the window will be on top of all other windows. Does not work if [member transient] is enabled.
</member>
<member name="auto_translate" type="bool" setter="set_auto_translate" getter="is_auto_translating" default="true">
<member name="auto_translate" type="bool" setter="set_auto_translate" getter="is_auto_translating" default="true" deprecated="Use [member Node.auto_translate_mode] instead.">
Toggles if any text should automatically change to its translated version depending on the current locale.
</member>
<member name="borderless" type="bool" setter="set_flag" getter="get_flag" default="false">

View file

@ -7143,14 +7143,14 @@ AnimationTrackEditor::AnimationTrackEditor() {
transition_selection->add_item(TTR("Back", "Transition Type"), Tween::TRANS_BACK);
transition_selection->add_item(TTR("Spring", "Transition Type"), Tween::TRANS_SPRING);
transition_selection->select(Tween::TRANS_LINEAR); // Default
transition_selection->set_auto_translate(false); // Translation context is needed.
transition_selection->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED); // Translation context is needed.
ease_selection = memnew(OptionButton);
ease_selection->add_item(TTR("In", "Ease Type"), Tween::EASE_IN);
ease_selection->add_item(TTR("Out", "Ease Type"), Tween::EASE_OUT);
ease_selection->add_item(TTR("InOut", "Ease Type"), Tween::EASE_IN_OUT);
ease_selection->add_item(TTR("OutIn", "Ease Type"), Tween::EASE_OUT_IN);
ease_selection->select(Tween::EASE_IN_OUT); // Default
ease_selection->set_auto_translate(false); // Translation context is needed.
ease_selection->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED); // Translation context is needed.
ease_fps = memnew(SpinBox);
ease_fps->set_min(1);
ease_fps->set_max(999);

View file

@ -794,7 +794,7 @@ CreateDialog::CreateDialog() {
rec_vb->set_v_size_flags(Control::SIZE_EXPAND_FILL);
recent = memnew(ItemList);
recent->set_auto_translate(false);
recent->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
rec_vb->add_margin_child(TTR("Recent:"), recent, true);
recent->set_allow_reselect(true);
recent->connect("item_selected", callable_mp(this, &CreateDialog::_history_selected));

View file

@ -398,7 +398,7 @@ DependencyEditorOwners::DependencyEditorOwners() {
file_options->connect("id_pressed", callable_mp(this, &DependencyEditorOwners::_file_option));
owners = memnew(ItemList);
owners->set_auto_translate(false);
owners->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
owners->set_select_mode(ItemList::SELECT_MULTI);
owners->connect("item_clicked", callable_mp(this, &DependencyEditorOwners::_list_rmb_clicked));
owners->connect("item_activated", callable_mp(this, &DependencyEditorOwners::_select_file));

View file

@ -100,7 +100,7 @@ ScrollContainer *EditorAbout::_populate_list(const String &p_name, const List<St
vbc->add_child(lbl);
ItemList *il = memnew(ItemList);
il->set_auto_translate(false);
il->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
il->set_h_size_flags(Control::SIZE_EXPAND_FILL);
il->set_same_column_width(true);
il->set_auto_height(true);

View file

@ -932,7 +932,7 @@ EditorFeatureProfileManager::EditorFeatureProfileManager() {
HBoxContainer *profiles_hbc = memnew(HBoxContainer);
profile_list = memnew(OptionButton);
profile_list->set_h_size_flags(Control::SIZE_EXPAND_FILL);
profile_list->set_auto_translate(false);
profile_list->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
profiles_hbc->add_child(profile_list);
profile_list->connect("item_selected", callable_mp(this, &EditorFeatureProfileManager::_profile_selected));

View file

@ -114,7 +114,7 @@ EditorLayoutsDialog::EditorLayoutsDialog() {
add_child(makevb);
layout_names = memnew(ItemList);
layout_names->set_auto_translate(false);
layout_names->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
layout_names->set_auto_height(true);
layout_names->set_custom_minimum_size(Size2(300 * EDSCALE, 50 * EDSCALE));
layout_names->set_visible(true);

View file

@ -6949,7 +6949,7 @@ EditorNode::EditorNode() {
editor_layouts = memnew(PopupMenu);
editor_layouts->set_name("Layouts");
editor_layouts->set_auto_translate(false);
editor_layouts->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
settings_menu->add_child(editor_layouts);
editor_layouts->connect("id_pressed", callable_mp(this, &EditorNode::_layout_menu_option));
settings_menu->add_submenu_item(TTR("Editor Layout"), "Layouts");

View file

@ -374,7 +374,7 @@ EditorPropertyTextEnum::EditorPropertyTextEnum() {
option_button->set_h_size_flags(SIZE_EXPAND_FILL);
option_button->set_clip_text(true);
option_button->set_flat(true);
option_button->set_auto_translate(false);
option_button->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
default_layout->add_child(option_button);
option_button->connect("item_selected", callable_mp(this, &EditorPropertyTextEnum::_option_selected));
@ -728,7 +728,7 @@ EditorPropertyEnum::EditorPropertyEnum() {
options = memnew(OptionButton);
options->set_clip_text(true);
options->set_flat(true);
options->set_auto_translate(false);
options->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
add_child(options);
add_focusable(options);
options->connect("item_selected", callable_mp(this, &EditorPropertyEnum::_option_selected));
@ -2955,7 +2955,7 @@ EditorPropertyNodePath::EditorPropertyNodePath() {
assign->set_flat(true);
assign->set_h_size_flags(SIZE_EXPAND_FILL);
assign->set_clip_text(true);
assign->set_auto_translate(false);
assign->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
assign->set_expand_icon(true);
assign->connect("pressed", callable_mp(this, &EditorPropertyNodePath::_node_assign));
SET_DRAG_FORWARDING_CD(assign, EditorPropertyNodePath);

View file

@ -1018,7 +1018,7 @@ EditorResourcePicker::EditorResourcePicker(bool p_hide_assign_button_controls) {
assign_button->set_h_size_flags(SIZE_EXPAND_FILL);
assign_button->set_expand_icon(true);
assign_button->set_clip_text(true);
assign_button->set_auto_translate(false);
assign_button->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
SET_DRAG_FORWARDING_GCD(assign_button, EditorResourcePicker);
add_child(assign_button);
assign_button->connect("pressed", callable_mp(this, &EditorResourcePicker::_resource_selected));

View file

@ -1212,7 +1212,7 @@ ProjectExportDialog::ProjectExportDialog() {
preset_vb->add_child(mc);
mc->set_v_size_flags(Control::SIZE_EXPAND_FILL);
presets = memnew(ItemList);
presets->set_auto_translate(false);
presets->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
SET_DRAG_FORWARDING_GCD(presets, ProjectExportDialog);
mc->add_child(presets);
presets->connect("item_selected", callable_mp(this, &ProjectExportDialog::_edit_preset));

View file

@ -1910,7 +1910,7 @@ EditorFileDialog::EditorFileDialog() {
fav_down->connect("pressed", callable_mp(this, &EditorFileDialog::_favorite_move_down));
favorites = memnew(ItemList);
favorites->set_auto_translate(false);
favorites->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
fav_vb->add_child(favorites);
favorites->set_v_size_flags(Control::SIZE_EXPAND_FILL);
favorites->connect("item_selected", callable_mp(this, &EditorFileDialog::_favorite_selected));
@ -1920,7 +1920,7 @@ EditorFileDialog::EditorFileDialog() {
rec_vb->set_custom_minimum_size(Size2(150, 100) * EDSCALE);
rec_vb->set_v_size_flags(Control::SIZE_EXPAND_FILL);
recent = memnew(ItemList);
recent->set_auto_translate(false);
recent->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
recent->set_allow_reselect(true);
rec_vb->add_margin_child(TTR("Recent:"), recent, true);
recent->connect("item_selected", callable_mp(this, &EditorFileDialog::_recent_selected));
@ -1944,7 +1944,7 @@ EditorFileDialog::EditorFileDialog() {
// Item (files and folders) list with context menu.
item_list = memnew(ItemList);
item_list->set_auto_translate(false);
item_list->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
item_list->set_v_size_flags(Control::SIZE_EXPAND_FILL);
item_list->connect("item_clicked", callable_mp(this, &EditorFileDialog::_item_list_item_rmb_clicked));
item_list->connect("empty_clicked", callable_mp(this, &EditorFileDialog::_item_list_empty_clicked));

View file

@ -238,7 +238,7 @@ EditorObjectSelector::EditorObjectSelector(EditorSelectionHistory *p_history) {
current_object_label = memnew(Label);
current_object_label->set_text_overrun_behavior(TextServer::OVERRUN_TRIM_ELLIPSIS);
current_object_label->set_h_size_flags(SIZE_EXPAND_FILL);
current_object_label->set_auto_translate(false);
current_object_label->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
main_hb->add_child(current_object_label);
sub_objects_icon = memnew(TextureRect);
@ -247,7 +247,7 @@ EditorObjectSelector::EditorObjectSelector(EditorSelectionHistory *p_history) {
main_hb->add_child(sub_objects_icon);
sub_objects_menu = memnew(PopupMenu);
sub_objects_menu->set_auto_translate(false);
sub_objects_menu->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
add_child(sub_objects_menu);
sub_objects_menu->connect("about_to_popup", callable_mp(this, &EditorObjectSelector::_about_to_show));
sub_objects_menu->connect("id_pressed", callable_mp(this, &EditorObjectSelector::_id_pressed));

View file

@ -377,7 +377,7 @@ EditorSceneTabs::EditorSceneTabs() {
scene_tabs->set_tab_close_display_policy((TabBar::CloseButtonDisplayPolicy)EDITOR_GET("interface/scene_tabs/display_close_button").operator int());
scene_tabs->set_max_tab_width(int(EDITOR_GET("interface/scene_tabs/maximum_width")) * EDSCALE);
scene_tabs->set_drag_to_rearrange_enabled(true);
scene_tabs->set_auto_translate(false);
scene_tabs->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
scene_tabs->set_h_size_flags(Control::SIZE_EXPAND_FILL);
tabbar_container->add_child(scene_tabs);

View file

@ -1601,7 +1601,7 @@ void SceneTreeDialog::set_valid_types(const Vector<StringName> &p_valid) {
Label *label = memnew(Label);
hb->add_child(label);
label->set_text(name);
label->set_auto_translate(false);
label->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
}
show_all_nodes->show();

View file

@ -248,7 +248,7 @@ HistoryDock::HistoryDock() {
global_history_checkbox->connect("toggled", callable_mp(this, &HistoryDock::refresh_history).unbind(1));
action_list = memnew(ItemList);
action_list->set_auto_translate(false);
action_list->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
add_child(action_list);
action_list->set_v_size_flags(Control::SIZE_EXPAND_FILL);
action_list->connect("item_selected", callable_mp(this, &HistoryDock::seek_history));

View file

@ -804,7 +804,7 @@ AnimationNodeBlendSpace1DEditor::AnimationNodeBlendSpace1DEditor() {
animations_menu = memnew(PopupMenu);
menu->add_child(animations_menu);
animations_menu->set_name("AddAnimations");
animations_menu->set_auto_translate(false);
animations_menu->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
animations_menu->connect("index_pressed", callable_mp(this, &AnimationNodeBlendSpace1DEditor::_add_animation_type));
open_file = memnew(EditorFileDialog);

View file

@ -1083,7 +1083,7 @@ AnimationNodeBlendSpace2DEditor::AnimationNodeBlendSpace2DEditor() {
animations_menu = memnew(PopupMenu);
menu->add_child(animations_menu);
animations_menu->set_name("AddAnimations");
animations_menu->set_auto_translate(false);
animations_menu->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
animations_menu->connect("index_pressed", callable_mp(this, &AnimationNodeBlendSpace2DEditor::_add_animation_type));
open_file = memnew(EditorFileDialog);

View file

@ -239,7 +239,7 @@ void AnimationNodeBlendTreeEditor::update_graph() {
MenuButton *mb = memnew(MenuButton);
mb->set_text(anim->get_animation());
mb->set_icon(get_editor_theme_icon(SNAME("Animation")));
mb->set_auto_translate(false);
mb->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
mb->set_disabled(read_only);
Array options;

View file

@ -1886,7 +1886,7 @@ AnimationPlayerEditor::AnimationPlayerEditor(AnimationPlayerEditorPlugin *p_plug
animation->set_h_size_flags(SIZE_EXPAND_FILL);
animation->set_tooltip_text(TTR("Display list of animations in player."));
animation->set_clip_text(true);
animation->set_auto_translate(false);
animation->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
autoplay = memnew(Button);
autoplay->set_theme_type_variation("FlatButton");
@ -1985,7 +1985,7 @@ AnimationPlayerEditor::AnimationPlayerEditor(AnimationPlayerEditorPlugin *p_plug
blend_editor.tree->connect(SNAME("item_edited"), callable_mp(this, &AnimationPlayerEditor::_blend_edited));
blend_editor.next = memnew(OptionButton);
blend_editor.next->set_auto_translate(false);
blend_editor.next->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
blend_vb->add_margin_child(TTR("Next (Auto Queue):"), blend_editor.next);
autoplay->connect(SNAME("pressed"), callable_mp(this, &AnimationPlayerEditor::_autoplay_pressed));

View file

@ -1779,7 +1779,7 @@ AnimationNodeStateMachineEditor::AnimationNodeStateMachineEditor() {
animations_menu = memnew(PopupMenu);
menu->add_child(animations_menu);
animations_menu->set_name("AddAnimations");
animations_menu->set_auto_translate(false);
animations_menu->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
animations_menu->connect("index_pressed", callable_mp(this, &AnimationNodeStateMachineEditor::_add_animation_type));
connect_menu = memnew(PopupMenu);

View file

@ -5544,7 +5544,7 @@ CanvasItemEditor::CanvasItemEditor() {
selection_menu = memnew(PopupMenu);
add_child(selection_menu);
selection_menu->set_min_size(Vector2(100, 0));
selection_menu->set_auto_translate(false);
selection_menu->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
selection_menu->connect("id_pressed", callable_mp(this, &CanvasItemEditor::_selection_result_pressed));
selection_menu->connect("popup_hide", callable_mp(this, &CanvasItemEditor::_selection_menu_hide), CONNECT_DEFERRED);

View file

@ -52,32 +52,58 @@ Error PackedSceneEditorTranslationParserPlugin::parse_file(const String &p_path,
Ref<SceneState> state = Ref<PackedScene>(loaded_res)->get_state();
Vector<String> parsed_strings;
List<String> tabcontainer_paths;
Vector<Pair<NodePath, bool>> atr_owners;
Vector<String> tabcontainer_paths;
for (int i = 0; i < state->get_node_count(); i++) {
String node_type = state->get_node_type(i);
bool is_control = ClassDB::is_parent_class(node_type, "Control");
if (!is_control && !ClassDB::is_parent_class(node_type, "Window")) {
continue;
String parent_path = state->get_node_path(i, true);
// Find the `auto_translate_mode` property.
bool auto_translating = true;
bool auto_translate_mode_found = false;
for (int j = 0; j < state->get_node_property_count(i); j++) {
if (state->get_node_property_name(i, j) != "auto_translate_mode") {
continue;
}
auto_translate_mode_found = true;
int idx_last = atr_owners.size() - 1;
if (idx_last > 0 && !parent_path.begins_with(atr_owners[idx_last].first)) {
// Switch to the previous auto translation owner this was nested in, if that was the case.
atr_owners.remove_at(idx_last);
idx_last -= 1;
}
int auto_translate_mode = (int)state->get_node_property_value(i, j);
if (auto_translate_mode == Node::AUTO_TRANSLATE_MODE_DISABLED) {
auto_translating = false;
}
atr_owners.push_back(Pair(state->get_node_path(i), auto_translating));
break;
}
// Find the `auto_translate` property, and abort the string parsing of the node if disabled.
bool auto_translating = true;
for (int j = 0; j < state->get_node_property_count(i); j++) {
if (state->get_node_property_name(i, j) == "auto_translate" && (bool)state->get_node_property_value(i, j) == false) {
auto_translating = false;
break;
// If `auto_translate_mode` wasn't found, that means it is set to its default value (`AUTO_TRANSLATE_MODE_INHERIT`).
if (!auto_translate_mode_found) {
int idx_last = atr_owners.size() - 1;
if (idx_last > 0 && atr_owners[idx_last].first == parent_path) {
auto_translating = atr_owners[idx_last].second;
} else {
atr_owners.push_back(Pair(state->get_node_path(i), true));
}
}
// Parse the names of children of `TabContainer`s, as they are used for tab titles.
if (!tabcontainer_paths.is_empty()) {
String parent_path = state->get_node_path(i, true);
if (!parent_path.begins_with(tabcontainer_paths[tabcontainer_paths.size() - 1])) {
// Switch to the previous `TabContainer` this was nested in, if that was the case.
tabcontainer_paths.pop_back();
tabcontainer_paths.remove_at(tabcontainer_paths.size() - 1);
}
if (is_control && auto_translating && !tabcontainer_paths.is_empty() && parent_path == tabcontainer_paths[tabcontainer_paths.size() - 1]) {
if (auto_translating && !tabcontainer_paths.is_empty() && ClassDB::is_parent_class(node_type, "Control") &&
parent_path == tabcontainer_paths[tabcontainer_paths.size() - 1]) {
parsed_strings.push_back(state->get_node_name(i));
}
}

View file

@ -3872,7 +3872,7 @@ ScriptEditor::ScriptEditor(WindowWrapper *p_wrapper) {
scripts_vbox->add_child(filter_scripts);
script_list = memnew(ItemList);
script_list->set_auto_translate(false);
script_list->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
scripts_vbox->add_child(script_list);
script_list->set_custom_minimum_size(Size2(150, 60) * EDSCALE); //need to give a bit of limit to avoid it from disappearing
script_list->set_v_size_flags(SIZE_EXPAND_FILL);
@ -3917,7 +3917,7 @@ ScriptEditor::ScriptEditor(WindowWrapper *p_wrapper) {
overview_vbox->add_child(filter_methods);
members_overview = memnew(ItemList);
members_overview->set_auto_translate(false);
members_overview->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
overview_vbox->add_child(members_overview);
members_overview->set_allow_reselect(true);
@ -3926,7 +3926,7 @@ ScriptEditor::ScriptEditor(WindowWrapper *p_wrapper) {
members_overview->set_allow_rmb_select(true);
help_overview = memnew(ItemList);
help_overview->set_auto_translate(false);
help_overview->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
overview_vbox->add_child(help_overview);
help_overview->set_allow_reselect(true);
help_overview->set_custom_minimum_size(Size2(0, 60) * EDSCALE); //need to give a bit of limit to avoid it from disappearing

View file

@ -659,7 +659,7 @@ ShaderEditorPlugin::ShaderEditorPlugin() {
window_wrapper->connect("window_visibility_changed", callable_mp(this, &ShaderEditorPlugin::_window_changed));
shader_list = memnew(ItemList);
shader_list->set_auto_translate(false);
shader_list->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
shader_list->set_v_size_flags(Control::SIZE_EXPAND_FILL);
vb->add_child(shader_list);
shader_list->connect("item_selected", callable_mp(this, &ShaderEditorPlugin::_shader_selected));

View file

@ -256,7 +256,7 @@ ShaderFileEditor::ShaderFileEditor() {
add_child(main_hs);
versions = memnew(ItemList);
versions->set_auto_translate(false);
versions->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
versions->connect("item_selected", callable_mp(this, &ShaderFileEditor::_version_selected));
versions->set_custom_minimum_size(Size2i(200 * EDSCALE, 0));
main_hs->add_child(versions);

View file

@ -1880,7 +1880,7 @@ SpriteFramesEditor::SpriteFramesEditor() {
add_child(file);
frame_list = memnew(ItemList);
frame_list->set_auto_translate(false);
frame_list->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
frame_list->set_v_size_flags(SIZE_EXPAND_FILL);
frame_list->set_icon_mode(ItemList::ICON_MODE_TOP);
frame_list->set_texture_filter(TEXTURE_FILTER_NEAREST_WITH_MIPMAPS);

View file

@ -2246,7 +2246,7 @@ ThemeTypeDialog::ThemeTypeDialog() {
add_type_vb->add_child(add_type_options_label);
add_type_options = memnew(ItemList);
add_type_options->set_auto_translate(false);
add_type_options->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
add_type_options->set_v_size_flags(Control::SIZE_EXPAND_FILL);
add_type_vb->add_child(add_type_options);
add_type_options->connect("item_selected", callable_mp(this, &ThemeTypeDialog::_add_type_options_cbk));
@ -3416,7 +3416,7 @@ ThemeTypeEditor::ThemeTypeEditor() {
theme_type_list = memnew(OptionButton);
theme_type_list->set_h_size_flags(SIZE_EXPAND_FILL);
theme_type_list->set_text_overrun_behavior(TextServer::OVERRUN_TRIM_ELLIPSIS);
theme_type_list->set_auto_translate(false);
theme_type_list->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
type_list_hb->add_child(theme_type_list);
theme_type_list->connect("item_selected", callable_mp(this, &ThemeTypeEditor::_list_type_selected));

View file

@ -311,7 +311,7 @@ AtlasMergingDialog::AtlasMergingDialog() {
// Atlas sources item list.
atlas_merging_atlases_list = memnew(ItemList);
atlas_merging_atlases_list->set_auto_translate(false);
atlas_merging_atlases_list->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
atlas_merging_atlases_list->set_fixed_icon_size(Size2(60, 60) * EDSCALE);
atlas_merging_atlases_list->set_h_size_flags(Control::SIZE_EXPAND_FILL);
atlas_merging_atlases_list->set_v_size_flags(Control::SIZE_EXPAND_FILL);

View file

@ -2401,7 +2401,7 @@ TileMapLayerEditorTilesPlugin::TileMapLayerEditorTilesPlugin() {
sources_bottom_actions->add_child(source_sort_button);
sources_list = memnew(ItemList);
sources_list->set_auto_translate(false);
sources_list->set_auto_translate_mode(Node::AUTO_TRANSLATE_MODE_DISABLED);
sources_list->set_fixed_icon_size(Size2(60, 60) * EDSCALE);
sources_list->set_h_size_flags(Control::SIZE_EXPAND_FILL);
sources_list->set_v_size_flags(Control::SIZE_EXPAND_FILL);
@ -2441,7 +2441,7 @@ TileMapLayerEditorTilesPlugin::TileMapLayerEditorTilesPlugin() {
// Scenes collection source.
scene_tiles_list = memnew(ItemList);
scene_tiles_list->set_auto_translate(false);
scene_tiles_list->set_auto_translate_mode(Node::AUTO_TRANSLATE_MODE_DISABLED);
scene_tiles_list->set_h_size_flags(Control::SIZE_EXPAND_FILL);
scene_tiles_list->set_v_size_flags(Control::SIZE_EXPAND_FILL);
scene_tiles_list->set_select_mode(ItemList::SELECT_MULTI);
@ -2467,7 +2467,7 @@ TileMapLayerEditorTilesPlugin::TileMapLayerEditorTilesPlugin() {
int thumbnail_size = 64;
patterns_item_list = memnew(ItemList);
patterns_item_list->set_auto_translate(false);
patterns_item_list->set_auto_translate_mode(Node::AUTO_TRANSLATE_MODE_DISABLED);
patterns_item_list->set_max_columns(0);
patterns_item_list->set_icon_mode(ItemList::ICON_MODE_TOP);
patterns_item_list->set_fixed_column_width(thumbnail_size * 3 / 2);
@ -3529,7 +3529,7 @@ TileMapLayerEditorTerrainsPlugin::TileMapLayerEditorTerrainsPlugin() {
tilemap_tab_terrains->add_child(terrains_tree);
terrains_tile_list = memnew(ItemList);
terrains_tile_list->set_auto_translate(false);
terrains_tile_list->set_auto_translate_mode(Node::AUTO_TRANSLATE_MODE_DISABLED);
terrains_tile_list->set_h_size_flags(Control::SIZE_EXPAND_FILL);
terrains_tile_list->set_max_columns(0);
terrains_tile_list->set_same_column_width(true);

View file

@ -345,7 +345,7 @@ TileProxiesManagerDialog::TileProxiesManagerDialog() {
vbox_container->add_child(source_level_label);
source_level_list = memnew(ItemList);
source_level_list->set_auto_translate(false);
source_level_list->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
source_level_list->set_v_size_flags(Control::SIZE_EXPAND_FILL);
source_level_list->set_select_mode(ItemList::SELECT_MULTI);
source_level_list->set_allow_rmb_select(true);
@ -357,7 +357,7 @@ TileProxiesManagerDialog::TileProxiesManagerDialog() {
vbox_container->add_child(coords_level_label);
coords_level_list = memnew(ItemList);
coords_level_list->set_auto_translate(false);
coords_level_list->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
coords_level_list->set_v_size_flags(Control::SIZE_EXPAND_FILL);
coords_level_list->set_select_mode(ItemList::SELECT_MULTI);
coords_level_list->set_allow_rmb_select(true);
@ -369,7 +369,7 @@ TileProxiesManagerDialog::TileProxiesManagerDialog() {
vbox_container->add_child(alternative_level_label);
alternative_level_list = memnew(ItemList);
alternative_level_list->set_auto_translate(false);
alternative_level_list->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
alternative_level_list->set_v_size_flags(Control::SIZE_EXPAND_FILL);
alternative_level_list->set_select_mode(ItemList::SELECT_MULTI);
alternative_level_list->set_allow_rmb_select(true);

View file

@ -854,7 +854,7 @@ TileSetEditor::TileSetEditor() {
p->set_item_checked(TilesEditorUtils::SOURCE_SORT_ID, true);
sources_list = memnew(ItemList);
sources_list->set_auto_translate(false);
sources_list->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
sources_list->set_fixed_icon_size(Size2(60, 60) * EDSCALE);
sources_list->set_h_size_flags(SIZE_EXPAND_FILL);
sources_list->set_v_size_flags(SIZE_EXPAND_FILL);
@ -934,7 +934,7 @@ TileSetEditor::TileSetEditor() {
//// Patterns ////
int thumbnail_size = 64;
patterns_item_list = memnew(ItemList);
patterns_item_list->set_auto_translate(false);
patterns_item_list->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
patterns_item_list->set_max_columns(0);
patterns_item_list->set_icon_mode(ItemList::ICON_MODE_TOP);
patterns_item_list->set_fixed_column_width(thumbnail_size * 3 / 2);

View file

@ -560,7 +560,7 @@ TileSetScenesCollectionSourceEditor::TileSetScenesCollectionSourceEditor() {
split_container_right_side->add_child(right_vbox_container);
scene_tiles_list = memnew(ItemList);
scene_tiles_list->set_auto_translate(false);
scene_tiles_list->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
scene_tiles_list->set_h_size_flags(SIZE_EXPAND_FILL);
scene_tiles_list->set_v_size_flags(SIZE_EXPAND_FILL);
SET_DRAG_FORWARDING_CDU(scene_tiles_list, TileSetScenesCollectionSourceEditor);

View file

@ -573,7 +573,7 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id, bool
String prop_name = dp.name.strip_edges();
if (!prop_name.is_empty()) {
Label *label = memnew(Label);
label->set_auto_translate(false); // TODO: Implement proper translation switch.
label->set_auto_translate_mode(Node::AUTO_TRANSLATE_MODE_DISABLED); // TODO: Implement proper translation switch.
label->set_text(prop_name + ":");
hbox->add_child(label);
}
@ -845,7 +845,7 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id, bool
hb->add_child(remove_btn);
} else {
Label *label = memnew(Label);
label->set_auto_translate(false); // TODO: Implement proper translation switch.
label->set_auto_translate_mode(Node::AUTO_TRANSLATE_MODE_DISABLED); // TODO: Implement proper translation switch.
label->set_text(name_left);
label->add_theme_style_override("normal", editor->get_theme_stylebox(SNAME("label_style"), SNAME("VShaderEditor"))); //more compact
hb->add_child(label);
@ -895,7 +895,7 @@ void VisualShaderGraphPlugin::add_node(VisualShader::Type p_type, int p_id, bool
type_box->connect("item_selected", callable_mp(editor, &VisualShaderEditor::_change_output_port_type).bind(p_id, i), CONNECT_DEFERRED);
} else {
Label *label = memnew(Label);
label->set_auto_translate(false); // TODO: Implement proper translation switch.
label->set_auto_translate_mode(Node::AUTO_TRANSLATE_MODE_DISABLED); // TODO: Implement proper translation switch.
label->set_text(name_right);
label->add_theme_style_override("normal", editor->get_theme_stylebox(SNAME("label_style"), SNAME("VShaderEditor"))); //more compact
hb->add_child(label);
@ -6771,7 +6771,7 @@ public:
} else {
prop_name_str = prop_name_str.capitalize() + ":";
}
prop_name->set_auto_translate(false); // TODO: Implement proper translation switch.
prop_name->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED); // TODO: Implement proper translation switch.
prop_name->set_text(prop_name_str);
prop_name->set_visible(false);
hbox->add_child(prop_name);

View file

@ -238,7 +238,7 @@ ProjectListItemControl::ProjectListItemControl() {
main_vbox->add_child(title_hb);
project_title = memnew(Label);
project_title->set_auto_translate(false);
project_title->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
project_title->set_name("ProjectName");
project_title->set_h_size_flags(Control::SIZE_EXPAND_FILL);
project_title->set_clip_text(true);

View file

@ -66,7 +66,7 @@ ProjectTag::ProjectTag(const String &p_text, bool p_display_close) {
button = memnew(Button);
add_child(button);
button->set_auto_translate(false);
button->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
button->set_text(p_text.capitalize());
button->set_focus_mode(FOCUS_NONE);
button->set_icon_alignment(HORIZONTAL_ALIGNMENT_RIGHT);

View file

@ -275,7 +275,7 @@ SceneCreateDialog::SceneCreateDialog() {
root_name_edit = memnew(LineEdit);
gc->add_child(root_name_edit);
root_name_edit->set_tooltip_text(TTR("When empty, the root node name is derived from the scene name based on the \"editor/naming/node_name_casing\" project setting."));
root_name_edit->set_auto_translate(false);
root_name_edit->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
root_name_edit->set_h_size_flags(Control::SIZE_EXPAND_FILL);
root_name_edit->connect("text_submitted", callable_mp(this, &SceneCreateDialog::accept_create).unbind(1));
}

View file

@ -1316,7 +1316,7 @@ GridMapEditor::GridMapEditor() {
EDITOR_DEF("editors/grid_map/preview_size", 64);
mesh_library_palette = memnew(ItemList);
mesh_library_palette->set_auto_translate(false);
mesh_library_palette->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED);
add_child(mesh_library_palette);
mesh_library_palette->set_v_size_flags(SIZE_EXPAND_FILL);
mesh_library_palette->connect("gui_input", callable_mp(this, &GridMapEditor::_mesh_library_palette_input));

View file

@ -268,6 +268,7 @@ String Control::properties_managed_by_container[] = {
bool Control::_set(const StringName &p_name, const Variant &p_value) {
ERR_MAIN_THREAD_GUARD_V(false);
String name = p_name;
if (!name.begins_with("theme_override")) {
return false;
}
@ -309,7 +310,6 @@ bool Control::_set(const StringName &p_name, const Variant &p_value) {
} else {
return false;
}
} else {
if (name.begins_with("theme_override_icons/")) {
String dname = name.get_slicec('/', 1);
@ -333,12 +333,14 @@ bool Control::_set(const StringName &p_name, const Variant &p_value) {
return false;
}
}
return true;
}
bool Control::_get(const StringName &p_name, Variant &r_ret) const {
ERR_MAIN_THREAD_GUARD_V(false);
String sname = p_name;
if (!sname.begins_with("theme_override")) {
return false;
}
@ -2996,7 +2998,6 @@ void Control::set_layout_direction(Control::LayoutDirection p_direction) {
ERR_FAIL_INDEX((int)p_direction, 4);
data.layout_dir = p_direction;
data.is_rtl_dirty = true;
propagate_notification(NOTIFICATION_LAYOUT_DIRECTION_CHANGED);
}
@ -3097,21 +3098,17 @@ bool Control::is_localizing_numeral_system() const {
return data.localize_numeral_system;
}
#ifndef DISABLE_DEPRECATED
void Control::set_auto_translate(bool p_enable) {
ERR_MAIN_THREAD_GUARD;
if (p_enable == data.auto_translate) {
return;
}
data.auto_translate = p_enable;
notification(MainLoop::NOTIFICATION_TRANSLATION_CHANGED);
set_auto_translate_mode(p_enable ? AUTO_TRANSLATE_MODE_ALWAYS : AUTO_TRANSLATE_MODE_DISABLED);
}
bool Control::is_auto_translating() const {
ERR_READ_THREAD_GUARD_V(false);
return data.auto_translate;
return can_auto_translate();
}
#endif
// Extra properties.
@ -3172,14 +3169,6 @@ void Control::_notification(int p_notification) {
} break;
case NOTIFICATION_ENTER_TREE: {
#ifdef TOOLS_ENABLED
if (is_part_of_edited_scene()) {
// Don't translate Controls on scene when inside editor.
set_message_translation(false);
notification(NOTIFICATION_TRANSLATION_CHANGED);
}
#endif
// Emits NOTIFICATION_THEME_CHANGED internally.
set_theme_context(ThemeDB::get_singleton()->get_nearest_theme_context(this));
} break;
@ -3192,6 +3181,7 @@ void Control::_notification(int p_notification) {
case NOTIFICATION_EXIT_TREE: {
set_theme_context(nullptr, false);
release_focus();
get_viewport()->_gui_remove_control(this);
} break;
@ -3506,8 +3496,10 @@ void Control::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_layout_direction"), &Control::get_layout_direction);
ClassDB::bind_method(D_METHOD("is_layout_rtl"), &Control::is_layout_rtl);
#ifndef DISABLE_DEPRECATED
ClassDB::bind_method(D_METHOD("set_auto_translate", "enable"), &Control::set_auto_translate);
ClassDB::bind_method(D_METHOD("is_auto_translating"), &Control::is_auto_translating);
#endif
ClassDB::bind_method(D_METHOD("set_localize_numeral_system", "enable"), &Control::set_localize_numeral_system);
ClassDB::bind_method(D_METHOD("is_localizing_numeral_system"), &Control::is_localizing_numeral_system);
@ -3558,9 +3550,12 @@ void Control::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "size_flags_stretch_ratio", PROPERTY_HINT_RANGE, "0,20,0.01,or_greater"), "set_stretch_ratio", "get_stretch_ratio");
ADD_GROUP("Localization", "");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "auto_translate"), "set_auto_translate", "is_auto_translating");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "localize_numeral_system"), "set_localize_numeral_system", "is_localizing_numeral_system");
#ifndef DISABLE_DEPRECATED
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "auto_translate", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_auto_translate", "is_auto_translating");
#endif
ADD_GROUP("Tooltip", "tooltip_");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "tooltip_text", PROPERTY_HINT_MULTILINE_TEXT), "set_tooltip_text", "get_tooltip_text");

View file

@ -253,7 +253,6 @@ private:
bool is_rtl_dirty = true;
bool is_rtl = false;
bool auto_translate = true;
bool localize_numeral_system = true;
// Extra properties.
@ -624,11 +623,10 @@ public:
void set_localize_numeral_system(bool p_enable);
bool is_localizing_numeral_system() const;
#ifndef DISABLE_DEPRECATED
void set_auto_translate(bool p_enable);
bool is_auto_translating() const;
_FORCE_INLINE_ String atr(const String p_string) const {
return is_auto_translating() ? tr(p_string) : p_string;
};
#endif
// Extra properties.

View file

@ -149,10 +149,6 @@ void MenuButton::_notification(int p_what) {
menu_btn_other->get_popup()->set_focused_item(-1);
}
} break;
case NOTIFICATION_TRANSLATION_CHANGED: {
popup->set_auto_translate(is_auto_translating());
} break;
}
}

View file

@ -127,10 +127,7 @@ void OptionButton::_notification(int p_what) {
theme_cache.arrow_icon->draw(ci, ofs, clr);
} break;
case NOTIFICATION_TRANSLATION_CHANGED: {
popup->set_auto_translate(is_auto_translating());
[[fallthrough]];
}
case NOTIFICATION_TRANSLATION_CHANGED:
case NOTIFICATION_LAYOUT_DIRECTION_CHANGED: {
popup->set_layout_direction((Window::LayoutDirection)get_layout_direction());
[[fallthrough]];

View file

@ -99,6 +99,26 @@ void Node::_notification(int p_notification) {
}
}
// Update auto translate mode.
if (data.auto_translate_mode == AUTO_TRANSLATE_MODE_INHERIT && !data.parent) {
ERR_PRINT("The root node can't be set to Inherit auto translate mode, reverting to Always instead.");
data.auto_translate_mode = AUTO_TRANSLATE_MODE_ALWAYS;
}
data.is_auto_translate_dirty = true;
#ifdef TOOLS_ENABLED
// Don't translate UI elements when they're being edited.
if (is_part_of_edited_scene()) {
set_message_translation(false);
} else if (data.auto_translate_mode != AUTO_TRANSLATE_MODE_DISABLED) {
notification(NOTIFICATION_TRANSLATION_CHANGED);
}
#else
if (data.auto_translate_mode != AUTO_TRANSLATE_MODE_DISABLED) {
notification(NOTIFICATION_TRANSLATION_CHANGED);
}
#endif
if (data.input) {
add_to_group("_vp_input" + itos(get_viewport()->get_instance_id()));
}
@ -136,11 +156,11 @@ void Node::_notification(int p_notification) {
remove_from_group("_vp_unhandled_key_input" + itos(get_viewport()->get_instance_id()));
}
// Remove from processing first
// Remove from processing first.
if (_is_any_processing()) {
_remove_from_process_thread_group();
}
// Remove the process group
// Remove the process group.
if (data.process_thread_group_owner == this) {
_remove_process_group();
}
@ -217,6 +237,12 @@ void Node::_notification(int p_notification) {
memdelete(child);
}
} break;
case NOTIFICATION_TRANSLATION_CHANGED: {
if (data.inside_tree) {
data.is_auto_translate_dirty = true;
}
} break;
}
}
@ -1149,6 +1175,49 @@ bool Node::is_processing_unhandled_key_input() const {
return data.unhandled_key_input;
}
void Node::set_auto_translate_mode(AutoTranslateMode p_mode) {
ERR_THREAD_GUARD
if (data.auto_translate_mode == p_mode) {
return;
}
if (p_mode == AUTO_TRANSLATE_MODE_INHERIT && data.inside_tree && !data.parent) {
ERR_FAIL_MSG("The root node can't be set to Inherit auto translate mode.");
}
data.auto_translate_mode = p_mode;
data.is_auto_translating = p_mode != AUTO_TRANSLATE_MODE_DISABLED;
data.is_auto_translate_dirty = true;
propagate_notification(NOTIFICATION_TRANSLATION_CHANGED);
}
Node::AutoTranslateMode Node::get_auto_translate_mode() const {
return data.auto_translate_mode;
}
bool Node::can_auto_translate() const {
ERR_READ_THREAD_GUARD_V(false);
if (!data.is_auto_translate_dirty || data.auto_translate_mode != AUTO_TRANSLATE_MODE_INHERIT) {
return data.is_auto_translating;
}
data.is_auto_translate_dirty = false;
Node *parent = data.parent;
while (parent) {
if (parent->data.auto_translate_mode == AUTO_TRANSLATE_MODE_INHERIT) {
parent = parent->data.parent;
continue;
}
data.is_auto_translating = parent->data.auto_translate_mode == AUTO_TRANSLATE_MODE_ALWAYS;
break;
}
return data.is_auto_translating;
}
StringName Node::get_name() const {
return data.name;
}
@ -3488,6 +3557,9 @@ void Node::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_physics_process_internal", "enable"), &Node::set_physics_process_internal);
ClassDB::bind_method(D_METHOD("is_physics_processing_internal"), &Node::is_physics_processing_internal);
ClassDB::bind_method(D_METHOD("set_auto_translate_mode", "mode"), &Node::set_auto_translate_mode);
ClassDB::bind_method(D_METHOD("get_auto_translate_mode"), &Node::get_auto_translate_mode);
ClassDB::bind_method(D_METHOD("get_window"), &Node::get_window);
ClassDB::bind_method(D_METHOD("get_last_exclusive_window"), &Node::get_last_exclusive_window);
ClassDB::bind_method(D_METHOD("get_tree"), &Node::get_tree);
@ -3525,6 +3597,9 @@ void Node::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_unique_name_in_owner", "enable"), &Node::set_unique_name_in_owner);
ClassDB::bind_method(D_METHOD("is_unique_name_in_owner"), &Node::is_unique_name_in_owner);
ClassDB::bind_method(D_METHOD("atr", "message", "context"), &Node::atr, DEFVAL(""));
ClassDB::bind_method(D_METHOD("atr_n", "message", "plural_message", "n", "context"), &Node::atr_n, DEFVAL(""));
#ifdef TOOLS_ENABLED
ClassDB::bind_method(D_METHOD("_set_property_pinned", "property", "pinned"), &Node::set_property_pinned);
#endif
@ -3635,6 +3710,10 @@ void Node::_bind_methods() {
BIND_ENUM_CONSTANT(INTERNAL_MODE_FRONT);
BIND_ENUM_CONSTANT(INTERNAL_MODE_BACK);
BIND_ENUM_CONSTANT(AUTO_TRANSLATE_MODE_INHERIT);
BIND_ENUM_CONSTANT(AUTO_TRANSLATE_MODE_ALWAYS);
BIND_ENUM_CONSTANT(AUTO_TRANSLATE_MODE_DISABLED);
ADD_SIGNAL(MethodInfo("ready"));
ADD_SIGNAL(MethodInfo("renamed"));
ADD_SIGNAL(MethodInfo("tree_entered"));
@ -3657,11 +3736,15 @@ void Node::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "process_mode", PROPERTY_HINT_ENUM, "Inherit,Pausable,When Paused,Always,Disabled"), "set_process_mode", "get_process_mode");
ADD_PROPERTY(PropertyInfo(Variant::INT, "process_priority"), "set_process_priority", "get_process_priority");
ADD_PROPERTY(PropertyInfo(Variant::INT, "process_physics_priority"), "set_physics_process_priority", "get_physics_process_priority");
ADD_SUBGROUP("Thread Group", "process_thread");
ADD_PROPERTY(PropertyInfo(Variant::INT, "process_thread_group", PROPERTY_HINT_ENUM, "Inherit,Main Thread,Sub Thread"), "set_process_thread_group", "get_process_thread_group");
ADD_PROPERTY(PropertyInfo(Variant::INT, "process_thread_group_order"), "set_process_thread_group_order", "get_process_thread_group_order");
ADD_PROPERTY(PropertyInfo(Variant::INT, "process_thread_messages", PROPERTY_HINT_FLAGS, "Process,Physics Process"), "set_process_thread_messages", "get_process_thread_messages");
ADD_GROUP("Auto Translate", "auto_translate_");
ADD_PROPERTY(PropertyInfo(Variant::INT, "auto_translate_mode", PROPERTY_HINT_ENUM, "Inherit,Always,Disabled"), "set_auto_translate_mode", "get_auto_translate_mode");
ADD_GROUP("Editor Description", "editor_");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "editor_description", PROPERTY_HINT_MULTILINE_TEXT), "set_editor_description", "get_editor_description");

View file

@ -108,6 +108,12 @@ public:
INTERNAL_MODE_BACK,
};
enum AutoTranslateMode {
AUTO_TRANSLATE_MODE_INHERIT,
AUTO_TRANSLATE_MODE_ALWAYS,
AUTO_TRANSLATE_MODE_DISABLED,
};
struct Comparator {
bool operator()(const Node *p_a, const Node *p_b) const { return p_b->is_greater_than(p_a); }
};
@ -211,6 +217,10 @@ private:
bool display_folded = false;
bool editable_instance = false;
AutoTranslateMode auto_translate_mode = AUTO_TRANSLATE_MODE_INHERIT;
mutable bool is_auto_translating = true;
mutable bool is_auto_translate_dirty = true;
mutable NodePath *path_cache = nullptr;
} data;
@ -506,6 +516,7 @@ public:
void propagate_call(const StringName &p_method, const Array &p_args = Array(), const bool p_parent_first = false);
/* PROCESSING */
void set_physics_process(bool p_process);
double get_physics_process_delta_time() const;
bool is_physics_processing() const;
@ -647,6 +658,7 @@ public:
void set_display_folded(bool p_folded);
bool is_displayed_folded() const;
/* NETWORK */
virtual void set_multiplayer_authority(int p_peer_id, bool p_recursive = true);
@ -666,6 +678,17 @@ public:
Ref<MultiplayerAPI> get_multiplayer() const;
/* INTERNATIONALIZATION */
void set_auto_translate_mode(AutoTranslateMode p_mode);
AutoTranslateMode get_auto_translate_mode() const;
bool can_auto_translate() const;
_FORCE_INLINE_ String atr(const String p_message, const StringName p_context = "") const { return can_auto_translate() ? tr(p_message, p_context) : p_message; }
_FORCE_INLINE_ String atr_n(const String p_message, const StringName &p_message_plural, int p_n, const StringName p_context = "") const { return can_auto_translate() ? tr_n(p_message, p_message_plural, p_n, p_context) : p_message; }
/* THREADING */
void call_deferred_thread_groupp(const StringName &p_method, const Variant **p_args, int p_argcount, bool p_show_error = false);
template <typename... VarArgs>
void call_deferred_thread_group(const StringName &p_method, VarArgs... p_args) {
@ -725,6 +748,7 @@ VARIANT_ENUM_CAST(Node::ProcessMode);
VARIANT_ENUM_CAST(Node::ProcessThreadGroup);
VARIANT_BITFIELD_CAST(Node::ProcessThreadMessages);
VARIANT_ENUM_CAST(Node::InternalMode);
VARIANT_ENUM_CAST(Node::AutoTranslateMode);
typedef HashSet<Node *, Node::Comparator> NodeSet;

View file

@ -1755,6 +1755,7 @@ SceneTree::SceneTree() {
root = memnew(Window);
root->set_min_size(Size2i(64, 64)); // Define a very small minimum window size to prevent bugs such as GH-37242.
root->set_process_mode(Node::PROCESS_MODE_PAUSABLE);
root->set_auto_translate_mode(Node::AUTO_TRANSLATE_MODE_ALWAYS);
root->set_name("root");
root->set_title(GLOBAL_GET("application/config/name"));

View file

@ -1517,7 +1517,6 @@ void Viewport::_gui_show_tooltip() {
if (!base_tooltip) {
gui.tooltip_label = memnew(Label);
gui.tooltip_label->set_theme_type_variation(SNAME("TooltipLabel"));
gui.tooltip_label->set_auto_translate(gui.tooltip_control->is_auto_translating());
gui.tooltip_label->set_text(gui.tooltip_text);
base_tooltip = gui.tooltip_label;
panel->connect("mouse_entered", callable_mp(this, &Viewport::_gui_cancel_tooltip));

View file

@ -52,8 +52,8 @@ void Window::set_root_layout_direction(int p_root_dir) {
bool Window::_set(const StringName &p_name, const Variant &p_value) {
ERR_MAIN_THREAD_GUARD_V(false);
String name = p_name;
if (!name.begins_with("theme_override")) {
return false;
}
@ -95,7 +95,6 @@ bool Window::_set(const StringName &p_name, const Variant &p_value) {
} else {
return false;
}
} else {
if (name.begins_with("theme_override_icons/")) {
String dname = name.get_slicec('/', 1);
@ -124,8 +123,8 @@ bool Window::_set(const StringName &p_name, const Variant &p_value) {
bool Window::_get(const StringName &p_name, Variant &r_ret) const {
ERR_READ_THREAD_GUARD_V(false);
String sname = p_name;
if (!sname.begins_with("theme_override")) {
return false;
}
@ -1308,14 +1307,6 @@ void Window::_notification(int p_what) {
RS::get_singleton()->viewport_set_active(get_viewport_rid(), true);
}
#ifdef TOOLS_ENABLED
if (is_part_of_edited_scene()) {
// Don't translate Windows on scene when inside editor.
set_message_translation(false);
notification(NOTIFICATION_TRANSLATION_CHANGED);
}
#endif
// Emits NOTIFICATION_THEME_CHANGED internally.
set_theme_context(ThemeDB::get_singleton()->get_nearest_theme_context(this));
} break;
@ -2649,21 +2640,17 @@ bool Window::is_layout_rtl() const {
}
}
#ifndef DISABLE_DEPRECATED
void Window::set_auto_translate(bool p_enable) {
ERR_MAIN_THREAD_GUARD;
if (p_enable == auto_translate) {
return;
}
auto_translate = p_enable;
notification(MainLoop::NOTIFICATION_TRANSLATION_CHANGED);
set_auto_translate_mode(p_enable ? AUTO_TRANSLATE_MODE_ALWAYS : AUTO_TRANSLATE_MODE_DISABLED);
}
bool Window::is_auto_translating() const {
ERR_READ_THREAD_GUARD_V(false);
return auto_translate;
return can_auto_translate();
}
#endif
Transform2D Window::get_final_transform() const {
ERR_READ_THREAD_GUARD_V(Transform2D());
@ -2894,8 +2881,10 @@ void Window::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_layout_direction"), &Window::get_layout_direction);
ClassDB::bind_method(D_METHOD("is_layout_rtl"), &Window::is_layout_rtl);
#ifndef DISABLE_DEPRECATED
ClassDB::bind_method(D_METHOD("set_auto_translate", "enable"), &Window::set_auto_translate);
ClassDB::bind_method(D_METHOD("is_auto_translating"), &Window::is_auto_translating);
#endif
ClassDB::bind_method(D_METHOD("popup", "rect"), &Window::popup, DEFVAL(Rect2i()));
ClassDB::bind_method(D_METHOD("popup_on_parent", "parent_rect"), &Window::popup_on_parent);
@ -2949,8 +2938,9 @@ void Window::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "content_scale_stretch", PROPERTY_HINT_ENUM, "Fractional,Integer"), "set_content_scale_stretch", "get_content_scale_stretch");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "content_scale_factor", PROPERTY_HINT_RANGE, "0.5,8.0,0.01"), "set_content_scale_factor", "get_content_scale_factor");
ADD_GROUP("Localization", "");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "auto_translate"), "set_auto_translate", "is_auto_translating");
#ifndef DISABLE_DEPRECATED
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "auto_translate", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), "set_auto_translate", "is_auto_translating");
#endif
ADD_GROUP("Theme", "theme_");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "theme", PROPERTY_HINT_RESOURCE_TYPE, "Theme"), "set_theme", "get_theme");

View file

@ -34,7 +34,6 @@
#include "scene/main/viewport.h"
#include "scene/resources/theme.h"
class Control;
class Font;
class Shortcut;
class StyleBox;
@ -138,8 +137,6 @@ private:
LayoutDirection layout_dir = LAYOUT_DIRECTION_INHERITED;
bool auto_translate = true;
void _update_child_controls();
void _update_embedded_window();
@ -389,15 +386,18 @@ public:
void grab_focus();
bool has_focus() const;
Rect2i get_usable_parent_rect() const;
// Internationalization.
void set_layout_direction(LayoutDirection p_direction);
LayoutDirection get_layout_direction() const;
bool is_layout_rtl() const;
#ifndef DISABLE_DEPRECATED
void set_auto_translate(bool p_enable);
bool is_auto_translating() const;
_FORCE_INLINE_ String atr(const String p_string) const { return is_auto_translating() ? tr(p_string) : p_string; };
Rect2i get_usable_parent_rect() const;
#endif
// Theming.