summaryrefslogtreecommitdiff
path: root/scene
diff options
context:
space:
mode:
authorJuan Linietsky <reduzio@gmail.com>2021-07-17 12:28:41 -0300
committerGitHub <noreply@github.com>2021-07-17 12:28:41 -0300
commitdeeec8894ad39d7254cf31f46321fb3cd869461f (patch)
tree3ea5917ef09ef5e431783284e3295eb90099a48e /scene
parent7537875d862837d43e50be2cc14de9d8db8f5fe3 (diff)
parenta3fb76cd450661816f2e4f65dc172917b47c11e6 (diff)
Merge pull request #50530 from reduz/create-popups-on-demand
Create many types of popups on demand
Diffstat (limited to 'scene')
-rw-r--r--scene/gui/color_picker.cpp2
-rw-r--r--scene/gui/line_edit.cpp69
-rw-r--r--scene/gui/line_edit.h3
-rw-r--r--scene/gui/spin_box.cpp2
-rw-r--r--scene/gui/text_edit.cpp110
-rw-r--r--scene/gui/text_edit.h9
6 files changed, 125 insertions, 70 deletions
diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp
index 659d14ae70..842cef3b83 100644
--- a/scene/gui/color_picker.cpp
+++ b/scene/gui/color_picker.cpp
@@ -1048,7 +1048,7 @@ void ColorPicker::_focus_exit() {
}
void ColorPicker::_html_focus_exit() {
- if (c_text->get_menu()->is_visible()) {
+ if (c_text->is_menu_visible()) {
return;
}
_html_submitted(c_text->get_text());
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp
index f2d0d9bb22..c862624f98 100644
--- a/scene/gui/line_edit.cpp
+++ b/scene/gui/line_edit.cpp
@@ -227,6 +227,7 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
return;
}
if (b->is_pressed() && b->get_button_index() == MOUSE_BUTTON_RIGHT && context_menu_enabled) {
+ _ensure_menu();
menu->set_position(get_screen_transform().xform(get_local_mouse_position()));
menu->set_size(Vector2(1, 1));
_generate_context_menu();
@@ -348,6 +349,7 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
if (context_menu_enabled) {
if (k->is_action("ui_menu", true)) {
+ _ensure_menu();
Point2 pos = Point2(get_caret_pixel_pos().x, (get_size().y + get_theme_font("font")->get_height(get_theme_font_size("font_size"))) / 2);
menu->set_position(get_global_transform().xform(pos));
menu->set_size(Vector2(1, 1));
@@ -612,7 +614,7 @@ void LineEdit::_notification(int p_what) {
update();
} break;
case NOTIFICATION_DRAW: {
- if ((!has_focus() && !menu->has_focus() && !caret_force_displayed) || !window_has_focus) {
+ if ((!has_focus() && !(menu && menu->has_focus()) && !caret_force_displayed) || !window_has_focus) {
draw_caret = false;
}
@@ -1252,10 +1254,12 @@ void LineEdit::set_text_direction(Control::TextDirection p_text_direction) {
}
_shape();
- menu_dir->set_item_checked(menu_dir->get_item_index(MENU_DIR_INHERITED), text_direction == TEXT_DIRECTION_INHERITED);
- menu_dir->set_item_checked(menu_dir->get_item_index(MENU_DIR_AUTO), text_direction == TEXT_DIRECTION_AUTO);
- menu_dir->set_item_checked(menu_dir->get_item_index(MENU_DIR_LTR), text_direction == TEXT_DIRECTION_LTR);
- menu_dir->set_item_checked(menu_dir->get_item_index(MENU_DIR_RTL), text_direction == TEXT_DIRECTION_RTL);
+ if (menu_dir) {
+ menu_dir->set_item_checked(menu_dir->get_item_index(MENU_DIR_INHERITED), text_direction == TEXT_DIRECTION_INHERITED);
+ menu_dir->set_item_checked(menu_dir->get_item_index(MENU_DIR_AUTO), text_direction == TEXT_DIRECTION_AUTO);
+ menu_dir->set_item_checked(menu_dir->get_item_index(MENU_DIR_LTR), text_direction == TEXT_DIRECTION_LTR);
+ menu_dir->set_item_checked(menu_dir->get_item_index(MENU_DIR_RTL), text_direction == TEXT_DIRECTION_RTL);
+ }
update();
}
}
@@ -1302,7 +1306,9 @@ String LineEdit::get_language() const {
void LineEdit::set_draw_control_chars(bool p_draw_control_chars) {
if (draw_control_chars != p_draw_control_chars) {
draw_control_chars = p_draw_control_chars;
- menu->set_item_checked(menu->get_item_index(MENU_DISPLAY_UCC), draw_control_chars);
+ if (menu && menu->get_item_index(MENU_DISPLAY_UCC) >= 0) {
+ menu->set_item_checked(menu->get_item_index(MENU_DISPLAY_UCC), draw_control_chars);
+ }
_shape();
update();
}
@@ -1810,7 +1816,12 @@ bool LineEdit::is_context_menu_enabled() {
return context_menu_enabled;
}
+bool LineEdit::is_menu_visible() const {
+ return menu && menu->is_visible();
+}
+
PopupMenu *LineEdit::get_menu() const {
+ const_cast<LineEdit *>(this)->_ensure_menu();
return menu;
}
@@ -2009,6 +2020,7 @@ int LineEdit::_get_menu_action_accelerator(const String &p_action) {
void LineEdit::_generate_context_menu() {
// Reorganize context menu.
+ _ensure_menu();
menu->clear();
if (editable) {
menu->add_item(RTR("Cut"), MENU_CUT, is_shortcut_keys_enabled() ? _get_menu_action_accelerator("ui_cut") : 0);
@@ -2148,6 +2160,7 @@ void LineEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_secret_character"), &LineEdit::get_secret_character);
ClassDB::bind_method(D_METHOD("menu_option", "option"), &LineEdit::menu_option);
ClassDB::bind_method(D_METHOD("get_menu"), &LineEdit::get_menu);
+ ClassDB::bind_method(D_METHOD("is_menu_visible"), &LineEdit::is_menu_visible);
ClassDB::bind_method(D_METHOD("set_context_menu_enabled", "enable"), &LineEdit::set_context_menu_enabled);
ClassDB::bind_method(D_METHOD("is_context_menu_enabled"), &LineEdit::is_context_menu_enabled);
ClassDB::bind_method(D_METHOD("set_virtual_keyboard_enabled", "enable"), &LineEdit::set_virtual_keyboard_enabled);
@@ -2230,23 +2243,14 @@ void LineEdit::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "caret_mid_grapheme"), "set_caret_mid_grapheme_enabled", "is_caret_mid_grapheme_enabled");
}
-LineEdit::LineEdit() {
- text_rid = TS->create_shaped_text();
- _create_undo_state();
-
- deselect();
- set_focus_mode(FOCUS_ALL);
- set_default_cursor_shape(CURSOR_IBEAM);
- set_mouse_filter(MOUSE_FILTER_STOP);
-
- caret_blink_timer = memnew(Timer);
- add_child(caret_blink_timer);
- caret_blink_timer->set_wait_time(0.65);
- caret_blink_timer->connect("timeout", callable_mp(this, &LineEdit::_toggle_draw_caret));
- set_caret_blink_enabled(false);
+void LineEdit::_ensure_menu() {
+ if (menu) {
+ return;
+ }
menu = memnew(PopupMenu);
add_child(menu);
+ menu->connect("id_pressed", callable_mp(this, &LineEdit::menu_option));
menu_dir = memnew(PopupMenu);
menu_dir->set_name("DirMenu");
@@ -2279,10 +2283,31 @@ LineEdit::LineEdit() {
menu_ctl->add_item(RTR("Soft hyphen (SHY)"), MENU_INSERT_SHY);
menu->add_child(menu_ctl);
- set_editable(true); // Initialise to opposite first, so we get past the early-out in set_editable.
- menu->connect("id_pressed", callable_mp(this, &LineEdit::menu_option));
menu_dir->connect("id_pressed", callable_mp(this, &LineEdit::menu_option));
menu_ctl->connect("id_pressed", callable_mp(this, &LineEdit::menu_option));
+
+ menu_dir->set_item_checked(menu_dir->get_item_index(MENU_DIR_INHERITED), text_direction == TEXT_DIRECTION_INHERITED);
+ menu_dir->set_item_checked(menu_dir->get_item_index(MENU_DIR_AUTO), text_direction == TEXT_DIRECTION_AUTO);
+ menu_dir->set_item_checked(menu_dir->get_item_index(MENU_DIR_LTR), text_direction == TEXT_DIRECTION_LTR);
+ menu_dir->set_item_checked(menu_dir->get_item_index(MENU_DIR_RTL), text_direction == TEXT_DIRECTION_RTL);
+}
+
+LineEdit::LineEdit() {
+ text_rid = TS->create_shaped_text();
+ _create_undo_state();
+
+ deselect();
+ set_focus_mode(FOCUS_ALL);
+ set_default_cursor_shape(CURSOR_IBEAM);
+ set_mouse_filter(MOUSE_FILTER_STOP);
+
+ caret_blink_timer = memnew(Timer);
+ add_child(caret_blink_timer);
+ caret_blink_timer->set_wait_time(0.65);
+ caret_blink_timer->connect("timeout", callable_mp(this, &LineEdit::_toggle_draw_caret));
+ set_caret_blink_enabled(false);
+
+ set_editable(true); // Initialise to opposite first, so we get past the early-out in set_editable.
}
LineEdit::~LineEdit() {
diff --git a/scene/gui/line_edit.h b/scene/gui/line_edit.h
index 12fec2f98b..16f3356637 100644
--- a/scene/gui/line_edit.h
+++ b/scene/gui/line_edit.h
@@ -198,6 +198,8 @@ private:
void _backspace(bool p_word = false, bool p_all_to_left = false);
void _delete(bool p_word = false, bool p_all_to_right = false);
+ void _ensure_menu();
+
protected:
void _notification(int p_what);
static void _bind_methods();
@@ -222,6 +224,7 @@ public:
void set_context_menu_enabled(bool p_enable);
bool is_context_menu_enabled();
PopupMenu *get_menu() const;
+ bool is_menu_visible() const;
void select(int p_from = 0, int p_to = -1);
void select_all();
diff --git a/scene/gui/spin_box.cpp b/scene/gui/spin_box.cpp
index 941dd30057..5c7b375608 100644
--- a/scene/gui/spin_box.cpp
+++ b/scene/gui/spin_box.cpp
@@ -170,7 +170,7 @@ void SpinBox::_gui_input(const Ref<InputEvent> &p_event) {
void SpinBox::_line_edit_focus_exit() {
// discontinue because the focus_exit was caused by right-click context menu
- if (line_edit->get_menu()->is_visible()) {
+ if (line_edit->is_menu_visible()) {
return;
}
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index 6f96b530a6..9450b39aed 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -599,7 +599,7 @@ void TextEdit::_notification(int p_what) {
Size2 size = get_size();
bool rtl = is_layout_rtl();
- if ((!has_focus() && !menu->has_focus()) || !window_has_focus) {
+ if ((!has_focus() && !(menu && menu->has_focus())) || !window_has_focus) {
draw_caret = false;
}
@@ -2470,6 +2470,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
}
}
+ _ensure_menu();
menu->set_position(get_screen_transform().xform(mpos));
menu->set_size(Vector2(1, 1));
_generate_context_menu();
@@ -2709,6 +2710,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
// MISC.
if (k->is_action("ui_menu", true)) {
if (context_menu_enabled) {
+ _ensure_menu();
menu->set_position(get_screen_transform().xform(_get_cursor_pixel_pos()));
menu->set_size(Vector2(1, 1));
_generate_context_menu();
@@ -3214,6 +3216,7 @@ int TextEdit::_get_menu_action_accelerator(const String &p_action) {
void TextEdit::_generate_context_menu() {
// Reorganize context menu.
+ _ensure_menu();
menu->clear();
if (!readonly) {
menu->add_item(RTR("Cut"), MENU_CUT, is_shortcut_keys_enabled() ? _get_menu_action_accelerator("ui_cut") : 0);
@@ -3858,10 +3861,12 @@ void TextEdit::set_text_direction(Control::TextDirection p_text_direction) {
text.set_direction_and_language(dir, (language != "") ? language : TranslationServer::get_singleton()->get_tool_locale());
text.invalidate_all();
- menu_dir->set_item_checked(menu_dir->get_item_index(MENU_DIR_INHERITED), text_direction == TEXT_DIRECTION_INHERITED);
- menu_dir->set_item_checked(menu_dir->get_item_index(MENU_DIR_AUTO), text_direction == TEXT_DIRECTION_AUTO);
- menu_dir->set_item_checked(menu_dir->get_item_index(MENU_DIR_LTR), text_direction == TEXT_DIRECTION_LTR);
- menu_dir->set_item_checked(menu_dir->get_item_index(MENU_DIR_RTL), text_direction == TEXT_DIRECTION_RTL);
+ if (menu_dir) {
+ menu_dir->set_item_checked(menu_dir->get_item_index(MENU_DIR_INHERITED), text_direction == TEXT_DIRECTION_INHERITED);
+ menu_dir->set_item_checked(menu_dir->get_item_index(MENU_DIR_AUTO), text_direction == TEXT_DIRECTION_AUTO);
+ menu_dir->set_item_checked(menu_dir->get_item_index(MENU_DIR_LTR), text_direction == TEXT_DIRECTION_LTR);
+ menu_dir->set_item_checked(menu_dir->get_item_index(MENU_DIR_RTL), text_direction == TEXT_DIRECTION_RTL);
+ }
update();
}
}
@@ -3917,7 +3922,9 @@ String TextEdit::get_language() const {
void TextEdit::set_draw_control_chars(bool p_draw_control_chars) {
if (draw_control_chars != p_draw_control_chars) {
draw_control_chars = p_draw_control_chars;
- menu->set_item_checked(menu->get_item_index(MENU_DISPLAY_UCC), draw_control_chars);
+ if (menu && menu->get_item_index(MENU_DISPLAY_UCC) >= 0) {
+ menu->set_item_checked(menu->get_item_index(MENU_DISPLAY_UCC), draw_control_chars);
+ }
text.set_draw_control_chars(draw_control_chars);
text.invalidate_all();
update();
@@ -5594,7 +5601,12 @@ bool TextEdit::is_virtual_keyboard_enabled() const {
return virtual_keyboard_enabled;
}
+bool TextEdit::is_menu_visible() const {
+ return menu && menu->is_visible();
+}
+
PopupMenu *TextEdit::get_menu() const {
+ const_cast<TextEdit *>(this)->_ensure_menu();
return menu;
}
@@ -5833,6 +5845,7 @@ void TextEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("menu_option", "option"), &TextEdit::menu_option);
ClassDB::bind_method(D_METHOD("get_menu"), &TextEdit::get_menu);
+ ClassDB::bind_method(D_METHOD("is_menu_visible"), &TextEdit::is_menu_visible);
ClassDB::bind_method(D_METHOD("draw_minimap", "draw"), &TextEdit::set_draw_minimap);
ClassDB::bind_method(D_METHOD("is_drawing_minimap"), &TextEdit::is_drawing_minimap);
@@ -5921,6 +5934,54 @@ void TextEdit::_bind_methods() {
ProjectSettings::get_singleton()->set_custom_property_info("gui/common/text_edit_undo_stack_max_size", PropertyInfo(Variant::INT, "gui/common/text_edit_undo_stack_max_size", PROPERTY_HINT_RANGE, "0,10000,1,or_greater")); // No negative numbers.
}
+void TextEdit::_ensure_menu() {
+ if (menu) {
+ return;
+ }
+
+ menu = memnew(PopupMenu);
+ add_child(menu);
+
+ menu_dir = memnew(PopupMenu);
+ menu_dir->set_name("DirMenu");
+ menu_dir->add_radio_check_item(RTR("Same as layout direction"), MENU_DIR_INHERITED);
+ menu_dir->add_radio_check_item(RTR("Auto-detect direction"), MENU_DIR_AUTO);
+ menu_dir->add_radio_check_item(RTR("Left-to-right"), MENU_DIR_LTR);
+ menu_dir->add_radio_check_item(RTR("Right-to-left"), MENU_DIR_RTL);
+ menu->add_child(menu_dir);
+
+ menu_ctl = memnew(PopupMenu);
+ menu_ctl->set_name("CTLMenu");
+ menu_ctl->add_item(RTR("Left-to-right mark (LRM)"), MENU_INSERT_LRM);
+ menu_ctl->add_item(RTR("Right-to-left mark (RLM)"), MENU_INSERT_RLM);
+ menu_ctl->add_item(RTR("Start of left-to-right embedding (LRE)"), MENU_INSERT_LRE);
+ menu_ctl->add_item(RTR("Start of right-to-left embedding (RLE)"), MENU_INSERT_RLE);
+ menu_ctl->add_item(RTR("Start of left-to-right override (LRO)"), MENU_INSERT_LRO);
+ menu_ctl->add_item(RTR("Start of right-to-left override (RLO)"), MENU_INSERT_RLO);
+ menu_ctl->add_item(RTR("Pop direction formatting (PDF)"), MENU_INSERT_PDF);
+ menu_ctl->add_separator();
+ menu_ctl->add_item(RTR("Arabic letter mark (ALM)"), MENU_INSERT_ALM);
+ menu_ctl->add_item(RTR("Left-to-right isolate (LRI)"), MENU_INSERT_LRI);
+ menu_ctl->add_item(RTR("Right-to-left isolate (RLI)"), MENU_INSERT_RLI);
+ menu_ctl->add_item(RTR("First strong isolate (FSI)"), MENU_INSERT_FSI);
+ menu_ctl->add_item(RTR("Pop direction isolate (PDI)"), MENU_INSERT_PDI);
+ menu_ctl->add_separator();
+ menu_ctl->add_item(RTR("Zero width joiner (ZWJ)"), MENU_INSERT_ZWJ);
+ menu_ctl->add_item(RTR("Zero width non-joiner (ZWNJ)"), MENU_INSERT_ZWNJ);
+ menu_ctl->add_item(RTR("Word joiner (WJ)"), MENU_INSERT_WJ);
+ menu_ctl->add_item(RTR("Soft hyphen (SHY)"), MENU_INSERT_SHY);
+ menu->add_child(menu_ctl);
+
+ menu->connect("id_pressed", callable_mp(this, &TextEdit::menu_option));
+ menu_dir->connect("id_pressed", callable_mp(this, &TextEdit::menu_option));
+ menu_ctl->connect("id_pressed", callable_mp(this, &TextEdit::menu_option));
+
+ menu_dir->set_item_checked(menu_dir->get_item_index(MENU_DIR_INHERITED), text_direction == TEXT_DIRECTION_INHERITED);
+ menu_dir->set_item_checked(menu_dir->get_item_index(MENU_DIR_AUTO), text_direction == TEXT_DIRECTION_AUTO);
+ menu_dir->set_item_checked(menu_dir->get_item_index(MENU_DIR_LTR), text_direction == TEXT_DIRECTION_LTR);
+ menu_dir->set_item_checked(menu_dir->get_item_index(MENU_DIR_RTL), text_direction == TEXT_DIRECTION_RTL);
+}
+
TextEdit::TextEdit() {
clear();
set_focus_mode(FOCUS_ALL);
@@ -5960,44 +6021,7 @@ TextEdit::TextEdit() {
undo_stack_max_size = GLOBAL_GET("gui/common/text_edit_undo_stack_max_size");
- menu = memnew(PopupMenu);
- add_child(menu);
-
- menu_dir = memnew(PopupMenu);
- menu_dir->set_name("DirMenu");
- menu_dir->add_radio_check_item(RTR("Same as layout direction"), MENU_DIR_INHERITED);
- menu_dir->add_radio_check_item(RTR("Auto-detect direction"), MENU_DIR_AUTO);
- menu_dir->add_radio_check_item(RTR("Left-to-right"), MENU_DIR_LTR);
- menu_dir->add_radio_check_item(RTR("Right-to-left"), MENU_DIR_RTL);
- menu_dir->set_item_checked(menu_dir->get_item_index(MENU_DIR_INHERITED), true);
- menu->add_child(menu_dir);
-
- menu_ctl = memnew(PopupMenu);
- menu_ctl->set_name("CTLMenu");
- menu_ctl->add_item(RTR("Left-to-right mark (LRM)"), MENU_INSERT_LRM);
- menu_ctl->add_item(RTR("Right-to-left mark (RLM)"), MENU_INSERT_RLM);
- menu_ctl->add_item(RTR("Start of left-to-right embedding (LRE)"), MENU_INSERT_LRE);
- menu_ctl->add_item(RTR("Start of right-to-left embedding (RLE)"), MENU_INSERT_RLE);
- menu_ctl->add_item(RTR("Start of left-to-right override (LRO)"), MENU_INSERT_LRO);
- menu_ctl->add_item(RTR("Start of right-to-left override (RLO)"), MENU_INSERT_RLO);
- menu_ctl->add_item(RTR("Pop direction formatting (PDF)"), MENU_INSERT_PDF);
- menu_ctl->add_separator();
- menu_ctl->add_item(RTR("Arabic letter mark (ALM)"), MENU_INSERT_ALM);
- menu_ctl->add_item(RTR("Left-to-right isolate (LRI)"), MENU_INSERT_LRI);
- menu_ctl->add_item(RTR("Right-to-left isolate (RLI)"), MENU_INSERT_RLI);
- menu_ctl->add_item(RTR("First strong isolate (FSI)"), MENU_INSERT_FSI);
- menu_ctl->add_item(RTR("Pop direction isolate (PDI)"), MENU_INSERT_PDI);
- menu_ctl->add_separator();
- menu_ctl->add_item(RTR("Zero width joiner (ZWJ)"), MENU_INSERT_ZWJ);
- menu_ctl->add_item(RTR("Zero width non-joiner (ZWNJ)"), MENU_INSERT_ZWNJ);
- menu_ctl->add_item(RTR("Word joiner (WJ)"), MENU_INSERT_WJ);
- menu_ctl->add_item(RTR("Soft hyphen (SHY)"), MENU_INSERT_SHY);
- menu->add_child(menu_ctl);
-
set_readonly(false);
- menu->connect("id_pressed", callable_mp(this, &TextEdit::menu_option));
- menu_dir->connect("id_pressed", callable_mp(this, &TextEdit::menu_option));
- menu_ctl->connect("id_pressed", callable_mp(this, &TextEdit::menu_option));
}
TextEdit::~TextEdit() {
diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h
index dcd5c6d0f8..7863499878 100644
--- a/scene/gui/text_edit.h
+++ b/scene/gui/text_edit.h
@@ -410,9 +410,11 @@ private:
Dictionary _search_bind(const String &p_key, uint32_t p_search_flags, int p_from_line, int p_from_column) const;
- PopupMenu *menu;
- PopupMenu *menu_dir;
- PopupMenu *menu_ctl;
+ PopupMenu *menu = nullptr;
+ PopupMenu *menu_dir = nullptr;
+ PopupMenu *menu_ctl = nullptr;
+
+ void _ensure_menu();
void _clear();
@@ -781,6 +783,7 @@ public:
void set_virtual_keyboard_enabled(bool p_enable);
bool is_virtual_keyboard_enabled() const;
+ bool is_menu_visible() const;
PopupMenu *get_menu() const;
String get_text_for_lookup_completion();