Add non-public {Line,Text}Edit::_set_text()
- [Web] Fix "Enter" not triggering LineEdit submits. Co-authored-by: Marwen Azouzi <marwen.azouzi@datadoghq.com>
This commit is contained in:
committed by
Rémi Verschelde
parent
7692a3d53b
commit
263589497b
@@ -437,26 +437,27 @@ void DisplayServerAndroid::window_set_drop_files_callback(const Callable &p_call
|
||||
// Not supported on Android.
|
||||
}
|
||||
|
||||
void DisplayServerAndroid::_window_callback(const Callable &p_callable, const Variant &p_arg, bool p_deferred) const {
|
||||
template <typename... Args>
|
||||
void DisplayServerAndroid::_window_callback(const Callable &p_callable, bool p_deferred, const Args &...p_rest_args) const {
|
||||
if (p_callable.is_valid()) {
|
||||
if (p_deferred) {
|
||||
p_callable.call_deferred(p_arg);
|
||||
p_callable.call_deferred(p_rest_args...);
|
||||
} else {
|
||||
p_callable.call(p_arg);
|
||||
p_callable.call(p_rest_args...);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DisplayServerAndroid::send_window_event(DisplayServer::WindowEvent p_event, bool p_deferred) const {
|
||||
_window_callback(window_event_callback, int(p_event), p_deferred);
|
||||
_window_callback(window_event_callback, p_deferred, int(p_event));
|
||||
}
|
||||
|
||||
void DisplayServerAndroid::send_input_event(const Ref<InputEvent> &p_event) const {
|
||||
_window_callback(input_event_callback, p_event);
|
||||
_window_callback(input_event_callback, false, p_event);
|
||||
}
|
||||
|
||||
void DisplayServerAndroid::send_input_text(const String &p_text) const {
|
||||
_window_callback(input_text_callback, p_text);
|
||||
_window_callback(input_text_callback, false, p_text, false);
|
||||
}
|
||||
|
||||
void DisplayServerAndroid::_dispatch_input_events(const Ref<InputEvent> &p_event) {
|
||||
|
||||
@@ -96,7 +96,8 @@ class DisplayServerAndroid : public DisplayServer {
|
||||
|
||||
Callable file_picker_callback;
|
||||
|
||||
void _window_callback(const Callable &p_callable, const Variant &p_arg, bool p_deferred = false) const;
|
||||
template <typename... Args>
|
||||
void _window_callback(const Callable &p_callable, bool p_deferred, const Args &...p_rest_args) const;
|
||||
|
||||
static void _dispatch_input_events(const Ref<InputEvent> &p_event);
|
||||
|
||||
|
||||
@@ -796,7 +796,7 @@ void DisplayServerWeb::_vk_input_text_callback(const String &p_text, int p_curso
|
||||
return;
|
||||
}
|
||||
// Call input_text
|
||||
ds->input_text_callback.call(p_text);
|
||||
ds->input_text_callback.call(p_text, true);
|
||||
// Insert key right to reach position.
|
||||
Input *input = Input::get_singleton();
|
||||
Ref<InputEventKey> k;
|
||||
|
||||
@@ -157,6 +157,7 @@ module.exports = [
|
||||
'GodotFS': true,
|
||||
'GodotOS': true,
|
||||
'GodotAudio': true,
|
||||
'GodotInput': true,
|
||||
'GodotRuntime': true,
|
||||
'IDHandler': true,
|
||||
'XRWebGLLayer': true,
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
const GodotDisplayVK = {
|
||||
|
||||
$GodotDisplayVK__deps: ['$GodotRuntime', '$GodotConfig', '$GodotEventListeners'],
|
||||
$GodotDisplayVK__deps: ['$GodotRuntime', '$GodotConfig', '$GodotEventListeners', '$GodotInput'],
|
||||
$GodotDisplayVK__postset: 'GodotOS.atexit(function(resolve, reject) { GodotDisplayVK.clear(); resolve(); });',
|
||||
$GodotDisplayVK: {
|
||||
textinput: null,
|
||||
@@ -61,6 +61,17 @@ const GodotDisplayVK = {
|
||||
input_cb(c_str, elem.selectionEnd);
|
||||
GodotRuntime.free(c_str);
|
||||
}, false);
|
||||
if (what === 'input') {
|
||||
// Handling the "Enter" key.
|
||||
const onKey = (pEvent, pEventName) => {
|
||||
if (pEvent.key !== 'Enter') {
|
||||
return;
|
||||
}
|
||||
GodotInput.onKeyEvent(pEventName === 'keydown', pEvent);
|
||||
};
|
||||
GodotEventListeners.add(elem, 'keydown', (pEvent) => onKey(pEvent, 'keydown'), false);
|
||||
GodotEventListeners.add(elem, 'keyup', (pEvent) => onKey(pEvent, 'keyup'), false);
|
||||
}
|
||||
GodotEventListeners.add(elem, 'blur', function (evt) {
|
||||
elem.style.display = 'none';
|
||||
elem.readonly = true;
|
||||
|
||||
@@ -482,9 +482,13 @@ mergeInto(LibraryManager.library, GodotInputDragDrop);
|
||||
const GodotInput = {
|
||||
$GodotInput__deps: ['$GodotRuntime', '$GodotConfig', '$GodotEventListeners', '$GodotInputGamepads', '$GodotInputDragDrop', '$GodotIME'],
|
||||
$GodotInput: {
|
||||
inputKeyCallback: null,
|
||||
setInputKeyData: null,
|
||||
|
||||
getModifiers: function (evt) {
|
||||
return (evt.shiftKey + 0) + ((evt.altKey + 0) << 1) + ((evt.ctrlKey + 0) << 2) + ((evt.metaKey + 0) << 3);
|
||||
},
|
||||
|
||||
computePosition: function (evt, rect) {
|
||||
const canvas = GodotConfig.canvas;
|
||||
const rw = canvas.width / rect.width;
|
||||
@@ -493,6 +497,20 @@ const GodotInput = {
|
||||
const y = (evt.clientY - rect.y) * rh;
|
||||
return [x, y];
|
||||
},
|
||||
|
||||
onKeyEvent: function (pIsPressed, pEvent) {
|
||||
if (GodotInput.inputKeyCallback == null) {
|
||||
throw new TypeError('GodotInput.onKeyEvent(): GodotInput.inputKeyCallback is null, cannot process key event.');
|
||||
}
|
||||
if (GodotInput.setInputKeyData == null) {
|
||||
throw new TypeError('GodotInput.onKeyEvent(): GodotInput.setInputKeyData is null, cannot process key event.');
|
||||
}
|
||||
|
||||
const modifiers = GodotInput.getModifiers(pEvent);
|
||||
GodotInput.setInputKeyData(pEvent.code, pEvent.key);
|
||||
GodotInput.inputKeyCallback(pIsPressed ? 1 : 0, pEvent.repeat, modifiers);
|
||||
pEvent.preventDefault();
|
||||
},
|
||||
},
|
||||
|
||||
/*
|
||||
@@ -590,17 +608,14 @@ const GodotInput = {
|
||||
*/
|
||||
godot_js_input_key_cb__proxy: 'sync',
|
||||
godot_js_input_key_cb__sig: 'viii',
|
||||
godot_js_input_key_cb: function (callback, code, key) {
|
||||
const func = GodotRuntime.get_func(callback);
|
||||
function key_cb(pressed, evt) {
|
||||
const modifiers = GodotInput.getModifiers(evt);
|
||||
GodotRuntime.stringToHeap(evt.code, code, 32);
|
||||
GodotRuntime.stringToHeap(evt.key, key, 32);
|
||||
func(pressed, evt.repeat, modifiers);
|
||||
evt.preventDefault();
|
||||
}
|
||||
GodotEventListeners.add(GodotConfig.canvas, 'keydown', key_cb.bind(null, 1), false);
|
||||
GodotEventListeners.add(GodotConfig.canvas, 'keyup', key_cb.bind(null, 0), false);
|
||||
godot_js_input_key_cb: function (pCallback, pCodePtr, pKeyPtr) {
|
||||
GodotInput.inputKeyCallback = GodotRuntime.get_func(pCallback);
|
||||
GodotInput.setInputKeyData = (pCode, pKey) => {
|
||||
GodotRuntime.stringToHeap(pCode, pCodePtr, 32);
|
||||
GodotRuntime.stringToHeap(pKey, pKeyPtr, 32);
|
||||
};
|
||||
GodotEventListeners.add(GodotConfig.canvas, 'keydown', GodotInput.onKeyEvent.bind(null, true), false);
|
||||
GodotEventListeners.add(GodotConfig.canvas, 'keyup', GodotInput.onKeyEvent.bind(null, false), false);
|
||||
},
|
||||
|
||||
/*
|
||||
|
||||
@@ -89,6 +89,7 @@ ignore-words-list = [
|
||||
"ot",
|
||||
"outin",
|
||||
"parm",
|
||||
"pEvent",
|
||||
"requestor",
|
||||
"streamin",
|
||||
"te",
|
||||
|
||||
@@ -2109,22 +2109,39 @@ void LineEdit::delete_text(int p_from_column, int p_to_column) {
|
||||
}
|
||||
}
|
||||
|
||||
void LineEdit::set_text(String p_text) {
|
||||
void LineEdit::_set_text(String p_text, bool p_emit_signal) {
|
||||
clear_internal();
|
||||
|
||||
String previous_text = get_text();
|
||||
insert_text_at_caret(p_text);
|
||||
_create_undo_state();
|
||||
|
||||
if (get_text() != previous_text) {
|
||||
_create_undo_state();
|
||||
if (p_emit_signal) {
|
||||
_text_changed();
|
||||
}
|
||||
}
|
||||
|
||||
queue_redraw();
|
||||
caret_column = 0;
|
||||
scroll_offset = 0.0;
|
||||
}
|
||||
|
||||
void LineEdit::set_text(String p_text) {
|
||||
_set_text(p_text);
|
||||
}
|
||||
|
||||
void LineEdit::set_text_with_selection(const String &p_text) {
|
||||
Selection selection_copy = selection;
|
||||
|
||||
clear_internal();
|
||||
|
||||
String previous_text = get_text();
|
||||
insert_text_at_caret(p_text);
|
||||
_create_undo_state();
|
||||
|
||||
if (get_text() != previous_text) {
|
||||
_create_undo_state();
|
||||
}
|
||||
|
||||
int tlen = text.length();
|
||||
selection = selection_copy;
|
||||
@@ -3299,6 +3316,10 @@ void LineEdit::_validate_property(PropertyInfo &p_property) const {
|
||||
}
|
||||
|
||||
void LineEdit::_bind_methods() {
|
||||
// Private exposed API.
|
||||
ClassDB::bind_method(D_METHOD("_set_text", "text", "emit_signal"), &LineEdit::_set_text, DEFVAL(false));
|
||||
|
||||
// Public API.
|
||||
ClassDB::bind_method(D_METHOD("has_ime_text"), &LineEdit::has_ime_text);
|
||||
ClassDB::bind_method(D_METHOD("cancel_ime"), &LineEdit::cancel_ime);
|
||||
ClassDB::bind_method(D_METHOD("apply_ime"), &LineEdit::apply_ime);
|
||||
|
||||
@@ -342,6 +342,7 @@ public:
|
||||
void delete_char();
|
||||
void delete_text(int p_from_column, int p_to_column);
|
||||
|
||||
void _set_text(String p_text, bool p_emit_signal = false);
|
||||
void set_text(String p_text);
|
||||
String get_text() const;
|
||||
void set_text_with_selection(const String &p_text); // Set text, while preserving selection.
|
||||
|
||||
@@ -3982,12 +3982,8 @@ void TextEdit::_clear() {
|
||||
emit_signal(SNAME("lines_edited_from"), old_text_size, 0);
|
||||
}
|
||||
|
||||
void TextEdit::set_text(const String &p_text) {
|
||||
void TextEdit::_set_text(const String &p_text, bool p_emit_signal) {
|
||||
setting_text = true;
|
||||
if (!undo_enabled) {
|
||||
_clear();
|
||||
insert_text_at_caret(p_text);
|
||||
}
|
||||
|
||||
if (undo_enabled) {
|
||||
remove_secondary_carets();
|
||||
@@ -3997,7 +3993,22 @@ void TextEdit::set_text(const String &p_text) {
|
||||
begin_complex_operation();
|
||||
deselect();
|
||||
_remove_text(0, 0, MAX(0, get_line_count() - 1), MAX(get_line(MAX(get_line_count() - 1, 0)).size() - 1, 0));
|
||||
insert_text_at_caret(p_text);
|
||||
} else {
|
||||
_clear();
|
||||
}
|
||||
|
||||
String previous_text;
|
||||
if (p_emit_signal) {
|
||||
previous_text = get_text();
|
||||
}
|
||||
|
||||
insert_text_at_caret(p_text);
|
||||
|
||||
if (p_emit_signal && get_text() != previous_text) {
|
||||
_text_changed();
|
||||
}
|
||||
|
||||
if (undo_enabled) {
|
||||
end_complex_operation();
|
||||
}
|
||||
|
||||
@@ -4009,6 +4020,10 @@ void TextEdit::set_text(const String &p_text) {
|
||||
emit_signal(SNAME("text_set"));
|
||||
}
|
||||
|
||||
void TextEdit::set_text(const String &p_text) {
|
||||
_set_text(p_text, false);
|
||||
}
|
||||
|
||||
String TextEdit::get_text() const {
|
||||
StringBuilder ret_text;
|
||||
const int text_size = text.size();
|
||||
@@ -7091,6 +7106,11 @@ Color TextEdit::get_font_color() const {
|
||||
}
|
||||
|
||||
void TextEdit::_bind_methods() {
|
||||
// Private API.
|
||||
ClassDB::bind_method(D_METHOD("_set_text", "text", "emit_signal"), &TextEdit::_set_text, DEFVAL(false));
|
||||
|
||||
// Public API.
|
||||
|
||||
/* Text */
|
||||
// Text properties
|
||||
ClassDB::bind_method(D_METHOD("has_ime_text"), &TextEdit::has_ime_text);
|
||||
|
||||
@@ -853,6 +853,7 @@ public:
|
||||
// Text manipulation
|
||||
void clear();
|
||||
|
||||
void _set_text(const String &p_text, bool p_emit_signal = false);
|
||||
void set_text(const String &p_text);
|
||||
String get_text() const;
|
||||
|
||||
|
||||
@@ -2828,16 +2828,22 @@ void Viewport::_post_gui_grab_click_focus() {
|
||||
|
||||
///////////////////////////////
|
||||
|
||||
void Viewport::push_text_input(const String &p_text) {
|
||||
void Viewport::_push_text_input(const String &p_text, bool p_emit_signal) {
|
||||
ERR_MAIN_THREAD_GUARD;
|
||||
if (gui.subwindow_focused) {
|
||||
gui.subwindow_focused->push_text_input(p_text);
|
||||
return;
|
||||
}
|
||||
|
||||
if (gui.key_focus) {
|
||||
gui.key_focus->call("set_text", p_text);
|
||||
StringName set_text_method = SNAME("_set_text");
|
||||
if (!gui.key_focus || !gui.key_focus->has_method(set_text_method)) {
|
||||
return;
|
||||
}
|
||||
gui.key_focus->call(set_text_method, p_text, p_emit_signal);
|
||||
}
|
||||
|
||||
void Viewport::push_text_input(const String &p_text) {
|
||||
_push_text_input(p_text, false);
|
||||
}
|
||||
|
||||
Viewport::SubWindowResize Viewport::_sub_window_get_resize_margin(Window *p_subwindow, const Point2 &p_point) {
|
||||
|
||||
@@ -608,6 +608,7 @@ public:
|
||||
Vector2 get_camera_coords(const Vector2 &p_viewport_coords) const;
|
||||
Vector2 get_camera_rect_size() const;
|
||||
|
||||
void _push_text_input(const String &p_text, bool p_emit_text_changed_signal = false);
|
||||
void push_text_input(const String &p_text);
|
||||
void push_input(RequiredParam<InputEvent> rp_event, bool p_local_coords = false);
|
||||
#ifndef DISABLE_DEPRECATED
|
||||
|
||||
@@ -1860,8 +1860,8 @@ void Window::_window_input(const Ref<InputEvent> &p_ev) {
|
||||
}
|
||||
}
|
||||
|
||||
void Window::_window_input_text(const String &p_text) {
|
||||
push_text_input(p_text);
|
||||
void Window::_window_input_text(const String &p_text, bool p_emit_signal) {
|
||||
_push_text_input(p_text, p_emit_signal);
|
||||
}
|
||||
|
||||
void Window::_window_drop_files(const Vector<String> &p_files) {
|
||||
|
||||
@@ -244,7 +244,7 @@ private:
|
||||
friend class Viewport; //friend back, can call the methods below
|
||||
|
||||
void _window_input(const Ref<InputEvent> &p_ev);
|
||||
void _window_input_text(const String &p_text);
|
||||
void _window_input_text(const String &p_text, bool p_emit_signal = false);
|
||||
void _window_drop_files(const Vector<String> &p_files);
|
||||
void _rect_changed_callback(const Rect2i &p_callback);
|
||||
void _event_callback(DisplayServer::WindowEvent p_event);
|
||||
|
||||
Reference in New Issue
Block a user