summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/config/project_settings.cpp1
-rw-r--r--core/string/translation.cpp20
-rw-r--r--doc/classes/ProjectSettings.xml5
-rw-r--r--scene/gui/control.cpp41
-rw-r--r--scene/main/window.cpp33
5 files changed, 77 insertions, 23 deletions
diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp
index 933b9891cc..f3c0bc2153 100644
--- a/core/config/project_settings.cpp
+++ b/core/config/project_settings.cpp
@@ -1331,6 +1331,7 @@ ProjectSettings::ProjectSettings() {
GLOBAL_DEF_RST(PropertyInfo(Variant::INT, "rendering/occlusion_culling/bvh_build_quality", PROPERTY_HINT_ENUM, "Low,Medium,High"), 2);
GLOBAL_DEF(PropertyInfo(Variant::INT, "memory/limits/multithreaded_server/rid_pool_prealloc", PROPERTY_HINT_RANGE, "0,500,1"), 60); // No negative and limit to 500 due to crashes.
GLOBAL_DEF_RST("internationalization/rendering/force_right_to_left_layout_direction", false);
+ GLOBAL_DEF_BASIC(PropertyInfo(Variant::INT, "internationalization/rendering/root_node_layout_direction", PROPERTY_HINT_RANGE, "Based on Locale,Left-to-Right,Right-to-Left"), 0);
GLOBAL_DEF(PropertyInfo(Variant::INT, "gui/timers/incremental_search_max_interval_msec", PROPERTY_HINT_RANGE, "0,10000,1,or_greater"), 2000);
diff --git a/core/string/translation.cpp b/core/string/translation.cpp
index b9d5d3b538..160bad14ab 100644
--- a/core/string/translation.cpp
+++ b/core/string/translation.cpp
@@ -712,7 +712,25 @@ String TranslationServer::get_tool_locale() {
#else
{
#endif
- return get_locale();
+ // Look for best matching loaded translation.
+ String best_locale = "en";
+ int best_score = 0;
+
+ for (const Ref<Translation> &E : translations) {
+ const Ref<Translation> &t = E;
+ ERR_FAIL_COND_V(t.is_null(), best_locale);
+ String l = t->get_locale();
+
+ int score = compare_locales(locale, l);
+ if (score > 0 && score >= best_score) {
+ best_locale = l;
+ best_score = score;
+ if (score == 10) {
+ break; // Exact match, skip the rest.
+ }
+ }
+ }
+ return best_locale;
}
}
diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml
index 27bec07cba..ed227047e5 100644
--- a/doc/classes/ProjectSettings.xml
+++ b/doc/classes/ProjectSettings.xml
@@ -1199,7 +1199,10 @@
[b]Note:[/b] This property is only read when the project starts. To toggle pseudolocalization at run-time, use [member TranslationServer.pseudolocalization_enabled] instead.
</member>
<member name="internationalization/rendering/force_right_to_left_layout_direction" type="bool" setter="" getter="" default="false">
- Force layout direction and text writing direction to RTL for all locales.
+ Force layout direction and text writing direction to RTL for all controls.
+ </member>
+ <member name="internationalization/rendering/root_node_layout_direction" type="int" setter="" getter="" default="0">
+ Root node default layout direction.
</member>
<member name="internationalization/rendering/text_driver" type="String" setter="" getter="" default="&quot;&quot;">
Specifies the [TextServer] to use. If left empty, the default will be used.
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index ec75fcb665..10f9529ca9 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -2793,19 +2793,34 @@ bool Control::is_layout_rtl() const {
if (data.is_rtl_dirty) {
const_cast<Control *>(this)->data.is_rtl_dirty = false;
if (data.layout_dir == LAYOUT_DIRECTION_INHERITED) {
- Window *parent_window = get_parent_window();
- Control *parent_control = get_parent_control();
- if (parent_control) {
- const_cast<Control *>(this)->data.is_rtl = parent_control->is_layout_rtl();
- } else if (parent_window) {
- const_cast<Control *>(this)->data.is_rtl = parent_window->is_layout_rtl();
- } else {
- if (GLOBAL_GET(SNAME("internationalization/rendering/force_right_to_left_layout_direction"))) {
- const_cast<Control *>(this)->data.is_rtl = true;
- } else {
- String locale = TranslationServer::get_singleton()->get_tool_locale();
- const_cast<Control *>(this)->data.is_rtl = TS->is_locale_right_to_left(locale);
+ if (GLOBAL_GET(SNAME("internationalization/rendering/force_right_to_left_layout_direction"))) {
+ const_cast<Control *>(this)->data.is_rtl = true;
+ return data.is_rtl;
+ }
+ Node *parent_node = get_parent();
+ while (parent_node) {
+ Control *parent_control = Object::cast_to<Control>(parent_node);
+ if (parent_control) {
+ const_cast<Control *>(this)->data.is_rtl = parent_control->is_layout_rtl();
+ return data.is_rtl;
}
+
+ Window *parent_window = Object::cast_to<Window>(parent_node);
+ if (parent_window) {
+ const_cast<Control *>(this)->data.is_rtl = parent_window->is_layout_rtl();
+ return data.is_rtl;
+ }
+ parent_node = parent_node->get_parent();
+ }
+
+ int root_dir = GLOBAL_GET(SNAME("internationalization/rendering/root_node_layout_direction"));
+ if (root_dir == 1) {
+ const_cast<Control *>(this)->data.is_rtl = false;
+ } else if (root_dir == 2) {
+ const_cast<Control *>(this)->data.is_rtl = true;
+ } else {
+ String locale = TranslationServer::get_singleton()->get_tool_locale();
+ const_cast<Control *>(this)->data.is_rtl = TS->is_locale_right_to_left(locale);
}
} else if (data.layout_dir == LAYOUT_DIRECTION_LOCALE) {
if (GLOBAL_GET(SNAME("internationalization/rendering/force_right_to_left_layout_direction"))) {
@@ -3230,7 +3245,7 @@ void Control::_bind_methods() {
ADD_GROUP("Layout", "");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "clip_contents"), "set_clip_contents", "is_clipping_contents");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "custom_minimum_size", PROPERTY_HINT_NONE, "suffix:px"), "set_custom_minimum_size", "get_custom_minimum_size");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "layout_direction", PROPERTY_HINT_ENUM, "Inherited,Locale,Left-to-Right,Right-to-Left"), "set_layout_direction", "get_layout_direction");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "layout_direction", PROPERTY_HINT_ENUM, "Inherited,Based on Locale,Left-to-Right,Right-to-Left"), "set_layout_direction", "get_layout_direction");
ADD_PROPERTY(PropertyInfo(Variant::INT, "layout_mode", PROPERTY_HINT_ENUM, "Position,Anchors,Container,Uncontrolled", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "_set_layout_mode", "_get_layout_mode");
ADD_PROPERTY_DEFAULT("layout_mode", LayoutMode::LAYOUT_MODE_POSITION);
diff --git a/scene/main/window.cpp b/scene/main/window.cpp
index 9fb4ed458f..5d3173a2a5 100644
--- a/scene/main/window.cpp
+++ b/scene/main/window.cpp
@@ -2116,22 +2116,39 @@ Window::LayoutDirection Window::get_layout_direction() const {
bool Window::is_layout_rtl() const {
if (layout_dir == LAYOUT_DIRECTION_INHERITED) {
- Window *parent_w = Object::cast_to<Window>(get_parent());
- if (parent_w) {
- return parent_w->is_layout_rtl();
- } else {
- if (GLOBAL_GET(SNAME("internationalization/rendering/force_right_to_left_layout_direction"))) {
- return true;
+ if (GLOBAL_GET(SNAME("internationalization/rendering/force_right_to_left_layout_direction"))) {
+ return true;
+ }
+ Node *parent_node = get_parent();
+ while (parent_node) {
+ Control *parent_control = Object::cast_to<Control>(parent_node);
+ if (parent_control) {
+ return parent_control->is_layout_rtl();
}
+
+ Window *parent_window = Object::cast_to<Window>(parent_node);
+ if (parent_window) {
+ return parent_window->is_layout_rtl();
+ }
+ parent_node = parent_node->get_parent();
+ }
+
+ int root_dir = GLOBAL_GET(SNAME("internationalization/rendering/root_node_layout_direction"));
+ if (root_dir == 1) {
+ return false;
+ } else if (root_dir == 2) {
+ return true;
+ } else {
String locale = TranslationServer::get_singleton()->get_tool_locale();
return TS->is_locale_right_to_left(locale);
}
} else if (layout_dir == LAYOUT_DIRECTION_LOCALE) {
if (GLOBAL_GET(SNAME("internationalization/rendering/force_right_to_left_layout_direction"))) {
return true;
+ } else {
+ String locale = TranslationServer::get_singleton()->get_tool_locale();
+ return TS->is_locale_right_to_left(locale);
}
- String locale = TranslationServer::get_singleton()->get_tool_locale();
- return TS->is_locale_right_to_left(locale);
} else {
return (layout_dir == LAYOUT_DIRECTION_RTL);
}