diff options
-rw-r--r-- | doc/classes/Control.xml | 3 | ||||
-rw-r--r-- | doc/classes/Window.xml | 3 | ||||
-rw-r--r-- | scene/gui/button.cpp | 4 | ||||
-rw-r--r-- | scene/gui/control.cpp | 22 | ||||
-rw-r--r-- | scene/gui/control.h | 6 | ||||
-rw-r--r-- | scene/gui/label.cpp | 4 | ||||
-rw-r--r-- | scene/gui/line_edit.cpp | 4 | ||||
-rw-r--r-- | scene/gui/popup_menu.cpp | 12 | ||||
-rw-r--r-- | scene/gui/tab_container.cpp | 7 | ||||
-rw-r--r-- | scene/gui/tabs.cpp | 6 | ||||
-rw-r--r-- | scene/main/viewport.cpp | 3 | ||||
-rw-r--r-- | scene/main/window.cpp | 35 | ||||
-rw-r--r-- | scene/main/window.h | 6 |
13 files changed, 92 insertions, 23 deletions
diff --git a/doc/classes/Control.xml b/doc/classes/Control.xml index 5c0856cb6a..4753b34efb 100644 --- a/doc/classes/Control.xml +++ b/doc/classes/Control.xml @@ -1081,6 +1081,9 @@ <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"> + Toggles if any text should automatically change to its translated version depending on the current locale. + </member> <member name="focus_mode" type="int" setter="set_focus_mode" getter="get_focus_mode" enum="Control.FocusMode" default="0"> The focus access mode for the control (None, Click or All). Only one Control can be focused at the same time, and it will receive keyboard signals. </member> diff --git a/doc/classes/Window.xml b/doc/classes/Window.xml index 390ebfabba..7b21d99d10 100644 --- a/doc/classes/Window.xml +++ b/doc/classes/Window.xml @@ -323,6 +323,9 @@ <members> <member name="always_on_top" type="bool" setter="set_flag" getter="get_flag" default="false"> </member> + <member name="auto_translate" type="bool" setter="set_auto_translate" getter="is_auto_translating" default="true"> + 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"> </member> <member name="content_scale_aspect" type="int" setter="set_content_scale_aspect" getter="get_content_scale_aspect" enum="Window.ContentScaleAspect" default="0"> diff --git a/scene/gui/button.cpp b/scene/gui/button.cpp index 4b6c0ef697..9cdf3bf210 100644 --- a/scene/gui/button.cpp +++ b/scene/gui/button.cpp @@ -79,7 +79,7 @@ void Button::_notification(int p_what) { update(); } break; case NOTIFICATION_TRANSLATION_CHANGED: { - xl_text = tr(text); + xl_text = atr(text); _shape(); minimum_size_changed(); @@ -355,7 +355,7 @@ void Button::_shape() { void Button::set_text(const String &p_text) { if (text != p_text) { text = p_text; - xl_text = tr(text); + xl_text = atr(text); _shape(); update(); diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index c19ee849d3..4179c8b246 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -495,6 +495,20 @@ bool Control::is_layout_rtl() const { return data.is_rtl; } +void Control::set_auto_translate(bool p_enable) { + if (p_enable == data.auto_translate) { + return; + } + + data.auto_translate = p_enable; + + notification(MainLoop::NOTIFICATION_TRANSLATION_CHANGED); +} + +bool Control::is_auto_translating() const { + return data.auto_translate; +} + void Control::_clear_size_warning() { data.size_warning = false; } @@ -2784,6 +2798,9 @@ 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); + 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); + BIND_VMETHOD(MethodInfo("_structured_text_parser", PropertyInfo(Variant::ARRAY, "args"), PropertyInfo(Variant::STRING, "text"))); BIND_VMETHOD(MethodInfo("_gui_input", PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent"))); @@ -2848,10 +2865,13 @@ void Control::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::INT, "size_flags_horizontal", PROPERTY_HINT_FLAGS, "Fill,Expand,Shrink Center,Shrink End"), "set_h_size_flags", "get_h_size_flags"); ADD_PROPERTY(PropertyInfo(Variant::INT, "size_flags_vertical", PROPERTY_HINT_FLAGS, "Fill,Expand,Shrink Center,Shrink End"), "set_v_size_flags", "get_v_size_flags"); 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("Theme", "theme_"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "theme", PROPERTY_HINT_RESOURCE_TYPE, "Theme"), "set_theme", "get_theme"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "theme_type_variation", PROPERTY_HINT_ENUM_SUGGESTION), "set_theme_type_variation", "get_theme_type_variation"); - ADD_GROUP("", ""); + + ADD_GROUP("Auto Translate", ""); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "auto_translate"), "set_auto_translate", "is_auto_translating"); BIND_ENUM_CONSTANT(FOCUS_NONE); BIND_ENUM_CONSTANT(FOCUS_CLICK); diff --git a/scene/gui/control.h b/scene/gui/control.h index 3779f9b308..8d669c7a6d 100644 --- a/scene/gui/control.h +++ b/scene/gui/control.h @@ -182,6 +182,8 @@ private: bool is_rtl_dirty = true; bool is_rtl = false; + bool auto_translate = true; + real_t rotation = 0.0; Vector2 scale = Vector2(1, 1); Vector2 pivot_offset; @@ -351,6 +353,10 @@ public: LayoutDirection get_layout_direction() const; virtual bool is_layout_rtl() const; + 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; }; + /* POSITIONING */ void set_anchors_preset(LayoutPreset p_preset, bool p_keep_offsets = true); diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp index 06faf3fa3e..1603989243 100644 --- a/scene/gui/label.cpp +++ b/scene/gui/label.cpp @@ -221,7 +221,7 @@ void Label::_update_visible() { void Label::_notification(int p_what) { if (p_what == NOTIFICATION_TRANSLATION_CHANGED) { - String new_text = tr(text); + String new_text = atr(text); if (new_text == xl_text) { return; //nothing new } @@ -509,7 +509,7 @@ void Label::set_text(const String &p_string) { return; } text = p_string; - xl_text = tr(p_string); + xl_text = atr(p_string); dirty = true; if (percent_visible < 1) { visible_chars = get_total_character_count() * percent_visible; diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index 19ffcfca6d..68e9171c15 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -597,7 +597,7 @@ void LineEdit::_notification(int p_what) { update(); } break; case NOTIFICATION_TRANSLATION_CHANGED: { - placeholder_translated = tr(placeholder); + placeholder_translated = atr(placeholder); _shape(); update(); } break; @@ -1364,7 +1364,7 @@ String LineEdit::get_text() const { void LineEdit::set_placeholder(String p_text) { placeholder = p_text; - placeholder_translated = tr(placeholder); + placeholder_translated = atr(placeholder); _shape(); update(); } diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index 7790a0970c..490548fce0 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -722,7 +722,7 @@ void PopupMenu::_notification(int p_what) { case Control::NOTIFICATION_LAYOUT_DIRECTION_CHANGED: case NOTIFICATION_TRANSLATION_CHANGED: { for (int i = 0; i < items.size(); i++) { - items.write[i].xl_text = tr(items[i].text); + items.write[i].xl_text = atr(items[i].text); items.write[i].dirty = true; _shape_item(i); } @@ -807,7 +807,7 @@ void PopupMenu::_notification(int p_what) { #define ITEM_SETUP_WITH_ACCEL(p_label, p_id, p_accel) \ item.text = p_label; \ - item.xl_text = tr(p_label); \ + item.xl_text = atr(p_label); \ item.id = p_id == -1 ? items.size() : p_id; \ item.accel = p_accel; @@ -887,7 +887,7 @@ void PopupMenu::add_multistate_item(const String &p_label, int p_max_states, int ERR_FAIL_COND_MSG(p_shortcut.is_null(), "Cannot add item with invalid Shortcut."); \ _ref_shortcut(p_shortcut); \ item.text = p_shortcut->get_name(); \ - item.xl_text = tr(item.text); \ + item.xl_text = atr(item.text); \ item.id = p_id == -1 ? items.size() : p_id; \ item.shortcut = p_shortcut; \ item.shortcut_is_global = p_global; @@ -956,7 +956,7 @@ void PopupMenu::add_icon_radio_check_shortcut(const Ref<Texture2D> &p_icon, cons void PopupMenu::add_submenu_item(const String &p_label, const String &p_submenu, int p_id) { Item item; item.text = p_label; - item.xl_text = tr(p_label); + item.xl_text = atr(p_label); item.id = p_id == -1 ? items.size() : p_id; item.submenu = p_submenu; items.push_back(item); @@ -973,7 +973,7 @@ void PopupMenu::add_submenu_item(const String &p_label, const String &p_submenu, void PopupMenu::set_item_text(int p_idx, const String &p_text) { ERR_FAIL_INDEX(p_idx, items.size()); items.write[p_idx].text = p_text; - items.write[p_idx].xl_text = tr(p_text); + items.write[p_idx].xl_text = atr(p_text); _shape_item(p_idx); control->update(); @@ -1402,7 +1402,7 @@ void PopupMenu::add_separator(const String &p_text, int p_id) { sep.id = p_id; if (p_text != String()) { sep.text = p_text; - sep.xl_text = tr(p_text); + sep.xl_text = atr(p_text); } items.push_back(sep); control->update(); diff --git a/scene/gui/tab_container.cpp b/scene/gui/tab_container.cpp index 8f84585f9b..4b8c4b3e16 100644 --- a/scene/gui/tab_container.cpp +++ b/scene/gui/tab_container.cpp @@ -550,7 +550,7 @@ void TabContainer::_draw_tab(Ref<StyleBox> &p_tab_style, Color &p_font_color, in // Draw the tab contents. Control *control = Object::cast_to<Control>(tabs[p_index]); - String text = control->has_meta("_tab_name") ? String(tr(String(control->get_meta("_tab_name")))) : String(tr(control->get_name())); + String text = control->has_meta("_tab_name") ? String(atr(String(control->get_meta("_tab_name")))) : String(atr(control->get_name())); int x_content = tab_rect.position.x + p_tab_style->get_margin(SIDE_LEFT); int top_margin = p_tab_style->get_margin(SIDE_TOP); @@ -584,7 +584,8 @@ void TabContainer::_refresh_texts() { int font_size = get_theme_font_size(SNAME("font_size")); for (int i = 0; i < tabs.size(); i++) { Control *control = Object::cast_to<Control>(tabs[i]); - String text = control->has_meta("_tab_name") ? String(tr(String(control->get_meta("_tab_name")))) : String(tr(control->get_name())); + String text = control->has_meta("_tab_name") ? String(atr(String(control->get_meta("_tab_name")))) : String(atr(control->get_name())); + Ref<TextLine> name; name.instantiate(); name->set_direction(rtl ? TextServer::DIRECTION_RTL : TextServer::DIRECTION_LTR); @@ -648,7 +649,7 @@ int TabContainer::_get_tab_width(int p_index) const { // Get the width of the text displayed on the tab. Ref<Font> font = get_theme_font(SNAME("font")); int font_size = get_theme_font_size(SNAME("font_size")); - String text = control->has_meta("_tab_name") ? String(tr(String(control->get_meta("_tab_name")))) : String(tr(control->get_name())); + String text = control->has_meta("_tab_name") ? String(atr(String(control->get_meta("_tab_name")))) : String(atr(control->get_name())); int width = font->get_string_size(text, font_size).width; // Add space for a tab icon. diff --git a/scene/gui/tabs.cpp b/scene/gui/tabs.cpp index 9e8fe27ffb..103860ad78 100644 --- a/scene/gui/tabs.cpp +++ b/scene/gui/tabs.cpp @@ -239,7 +239,7 @@ void Tabs::_shape(int p_tab) { Ref<Font> font = get_theme_font(SNAME("font")); int font_size = get_theme_font_size(SNAME("font_size")); - tabs.write[p_tab].xl_text = tr(tabs[p_tab].text); + tabs.write[p_tab].xl_text = atr(tabs[p_tab].text); tabs.write[p_tab].text_buf->clear(); if (tabs[p_tab].text_direction == Control::TEXT_DIRECTION_INHERITED) { tabs.write[p_tab].text_buf->set_direction(is_layout_rtl() ? TextServer::DIRECTION_RTL : TextServer::DIRECTION_LTR); @@ -529,7 +529,7 @@ bool Tabs::get_offset_buttons_visible() const { void Tabs::set_tab_title(int p_tab, const String &p_title) { ERR_FAIL_INDEX(p_tab, tabs.size()); tabs.write[p_tab].text = p_title; - tabs.write[p_tab].xl_text = tr(p_title); + tabs.write[p_tab].xl_text = atr(p_title); _shape(p_tab); update(); minimum_size_changed(); @@ -742,7 +742,7 @@ void Tabs::_on_mouse_exited() { void Tabs::add_tab(const String &p_str, const Ref<Texture2D> &p_icon) { Tab t; t.text = p_str; - t.xl_text = tr(p_str); + t.xl_text = atr(p_str); t.text_buf.instantiate(); t.text_buf->set_direction(is_layout_rtl() ? TextServer::DIRECTION_RTL : TextServer::DIRECTION_LTR); t.text_buf->add_string(t.xl_text, get_theme_font(SNAME("font")), get_theme_font_size(SNAME("font_size")), Dictionary(), TranslationServer::get_singleton()->get_tool_locale()); diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 7b74d049fb..8e7182df46 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -260,7 +260,7 @@ void Viewport::_sub_window_update(Window *p_window) { int close_h_ofs = p_window->get_theme_constant(SNAME("close_h_ofs")); int close_v_ofs = p_window->get_theme_constant(SNAME("close_v_ofs")); - TextLine title_text = TextLine(p_window->get_title(), title_font, font_size, Dictionary(), TranslationServer::get_singleton()->get_tool_locale()); + TextLine title_text = TextLine(p_window->atr(p_window->get_title()), title_font, font_size, Dictionary(), TranslationServer::get_singleton()->get_tool_locale()); title_text.set_width(r.size.width - panel->get_minimum_size().x - close_h_ofs); title_text.set_direction(p_window->is_layout_rtl() ? TextServer::DIRECTION_RTL : TextServer::DIRECTION_LTR); int x = (r.size.width - title_text.get_size().x) / 2; @@ -1558,6 +1558,7 @@ void Viewport::_gui_show_tooltip() { // If no custom tooltip is given, use a default implementation. if (!base_tooltip) { gui.tooltip_label = memnew(TooltipLabel); + gui.tooltip_label->set_auto_translate(gui.tooltip_control->is_auto_translating()); gui.tooltip_label->set_text(tooltip_text); base_tooltip = gui.tooltip_label; panel->connect("mouse_entered", callable_mp(this, &Viewport::_gui_cancel_tooltip)); diff --git a/scene/main/window.cpp b/scene/main/window.cpp index bed8a1ba56..1f1da7cefb 100644 --- a/scene/main/window.cpp +++ b/scene/main/window.cpp @@ -42,9 +42,8 @@ void Window::set_title(const String &p_title) { if (embedder) { embedder->_sub_window_update(this); - } else if (window_id != DisplayServer::INVALID_WINDOW_ID) { - DisplayServer::get_singleton()->window_set_title(p_title, window_id); + DisplayServer::get_singleton()->window_set_title(atr(p_title), window_id); } } @@ -233,7 +232,7 @@ void Window::_make_window() { DisplayServer::get_singleton()->window_set_current_screen(current_screen, window_id); DisplayServer::get_singleton()->window_set_max_size(max_size, window_id); DisplayServer::get_singleton()->window_set_min_size(min_size, window_id); - DisplayServer::get_singleton()->window_set_title(tr(title), window_id); + DisplayServer::get_singleton()->window_set_title(atr(title), window_id); DisplayServer::get_singleton()->window_attach_instance_id(get_instance_id(), window_id); _update_window_size(); @@ -761,6 +760,12 @@ void Window::_notification(int p_what) { } } break; case NOTIFICATION_TRANSLATION_CHANGED: { + if (embedder) { + embedder->_sub_window_update(this); + } else if (window_id != DisplayServer::INVALID_WINDOW_ID) { + DisplayServer::get_singleton()->window_set_title(atr(title), window_id); + } + child_controls_changed(); } break; case NOTIFICATION_EXIT_TREE: { @@ -1341,6 +1346,20 @@ bool Window::is_layout_rtl() const { } } +void Window::set_auto_translate(bool p_enable) { + if (p_enable == auto_translate) { + return; + } + + auto_translate = p_enable; + + notification(MainLoop::NOTIFICATION_TRANSLATION_CHANGED); +} + +bool Window::is_auto_translating() const { + return auto_translate; +} + void Window::_validate_property(PropertyInfo &property) const { if (property.name == "theme_type_variation") { List<StringName> names; @@ -1467,6 +1486,9 @@ 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); + 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); + 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); ClassDB::bind_method(D_METHOD("popup_centered_ratio", "ratio"), &Window::popup_centered_ratio, DEFVAL(0.8)); @@ -1478,6 +1500,7 @@ void Window::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "size"), "set_size", "get_size"); ADD_PROPERTY(PropertyInfo(Variant::INT, "mode", PROPERTY_HINT_ENUM, "Windowed,Minimized,Maximized,Fullscreen"), "set_mode", "get_mode"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "current_screen"), "set_current_screen", "get_current_screen"); + ADD_GROUP("Flags", ""); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "visible"), "set_visible", "is_visible"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "wrap_controls"), "set_wrap_controls", "is_wrapping_controls"); @@ -1488,17 +1511,23 @@ void Window::_bind_methods() { ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "always_on_top"), "set_flag", "get_flag", FLAG_ALWAYS_ON_TOP); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "transparent"), "set_flag", "get_flag", FLAG_TRANSPARENT); ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "unfocusable"), "set_flag", "get_flag", FLAG_NO_FOCUS); + ADD_GROUP("Limits", ""); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "min_size"), "set_min_size", "get_min_size"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "max_size"), "set_max_size", "get_max_size"); + ADD_GROUP("Content Scale", "content_scale_"); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2I, "content_scale_size"), "set_content_scale_size", "get_content_scale_size"); ADD_PROPERTY(PropertyInfo(Variant::INT, "content_scale_mode", PROPERTY_HINT_ENUM, "Disabled,Canvas Items,Viewport"), "set_content_scale_mode", "get_content_scale_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "content_scale_aspect", PROPERTY_HINT_ENUM, "Ignore,Keep,Keep Width,Keep Height,Expand"), "set_content_scale_aspect", "get_content_scale_aspect"); + ADD_GROUP("Theme", "theme_"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "theme", PROPERTY_HINT_RESOURCE_TYPE, "Theme"), "set_theme", "get_theme"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "theme_type_variation", PROPERTY_HINT_ENUM_SUGGESTION), "set_theme_type_variation", "get_theme_type_variation"); + ADD_GROUP("Auto Translate", ""); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "auto_translate"), "set_auto_translate", "is_auto_translating"); + ADD_SIGNAL(MethodInfo("window_input", PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent"))); ADD_SIGNAL(MethodInfo("files_dropped", PropertyInfo(Variant::PACKED_STRING_ARRAY, "files"))); ADD_SIGNAL(MethodInfo("mouse_entered")); diff --git a/scene/main/window.h b/scene/main/window.h index e92b5e22ed..7013694a06 100644 --- a/scene/main/window.h +++ b/scene/main/window.h @@ -103,6 +103,8 @@ private: LayoutDirection layout_dir = LAYOUT_DIRECTION_INHERITED; + bool auto_translate = true; + void _update_child_controls(); Size2i content_scale_size; @@ -256,6 +258,10 @@ public: LayoutDirection get_layout_direction() const; bool is_layout_rtl() const; + 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; Ref<Texture2D> get_theme_icon(const StringName &p_name, const StringName &p_theme_type = StringName()) const; |