mirror of
https://github.com/godotengine/godot.git
synced 2025-01-23 19:12:24 -05:00
Create many types of popups on demand
* LineEdit popups created on demand. * TextEdit popups created on demand. * SpinSlider popups created on demand. * ResourcePicker popups created on demand. Improves editor responsiveness.
This commit is contained in:
parent
de83ee57e5
commit
a3fb76cd45
12 changed files with 208 additions and 108 deletions
|
@ -102,6 +102,13 @@
|
|||
Inserts [code]text[/code] at the caret. If the resulting value is longer than [member max_length], nothing happens.
|
||||
</description>
|
||||
</method>
|
||||
<method name="is_menu_visible" qualifiers="const">
|
||||
<return type="bool">
|
||||
</return>
|
||||
<description>
|
||||
Returns whether the menu is visible. Use this instead of [code]get_menu().visible[/code] to improve performance (so the creation of the menu is avoided).
|
||||
</description>
|
||||
</method>
|
||||
<method name="menu_option">
|
||||
<return type="void">
|
||||
</return>
|
||||
|
|
|
@ -382,6 +382,13 @@
|
|||
<description>
|
||||
</description>
|
||||
</method>
|
||||
<method name="is_menu_visible" qualifiers="const">
|
||||
<return type="bool">
|
||||
</return>
|
||||
<description>
|
||||
Returns whether the menu is visible. Use this instead of [code]get_menu().visible[/code] to improve performance (so the creation of the menu is avoided).
|
||||
</description>
|
||||
</method>
|
||||
<method name="is_selection_active" qualifiers="const">
|
||||
<return type="bool">
|
||||
</return>
|
||||
|
|
|
@ -141,6 +141,7 @@ void EditorResourcePicker::_update_menu() {
|
|||
}
|
||||
|
||||
void EditorResourcePicker::_update_menu_items() {
|
||||
_ensure_resource_menu();
|
||||
edit_menu->clear();
|
||||
|
||||
// Add options for creating specific subtypes of the base resource type.
|
||||
|
@ -360,6 +361,7 @@ void EditorResourcePicker::_edit_menu_cbk(int p_which) {
|
|||
}
|
||||
|
||||
void EditorResourcePicker::set_create_options(Object *p_menu_node) {
|
||||
_ensure_resource_menu();
|
||||
// If a subclass implements this method, use it to replace all create items.
|
||||
if (get_script_instance() && get_script_instance()->has_method("_set_create_options")) {
|
||||
get_script_instance()->call("_set_create_options", p_menu_node);
|
||||
|
@ -783,6 +785,15 @@ bool EditorResourcePicker::is_editable() const {
|
|||
return editable;
|
||||
}
|
||||
|
||||
void EditorResourcePicker::_ensure_resource_menu() {
|
||||
if (edit_menu) {
|
||||
return;
|
||||
}
|
||||
edit_menu = memnew(PopupMenu);
|
||||
add_child(edit_menu);
|
||||
edit_menu->connect("id_pressed", callable_mp(this, &EditorResourcePicker::_edit_menu_cbk));
|
||||
edit_menu->connect("popup_hide", callable_mp((BaseButton *)edit_button, &BaseButton::set_pressed), varray(false));
|
||||
}
|
||||
EditorResourcePicker::EditorResourcePicker() {
|
||||
assign_button = memnew(Button);
|
||||
assign_button->set_flat(true);
|
||||
|
@ -808,10 +819,6 @@ EditorResourcePicker::EditorResourcePicker() {
|
|||
edit_button->connect("pressed", callable_mp(this, &EditorResourcePicker::_update_menu));
|
||||
add_child(edit_button);
|
||||
edit_button->connect("gui_input", callable_mp(this, &EditorResourcePicker::_button_input));
|
||||
edit_menu = memnew(PopupMenu);
|
||||
add_child(edit_menu);
|
||||
edit_menu->connect("id_pressed", callable_mp(this, &EditorResourcePicker::_edit_menu_cbk));
|
||||
edit_menu->connect("popup_hide", callable_mp((BaseButton *)edit_button, &BaseButton::set_pressed), varray(false));
|
||||
}
|
||||
|
||||
void EditorScriptPicker::set_create_options(Object *p_menu_node) {
|
||||
|
|
|
@ -67,7 +67,7 @@ class EditorResourcePicker : public HBoxContainer {
|
|||
CONVERT_BASE_ID = 1000,
|
||||
};
|
||||
|
||||
PopupMenu *edit_menu;
|
||||
PopupMenu *edit_menu = nullptr;
|
||||
|
||||
void _update_resource();
|
||||
void _update_resource_preview(const String &p_path, const Ref<Texture2D> &p_preview, const Ref<Texture2D> &p_small_preview, ObjectID p_obj);
|
||||
|
@ -90,6 +90,8 @@ class EditorResourcePicker : public HBoxContainer {
|
|||
bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from) const;
|
||||
void drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_from);
|
||||
|
||||
void _ensure_resource_menu();
|
||||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
void _notification(int p_what);
|
||||
|
|
|
@ -185,6 +185,27 @@ void EditorSpinSlider::_grabber_gui_input(const Ref<InputEvent> &p_event) {
|
|||
}
|
||||
}
|
||||
|
||||
void EditorSpinSlider::_update_value_input_stylebox() {
|
||||
if (!value_input) {
|
||||
return;
|
||||
}
|
||||
// Add a left margin to the stylebox to make the number align with the Label
|
||||
// when it's edited. The LineEdit "focus" stylebox uses the "normal" stylebox's
|
||||
// default margins.
|
||||
Ref<StyleBoxFlat> stylebox =
|
||||
EditorNode::get_singleton()->get_theme_base()->get_theme_stylebox("normal", "LineEdit")->duplicate();
|
||||
// EditorSpinSliders with a label have more space on the left, so add an
|
||||
// higher margin to match the location where the text begins.
|
||||
// The margin values below were determined by empirical testing.
|
||||
if (is_layout_rtl()) {
|
||||
stylebox->set_default_margin(SIDE_LEFT, 0);
|
||||
stylebox->set_default_margin(SIDE_RIGHT, (get_label() != String() ? 23 : 16) * EDSCALE);
|
||||
} else {
|
||||
stylebox->set_default_margin(SIDE_LEFT, (get_label() != String() ? 23 : 16) * EDSCALE);
|
||||
stylebox->set_default_margin(SIDE_RIGHT, 0);
|
||||
}
|
||||
value_input->add_theme_style_override("normal", stylebox);
|
||||
}
|
||||
void EditorSpinSlider::_notification(int p_what) {
|
||||
if (p_what == NOTIFICATION_WM_WINDOW_FOCUS_OUT ||
|
||||
p_what == NOTIFICATION_WM_WINDOW_FOCUS_IN ||
|
||||
|
@ -197,23 +218,8 @@ void EditorSpinSlider::_notification(int p_what) {
|
|||
}
|
||||
}
|
||||
|
||||
if (p_what == NOTIFICATION_READY) {
|
||||
// Add a left margin to the stylebox to make the number align with the Label
|
||||
// when it's edited. The LineEdit "focus" stylebox uses the "normal" stylebox's
|
||||
// default margins.
|
||||
Ref<StyleBoxFlat> stylebox =
|
||||
EditorNode::get_singleton()->get_theme_base()->get_theme_stylebox("normal", "LineEdit")->duplicate();
|
||||
// EditorSpinSliders with a label have more space on the left, so add an
|
||||
// higher margin to match the location where the text begins.
|
||||
// The margin values below were determined by empirical testing.
|
||||
if (is_layout_rtl()) {
|
||||
stylebox->set_default_margin(SIDE_LEFT, 0);
|
||||
stylebox->set_default_margin(SIDE_RIGHT, (get_label() != String() ? 23 : 16) * EDSCALE);
|
||||
} else {
|
||||
stylebox->set_default_margin(SIDE_LEFT, (get_label() != String() ? 23 : 16) * EDSCALE);
|
||||
stylebox->set_default_margin(SIDE_RIGHT, 0);
|
||||
}
|
||||
value_input->add_theme_style_override("normal", stylebox);
|
||||
if (p_what == NOTIFICATION_READY || p_what == NOTIFICATION_THEME_CHANGED) {
|
||||
_update_value_input_stylebox();
|
||||
}
|
||||
|
||||
if (p_what == NOTIFICATION_DRAW) {
|
||||
|
@ -332,7 +338,7 @@ void EditorSpinSlider::_notification(int p_what) {
|
|||
|
||||
grabbing_spinner_mouse_pos = get_global_position() + grabber_rect.position + grabber_rect.size * 0.5;
|
||||
|
||||
bool display_grabber = (mouse_over_spin || mouse_over_grabber) && !grabbing_spinner && !value_input_popup->is_visible();
|
||||
bool display_grabber = (mouse_over_spin || mouse_over_grabber) && !grabbing_spinner && !(value_input_popup && value_input_popup->is_visible());
|
||||
if (grabber->is_visible() != display_grabber) {
|
||||
if (display_grabber) {
|
||||
grabber->show();
|
||||
|
@ -445,7 +451,9 @@ void EditorSpinSlider::_evaluate_input_text() {
|
|||
//text_submitted signal
|
||||
void EditorSpinSlider::_value_input_submitted(const String &p_text) {
|
||||
value_input_just_closed = true;
|
||||
value_input_popup->hide();
|
||||
if (value_input_popup) {
|
||||
value_input_popup->hide();
|
||||
}
|
||||
}
|
||||
|
||||
//modal_closed signal
|
||||
|
@ -457,7 +465,7 @@ void EditorSpinSlider::_value_input_closed() {
|
|||
//focus_exited signal
|
||||
void EditorSpinSlider::_value_focus_exited() {
|
||||
// discontinue because the focus_exit was caused by right-click context menu
|
||||
if (value_input->get_menu()->is_visible()) {
|
||||
if (value_input->is_menu_visible()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -468,7 +476,9 @@ void EditorSpinSlider::_value_focus_exited() {
|
|||
// -> modal_close was not called
|
||||
// -> need to close/hide manually
|
||||
if (!value_input_just_closed) { //value_input_just_closed should do the same
|
||||
value_input_popup->hide();
|
||||
if (value_input_popup) {
|
||||
value_input_popup->hide();
|
||||
}
|
||||
//tab was pressed
|
||||
} else {
|
||||
//enter, click, esc
|
||||
|
@ -509,6 +519,7 @@ void EditorSpinSlider::set_custom_label_color(bool p_use_custom_label_color, Col
|
|||
}
|
||||
|
||||
void EditorSpinSlider::_focus_entered() {
|
||||
_ensure_input_popup();
|
||||
Rect2 gr = get_screen_rect();
|
||||
value_input->set_text(get_text_value());
|
||||
value_input_popup->set_position(gr.position);
|
||||
|
@ -541,6 +552,23 @@ void EditorSpinSlider::_bind_methods() {
|
|||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flat"), "set_flat", "is_flat");
|
||||
}
|
||||
|
||||
void EditorSpinSlider::_ensure_input_popup() {
|
||||
if (value_input_popup) {
|
||||
return;
|
||||
}
|
||||
value_input_popup = memnew(Popup);
|
||||
add_child(value_input_popup);
|
||||
value_input = memnew(LineEdit);
|
||||
value_input_popup->add_child(value_input);
|
||||
value_input_popup->set_wrap_controls(true);
|
||||
value_input->set_anchors_and_offsets_preset(PRESET_WIDE);
|
||||
value_input_popup->connect("popup_hide", callable_mp(this, &EditorSpinSlider::_value_input_closed));
|
||||
value_input->connect("text_submitted", callable_mp(this, &EditorSpinSlider::_value_input_submitted));
|
||||
value_input->connect("focus_exited", callable_mp(this, &EditorSpinSlider::_value_focus_exited));
|
||||
if (is_inside_tree()) {
|
||||
_update_value_input_stylebox();
|
||||
}
|
||||
}
|
||||
EditorSpinSlider::EditorSpinSlider() {
|
||||
flat = false;
|
||||
grabbing_spinner_attempt = false;
|
||||
|
@ -563,15 +591,6 @@ EditorSpinSlider::EditorSpinSlider() {
|
|||
mousewheel_over_grabber = false;
|
||||
grabbing_grabber = false;
|
||||
grabber_range = 1;
|
||||
value_input_popup = memnew(Popup);
|
||||
add_child(value_input_popup);
|
||||
value_input = memnew(LineEdit);
|
||||
value_input_popup->add_child(value_input);
|
||||
value_input_popup->set_wrap_controls(true);
|
||||
value_input->set_anchors_and_offsets_preset(PRESET_WIDE);
|
||||
value_input_popup->connect("popup_hide", callable_mp(this, &EditorSpinSlider::_value_input_closed));
|
||||
value_input->connect("text_submitted", callable_mp(this, &EditorSpinSlider::_value_input_submitted));
|
||||
value_input->connect("focus_exited", callable_mp(this, &EditorSpinSlider::_value_focus_exited));
|
||||
value_input_just_closed = false;
|
||||
hide_slider = false;
|
||||
read_only = false;
|
||||
|
|
|
@ -63,9 +63,9 @@ class EditorSpinSlider : public Range {
|
|||
Vector2 grabbing_spinner_mouse_pos;
|
||||
double pre_grab_value;
|
||||
|
||||
Popup *value_input_popup;
|
||||
LineEdit *value_input;
|
||||
bool value_input_just_closed;
|
||||
Popup *value_input_popup = nullptr;
|
||||
LineEdit *value_input = nullptr;
|
||||
bool value_input_just_closed = false;
|
||||
|
||||
void _grabber_gui_input(const Ref<InputEvent> &p_event);
|
||||
void _value_input_closed();
|
||||
|
@ -79,6 +79,9 @@ class EditorSpinSlider : public Range {
|
|||
|
||||
void _evaluate_input_text();
|
||||
|
||||
void _update_value_input_stylebox();
|
||||
void _ensure_input_popup();
|
||||
|
||||
protected:
|
||||
void _notification(int p_what);
|
||||
void _gui_input(const Ref<InputEvent> &p_event);
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Add table
Reference in a new issue