From fb107e04d36f4522dde4c9ca473295ee359ccbfb Mon Sep 17 00:00:00 2001 From: Danil Alexeev Date: Fri, 3 Feb 2023 12:07:36 +0300 Subject: Fix `RichTextLabel` context menu not customizable --- scene/gui/rich_text_label.cpp | 46 +++++++++++++++++++++++++++++++------------ scene/gui/rich_text_label.h | 5 ++++- 2 files changed, 37 insertions(+), 14 deletions(-) (limited to 'scene/gui') diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index 3051502dd0..f9c9906efa 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -2031,7 +2031,7 @@ void RichTextLabel::gui_input(const Ref &p_event) { } } if (b->get_button_index() == MouseButton::RIGHT && context_menu_enabled) { - _generate_context_menu(); + _update_context_menu(); menu->set_position(get_screen_position() + b->get_position()); menu->reset_size(); menu->popup(); @@ -2090,7 +2090,7 @@ void RichTextLabel::gui_input(const Ref &p_event) { } if (k->is_action("ui_menu", true)) { if (context_menu_enabled) { - _generate_context_menu(); + _update_context_menu(); menu->set_position(get_screen_position()); menu->reset_size(); menu->popup(); @@ -4992,7 +4992,9 @@ bool RichTextLabel::is_shortcut_keys_enabled() const { // Context menu. PopupMenu *RichTextLabel::get_menu() const { - const_cast(this)->_generate_context_menu(); + if (!menu) { + const_cast(this)->_generate_context_menu(); + } return menu; } @@ -5466,6 +5468,7 @@ void RichTextLabel::_bind_methods() { ClassDB::bind_method(D_METHOD("get_menu"), &RichTextLabel::get_menu); ClassDB::bind_method(D_METHOD("is_menu_visible"), &RichTextLabel::is_menu_visible); + ClassDB::bind_method(D_METHOD("menu_option", "option"), &RichTextLabel::menu_option); ClassDB::bind_method(D_METHOD("_thread_end"), &RichTextLabel::_thread_end); @@ -5544,6 +5547,10 @@ void RichTextLabel::_bind_methods() { BIND_ENUM_CONSTANT(ITEM_HINT); BIND_ENUM_CONSTANT(ITEM_DROPCAP); BIND_ENUM_CONSTANT(ITEM_CUSTOMFX); + + BIND_ENUM_CONSTANT(MENU_COPY); + BIND_ENUM_CONSTANT(MENU_SELECT_ALL); + BIND_ENUM_CONSTANT(MENU_MAX); } TextServer::VisibleCharactersBehavior RichTextLabel::get_visible_characters_behavior() const { @@ -5675,19 +5682,32 @@ Size2 RichTextLabel::get_minimum_size() const { // Context menu. void RichTextLabel::_generate_context_menu() { - if (!menu) { - menu = memnew(PopupMenu); - add_child(menu, false, INTERNAL_MODE_FRONT); + menu = memnew(PopupMenu); + add_child(menu, false, INTERNAL_MODE_FRONT); + menu->connect("id_pressed", callable_mp(this, &RichTextLabel::menu_option)); + + menu->add_item(RTR("Copy"), MENU_COPY); + menu->add_item(RTR("Select All"), MENU_SELECT_ALL); +} - menu->connect("id_pressed", callable_mp(this, &RichTextLabel::_menu_option)); +void RichTextLabel::_update_context_menu() { + if (!menu) { + _generate_context_menu(); } - // Reorganize context menu. - menu->clear(); - if (selection.enabled) { - menu->add_item(RTR("Copy"), MENU_COPY, is_shortcut_keys_enabled() ? _get_menu_action_accelerator("ui_copy") : Key::NONE); - menu->add_item(RTR("Select All"), MENU_SELECT_ALL, is_shortcut_keys_enabled() ? _get_menu_action_accelerator("ui_text_select_all") : Key::NONE); + int idx = -1; + +#define MENU_ITEM_ACTION_DISABLED(m_menu, m_id, m_action, m_disabled) \ + idx = m_menu->get_item_index(m_id); \ + if (idx >= 0) { \ + m_menu->set_item_accelerator(idx, shortcut_keys_enabled ? _get_menu_action_accelerator(m_action) : Key::NONE); \ + m_menu->set_item_disabled(idx, m_disabled); \ } + + MENU_ITEM_ACTION_DISABLED(menu, MENU_COPY, "ui_copy", !selection.enabled) + MENU_ITEM_ACTION_DISABLED(menu, MENU_SELECT_ALL, "ui_text_select_all", !selection.enabled) + +#undef MENU_ITEM_ACTION_DISABLED } Key RichTextLabel::_get_menu_action_accelerator(const String &p_action) { @@ -5715,7 +5735,7 @@ Key RichTextLabel::_get_menu_action_accelerator(const String &p_action) { } } -void RichTextLabel::_menu_option(int p_option) { +void RichTextLabel::menu_option(int p_option) { switch (p_option) { case MENU_COPY: { selection_copy(); diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h index fcbb91f67e..b01fccf14c 100644 --- a/scene/gui/rich_text_label.h +++ b/scene/gui/rich_text_label.h @@ -81,6 +81,7 @@ public: enum MenuItems { MENU_COPY, MENU_SELECT_ALL, + MENU_MAX }; enum DefaultFont { @@ -454,8 +455,8 @@ private: // Context menu. PopupMenu *menu = nullptr; void _generate_context_menu(); + void _update_context_menu(); Key _get_menu_action_accelerator(const String &p_action); - void _menu_option(int p_option); int visible_characters = -1; float visible_ratio = 1.0; @@ -688,6 +689,7 @@ public: // Context menu. PopupMenu *get_menu() const; bool is_menu_visible() const; + void menu_option(int p_option); void parse_bbcode(const String &p_bbcode); void append_text(const String &p_bbcode); @@ -739,5 +741,6 @@ public: VARIANT_ENUM_CAST(RichTextLabel::ListType); VARIANT_ENUM_CAST(RichTextLabel::ItemType); +VARIANT_ENUM_CAST(RichTextLabel::MenuItems); #endif // RICH_TEXT_LABEL_H -- cgit v1.2.3