diff --git a/doc/classes/OptionButton.xml b/doc/classes/OptionButton.xml index f04b0d942f7..aab6a113060 100644 --- a/doc/classes/OptionButton.xml +++ b/doc/classes/OptionButton.xml @@ -42,6 +42,13 @@ Clears all the items in the [OptionButton]. + + + + + Returns the auto translate mode of the item at index [param idx]. + + @@ -153,6 +160,15 @@ If [code]true[/code], shortcuts are disabled and cannot be used to trigger the button. + + + + + + Sets the auto translate mode of the item at index [param idx]. + Items use [constant Node.AUTO_TRANSLATE_MODE_INHERIT] by default, which uses the same auto translate mode as the [OptionButton] itself. + + diff --git a/doc/classes/PopupMenu.xml b/doc/classes/PopupMenu.xml index 8c14081366c..7f54656331c 100644 --- a/doc/classes/PopupMenu.xml +++ b/doc/classes/PopupMenu.xml @@ -237,6 +237,13 @@ Returns the accelerator of the item at the given [param index]. An accelerator is a keyboard shortcut that can be pressed to trigger the menu button even if it's not currently open. The return value is an integer which is generally a combination of [enum KeyModifierMask]s and [enum Key]s using bitwise OR such as [code]KEY_MASK_CTRL | KEY_A[/code] ([kbd]Ctrl + A[/kbd]). If no accelerator is defined for the specified [param index], [method get_item_accelerator] returns [code]0[/code] (corresponding to [constant @GlobalScope.KEY_NONE]). + + + + + Returns the auto translate mode of the item at the given [param index]. + + @@ -462,6 +469,15 @@ Mark the item at the given [param index] as a separator, which means that it would be displayed as a line. If [code]false[/code], sets the type of the item to plain text. + + + + + + Sets the auto translate mode of the item at the given [param index]. + Items use [constant Node.AUTO_TRANSLATE_MODE_INHERIT] by default, which uses the same auto translate mode as the [PopupMenu] itself. + + diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 22e86bdbaba..5386314536e 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -4688,6 +4688,7 @@ void EditorNode::_update_recent_scenes() { recent_scenes->add_separator(); recent_scenes->add_shortcut(ED_SHORTCUT("editor/clear_recent", TTRC("Clear Recent Scenes"))); + recent_scenes->set_item_auto_translate_mode(-1, AUTO_TRANSLATE_MODE_ALWAYS); recent_scenes->reset_size(); } @@ -5639,6 +5640,7 @@ void EditorNode::_update_layouts_menu() { } editor_layouts->add_item(layout); + editor_layouts->set_item_auto_translate_mode(-1, AUTO_TRANSLATE_MODE_DISABLED); } } @@ -7448,6 +7450,7 @@ EditorNode::EditorNode() { file_menu->add_shortcut(ED_SHORTCUT_AND_COMMAND("editor/reopen_closed_scene", TTRC("Reopen Closed Scene"), KeyModifierMask::CMD_OR_CTRL + KeyModifierMask::SHIFT + Key::T), FILE_OPEN_PREV); recent_scenes = memnew(PopupMenu); + recent_scenes->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED); file_menu->add_submenu_node_item(TTR("Open Recent"), recent_scenes, FILE_OPEN_RECENT); recent_scenes->connect(SceneStringName(id_pressed), callable_mp(this, &EditorNode::_open_recent_scene)); @@ -7576,7 +7579,6 @@ EditorNode::EditorNode() { settings_menu->add_submenu_node_item(TTR("Editor Docks"), editor_dock_manager->get_docks_menu()); editor_layouts = memnew(PopupMenu); - editor_layouts->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED); settings_menu->add_submenu_node_item(TTR("Editor Layout"), editor_layouts); editor_layouts->connect(SceneStringName(id_pressed), callable_mp(this, &EditorNode::_layout_menu_option)); settings_menu->add_separator(); diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp index 2ec65c1ca4f..9be23c38374 100644 --- a/editor/plugins/script_editor_plugin.cpp +++ b/editor/plugins/script_editor_plugin.cpp @@ -824,7 +824,8 @@ void ScriptEditor::_update_recent_scripts() { recent_scripts->add_separator(); recent_scripts->add_shortcut(ED_GET_SHORTCUT("script_editor/clear_recent")); - recent_scripts->set_item_disabled(recent_scripts->get_item_id(recent_scripts->get_item_count() - 1), rc.is_empty()); + recent_scripts->set_item_auto_translate_mode(-1, AUTO_TRANSLATE_MODE_ALWAYS); + recent_scripts->set_item_disabled(-1, rc.is_empty()); recent_scripts->reset_size(); } @@ -4278,6 +4279,7 @@ ScriptEditor::ScriptEditor(WindowWrapper *p_wrapper) { file_menu->get_popup()->add_shortcut(ED_GET_SHORTCUT("script_editor/reopen_closed_script"), FILE_REOPEN_CLOSED); recent_scripts = memnew(PopupMenu); + recent_scripts->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED); file_menu->get_popup()->add_submenu_node_item(TTR("Open Recent"), recent_scripts, FILE_OPEN_RECENT); recent_scripts->connect(SceneStringName(id_pressed), callable_mp(this, &ScriptEditor::_open_recent_script)); diff --git a/editor/scene_create_dialog.cpp b/editor/scene_create_dialog.cpp index 1b4941d4735..971735760b9 100644 --- a/editor/scene_create_dialog.cpp +++ b/editor/scene_create_dialog.cpp @@ -261,6 +261,7 @@ SceneCreateDialog::SceneCreateDialog() { ResourceSaver::get_recognized_extensions(sd, &extensions); scene_extension_picker = memnew(OptionButton); + scene_extension_picker->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED); hb->add_child(scene_extension_picker); for (const String &E : extensions) { scene_extension_picker->add_item("." + E); diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp index 2b0f8214710..4850b4cc1e3 100644 --- a/editor/script_create_dialog.cpp +++ b/editor/script_create_dialog.cpp @@ -566,6 +566,7 @@ void ScriptCreateDialog::_update_template_menu() { if (!separator) { template_menu->add_separator(); template_menu->set_item_text(-1, display_name); + template_menu->set_item_auto_translate_mode(-1, AUTO_TRANSLATE_MODE_ALWAYS); separator = true; } for (ScriptLanguage::ScriptTemplate &t : templates_found) { @@ -670,7 +671,7 @@ void ScriptCreateDialog::_update_dialog() { validation_panel->set_message(MSG_ID_PATH, TTR("Built-in script (into scene file)."), EditorValidationPanel::MSG_OK); } } else { - template_inactive_message = TTR("Using existing script file."); + template_inactive_message = TTRC("Using existing script file."); if (load_enabled) { if (is_path_valid) { validation_panel->set_message(MSG_ID_PATH, TTR("Will load an existing script file."), EditorValidationPanel::MSG_OK); @@ -684,16 +685,17 @@ void ScriptCreateDialog::_update_dialog() { if (is_using_templates) { // Check if at least one suitable template has been found. if (template_menu->get_item_count() == 0 && template_inactive_message.is_empty()) { - template_inactive_message = TTR("No suitable template."); + template_inactive_message = TTRC("No suitable template."); } } else { - template_inactive_message = TTR("Empty"); + template_inactive_message = TTRC("Empty"); } if (!template_inactive_message.is_empty()) { template_menu->set_disabled(true); template_menu->clear(); template_menu->add_item(template_inactive_message); + template_menu->set_item_auto_translate_mode(-1, AUTO_TRANSLATE_MODE_ALWAYS); validation_panel->set_message(MSG_ID_TEMPLATE, "", EditorValidationPanel::MSG_INFO); } } @@ -821,11 +823,11 @@ ScriptLanguage::ScriptTemplate ScriptCreateDialog::_parse_template(const ScriptL String ScriptCreateDialog::_get_script_origin_label(const ScriptLanguage::TemplateLocation &p_origin) const { switch (p_origin) { case ScriptLanguage::TEMPLATE_BUILT_IN: - return TTR("Built-in"); + return TTRC("Built-in"); case ScriptLanguage::TEMPLATE_EDITOR: - return TTR("Editor"); + return TTRC("Editor"); case ScriptLanguage::TEMPLATE_PROJECT: - return TTR("Project"); + return TTRC("Project"); } return ""; } @@ -868,6 +870,7 @@ ScriptCreateDialog::ScriptCreateDialog() { /* Language */ language_menu = memnew(OptionButton); + language_menu->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED); language_menu->set_custom_minimum_size(Size2(350, 0) * EDSCALE); language_menu->set_expand_icon(true); language_menu->set_h_size_flags(Control::SIZE_EXPAND_FILL); @@ -921,6 +924,7 @@ ScriptCreateDialog::ScriptCreateDialog() { template_inactive_message = ""; template_menu = memnew(OptionButton); + template_menu->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED); template_menu->set_h_size_flags(Control::SIZE_EXPAND_FILL); template_menu->connect(SceneStringName(item_selected), callable_mp(this, &ScriptCreateDialog::_template_changed)); template_hb->add_child(template_menu); diff --git a/editor/shader_create_dialog.cpp b/editor/shader_create_dialog.cpp index 9423a8308a5..684208f64a3 100644 --- a/editor/shader_create_dialog.cpp +++ b/editor/shader_create_dialog.cpp @@ -312,13 +312,13 @@ void ShaderCreateDialog::_type_changed(int p_language) { if (shader_type_data.use_templates) { int last_template = EditorSettings::get_singleton()->get_project_metadata("shader_setup", "last_selected_template", 0); - template_menu->add_item(TTR("Default")); - template_menu->add_item(TTR("Empty")); + template_menu->add_item(TTRC("Default")); + template_menu->add_item(TTRC("Empty")); template_menu->select(last_template); current_template = last_template; } else { - template_menu->add_item(TTR("N/A")); + template_menu->add_item(TTRC("N/A")); } EditorSettings::get_singleton()->set_project_metadata("shader_setup", "last_selected_language", type_menu->get_item_text(type_menu->get_selected())); @@ -572,6 +572,7 @@ ShaderCreateDialog::ShaderCreateDialog() { // Type. type_menu = memnew(OptionButton); + type_menu->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED); type_menu->set_custom_minimum_size(Size2(250, 0) * EDSCALE); type_menu->set_h_size_flags(Control::SIZE_EXPAND_FILL); gc->add_child(memnew(Label(TTR("Type:")))); @@ -612,6 +613,7 @@ ShaderCreateDialog::ShaderCreateDialog() { // Modes. mode_menu = memnew(OptionButton); + mode_menu->set_auto_translate_mode(AUTO_TRANSLATE_MODE_DISABLED); for (const String &type_name : ShaderTypes::get_singleton()->get_types_list()) { mode_menu->add_item(type_name.capitalize()); } diff --git a/scene/gui/button.cpp b/scene/gui/button.cpp index 738637ef36a..48a2a27a67b 100644 --- a/scene/gui/button.cpp +++ b/scene/gui/button.cpp @@ -48,6 +48,10 @@ void Button::_set_internal_margin(Side p_side, float p_value) { void Button::_queue_update_size_cache() { } +String Button::_get_translated_text(const String &p_text) const { + return atr(p_text); +} + void Button::_update_theme_item_cache() { Control::_update_theme_item_cache(); @@ -186,7 +190,7 @@ void Button::_notification(int p_what) { } break; case NOTIFICATION_TRANSLATION_CHANGED: { - xl_text = atr(text); + xl_text = _get_translated_text(text); _shape(); update_minimum_size(); @@ -598,14 +602,16 @@ TextServer::OverrunBehavior Button::get_text_overrun_behavior() const { } void Button::set_text(const String &p_text) { - if (text != p_text) { - text = p_text; - xl_text = atr(text); - _shape(); - - queue_redraw(); - update_minimum_size(); + const String translated_text = _get_translated_text(p_text); + if (text == p_text && xl_text == translated_text) { + return; } + text = p_text; + xl_text = translated_text; + _shape(); + + queue_redraw(); + update_minimum_size(); } String Button::get_text() const { diff --git a/scene/gui/button.h b/scene/gui/button.h index 26e6154bf7f..97ff13cf77a 100644 --- a/scene/gui/button.h +++ b/scene/gui/button.h @@ -110,6 +110,7 @@ protected: void _set_internal_margin(Side p_side, float p_value); virtual void _queue_update_size_cache(); + virtual String _get_translated_text(const String &p_text) const; Size2 _fit_icon_size(const Size2 &p_size) const; Ref _get_current_stylebox() const; diff --git a/scene/gui/option_button.cpp b/scene/gui/option_button.cpp index c63608423ad..af2cc8ffde4 100644 --- a/scene/gui/option_button.cpp +++ b/scene/gui/option_button.cpp @@ -240,6 +240,21 @@ void OptionButton::set_item_tooltip(int p_idx, const String &p_tooltip) { popup->set_item_tooltip(p_idx, p_tooltip); } +void OptionButton::set_item_auto_translate_mode(int p_idx, AutoTranslateMode p_mode) { + if (p_idx < 0) { + p_idx += get_item_count(); + } + if (popup->get_item_auto_translate_mode(p_idx) == p_mode) { + return; + } + popup->set_item_auto_translate_mode(p_idx, p_mode); + + if (current == p_idx) { + set_text(popup->get_item_text(p_idx)); + } + _queue_update_size_cache(); +} + void OptionButton::set_item_disabled(int p_idx, bool p_disabled) { popup->set_item_disabled(p_idx, p_disabled); } @@ -272,6 +287,10 @@ String OptionButton::get_item_tooltip(int p_idx) const { return popup->get_item_tooltip(p_idx); } +Node::AutoTranslateMode OptionButton::get_item_auto_translate_mode(int p_idx) const { + return popup->get_item_auto_translate_mode(p_idx); +} + bool OptionButton::is_item_disabled(int p_idx) const { return popup->is_item_disabled(p_idx); } @@ -431,6 +450,25 @@ void OptionButton::_queue_update_size_cache() { callable_mp(this, &OptionButton::_refresh_size_cache).call_deferred(); } +String OptionButton::_get_translated_text(const String &p_text) const { + if (0 <= current && current < popup->get_item_count()) { + AutoTranslateMode mode = popup->get_item_auto_translate_mode(current); + switch (mode) { + case AUTO_TRANSLATE_MODE_INHERIT: { + return atr(p_text); + } break; + case AUTO_TRANSLATE_MODE_ALWAYS: { + return tr(p_text); + } break; + case AUTO_TRANSLATE_MODE_DISABLED: { + return p_text; + } break; + } + ERR_FAIL_V_MSG(atr(p_text), "Unexpected auto translate mode: " + itos(mode)); + } + return atr(p_text); +} + void OptionButton::select(int p_idx) { _select(p_idx, false); } @@ -510,12 +548,14 @@ void OptionButton::_bind_methods() { ClassDB::bind_method(D_METHOD("set_item_id", "idx", "id"), &OptionButton::set_item_id); ClassDB::bind_method(D_METHOD("set_item_metadata", "idx", "metadata"), &OptionButton::set_item_metadata); ClassDB::bind_method(D_METHOD("set_item_tooltip", "idx", "tooltip"), &OptionButton::set_item_tooltip); + ClassDB::bind_method(D_METHOD("set_item_auto_translate_mode", "idx", "mode"), &OptionButton::set_item_auto_translate_mode); ClassDB::bind_method(D_METHOD("get_item_text", "idx"), &OptionButton::get_item_text); ClassDB::bind_method(D_METHOD("get_item_icon", "idx"), &OptionButton::get_item_icon); ClassDB::bind_method(D_METHOD("get_item_id", "idx"), &OptionButton::get_item_id); ClassDB::bind_method(D_METHOD("get_item_index", "id"), &OptionButton::get_item_index); ClassDB::bind_method(D_METHOD("get_item_metadata", "idx"), &OptionButton::get_item_metadata); ClassDB::bind_method(D_METHOD("get_item_tooltip", "idx"), &OptionButton::get_item_tooltip); + ClassDB::bind_method(D_METHOD("get_item_auto_translate_mode", "idx"), &OptionButton::get_item_auto_translate_mode); ClassDB::bind_method(D_METHOD("is_item_disabled", "idx"), &OptionButton::is_item_disabled); ClassDB::bind_method(D_METHOD("is_item_separator", "idx"), &OptionButton::is_item_separator); ClassDB::bind_method(D_METHOD("add_separator", "text"), &OptionButton::add_separator, DEFVAL(String())); diff --git a/scene/gui/option_button.h b/scene/gui/option_button.h index 2e6fcc4bdbf..e35bb7fd0c3 100644 --- a/scene/gui/option_button.h +++ b/scene/gui/option_button.h @@ -79,6 +79,7 @@ class OptionButton : public Button { protected: Size2 get_minimum_size() const override; virtual void _queue_update_size_cache() override; + virtual String _get_translated_text(const String &p_text) const override; void _notification(int p_what); bool _set(const StringName &p_name, const Variant &p_value); @@ -105,6 +106,7 @@ public: void set_item_metadata(int p_idx, const Variant &p_metadata); void set_item_disabled(int p_idx, bool p_disabled); void set_item_tooltip(int p_idx, const String &p_tooltip); + void set_item_auto_translate_mode(int p_idx, AutoTranslateMode p_mode); String get_item_text(int p_idx) const; Ref get_item_icon(int p_idx) const; @@ -114,6 +116,7 @@ public: bool is_item_disabled(int p_idx) const; bool is_item_separator(int p_idx) const; String get_item_tooltip(int p_idx) const; + AutoTranslateMode get_item_auto_translate_mode(int p_idx) const; bool has_selectable_items() const; int get_selectable_item(bool p_from_last = false) const; diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp index b6dc7575469..5d4ffc9ea08 100644 --- a/scene/gui/popup_menu.cpp +++ b/scene/gui/popup_menu.cpp @@ -1146,7 +1146,7 @@ void PopupMenu::_notification(int p_what) { } for (int i = 0; i < items.size(); i++) { Item &item = items.write[i]; - item.xl_text = atr(item.text); + item.xl_text = _atr(i, item.text); item.dirty = true; if (is_global) { nmenu->set_item_text(global_menu, i, item.xl_text); @@ -1731,7 +1731,7 @@ void PopupMenu::set_item_text(int p_idx, const String &p_text) { return; } items.write[p_idx].text = p_text; - items.write[p_idx].xl_text = atr(p_text); + items.write[p_idx].xl_text = _atr(p_idx, p_text); items.write[p_idx].dirty = true; if (global_menu.is_valid()) { @@ -1769,6 +1769,20 @@ void PopupMenu::set_item_language(int p_idx, const String &p_language) { } } +void PopupMenu::set_item_auto_translate_mode(int p_idx, AutoTranslateMode p_mode) { + if (p_idx < 0) { + p_idx += get_item_count(); + } + ERR_FAIL_INDEX(p_idx, items.size()); + if (items[p_idx].auto_translate_mode == p_mode) { + return; + } + items.write[p_idx].auto_translate_mode = p_mode; + items.write[p_idx].xl_text = _atr(p_idx, items[p_idx].text); + items.write[p_idx].dirty = true; + control->queue_redraw(); +} + void PopupMenu::set_item_icon(int p_idx, const Ref &p_icon) { if (p_idx < 0) { p_idx += get_item_count(); @@ -2009,6 +2023,11 @@ String PopupMenu::get_item_language(int p_idx) const { return items[p_idx].language; } +Node::AutoTranslateMode PopupMenu::get_item_auto_translate_mode(int p_idx) const { + ERR_FAIL_INDEX_V(p_idx, items.size(), AUTO_TRANSLATE_MODE_INHERIT); + return items[p_idx].auto_translate_mode; +} + int PopupMenu::get_item_idx_from_text(const String &text) const { for (int idx = 0; idx < items.size(); idx++) { if (items[idx].text == text) { @@ -2818,6 +2837,7 @@ void PopupMenu::_bind_methods() { ClassDB::bind_method(D_METHOD("set_item_text", "index", "text"), &PopupMenu::set_item_text); ClassDB::bind_method(D_METHOD("set_item_text_direction", "index", "direction"), &PopupMenu::set_item_text_direction); ClassDB::bind_method(D_METHOD("set_item_language", "index", "language"), &PopupMenu::set_item_language); + ClassDB::bind_method(D_METHOD("set_item_auto_translate_mode", "index", "mode"), &PopupMenu::set_item_auto_translate_mode); ClassDB::bind_method(D_METHOD("set_item_icon", "index", "icon"), &PopupMenu::set_item_icon); ClassDB::bind_method(D_METHOD("set_item_icon_max_width", "index", "width"), &PopupMenu::set_item_icon_max_width); ClassDB::bind_method(D_METHOD("set_item_icon_modulate", "index", "modulate"), &PopupMenu::set_item_icon_modulate); @@ -2844,6 +2864,7 @@ void PopupMenu::_bind_methods() { ClassDB::bind_method(D_METHOD("get_item_text", "index"), &PopupMenu::get_item_text); ClassDB::bind_method(D_METHOD("get_item_text_direction", "index"), &PopupMenu::get_item_text_direction); ClassDB::bind_method(D_METHOD("get_item_language", "index"), &PopupMenu::get_item_language); + ClassDB::bind_method(D_METHOD("get_item_auto_translate_mode", "index"), &PopupMenu::get_item_auto_translate_mode); ClassDB::bind_method(D_METHOD("get_item_icon", "index"), &PopupMenu::get_item_icon); ClassDB::bind_method(D_METHOD("get_item_icon_max_width", "index"), &PopupMenu::get_item_icon_max_width); ClassDB::bind_method(D_METHOD("get_item_icon_modulate", "index"), &PopupMenu::get_item_icon_modulate); @@ -2983,6 +3004,23 @@ void PopupMenu::_native_popup(const Rect2i &p_rect) { NativeMenu::get_singleton()->popup(global_menu, popup_pos); } +String PopupMenu::_atr(int p_idx, const String &p_text) const { + ERR_FAIL_INDEX_V(p_idx, items.size(), atr(p_text)); + switch (items[p_idx].auto_translate_mode) { + case AUTO_TRANSLATE_MODE_INHERIT: { + return atr(p_text); + } break; + case AUTO_TRANSLATE_MODE_ALWAYS: { + return tr(p_text); + } break; + case AUTO_TRANSLATE_MODE_DISABLED: { + return p_text; + } break; + } + + ERR_FAIL_V_MSG(atr(p_text), "Unexpected auto translate mode: " + itos(items[p_idx].auto_translate_mode)); +} + void PopupMenu::popup(const Rect2i &p_bounds) { bool native = global_menu.is_valid(); #ifdef TOOLS_ENABLED diff --git a/scene/gui/popup_menu.h b/scene/gui/popup_menu.h index d995a68f3f4..b014b76fd0e 100644 --- a/scene/gui/popup_menu.h +++ b/scene/gui/popup_menu.h @@ -54,6 +54,7 @@ class PopupMenu : public Popup { String language; Control::TextDirection text_direction = Control::TEXT_DIRECTION_AUTO; + AutoTranslateMode auto_translate_mode = AUTO_TRANSLATE_MODE_INHERIT; bool checked = false; enum { @@ -215,6 +216,7 @@ class PopupMenu : public Popup { void _set_item_checkable_type(int p_index, int p_checkable_type); int _get_item_checkable_type(int p_index) const; void _native_popup(const Rect2i &p_rect); + String _atr(int p_idx, const String &p_text) const; protected: virtual Rect2i _popup_adjust_rect() const override; @@ -279,6 +281,7 @@ public: void set_item_text_direction(int p_idx, Control::TextDirection p_text_direction); void set_item_language(int p_idx, const String &p_language); + void set_item_auto_translate_mode(int p_idx, AutoTranslateMode p_mode); void set_item_icon(int p_idx, const Ref &p_icon); void set_item_icon_max_width(int p_idx, int p_width); void set_item_icon_modulate(int p_idx, const Color &p_modulate); @@ -306,6 +309,7 @@ public: String get_item_xl_text(int p_idx) const; Control::TextDirection get_item_text_direction(int p_idx) const; String get_item_language(int p_idx) const; + AutoTranslateMode get_item_auto_translate_mode(int p_idx) const; int get_item_idx_from_text(const String &text) const; Ref get_item_icon(int p_idx) const; int get_item_icon_max_width(int p_idx) const;