From d59a925ca12fcc10cd586b3791f8389c55dea7b5 Mon Sep 17 00:00:00 2001 From: Leroy Hopson Date: Thu, 15 Feb 2024 07:27:51 +1300 Subject: [PATCH] Add selection support --- addons/godot_xterm/native/src/terminal.cpp | 59 ++++++++++++++++++++++ addons/godot_xterm/native/src/terminal.h | 8 +++ 2 files changed, 67 insertions(+) diff --git a/addons/godot_xterm/native/src/terminal.cpp b/addons/godot_xterm/native/src/terminal.cpp index 7798614..71597b5 100644 --- a/addons/godot_xterm/native/src/terminal.cpp +++ b/addons/godot_xterm/native/src/terminal.cpp @@ -6,7 +6,10 @@ #include #include #include +#include #include +#include +#include #include #include #include @@ -67,6 +70,7 @@ void Terminal::_bind_methods() ClassDB::bind_method(D_METHOD("write", "data"), &Terminal::write); ClassDB::bind_method(D_METHOD("get_cursor_pos"), &Terminal::get_cursor_pos); ClassDB::bind_method(D_METHOD("_on_gui_input", "event"), &Terminal::_gui_input); + ClassDB::bind_method(D_METHOD("_on_selection_held"), &Terminal::_on_selection_held); } Terminal::Terminal() @@ -171,6 +175,7 @@ String Terminal::write(const Variant data) void Terminal::_gui_input(const Ref &event) { _handle_key_input(event); + _handle_selection(event); } void Terminal::_notification(int what) @@ -605,6 +610,13 @@ int Terminal::get_inverse_mode() const { } void Terminal::initialize_input() { + selecting = false; + selection_mode = SelectionMode::NONE; + selection_timer = memnew(Timer); + selection_timer->set_wait_time(0.05); + selection_timer->connect("timeout", Callable(this, "_on_selection_held")); + add_child(selection_timer, false, INTERNAL_MODE_FRONT); + connect("gui_input", Callable(this, "_on_gui_input")); } @@ -645,3 +657,50 @@ void Terminal::_handle_key_input(Ref event) { if (tab_arrow_keys.find(keycode) != tab_arrow_keys.end()) accept_event(); } + +void Terminal::_handle_selection(Ref event) { + if (!event.is_valid()) + return; + + Ref mb = event; + if (mb.is_valid()) { + if (!mb->is_pressed() || !mb->get_button_index() == MOUSE_BUTTON_LEFT) + return; + + if (selecting) { + selecting = false; + selection_mode = SelectionMode::NONE; + tsm_screen_selection_reset(screen); + queue_redraw(); + } + + selecting = false; + selection_mode = SelectionMode::POINTER; + + return; + } + + Ref mm = event; + if (mm.is_valid()) { + if ((mm->get_button_mask() & MOUSE_BUTTON_MASK_LEFT) && selection_mode != SelectionMode::NONE && !selecting) { + selecting = true; + Vector2 start = event->get_position() / cell_size; + tsm_screen_selection_start(screen, start.x, start.y); + queue_redraw(); + selection_timer->start(); + } + return; + } +} + +void Terminal::_on_selection_held() { + if (!(Input::get_singleton()->is_mouse_button_pressed(MOUSE_BUTTON_LEFT)) || selection_mode == SelectionMode::NONE) { + selection_timer->stop(); + return; + } + + Vector2 target = get_local_mouse_position() / cell_size; + tsm_screen_selection_target(screen, target.x, target.y); + queue_redraw(); + selection_timer->start(); +} diff --git a/addons/godot_xterm/native/src/terminal.h b/addons/godot_xterm/native/src/terminal.h index 9851bf3..2b2a73e 100644 --- a/addons/godot_xterm/native/src/terminal.h +++ b/addons/godot_xterm/native/src/terminal.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -152,6 +153,13 @@ namespace godot Ref last_input_event_key; void initialize_input(); void _handle_key_input(Ref event); + + enum SelectionMode { NONE, POINTER }; + bool selecting = false; + SelectionMode selection_mode = SelectionMode::NONE; + Timer *selection_timer = new Timer(); + void _handle_selection(Ref event); + void _on_selection_held(); }; } // namespace godot