-Translation text will change automatically for in-game buttons, labels, poups when translation is changed.

-Added a NOTIFICATION_TRANSLATION_CHANGED for controls that need custom code
-Sorry, editor will not update automatically because it uses a different translatio method.
This commit is contained in:
Juan Linietsky 2017-01-09 16:43:44 -03:00
parent e9bb65db81
commit 1f8451001d
10 changed files with 72 additions and 31 deletions

View File

@ -54,6 +54,7 @@ public:
NOTIFICATION_WM_QUIT_REQUEST = 7, NOTIFICATION_WM_QUIT_REQUEST = 7,
NOTIFICATION_WM_UNFOCUS_REQUEST = 8, NOTIFICATION_WM_UNFOCUS_REQUEST = 8,
NOTIFICATION_OS_MEMORY_WARNING = 9, NOTIFICATION_OS_MEMORY_WARNING = 9,
NOTIFICATION_TRANSLATION_CHANGED = 10,
}; };
virtual void input_event( const InputEvent& p_event ); virtual void input_event( const InputEvent& p_event );

View File

@ -939,6 +939,10 @@ void TranslationServer::set_locale(const String& p_locale) {
else { else {
locale=univ_locale; locale=univ_locale;
} }
if (OS::get_singleton()->get_main_loop()) {
OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_TRANSLATION_CHANGED);
}
} }
String TranslationServer::get_locale() const { String TranslationServer::get_locale() const {

View File

@ -34,7 +34,7 @@
Size2 Button::get_minimum_size() const { Size2 Button::get_minimum_size() const {
Size2 minsize=get_font("font")->get_string_size( text ); Size2 minsize=get_font("font")->get_string_size( xl_text );
if (clip_text) if (clip_text)
minsize.width=0; minsize.width=0;
@ -48,7 +48,7 @@ Size2 Button::get_minimum_size() const {
minsize.height=MAX( minsize.height, _icon->get_height() ); minsize.height=MAX( minsize.height, _icon->get_height() );
minsize.width+=_icon->get_width(); minsize.width+=_icon->get_width();
if (text!="") if (xl_text!="")
minsize.width+=get_constant("hseparation"); minsize.width+=get_constant("hseparation");
} }
@ -59,6 +59,13 @@ Size2 Button::get_minimum_size() const {
void Button::_notification(int p_what) { void Button::_notification(int p_what) {
if (p_what==NOTIFICATION_TRANSLATION_CHANGED) {
xl_text=XL_MESSAGE(text);
minimum_size_changed();
update();
}
if (p_what==NOTIFICATION_DRAW) { if (p_what==NOTIFICATION_DRAW) {
RID ci = get_canvas_item(); RID ci = get_canvas_item();
@ -114,7 +121,7 @@ void Button::_notification(int p_what) {
Point2 icon_ofs = (!_icon.is_null())?Point2( _icon->get_width() + get_constant("hseparation"), 0):Point2(); Point2 icon_ofs = (!_icon.is_null())?Point2( _icon->get_width() + get_constant("hseparation"), 0):Point2();
int text_clip=size.width - style->get_minimum_size().width - icon_ofs.width; int text_clip=size.width - style->get_minimum_size().width - icon_ofs.width;
Point2 text_ofs = (size - style->get_minimum_size() - icon_ofs - font->get_string_size( text ) )/2.0; Point2 text_ofs = (size - style->get_minimum_size() - icon_ofs - font->get_string_size( xl_text ) )/2.0;
switch(align) { switch(align) {
case ALIGN_LEFT: { case ALIGN_LEFT: {
@ -128,14 +135,14 @@ void Button::_notification(int p_what) {
text_ofs+=style->get_offset(); text_ofs+=style->get_offset();
} break; } break;
case ALIGN_RIGHT: { case ALIGN_RIGHT: {
text_ofs.x=size.x - style->get_margin(MARGIN_RIGHT) - font->get_string_size( text ).x; text_ofs.x=size.x - style->get_margin(MARGIN_RIGHT) - font->get_string_size( xl_text ).x;
text_ofs.y+=style->get_offset().y; text_ofs.y+=style->get_offset().y;
} break; } break;
} }
text_ofs.y+=font->get_ascent(); text_ofs.y+=font->get_ascent();
font->draw( ci, text_ofs.floor(), text, color,clip_text?text_clip:-1); font->draw( ci, text_ofs.floor(), xl_text, color,clip_text?text_clip:-1);
if (!_icon.is_null()) { if (!_icon.is_null()) {
int valign = size.height-style->get_minimum_size().y; int valign = size.height-style->get_minimum_size().y;
@ -152,7 +159,8 @@ void Button::set_text(const String& p_text) {
if (text==p_text) if (text==p_text)
return; return;
text=XL_MESSAGE(p_text); text=p_text;
xl_text=XL_MESSAGE(p_text);
update(); update();
_change_notify("text"); _change_notify("text");
minimum_size_changed(); minimum_size_changed();

View File

@ -49,6 +49,7 @@ private:
bool flat; bool flat;
String text; String text;
String xl_text;
Ref<Texture> icon; Ref<Texture> icon;
bool clip_text; bool clip_text;
TextAlign align; TextAlign align;

View File

@ -68,6 +68,13 @@ int Label::get_line_height() const {
void Label::_notification(int p_what) { void Label::_notification(int p_what) {
if (p_what==NOTIFICATION_TRANSLATION_CHANGED) {
xl_text=XL_MESSAGE(text);
minimum_size_changed();
update();
}
if (p_what==NOTIFICATION_DRAW) { if (p_what==NOTIFICATION_DRAW) {
if (clip || autowrap) { if (clip || autowrap) {
@ -240,8 +247,8 @@ void Label::_notification(int p_what) {
for (int i=0;i<from->word_len;i++) { for (int i=0;i<from->word_len;i++) {
if (visible_chars < 0 || chars_total_shadow<visible_chars) { if (visible_chars < 0 || chars_total_shadow<visible_chars) {
CharType c = text[i+pos]; CharType c = xl_text[i+pos];
CharType n = text[i+pos+1]; CharType n = xl_text[i+pos+1];
if (uppercase) { if (uppercase) {
c=String::char_uppercase(c); c=String::char_uppercase(c);
n=String::char_uppercase(c); n=String::char_uppercase(c);
@ -263,8 +270,8 @@ void Label::_notification(int p_what) {
for (int i=0;i<from->word_len;i++) { for (int i=0;i<from->word_len;i++) {
if (visible_chars < 0 || chars_total<visible_chars) { if (visible_chars < 0 || chars_total<visible_chars) {
CharType c = text[i+pos]; CharType c = xl_text[i+pos];
CharType n = text[i+pos+1]; CharType n = xl_text[i+pos+1];
if (uppercase) { if (uppercase) {
c=String::char_uppercase(c); c=String::char_uppercase(c);
n=String::char_uppercase(c); n=String::char_uppercase(c);
@ -319,9 +326,9 @@ int Label::get_longest_line_width() const {
int max_line_width=0; int max_line_width=0;
int line_width=0; int line_width=0;
for (int i=0;i<text.size();i++) { for (int i=0;i<xl_text.size();i++) {
CharType current=text[i]; CharType current=xl_text[i];
if (uppercase) if (uppercase)
current=String::char_uppercase(current); current=String::char_uppercase(current);
@ -335,7 +342,7 @@ int Label::get_longest_line_width() const {
} }
} else { } else {
int char_width=font->get_char_size(current,text[i+1]).width; int char_width=font->get_char_size(current,xl_text[i+1]).width;
line_width+=char_width; line_width+=char_width;
} }
@ -396,9 +403,9 @@ void Label::regenerate_word_cache() {
WordCache *last=NULL; WordCache *last=NULL;
for (int i=0;i<text.size()+1;i++) { for (int i=0;i<xl_text.size()+1;i++) {
CharType current=i<text.length()?text[i]:' '; //always a space at the end, so the algo works CharType current=i<xl_text.length()?xl_text[i]:' '; //always a space at the end, so the algo works
if (uppercase) if (uppercase)
current=String::char_uppercase(current); current=String::char_uppercase(current);
@ -438,7 +445,7 @@ void Label::regenerate_word_cache() {
total_char_cache++; total_char_cache++;
} }
if (i<text.length() && text[i] == ' ') { if (i<xl_text.length() && xl_text[i] == ' ') {
total_char_cache--; // do not count spaces total_char_cache--; // do not count spaces
if (line_width > 0 || last==NULL || last->char_pos!=WordCache::CHAR_WRAPLINE) { if (line_width > 0 || last==NULL || last->char_pos!=WordCache::CHAR_WRAPLINE) {
space_count++; space_count++;
@ -455,7 +462,7 @@ void Label::regenerate_word_cache() {
word_pos=i; word_pos=i;
} }
char_width=font->get_char_size(current,text[i+1]).width; char_width=font->get_char_size(current,xl_text[i+1]).width;
current_word_size+=char_width; current_word_size+=char_width;
line_width+=char_width; line_width+=char_width;
total_char_cache++; total_char_cache++;
@ -541,12 +548,11 @@ Label::VAlign Label::get_valign() const{
void Label::set_text(const String& p_string) { void Label::set_text(const String& p_string) {
String str = XL_MESSAGE(p_string);
if (text==str) if (text==p_string)
return; return;
text=p_string;
text=str; xl_text=XL_MESSAGE(p_string);
word_cache_dirty=true; word_cache_dirty=true;
if (percent_visible<1) if (percent_visible<1)
visible_chars=get_total_character_count()*percent_visible; visible_chars=get_total_character_count()*percent_visible;
@ -693,7 +699,7 @@ Label::Label(const String &p_text) {
align=ALIGN_LEFT; align=ALIGN_LEFT;
valign=VALIGN_TOP; valign=VALIGN_TOP;
text=""; xl_text="";
word_cache=NULL; word_cache=NULL;
word_cache_dirty=true; word_cache_dirty=true;
autowrap=false; autowrap=false;

View File

@ -58,6 +58,7 @@ private:
Align align; Align align;
VAlign valign; VAlign valign;
String text; String text;
String xl_text;
bool autowrap; bool autowrap;
bool clip; bool clip;
Size2 minsize; Size2 minsize;

View File

@ -96,7 +96,7 @@ Size2 PopupMenu::get_minimum_size() const {
size.width+=check_w+hseparation; size.width+=check_w+hseparation;
} }
String text = items[i].shortcut.is_valid() ? String(tr(items[i].shortcut->get_name())) : items[i].text; String text = items[i].shortcut.is_valid() ? String(tr(items[i].shortcut->get_name())) : items[i].xl_text;
size.width+=font->get_string_size(text).width; size.width+=font->get_string_size(text).width;
if (i>0) if (i>0)
size.height+=vseparation; size.height+=vseparation;
@ -421,7 +421,16 @@ void PopupMenu::_notification(int p_what) {
switch(p_what) { switch(p_what) {
case NOTIFICATION_TRANSLATION_CHANGED: {
for(int i=0;i<items.size();i++) {
items[i].xl_text=XL_MESSAGE(items[i].text);
}
minimum_size_changed();
update();
} break;
case NOTIFICATION_DRAW: { case NOTIFICATION_DRAW: {
RID ci = get_canvas_item(); RID ci = get_canvas_item();
@ -496,7 +505,7 @@ void PopupMenu::_notification(int p_what) {
} }
item_ofs.y+=font->get_ascent(); item_ofs.y+=font->get_ascent();
String text = items[i].shortcut.is_valid() ? String(tr(items[i].shortcut->get_name())) : items[i].text; String text = items[i].shortcut.is_valid() ? String(tr(items[i].shortcut->get_name())) : items[i].xl_text;
if (!items[i].separator) { if (!items[i].separator) {
font->draw(ci,item_ofs+Point2(0,Math::floor((h-font_h)/2.0)),text,items[i].disabled?font_color_disabled:(i==mouse_over?font_color_hover:font_color)); font->draw(ci,item_ofs+Point2(0,Math::floor((h-font_h)/2.0)),text,items[i].disabled?font_color_disabled:(i==mouse_over?font_color_hover:font_color));
@ -537,6 +546,7 @@ void PopupMenu::add_icon_item(const Ref<Texture>& p_icon,const String& p_label,i
Item item; Item item;
item.icon=p_icon; item.icon=p_icon;
item.text=p_label; item.text=p_label;
item.xl_text=XL_MESSAGE(p_label);
item.accel=p_accel; item.accel=p_accel;
item.ID=p_ID; item.ID=p_ID;
items.push_back(item); items.push_back(item);
@ -545,7 +555,8 @@ void PopupMenu::add_icon_item(const Ref<Texture>& p_icon,const String& p_label,i
void PopupMenu::add_item(const String& p_label,int p_ID,uint32_t p_accel) { void PopupMenu::add_item(const String& p_label,int p_ID,uint32_t p_accel) {
Item item; Item item;
item.text=XL_MESSAGE(p_label); item.text=p_label;
item.xl_text=XL_MESSAGE(p_label);
item.accel=p_accel; item.accel=p_accel;
item.ID=p_ID; item.ID=p_ID;
items.push_back(item); items.push_back(item);
@ -555,7 +566,8 @@ void PopupMenu::add_item(const String& p_label,int p_ID,uint32_t p_accel) {
void PopupMenu::add_submenu_item(const String& p_label, const String& p_submenu,int p_ID){ void PopupMenu::add_submenu_item(const String& p_label, const String& p_submenu,int p_ID){
Item item; Item item;
item.text=XL_MESSAGE(p_label); item.text=p_label;
item.xl_text=XL_MESSAGE(p_label);
item.ID=p_ID; item.ID=p_ID;
item.submenu=p_submenu; item.submenu=p_submenu;
items.push_back(item); items.push_back(item);
@ -566,7 +578,8 @@ void PopupMenu::add_icon_check_item(const Ref<Texture>& p_icon,const String& p_l
Item item; Item item;
item.icon=p_icon; item.icon=p_icon;
item.text=XL_MESSAGE(p_label); item.text=p_label;
item.xl_text=XL_MESSAGE(p_label);
item.accel=p_accel; item.accel=p_accel;
item.ID=p_ID; item.ID=p_ID;
item.checkable=true; item.checkable=true;
@ -576,7 +589,8 @@ void PopupMenu::add_icon_check_item(const Ref<Texture>& p_icon,const String& p_l
void PopupMenu::add_check_item(const String& p_label,int p_ID,uint32_t p_accel) { void PopupMenu::add_check_item(const String& p_label,int p_ID,uint32_t p_accel) {
Item item; Item item;
item.text=XL_MESSAGE(p_label); item.text=p_label;
item.xl_text=XL_MESSAGE(p_label);
item.accel=p_accel; item.accel=p_accel;
item.ID=p_ID; item.ID=p_ID;
item.checkable=true; item.checkable=true;
@ -649,7 +663,8 @@ void PopupMenu::add_check_shortcut(const Ref<ShortCut>& p_shortcut, int p_ID, bo
void PopupMenu::set_item_text(int p_idx,const String& p_text) { void PopupMenu::set_item_text(int p_idx,const String& p_text) {
ERR_FAIL_INDEX(p_idx,items.size()); ERR_FAIL_INDEX(p_idx,items.size());
items[p_idx].text=XL_MESSAGE(p_text); items[p_idx].text=p_text;
items[p_idx].xl_text=XL_MESSAGE(p_text);
update(); update();
@ -1082,8 +1097,8 @@ void PopupMenu::get_translatable_strings(List<String> *p_strings) const {
for(int i=0;i<items.size();i++) { for(int i=0;i<items.size();i++) {
if (items[i].text!="") if (items[i].xl_text!="")
p_strings->push_back(items[i].text); p_strings->push_back(items[i].xl_text);
} }
} }

View File

@ -44,6 +44,7 @@ class PopupMenu : public Popup {
struct Item { struct Item {
Ref<Texture> icon; Ref<Texture> icon;
String text; String text;
String xl_text;
bool checked; bool checked;
bool checkable; bool checkable;
bool separator; bool separator;

View File

@ -222,6 +222,7 @@ public:
NOTIFICATION_DRAG_BEGIN=21, NOTIFICATION_DRAG_BEGIN=21,
NOTIFICATION_DRAG_END=22, NOTIFICATION_DRAG_END=22,
NOTIFICATION_PATH_CHANGED=23, NOTIFICATION_PATH_CHANGED=23,
NOTIFICATION_TRANSLATION_CHANGED=24,
}; };
/* NODE/TREE */ /* NODE/TREE */

View File

@ -650,6 +650,9 @@ void SceneTree::_notification(int p_notification) {
get_root()->propagate_notification(p_notification); get_root()->propagate_notification(p_notification);
} break; } break;
case NOTIFICATION_TRANSLATION_CHANGED: {
get_root()->propagate_notification(Node::NOTIFICATION_TRANSLATION_CHANGED);
} break;
case NOTIFICATION_WM_UNFOCUS_REQUEST: { case NOTIFICATION_WM_UNFOCUS_REQUEST: {
notify_group(GROUP_CALL_REALTIME|GROUP_CALL_MULIILEVEL,"input",NOTIFICATION_WM_UNFOCUS_REQUEST); notify_group(GROUP_CALL_REALTIME|GROUP_CALL_MULIILEVEL,"input",NOTIFICATION_WM_UNFOCUS_REQUEST);