mirror of
https://github.com/lihop/godot-xterm.git
synced 2024-11-22 01:30:25 +01:00
feat(term): add select method
Adds select() method to Terminal. Method behaves the same way as TextEdit's select method.
This commit is contained in:
parent
43303a51bf
commit
dd118d72f3
5 changed files with 112 additions and 8 deletions
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include "terminal.h"
|
#include "terminal.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <godot_cpp/classes/control.hpp>
|
#include <godot_cpp/classes/control.hpp>
|
||||||
#include <godot_cpp/classes/font.hpp>
|
#include <godot_cpp/classes/font.hpp>
|
||||||
#include <godot_cpp/classes/image_texture.hpp>
|
#include <godot_cpp/classes/image_texture.hpp>
|
||||||
|
@ -70,6 +71,9 @@ void Terminal::_bind_methods()
|
||||||
ClassDB::bind_method(D_METHOD("set_blink_off_time", "time"), &Terminal::set_blink_off_time);
|
ClassDB::bind_method(D_METHOD("set_blink_off_time", "time"), &Terminal::set_blink_off_time);
|
||||||
ClassDB::add_property("Terminal", PropertyInfo(Variant::FLOAT, "blink_off_time"), "set_blink_off_time", "get_blink_off_time");
|
ClassDB::add_property("Terminal", PropertyInfo(Variant::FLOAT, "blink_off_time"), "set_blink_off_time", "get_blink_off_time");
|
||||||
|
|
||||||
|
// Selection.
|
||||||
|
ClassDB::bind_method(D_METHOD("select", "from_line", "from_column", "to_line", "to_column"), &Terminal::select);
|
||||||
|
|
||||||
// Copying.
|
// Copying.
|
||||||
ClassDB::bind_method(D_METHOD("copy_all"), &Terminal::copy_all);
|
ClassDB::bind_method(D_METHOD("copy_all"), &Terminal::copy_all);
|
||||||
ClassDB::bind_method(D_METHOD("copy_selection"), &Terminal::copy_selection);
|
ClassDB::bind_method(D_METHOD("copy_selection"), &Terminal::copy_selection);
|
||||||
|
@ -657,6 +661,26 @@ String Terminal::_copy_screen(ScreenCopyFunction func) {
|
||||||
return data.get_string_from_utf8();
|
return data.get_string_from_utf8();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Terminal::select(const int p_from_line, const int p_from_column, const int p_to_line, const int p_to_column) {
|
||||||
|
int from_line = std::clamp((int)p_from_line, 0, (int)rows);
|
||||||
|
int from_column = std::clamp((int)p_from_column, 0, (int)cols);
|
||||||
|
int to_line = std::clamp((int)p_to_line, 0, (int)rows);
|
||||||
|
int to_column = std::clamp((int)p_to_column, 0, (int)cols);
|
||||||
|
|
||||||
|
if (from_line > to_line) {
|
||||||
|
std::swap(to_line, from_line);
|
||||||
|
std::swap(to_column, from_column);
|
||||||
|
} else if ((from_line == to_line) && (from_column > to_column)) {
|
||||||
|
std::swap(to_column, from_column);
|
||||||
|
}
|
||||||
|
|
||||||
|
to_column -= 1;
|
||||||
|
|
||||||
|
tsm_screen_selection_reset(screen);
|
||||||
|
tsm_screen_selection_start(screen, from_column, from_line);
|
||||||
|
tsm_screen_selection_target(screen, to_column, to_line);
|
||||||
|
}
|
||||||
|
|
||||||
String Terminal::copy_all() {
|
String Terminal::copy_all() {
|
||||||
return _copy_screen(&tsm_screen_copy_all);
|
return _copy_screen(&tsm_screen_copy_all);
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,6 +74,8 @@ namespace godot
|
||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
|
void select(const int p_from_line, const int p_from_column, const int p_to_line, const int p_to_column);
|
||||||
|
|
||||||
String copy_all();
|
String copy_all();
|
||||||
String copy_selection();
|
String copy_selection();
|
||||||
void set_copy_on_selection(const bool p_enable);
|
void set_copy_on_selection(const bool p_enable);
|
||||||
|
|
|
@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
|
|
||||||
## [Unreleased](https://github.com/lihop/godot-xterm/compare/v2.2.0...HEAD)
|
## [Unreleased](https://github.com/lihop/godot-xterm/compare/v2.2.0...HEAD)
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Added select() method to Terminal.
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Custom export templates are no longer required when exporting to HTML5 from Godot v3.5.x.
|
- Custom export templates are no longer required when exporting to HTML5 from Godot v3.5.x.
|
||||||
|
|
|
@ -43,12 +43,13 @@ For example if the string `"\u001b[38;2;0;255;0;mA"` was written to the terminal
|
||||||
## Methods
|
## Methods
|
||||||
|
|
||||||
| Returns | Signature |
|
| Returns | Signature |
|
||||||
| ---------- | ------------------------------------------------------------------- |
|
| ---------- | ------------------------------------------------------------------------------------------------------------ |
|
||||||
| void | [clear](#mthd-clear) **( )** |
|
| void | [clear](#mthd-clear) **( )** |
|
||||||
| {{String}} | [copy_all](#mthd-copy_all) **( )** |
|
| {{String}} | [copy_all](#mthd-copy_all) **( )** |
|
||||||
| {{String}} | [copy_selection](#mthd-copy_selection) **( )** |
|
| {{String}} | [copy_selection](#mthd-copy_selection) **( )** |
|
||||||
| {{int}} | [get_cols](#mthd-get_cols) **( )** |
|
| {{int}} | [get_cols](#mthd-get_cols) **( )** |
|
||||||
| {{int}} | [get_rows](#mthd-get_rows) **( )** |
|
| {{int}} | [get_rows](#mthd-get_rows) **( )** |
|
||||||
|
| void | [select](#mthd-select) **(** {{int}} from_line, {{int}} from_column, {{int}} to_line {{int}} to_column **)** |
|
||||||
| void | [write](#mthd-write) **(** {{String}}\|{{PoolByteArray}} data **)** |
|
| void | [write](#mthd-write) **(** {{String}}\|{{PoolByteArray}} data **)** |
|
||||||
|
|
||||||
## Signals
|
## Signals
|
||||||
|
@ -189,6 +190,12 @@ Returns the height of the terminal in characters.
|
||||||
When using a monospace font, this is the number of visible characters that can fit from the top of the terminal to the bottom in a single column.
|
When using a monospace font, this is the number of visible characters that can fit from the top of the terminal to the bottom in a single column.
|
||||||
It will automatically update according to the terminal's rect_size and theme's font size.
|
It will automatically update according to the terminal's rect_size and theme's font size.
|
||||||
|
|
||||||
|
<hr id="mthd-select" />
|
||||||
|
|
||||||
|
void **select** **(** {{int}} from_line, {{int}} from_column, {{int}} to_line, {{int}} to_column **)**
|
||||||
|
|
||||||
|
Perform selection, from line/column to line/column.
|
||||||
|
|
||||||
<hr id="mthd-write" />
|
<hr id="mthd-write" />
|
||||||
|
|
||||||
void **write** **(** {{String}}\|{{PoolByteArray}} data **)**
|
void **write** **(** {{String}}\|{{PoolByteArray}} data **)**
|
||||||
|
|
|
@ -243,3 +243,70 @@ class TestClear:
|
||||||
var screen_after = subject.copy_all()
|
var screen_after = subject.copy_all()
|
||||||
var expected = final_line + "\n".repeat(subject.get_rows())
|
var expected = final_line + "\n".repeat(subject.get_rows())
|
||||||
assert_eq(screen_after, expected)
|
assert_eq(screen_after, expected)
|
||||||
|
|
||||||
|
|
||||||
|
class TestSelect:
|
||||||
|
extends TerminalTest
|
||||||
|
|
||||||
|
# Use the behavior of TextEdit's select() method as a reference.
|
||||||
|
var text_edit: TextEdit
|
||||||
|
|
||||||
|
func assert_select_eq(argv, expected):
|
||||||
|
text_edit.callv("select", argv)
|
||||||
|
subject.callv("select", argv)
|
||||||
|
assert_eq(
|
||||||
|
expected,
|
||||||
|
text_edit.get_selected_text(),
|
||||||
|
"expected does not match reference implementation"
|
||||||
|
)
|
||||||
|
assert_eq(subject.copy_selection(), expected)
|
||||||
|
|
||||||
|
func before_each():
|
||||||
|
super.before_each()
|
||||||
|
text_edit = TextEdit.new()
|
||||||
|
text_edit.text = "0123456789\nABCDEFGHIJ\n)!@#$%^&*(\n\n\n\n\n\n\n"
|
||||||
|
add_child_autofree(text_edit)
|
||||||
|
subject.write("0123456789\r\nABCDEFGHIJ\r\n)!@#$%^&*(")
|
||||||
|
|
||||||
|
func test_select_nothing():
|
||||||
|
assert_select_eq([0, 0, 0, 0], "")
|
||||||
|
|
||||||
|
func test_select_first_character():
|
||||||
|
assert_select_eq([0, 0, 0, 1], "0")
|
||||||
|
|
||||||
|
func test_select_last_character():
|
||||||
|
assert_select_eq([2, 9, 2, 10], "(")
|
||||||
|
|
||||||
|
func test_select_reverse_column():
|
||||||
|
assert_select_eq([0, 6, 0, 1], "12345")
|
||||||
|
|
||||||
|
func test_select_preceeds_column_bounds():
|
||||||
|
assert_select_eq([0, -2, 0, -1], "")
|
||||||
|
assert_select_eq([0, -2, 0, 0], "")
|
||||||
|
assert_select_eq([0, -2, 0, 1], "0")
|
||||||
|
|
||||||
|
func test_select_exceeds_column_bounds():
|
||||||
|
assert_select_eq([0, 5, 0, 999], "56789")
|
||||||
|
|
||||||
|
func test_select_first_row():
|
||||||
|
assert_select_eq([0, 0, 0, 10], "0123456789")
|
||||||
|
|
||||||
|
func test_select_second_row():
|
||||||
|
assert_select_eq([1, 0, 1, 10], "ABCDEFGHIJ")
|
||||||
|
|
||||||
|
func test_select_multiple_rows():
|
||||||
|
assert_select_eq([0, 0, 1, 10], "0123456789\nABCDEFGHIJ")
|
||||||
|
|
||||||
|
func test_select_rows_reverse():
|
||||||
|
assert_select_eq([1, 5, 0, 0], "0123456789\nABCDE")
|
||||||
|
|
||||||
|
func test_select_preceeds_row_bounds():
|
||||||
|
assert_select_eq([-2, 0, -1, 10], "0123456789")
|
||||||
|
assert_select_eq([-2, 0, 0, 10], "0123456789")
|
||||||
|
assert_select_eq([-2, 0, 1, 10], "0123456789\nABCDEFGHIJ")
|
||||||
|
|
||||||
|
func test_select_exceeds_row_bounds():
|
||||||
|
assert_select_eq([1, 5, 999, 999], "FGHIJ\n)!@#$%^&*(\n\n\n\n\n\n\n")
|
||||||
|
|
||||||
|
func test_wide_bounds():
|
||||||
|
assert_select_eq([-999, -999, 999, 999], "0123456789\nABCDEFGHIJ\n)!@#$%^&*(\n\n\n\n\n\n\n")
|
||||||
|
|
Loading…
Reference in a new issue