summaryrefslogtreecommitdiffstats
path: root/editor
diff options
context:
space:
mode:
authorbruvzg <7645683+bruvzg@users.noreply.github.com>2022-03-04 15:04:59 +0200
committerbruvzg <7645683+bruvzg@users.noreply.github.com>2022-03-04 18:11:31 +0200
commit12cb6386f6bb4e82dcc1105616181a7dc251fe02 (patch)
tree4abae767b1007e752bacc018ea467419d6ccb78e /editor
parentbb8c4acdc9f07d318154a95331c4f77b00825bf5 (diff)
downloadredot-engine-12cb6386f6bb4e82dcc1105616181a7dc251fe02.tar.gz
Improve app name and system permission message localization.
Add localizable string (Dictionary<Lang Code, String>) property editor and property hint. Add localized "app name" property to the project settings. Add localized permission and copyright properties to the macOS and iOS export settings. Remove some duplicated ("app name") and deprecated ("info") macOS and iOS export properties.
Diffstat (limited to 'editor')
-rw-r--r--editor/editor_properties.cpp9
-rw-r--r--editor/editor_properties_array_dict.cpp232
-rw-r--r--editor/editor_properties_array_dict.h36
3 files changed, 271 insertions, 6 deletions
diff --git a/editor/editor_properties.cpp b/editor/editor_properties.cpp
index 68a3fabe1e..be858ff898 100644
--- a/editor/editor_properties.cpp
+++ b/editor/editor_properties.cpp
@@ -3738,8 +3738,13 @@ EditorProperty *EditorInspectorDefaultPlugin::get_editor_for_property(Object *p_
} break;
case Variant::DICTIONARY: {
- EditorPropertyDictionary *editor = memnew(EditorPropertyDictionary);
- return editor;
+ if (p_hint == PROPERTY_HINT_LOCALIZABLE_STRING) {
+ EditorPropertyLocalizableString *editor = memnew(EditorPropertyLocalizableString);
+ return editor;
+ } else {
+ EditorPropertyDictionary *editor = memnew(EditorPropertyDictionary);
+ return editor;
+ }
} break;
case Variant::ARRAY: {
EditorPropertyArray *editor = memnew(EditorPropertyArray);
diff --git a/editor/editor_properties_array_dict.cpp b/editor/editor_properties_array_dict.cpp
index 61261af608..302cc9c28c 100644
--- a/editor/editor_properties_array_dict.cpp
+++ b/editor/editor_properties_array_dict.cpp
@@ -742,7 +742,7 @@ void EditorPropertyDictionary::_property_changed(const String &p_property, Varia
emit_changed(get_edited_property(), dict, "", true);
- dict = dict.duplicate(); // Duplicate, so undo/redo works better\.
+ dict = dict.duplicate(); // Duplicate, so undo/redo works better.
object->set_dict(dict);
}
}
@@ -805,7 +805,7 @@ void EditorPropertyDictionary::_change_type_menu(int p_index) {
emit_changed(get_edited_property(), dict, "", false);
- dict = dict.duplicate(); // Duplicate, so undo/redo works better\.
+ dict = dict.duplicate(); // Duplicate, so undo/redo works better.
object->set_dict(dict);
update_property();
}
@@ -814,7 +814,7 @@ void EditorPropertyDictionary::update_property() {
Variant updated_val = get_edited_object()->get(get_edited_property());
if (updated_val.get_type() == Variant::NIL) {
- edit->set_text("Dictionary (Nil)"); // This provides symmetry with the array property.
+ edit->set_text(TTR("Dictionary (Nil)")); // This provides symmetry with the array property.
edit->set_pressed(false);
if (vbox) {
set_bottom_editor(nullptr);
@@ -826,7 +826,7 @@ void EditorPropertyDictionary::update_property() {
Dictionary dict = updated_val;
- edit->set_text("Dictionary (size " + itos(dict.size()) + ")");
+ edit->set_text(vformat(TTR("Dictionary (size %d)"), dict.size()));
bool unfolded = get_edited_object()->editor_is_section_unfolded(get_edited_property());
if (edit->is_pressed() != unfolded) {
@@ -1144,6 +1144,7 @@ void EditorPropertyDictionary::update_property() {
if (vbox) {
set_bottom_editor(nullptr);
memdelete(vbox);
+ button_add_item = nullptr;
vbox = nullptr;
}
}
@@ -1216,3 +1217,226 @@ EditorPropertyDictionary::EditorPropertyDictionary() {
change_type->connect("id_pressed", callable_mp(this, &EditorPropertyDictionary::_change_type_menu));
changing_type_index = -1;
}
+
+///////////////////// LOCALIZABLE STRING ///////////////////////////
+
+void EditorPropertyLocalizableString::_property_changed(const String &p_property, Variant p_value, const String &p_name, bool p_changing) {
+ if (p_property.begins_with("indices")) {
+ int index = p_property.get_slice("/", 1).to_int();
+ Dictionary dict = object->get_dict();
+ Variant key = dict.get_key_at_index(index);
+ dict[key] = p_value;
+
+ emit_changed(get_edited_property(), dict, "", true);
+
+ dict = dict.duplicate(); // Duplicate, so undo/redo works better.
+ object->set_dict(dict);
+ }
+}
+
+void EditorPropertyLocalizableString::_add_locale_popup() {
+ locale_select->popup_locale_dialog();
+}
+
+void EditorPropertyLocalizableString::_add_locale(const String &p_locale) {
+ Dictionary dict = object->get_dict();
+
+ object->set_new_item_key(p_locale);
+ object->set_new_item_value(String());
+ dict[object->get_new_item_key()] = object->get_new_item_value();
+
+ emit_changed(get_edited_property(), dict, "", false);
+
+ dict = dict.duplicate(); // Duplicate, so undo/redo works better.
+ object->set_dict(dict);
+ update_property();
+}
+
+void EditorPropertyLocalizableString::_remove_item(Object *p_button, int p_index) {
+ Dictionary dict = object->get_dict();
+
+ Variant key = dict.get_key_at_index(p_index);
+ dict.erase(key);
+
+ emit_changed(get_edited_property(), dict, "", false);
+
+ dict = dict.duplicate(); // Duplicate, so undo/redo works better.
+ object->set_dict(dict);
+ update_property();
+}
+
+void EditorPropertyLocalizableString::update_property() {
+ Variant updated_val = get_edited_object()->get(get_edited_property());
+
+ if (updated_val.get_type() == Variant::NIL) {
+ edit->set_text(TTR("Localizable String (Nil)")); // This provides symmetry with the array property.
+ edit->set_pressed(false);
+ if (vbox) {
+ set_bottom_editor(nullptr);
+ memdelete(vbox);
+ vbox = nullptr;
+ }
+ return;
+ }
+
+ Dictionary dict = updated_val;
+
+ edit->set_text(vformat(TTR("Localizable String (size %d)"), dict.size()));
+
+ bool unfolded = get_edited_object()->editor_is_section_unfolded(get_edited_property());
+ if (edit->is_pressed() != unfolded) {
+ edit->set_pressed(unfolded);
+ }
+
+ if (unfolded) {
+ updating = true;
+
+ if (!vbox) {
+ vbox = memnew(VBoxContainer);
+ add_child(vbox);
+ set_bottom_editor(vbox);
+
+ property_vbox = memnew(VBoxContainer);
+ property_vbox->set_h_size_flags(SIZE_EXPAND_FILL);
+ vbox->add_child(property_vbox);
+
+ paginator = memnew(EditorPaginator);
+ paginator->connect("page_changed", callable_mp(this, &EditorPropertyLocalizableString::_page_changed));
+ vbox->add_child(paginator);
+ } else {
+ // Queue children for deletion, deleting immediately might cause errors.
+ for (int i = property_vbox->get_child_count() - 1; i >= 0; i--) {
+ property_vbox->get_child(i)->queue_delete();
+ }
+ }
+
+ int size = dict.size();
+
+ int max_page = MAX(0, size - 1) / page_length;
+ page_index = MIN(page_index, max_page);
+
+ paginator->update(page_index, max_page);
+ paginator->set_visible(max_page > 0);
+
+ int offset = page_index * page_length;
+
+ int amount = MIN(size - offset, page_length);
+
+ dict = dict.duplicate();
+
+ object->set_dict(dict);
+
+ for (int i = 0; i < amount; i++) {
+ String prop_name;
+ Variant key;
+ Variant value;
+
+ prop_name = "indices/" + itos(i + offset);
+ key = dict.get_key_at_index(i + offset);
+ value = dict.get_value_at_index(i + offset);
+
+ EditorProperty *prop = memnew(EditorPropertyText);
+
+ prop->set_object_and_property(object.ptr(), prop_name);
+ int remove_index = 0;
+
+ String cs = key.get_construct_string();
+ prop->set_label(cs);
+ prop->set_tooltip(cs);
+ remove_index = i + offset;
+
+ prop->set_selectable(false);
+ prop->connect("property_changed", callable_mp(this, &EditorPropertyLocalizableString::_property_changed));
+ prop->connect("object_id_selected", callable_mp(this, &EditorPropertyLocalizableString::_object_id_selected));
+
+ HBoxContainer *hbox = memnew(HBoxContainer);
+ property_vbox->add_child(hbox);
+ hbox->add_child(prop);
+ prop->set_h_size_flags(SIZE_EXPAND_FILL);
+ Button *edit = memnew(Button);
+ edit->set_icon(get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")));
+ hbox->add_child(edit);
+ edit->connect("pressed", callable_mp(this, &EditorPropertyLocalizableString::_remove_item), varray(edit, remove_index));
+
+ prop->update_property();
+ }
+
+ if (page_index == max_page) {
+ button_add_item = memnew(Button);
+ button_add_item->set_text(TTR("Add Translation"));
+ button_add_item->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons")));
+ button_add_item->connect("pressed", callable_mp(this, &EditorPropertyLocalizableString::_add_locale_popup));
+ property_vbox->add_child(button_add_item);
+ }
+
+ updating = false;
+
+ } else {
+ if (vbox) {
+ set_bottom_editor(nullptr);
+ memdelete(vbox);
+ button_add_item = nullptr;
+ vbox = nullptr;
+ }
+ }
+}
+
+void EditorPropertyLocalizableString::_object_id_selected(const StringName &p_property, ObjectID p_id) {
+ emit_signal(SNAME("object_id_selected"), p_property, p_id);
+}
+
+void EditorPropertyLocalizableString::_notification(int p_what) {
+ switch (p_what) {
+ case NOTIFICATION_THEME_CHANGED:
+ case NOTIFICATION_ENTER_TREE: {
+ if (Object::cast_to<Button>(button_add_item)) {
+ button_add_item->set_icon(get_theme_icon(SNAME("Add"), SNAME("EditorIcons")));
+ }
+ } break;
+ }
+}
+
+void EditorPropertyLocalizableString::_edit_pressed() {
+ Variant prop_val = get_edited_object()->get(get_edited_property());
+ if (prop_val.get_type() == Variant::NIL) {
+ Callable::CallError ce;
+ Variant::construct(Variant::DICTIONARY, prop_val, nullptr, 0, ce);
+ get_edited_object()->set(get_edited_property(), prop_val);
+ }
+
+ get_edited_object()->editor_set_section_unfold(get_edited_property(), edit->is_pressed());
+ update_property();
+}
+
+void EditorPropertyLocalizableString::_page_changed(int p_page) {
+ if (updating) {
+ return;
+ }
+ page_index = p_page;
+ update_property();
+}
+
+void EditorPropertyLocalizableString::_bind_methods() {
+}
+
+EditorPropertyLocalizableString::EditorPropertyLocalizableString() {
+ object.instantiate();
+ page_length = int(EDITOR_GET("interface/inspector/max_array_dictionary_items_per_page"));
+
+ edit = memnew(Button);
+ edit->set_h_size_flags(SIZE_EXPAND_FILL);
+ edit->set_clip_text(true);
+ edit->connect("pressed", callable_mp(this, &EditorPropertyLocalizableString::_edit_pressed));
+ edit->set_toggle_mode(true);
+ add_child(edit);
+ add_focusable(edit);
+
+ vbox = nullptr;
+ button_add_item = nullptr;
+ paginator = nullptr;
+ updating = false;
+
+ locale_select = memnew(EditorLocaleDialog);
+ locale_select->connect("locale_selected", callable_mp(this, &EditorPropertyLocalizableString::_add_locale));
+ add_child(locale_select);
+}
diff --git a/editor/editor_properties_array_dict.h b/editor/editor_properties_array_dict.h
index 292de6d6db..6c22f7f606 100644
--- a/editor/editor_properties_array_dict.h
+++ b/editor/editor_properties_array_dict.h
@@ -32,6 +32,7 @@
#define EDITOR_PROPERTIES_ARRAY_DICT_H
#include "editor/editor_inspector.h"
+#include "editor/editor_locale_dialog.h"
#include "editor/editor_spin_slider.h"
#include "editor/filesystem_dock.h"
#include "scene/gui/button.h"
@@ -169,4 +170,39 @@ public:
EditorPropertyDictionary();
};
+class EditorPropertyLocalizableString : public EditorProperty {
+ GDCLASS(EditorPropertyLocalizableString, EditorProperty);
+
+ EditorLocaleDialog *locale_select;
+
+ bool updating;
+
+ Ref<EditorPropertyDictionaryObject> object;
+ int page_length = 20;
+ int page_index = 0;
+ Button *edit;
+ VBoxContainer *vbox;
+ VBoxContainer *property_vbox;
+ EditorSpinSlider *size_slider;
+ Button *button_add_item;
+ EditorPaginator *paginator;
+
+ void _page_changed(int p_page);
+ void _edit_pressed();
+ void _remove_item(Object *p_button, int p_index);
+ void _property_changed(const String &p_property, Variant p_value, const String &p_name = "", bool p_changing = false);
+
+ void _add_locale_popup();
+ void _add_locale(const String &p_locale);
+ void _object_id_selected(const StringName &p_property, ObjectID p_id);
+
+protected:
+ static void _bind_methods();
+ void _notification(int p_what);
+
+public:
+ virtual void update_property() override;
+ EditorPropertyLocalizableString();
+};
+
#endif // EDITOR_PROPERTIES_ARRAY_DICT_H