diff options
author | Haoyu Qiu <timothyqiu32@gmail.com> | 2022-10-16 20:37:35 +0800 |
---|---|---|
committer | Haoyu Qiu <timothyqiu32@gmail.com> | 2022-10-29 09:58:42 +0800 |
commit | 3aed3edc0677c59ebd96175410d9cc1f5427c053 (patch) | |
tree | 3110dbcf3d4e140d5d9f640f10deaa8a1c63bcd3 | |
parent | 11e1bac768349ae821647a582282458e83b8d72b (diff) |
Allow selecting SpinBox & LineEdit text when focus enters
-rw-r--r-- | doc/classes/LineEdit.xml | 3 | ||||
-rw-r--r-- | doc/classes/SpinBox.xml | 3 | ||||
-rw-r--r-- | editor/plugins/canvas_item_editor_plugin.cpp | 8 | ||||
-rw-r--r-- | editor/plugins/node_3d_editor_plugin.cpp | 9 | ||||
-rw-r--r-- | scene/gui/color_picker.cpp | 41 | ||||
-rw-r--r-- | scene/gui/color_picker.h | 2 | ||||
-rw-r--r-- | scene/gui/line_edit.cpp | 29 | ||||
-rw-r--r-- | scene/gui/line_edit.h | 7 | ||||
-rw-r--r-- | scene/gui/spin_box.cpp | 17 | ||||
-rw-r--r-- | scene/gui/spin_box.h | 3 |
10 files changed, 81 insertions, 41 deletions
diff --git a/doc/classes/LineEdit.xml b/doc/classes/LineEdit.xml index 14fb864ca8..e57cc68b36 100644 --- a/doc/classes/LineEdit.xml +++ b/doc/classes/LineEdit.xml @@ -224,6 +224,9 @@ <member name="secret_character" type="String" setter="set_secret_character" getter="get_secret_character" default=""•""> The character to use to mask secret input (defaults to "•"). Only a single character can be used as the secret character. </member> + <member name="select_all_on_focus" type="bool" setter="set_select_all_on_focus" getter="is_select_all_on_focus" default="false"> + If [code]true[/code], the [LineEdit] will select the whole text when it gains focus. + </member> <member name="selecting_enabled" type="bool" setter="set_selecting_enabled" getter="is_selecting_enabled" default="true"> If [code]false[/code], it's impossible to select the text using mouse nor keyboard. </member> diff --git a/doc/classes/SpinBox.xml b/doc/classes/SpinBox.xml index 8df039794a..93799b58f0 100644 --- a/doc/classes/SpinBox.xml +++ b/doc/classes/SpinBox.xml @@ -56,6 +56,9 @@ <member name="prefix" type="String" setter="set_prefix" getter="get_prefix" default=""""> Adds the specified [code]prefix[/code] string before the numerical value of the [SpinBox]. </member> + <member name="select_all_on_focus" type="bool" setter="set_select_all_on_focus" getter="is_select_all_on_focus" default="false"> + If [code]true[/code], the [SpinBox] will select the whole text when the [LineEdit] gains focus. Clicking the up and down arrows won't trigger this behavior. + </member> <member name="suffix" type="String" setter="set_suffix" getter="get_suffix" default=""""> Adds the specified [code]suffix[/code] string after the numerical value of the [SpinBox]. </member> diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp index fe33a91a41..e3fee1f2f2 100644 --- a/editor/plugins/canvas_item_editor_plugin.cpp +++ b/editor/plugins/canvas_item_editor_plugin.cpp @@ -116,6 +116,7 @@ public: grid_offset_x->set_allow_greater(true); grid_offset_x->set_suffix("px"); grid_offset_x->set_h_size_flags(Control::SIZE_EXPAND_FILL); + grid_offset_x->set_select_all_on_focus(true); child_container->add_child(grid_offset_x); grid_offset_y = memnew(SpinBox); @@ -125,6 +126,7 @@ public: grid_offset_y->set_allow_greater(true); grid_offset_y->set_suffix("px"); grid_offset_y->set_h_size_flags(Control::SIZE_EXPAND_FILL); + grid_offset_y->set_select_all_on_focus(true); child_container->add_child(grid_offset_y); label = memnew(Label); @@ -138,6 +140,7 @@ public: grid_step_x->set_allow_greater(true); grid_step_x->set_suffix("px"); grid_step_x->set_h_size_flags(Control::SIZE_EXPAND_FILL); + grid_step_x->set_select_all_on_focus(true); child_container->add_child(grid_step_x); grid_step_y = memnew(SpinBox); @@ -146,6 +149,7 @@ public: grid_step_y->set_allow_greater(true); grid_step_y->set_suffix("px"); grid_step_y->set_h_size_flags(Control::SIZE_EXPAND_FILL); + grid_step_y->set_select_all_on_focus(true); child_container->add_child(grid_step_y); child_container = memnew(GridContainer); @@ -164,6 +168,7 @@ public: primary_grid_steps->set_allow_greater(true); primary_grid_steps->set_suffix(TTR("steps")); primary_grid_steps->set_h_size_flags(Control::SIZE_EXPAND_FILL); + primary_grid_steps->set_select_all_on_focus(true); child_container->add_child(primary_grid_steps); container->add_child(memnew(HSeparator)); @@ -184,6 +189,7 @@ public: rotation_offset->set_max(SPIN_BOX_ROTATION_RANGE); rotation_offset->set_suffix("deg"); rotation_offset->set_h_size_flags(Control::SIZE_EXPAND_FILL); + rotation_offset->set_select_all_on_focus(true); child_container->add_child(rotation_offset); label = memnew(Label); @@ -196,6 +202,7 @@ public: rotation_step->set_max(SPIN_BOX_ROTATION_RANGE); rotation_step->set_suffix("deg"); rotation_step->set_h_size_flags(Control::SIZE_EXPAND_FILL); + rotation_step->set_select_all_on_focus(true); child_container->add_child(rotation_step); container->add_child(memnew(HSeparator)); @@ -214,6 +221,7 @@ public: scale_step->set_allow_greater(true); scale_step->set_h_size_flags(Control::SIZE_EXPAND_FILL); scale_step->set_step(0.01f); + scale_step->set_select_all_on_focus(true); child_container->add_child(scale_step); } diff --git a/editor/plugins/node_3d_editor_plugin.cpp b/editor/plugins/node_3d_editor_plugin.cpp index 3c9d93f13a..b61cacde9f 100644 --- a/editor/plugins/node_3d_editor_plugin.cpp +++ b/editor/plugins/node_3d_editor_plugin.cpp @@ -8046,12 +8046,15 @@ Node3DEditor::Node3DEditor() { snap_dialog->add_child(snap_dialog_vbc); snap_translate = memnew(LineEdit); + snap_translate->set_select_all_on_focus(true); snap_dialog_vbc->add_margin_child(TTR("Translate Snap:"), snap_translate); snap_rotate = memnew(LineEdit); + snap_rotate->set_select_all_on_focus(true); snap_dialog_vbc->add_margin_child(TTR("Rotate Snap (deg.):"), snap_rotate); snap_scale = memnew(LineEdit); + snap_scale->set_select_all_on_focus(true); snap_dialog_vbc->add_margin_child(TTR("Scale Snap (%):"), snap_scale); _snap_update(); @@ -8070,6 +8073,7 @@ Node3DEditor::Node3DEditor() { settings_fov->set_min(MIN_FOV); settings_fov->set_step(0.1); settings_fov->set_value(EDITOR_GET("editors/3d/default_fov")); + settings_fov->set_select_all_on_focus(true); settings_vbc->add_margin_child(TTR("Perspective FOV (deg.):"), settings_fov); settings_znear = memnew(SpinBox); @@ -8077,6 +8081,7 @@ Node3DEditor::Node3DEditor() { settings_znear->set_min(MIN_Z); settings_znear->set_step(0.01); settings_znear->set_value(EDITOR_GET("editors/3d/default_z_near")); + settings_znear->set_select_all_on_focus(true); settings_vbc->add_margin_child(TTR("View Z-Near:"), settings_znear); settings_zfar = memnew(SpinBox); @@ -8084,6 +8089,7 @@ Node3DEditor::Node3DEditor() { settings_zfar->set_min(MIN_Z); settings_zfar->set_step(0.1); settings_zfar->set_value(EDITOR_GET("editors/3d/default_z_far")); + settings_zfar->set_select_all_on_focus(true); settings_vbc->add_margin_child(TTR("View Z-Far:"), settings_zfar); for (uint32_t i = 0; i < VIEWPORTS_COUNT; ++i) { @@ -8109,6 +8115,7 @@ Node3DEditor::Node3DEditor() { for (int i = 0; i < 3; i++) { xform_translate[i] = memnew(LineEdit); xform_translate[i]->set_h_size_flags(SIZE_EXPAND_FILL); + xform_translate[i]->set_select_all_on_focus(true); xform_hbc->add_child(xform_translate[i]); } @@ -8122,6 +8129,7 @@ Node3DEditor::Node3DEditor() { for (int i = 0; i < 3; i++) { xform_rotate[i] = memnew(LineEdit); xform_rotate[i]->set_h_size_flags(SIZE_EXPAND_FILL); + xform_rotate[i]->set_select_all_on_focus(true); xform_hbc->add_child(xform_rotate[i]); } @@ -8135,6 +8143,7 @@ Node3DEditor::Node3DEditor() { for (int i = 0; i < 3; i++) { xform_scale[i] = memnew(LineEdit); xform_scale[i]->set_h_size_flags(SIZE_EXPAND_FILL); + xform_scale[i]->set_select_all_on_focus(true); xform_hbc->add_child(xform_scale[i]); } diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp index 929bf27be6..23e88a71d6 100644 --- a/scene/gui/color_picker.cpp +++ b/scene/gui/color_picker.cpp @@ -368,11 +368,10 @@ void ColorPicker::create_slider(GridContainer *gc, int idx) { SpinBox *val = memnew(SpinBox); slider->share(val); + val->set_select_all_on_focus(true); gc->add_child(val); LineEdit *vle = val->get_line_edit(); - vle->connect("focus_entered", callable_mp(this, &ColorPicker::_focus_enter), CONNECT_DEFERRED); - vle->connect("focus_exited", callable_mp(this, &ColorPicker::_focus_exit)); vle->connect("text_changed", callable_mp(this, &ColorPicker::_text_changed)); vle->connect("gui_input", callable_mp(this, &ColorPicker::_line_edit_input)); vle->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_RIGHT); @@ -1407,47 +1406,11 @@ void ColorPicker::_screen_pick_pressed() { //screen->show_modal(); } -void ColorPicker::_focus_enter() { - bool has_ctext_focus = c_text->has_focus(); - if (has_ctext_focus) { - c_text->select_all(); - } else { - c_text->select(0, 0); - } - - for (int i = 0; i < current_slider_count; i++) { - if (values[i]->get_line_edit()->has_focus() && !has_ctext_focus) { - values[i]->get_line_edit()->select_all(); - } else { - values[i]->get_line_edit()->select(0, 0); - } - } - if (alpha_value->get_line_edit()->has_focus() && !has_ctext_focus) { - alpha_value->get_line_edit()->select_all(); - } else { - alpha_value->get_line_edit()->select(0, 0); - } -} - -void ColorPicker::_focus_exit() { - for (int i = 0; i < current_slider_count; i++) { - if (!values[i]->get_line_edit()->get_menu()->is_visible()) { - values[i]->get_line_edit()->select(0, 0); - } - } - if (!alpha_value->get_line_edit()->get_menu()->is_visible()) { - alpha_value->get_line_edit()->select(0, 0); - } - - c_text->select(0, 0); -} - void ColorPicker::_html_focus_exit() { if (c_text->is_menu_visible()) { return; } _html_submitted(c_text->get_text()); - _focus_exit(); } void ColorPicker::set_presets_enabled(bool p_enabled) { @@ -1658,9 +1621,9 @@ ColorPicker::ColorPicker() : c_text = memnew(LineEdit); hhb->add_child(c_text); + c_text->set_select_all_on_focus(true); c_text->connect("text_submitted", callable_mp(this, &ColorPicker::_html_submitted)); c_text->connect("text_changed", callable_mp(this, &ColorPicker::_text_changed)); - c_text->connect("focus_entered", callable_mp(this, &ColorPicker::_focus_enter), CONNECT_DEFERRED); c_text->connect("focus_exited", callable_mp(this, &ColorPicker::_html_focus_exit)); wheel_edit = memnew(AspectRatioContainer); diff --git a/scene/gui/color_picker.h b/scene/gui/color_picker.h index 6c91575893..a0843d6fa2 100644 --- a/scene/gui/color_picker.h +++ b/scene/gui/color_picker.h @@ -202,8 +202,6 @@ private: void _text_changed(const String &p_new_text); void _add_preset_pressed(); void _screen_pick_pressed(); - void _focus_enter(); - void _focus_exit(); void _html_focus_exit(); inline int _get_preset_size(); diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index 65670b7786..fb5ab9f923 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -372,6 +372,11 @@ void LineEdit::gui_input(const Ref<InputEvent> &p_event) { selection.drag_attempt = false; } + if (pending_select_all_on_focus) { + select_all(); + pending_select_all_on_focus = false; + } + show_virtual_keyboard(); } @@ -1056,6 +1061,15 @@ void LineEdit::_notification(int p_what) { } } + if (select_all_on_focus) { + if (Input::get_singleton()->is_mouse_button_pressed(MouseButton::LEFT)) { + // Select all when the mouse button is up. + pending_select_all_on_focus = true; + } else { + select_all(); + } + } + if (get_viewport()->get_window_id() != DisplayServer::INVALID_WINDOW_ID && DisplayServer::get_singleton()->has_feature(DisplayServer::FEATURE_IME)) { DisplayServer::get_singleton()->window_set_ime_active(true, get_viewport()->get_window_id()); Point2 column = Point2(get_caret_column(), 1) * get_minimum_size().height; @@ -2164,6 +2178,18 @@ bool LineEdit::is_flat() const { return flat; } +void LineEdit::set_select_all_on_focus(bool p_enabled) { + select_all_on_focus = p_enabled; +} + +bool LineEdit::is_select_all_on_focus() const { + return select_all_on_focus; +} + +void LineEdit::clear_pending_select_all_on_focus() { + pending_select_all_on_focus = false; +} + void LineEdit::_text_changed() { _emit_text_change(); _clear_redo(); @@ -2367,6 +2393,8 @@ void LineEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("get_right_icon"), &LineEdit::get_right_icon); ClassDB::bind_method(D_METHOD("set_flat", "enabled"), &LineEdit::set_flat); ClassDB::bind_method(D_METHOD("is_flat"), &LineEdit::is_flat); + ClassDB::bind_method(D_METHOD("set_select_all_on_focus", "enabled"), &LineEdit::set_select_all_on_focus); + ClassDB::bind_method(D_METHOD("is_select_all_on_focus"), &LineEdit::is_select_all_on_focus); ADD_SIGNAL(MethodInfo("text_changed", PropertyInfo(Variant::STRING, "new_text"))); ADD_SIGNAL(MethodInfo("text_change_rejected", PropertyInfo(Variant::STRING, "rejected_substring"))); @@ -2430,6 +2458,7 @@ void LineEdit::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "right_icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_right_icon", "get_right_icon"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flat"), "set_flat", "is_flat"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "draw_control_chars"), "set_draw_control_chars", "get_draw_control_chars"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "select_all_on_focus"), "set_select_all_on_focus", "is_select_all_on_focus"); ADD_GROUP("Caret", "caret_"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "caret_blink"), "set_caret_blink_enabled", "is_caret_blink_enabled"); diff --git a/scene/gui/line_edit.h b/scene/gui/line_edit.h index 861c7f273b..e0a079b623 100644 --- a/scene/gui/line_edit.h +++ b/scene/gui/line_edit.h @@ -174,6 +174,9 @@ private: double caret_blink_timer = 0.0; bool caret_blinking = false; + bool pending_select_all_on_focus = false; + bool select_all_on_focus = false; + struct ThemeCache { Ref<StyleBox> normal; Ref<StyleBox> read_only; @@ -365,6 +368,10 @@ public: void set_flat(bool p_enabled); bool is_flat() const; + void set_select_all_on_focus(bool p_enabled); + bool is_select_all_on_focus() const; + void clear_pending_select_all_on_focus(); // For other controls, e.g. SpinBox. + virtual bool is_text_field() const override; void show_virtual_keyboard(); diff --git a/scene/gui/spin_box.cpp b/scene/gui/spin_box.cpp index fe14049d93..c4000120c8 100644 --- a/scene/gui/spin_box.cpp +++ b/scene/gui/spin_box.cpp @@ -168,6 +168,7 @@ void SpinBox::gui_input(const Ref<InputEvent> &p_event) { range_click_timer->stop(); _release_mouse(); drag.allowed = false; + line_edit->clear_pending_select_all_on_focus(); } Ref<InputEventMouseMotion> mm = p_event; @@ -190,6 +191,11 @@ void SpinBox::_line_edit_focus_enter() { int col = line_edit->get_caret_column(); _value_changed(0); // Update the LineEdit's text. line_edit->set_caret_column(col); + + // LineEdit text might change and it clears any selection. Have to re-select here. + if (line_edit->is_select_all_on_focus() && !Input::get_singleton()->is_mouse_button_pressed(MouseButton::LEFT)) { + line_edit->select_all(); + } } void SpinBox::_line_edit_focus_exit() { @@ -308,6 +314,14 @@ bool SpinBox::get_update_on_text_changed() const { return update_on_text_changed; } +void SpinBox::set_select_all_on_focus(bool p_enabled) { + line_edit->set_select_all_on_focus(p_enabled); +} + +bool SpinBox::is_select_all_on_focus() const { + return line_edit->is_select_all_on_focus(); +} + void SpinBox::set_editable(bool p_enabled) { line_edit->set_editable(p_enabled); } @@ -341,6 +355,8 @@ void SpinBox::_bind_methods() { ClassDB::bind_method(D_METHOD("is_editable"), &SpinBox::is_editable); ClassDB::bind_method(D_METHOD("set_update_on_text_changed", "enabled"), &SpinBox::set_update_on_text_changed); ClassDB::bind_method(D_METHOD("get_update_on_text_changed"), &SpinBox::get_update_on_text_changed); + ClassDB::bind_method(D_METHOD("set_select_all_on_focus", "enabled"), &SpinBox::set_select_all_on_focus); + ClassDB::bind_method(D_METHOD("is_select_all_on_focus"), &SpinBox::is_select_all_on_focus); ClassDB::bind_method(D_METHOD("apply"), &SpinBox::apply); ClassDB::bind_method(D_METHOD("get_line_edit"), &SpinBox::get_line_edit); @@ -350,6 +366,7 @@ void SpinBox::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::STRING, "prefix"), "set_prefix", "get_prefix"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "suffix"), "set_suffix", "get_suffix"); ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "custom_arrow_step"), "set_custom_arrow_step", "get_custom_arrow_step"); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "select_all_on_focus"), "set_select_all_on_focus", "is_select_all_on_focus"); } SpinBox::SpinBox() { diff --git a/scene/gui/spin_box.h b/scene/gui/spin_box.h index c2f2ac3f5a..00f5a95699 100644 --- a/scene/gui/spin_box.h +++ b/scene/gui/spin_box.h @@ -101,6 +101,9 @@ public: void set_update_on_text_changed(bool p_enabled); bool get_update_on_text_changed() const; + void set_select_all_on_focus(bool p_enabled); + bool is_select_all_on_focus() const; + void apply(); void set_custom_arrow_step(const double p_custom_arrow_step); double get_custom_arrow_step() const; |