From d2f073d7aed9a9f5de790b1463c563b05f0707ac Mon Sep 17 00:00:00 2001 From: Leroy Hopson Date: Sat, 19 Jun 2021 20:57:05 +0700 Subject: [PATCH] Multiple updates - Use viewport as render target for terminal: Terminal now only draws cells which changed since the last _draw() call. A viewport is used with clear mode set to NEVER to cache previous draw calls. The terminal node and viewport are wrapped by a GDScript Terminal node which takes care of resizing the viewport scene, and forcing the terminal to redraw all cells when necessary (i.e. on resize or theme change). Adds update_mode to terminal interface which can be set to one of: - DISABLED: terminal will never be drawn - AUTO: terminal will only draw the cells that changed, but automatically redraw the full screen when necessary (for example, when the size or theme changed). - ALL: terminal will always draw every cell on every update. This is the most reliable but least performant option. - ALL_NEXT_FRAME: Will use update_mode ALL for the next _draw() call, then change update_mode back to AUTO. - Upgraded libtsm: Includes changes from Fredrik Wikstrom (salass00)'s fork of libtsm. - Don't require theme to be set. Terminal will use default fonts/colors if no theme is set. --- addons/godot_xterm/native/src/terminal.cpp | 222 ++++++++---------- addons/godot_xterm/native/src/terminal.h | 30 +-- addons/godot_xterm/native/thirdparty/libtsm | 2 +- addons/godot_xterm/nodes/terminal/terminal.gd | 99 ++++++++ addons/godot_xterm/nodes/terminal/viewport.gd | 2 + .../godot_xterm/nodes/terminal/viewport.tscn | 32 +++ examples/asciicast/asciicast.tscn | 12 +- examples/menu/menu.tscn | 13 +- examples/terminal/terminal.tscn | 10 +- examples/web_console/web_console.tscn | 8 +- test/scenes/basic.gd | 10 + test/scenes/basic.tscn | 29 +++ test/scenes/basic_fullscreen.tscn | 21 ++ 13 files changed, 312 insertions(+), 178 deletions(-) create mode 100644 addons/godot_xterm/nodes/terminal/terminal.gd create mode 100644 addons/godot_xterm/nodes/terminal/viewport.gd create mode 100644 addons/godot_xterm/nodes/terminal/viewport.tscn create mode 100644 test/scenes/basic.gd create mode 100644 test/scenes/basic.tscn create mode 100644 test/scenes/basic_fullscreen.tscn diff --git a/addons/godot_xterm/native/src/terminal.cpp b/addons/godot_xterm/native/src/terminal.cpp index b3fd23f..d619458 100644 --- a/addons/godot_xterm/native/src/terminal.cpp +++ b/addons/godot_xterm/native/src/terminal.cpp @@ -14,8 +14,6 @@ using namespace godot; -const struct Terminal::cell Terminal::empty_cell = {{0, 0, 0, 0, 0}, {}}; - std::map, int> Terminal::_key_list = {}; void Terminal::_populate_key_list() { if (!_key_list.empty()) @@ -243,29 +241,27 @@ static void write_cb(struct tsm_vte *vte, const char *u8, size_t len, } static int text_draw_cb(struct tsm_screen *con, uint64_t id, const uint32_t *ch, - size_t len, unsigned int width, unsigned int posx, - unsigned int posy, const struct tsm_screen_attr *attr, + size_t len, unsigned int width, unsigned int col, + unsigned int row, const struct tsm_screen_attr *attr, tsm_age_t age, void *data) { - Terminal *terminal = static_cast(data); - if (age <= terminal->framebuffer_age) + if (terminal->update_mode == Terminal::UpdateMode::AUTO && age != 0 && + age <= terminal->framebuffer_age) return 0; + std::pair color_pair = terminal->get_cell_colors(attr); + terminal->draw_background(row, col, color_pair.first); + size_t ulen; char buf[5] = {0}; - if (len > 0) { - char *utf8 = tsm_ucs4_to_utf8_alloc(ch, len, &ulen); - memcpy(terminal->cells[posy][posx].ch, utf8, ulen); - } else { - terminal->cells[posy][posx] = {}; - } + if (len < 1) // No foreground to draw. + return 0; - memcpy(&terminal->cells[posy][posx].attr, attr, sizeof(tsm_screen_attr)); - - if (!terminal->sleep) - terminal->update(); + char *utf8 = tsm_ucs4_to_utf8_alloc(ch, len, &ulen); + memcpy(buf, utf8, ulen); + terminal->draw_foreground(row, col, buf, attr, color_pair.second); return 0; } @@ -273,15 +269,19 @@ static int text_draw_cb(struct tsm_screen *con, uint64_t id, const uint32_t *ch, void Terminal::_register_methods() { register_method("_init", &Terminal::_init); register_method("_ready", &Terminal::_ready); + register_method("_notification", &Terminal::_notification); register_method("_gui_input", &Terminal::_gui_input); register_method("_draw", &Terminal::_draw); - register_method("_notification", &Terminal::_notification); register_method("write", &Terminal::write); - register_method("update_size", &Terminal::update_size); + + register_method("_update_theme", &Terminal::update_theme); + register_method("_update_size", &Terminal::update_theme); register_property("rows", &Terminal::rows, 24); register_property("cols", &Terminal::cols, 80); + register_property("update_mode", &Terminal::update_mode, + UpdateMode::AUTO); register_signal("data_sent", "data", GODOT_VARIANT_TYPE_POOL_BYTE_ARRAY); @@ -296,7 +296,8 @@ Terminal::Terminal() {} Terminal::~Terminal() {} void Terminal::_init() { - sleep = true; + framebuffer_age = 0; + update_mode = UpdateMode::AUTO; if (tsm_screen_new(&screen, NULL, NULL)) { ERR_PRINT("Error creating new tsm screen"); @@ -307,14 +308,9 @@ void Terminal::_init() { if (tsm_vte_new(&vte, screen, write_cb, this, NULL, NULL)) { ERR_PRINT("Error creating new tsm vte"); } - - update_theme(); } -void Terminal::_ready() { - update_size(); - connect("resized", this, "update_size"); -} +void Terminal::_ready() { update_theme(); } void Terminal::_notification(int what) { switch (what) { @@ -322,7 +318,7 @@ void Terminal::_notification(int what) { update_size(); break; case NOTIFICATION_THEME_CHANGED: - update_theme(); + // update_theme(); break; } } @@ -356,42 +352,32 @@ void Terminal::_gui_input(Variant event) { } void Terminal::_draw() { - if (sleep) + if (update_mode == UpdateMode::DISABLED) return; - /* Draw the full terminal rect background */ - Color background_color = palette[TSM_COLOR_BACKGROUND]; - - draw_rect(Rect2(Vector2(0, 0), get_rect().size), background_color); - - for (int row = 0; row < rows; row++) { - for (int col = 0; col < cols; col++) { - /* Draw cell background and foreground */ - std::pair color_pair = get_cell_colors(row, col); - draw_background(row, col, color_pair.first); - draw_foreground(row, col, color_pair.second); - } + if ((update_mode > UpdateMode::AUTO) || framebuffer_age == 0) { + /* Draw the full terminal rect background */ + // Draw the rectangle slightly larger, so it fills the entire viewport. + Color background_color = palette[TSM_COLOR_BACKGROUND]; + draw_rect(Rect2(Vector2(-4, -4), get_rect().size + Vector2(8, 8)), + background_color); } + + framebuffer_age = tsm_screen_draw(screen, text_draw_cb, this); + + if (update_mode == UpdateMode::ALL_NEXT_FRAME) + update_mode = UpdateMode::AUTO; } void Terminal::update_theme() { /* Generate color palette based on theme */ - // Converts a color from the Control's theme to one that can - // be used in a tsm color palette. auto set_pallete_color = [this](tsm_vte_color color, String theme_color, - int default_r, int default_g, - int default_b) -> void { + Color default_color) -> void { Color c; - if (has_color(theme_color, "Terminal")) { - c = get_color(theme_color, "Terminal"); - } else { - int r = default_r; - int g = default_g; - int b = default_b; - c = Color((float)r / 255.0, (float)g / 255.0, (float)b / 255.0); - } + c = has_color(theme_color, "Terminal") ? get_color(theme_color, "Terminal") + : default_color; color_palette[color][0] = c.get_r8(); color_palette[color][1] = c.get_g8(); @@ -400,25 +386,30 @@ void Terminal::update_theme() { palette[color] = c; }; - set_pallete_color(TSM_COLOR_BLACK, "Black", 0, 0, 0); - set_pallete_color(TSM_COLOR_RED, "Red", 205, 0, 0); - set_pallete_color(TSM_COLOR_GREEN, "Green", 0, 205, 0); - set_pallete_color(TSM_COLOR_YELLOW, "Yellow", 205, 205, 0); - set_pallete_color(TSM_COLOR_BLUE, "Blue", 0, 0, 238); - set_pallete_color(TSM_COLOR_MAGENTA, "Magenta", 205, 0, 205); - set_pallete_color(TSM_COLOR_CYAN, "Cyan", 0, 205, 205); - set_pallete_color(TSM_COLOR_LIGHT_GREY, "Light Grey", 229, 229, 229); - set_pallete_color(TSM_COLOR_DARK_GREY, "Dark Grey", 127, 127, 127); - set_pallete_color(TSM_COLOR_LIGHT_RED, "Light Red", 255, 0, 0); - set_pallete_color(TSM_COLOR_LIGHT_GREEN, "Light Green", 0, 255, 0); - set_pallete_color(TSM_COLOR_LIGHT_YELLOW, "Light Yellow", 255, 255, 0); - set_pallete_color(TSM_COLOR_LIGHT_BLUE, "Light Blue", 0, 0, 255); - set_pallete_color(TSM_COLOR_LIGHT_MAGENTA, "Light Magenta", 255, 0, 255); - set_pallete_color(TSM_COLOR_LIGHT_CYAN, "Light Cyan", 0, 255, 255); - set_pallete_color(TSM_COLOR_WHITE, "White", 255, 255, 255); + set_pallete_color(TSM_COLOR_BLACK, "Black", Color(0, 0, 0, 1)); + set_pallete_color(TSM_COLOR_RED, "Red", Color(0.501961, 0, 0, 1)); + set_pallete_color(TSM_COLOR_GREEN, "Green", Color(0, 0.501961, 0, 1)); + set_pallete_color(TSM_COLOR_YELLOW, "Yellow", + Color(0.501961, 0.501961, 0, 1)); + set_pallete_color(TSM_COLOR_BLUE, "Blue", Color(0, 0, 0.501961, 1)); + set_pallete_color(TSM_COLOR_MAGENTA, "Magenta", + Color(0.501961, 0, 0.501961, 1)); + set_pallete_color(TSM_COLOR_CYAN, "Cyan", Color(0, 0.501961, 0.501961, 1)); + set_pallete_color(TSM_COLOR_DARK_GREY, "Dark Grey", + Color(0.501961, 0.501961, 0.501961, 1)); + set_pallete_color(TSM_COLOR_LIGHT_GREY, "Light Grey", + Color(0.752941, 0.752941, 0.752941, 1)); + set_pallete_color(TSM_COLOR_LIGHT_RED, "Light Red", Color(1, 0, 0, 1)); + set_pallete_color(TSM_COLOR_LIGHT_GREEN, "Light Green", Color(0, 1, 0, 1)); + set_pallete_color(TSM_COLOR_LIGHT_YELLOW, "Light Yellow", Color(1, 1, 0, 1)); + set_pallete_color(TSM_COLOR_LIGHT_BLUE, "Light Blue", Color(0, 0, 1, 1)); + set_pallete_color(TSM_COLOR_LIGHT_MAGENTA, "Light Magenta", + Color(1, 0, 1, 1)); + set_pallete_color(TSM_COLOR_LIGHT_CYAN, "Light Cyan", Color(0, 1, 1, 1)); + set_pallete_color(TSM_COLOR_WHITE, "White", Color(1, 1, 1, 1)); - set_pallete_color(TSM_COLOR_BACKGROUND, "Background", 255, 255, 255); - set_pallete_color(TSM_COLOR_FOREGROUND, "Foreground", 0, 0, 0); + set_pallete_color(TSM_COLOR_BACKGROUND, "Background", Color(0, 0, 0, 1)); + set_pallete_color(TSM_COLOR_FOREGROUND, "Foreground", Color(1, 1, 1, 1)); if (tsm_vte_set_custom_palette(vte, color_palette)) { ERR_PRINT("Error setting custom palette"); @@ -442,9 +433,8 @@ void Terminal::update_theme() { fontmap.insert(std::pair>(font_style, fontref)); }; - set_font( - "Bold Italic", - "res://addons/godot_xterm/themes/fonts/cousine/cousine_bold_italic.tres"); + set_font("Bold Italic", "res://addons/godot_xterm/themes/fonts/cousine/" + "cousine_bold_italic.tres"); set_font("Bold", "res://addons/godot_xterm/themes/fonts/cousine/cousine_bold.tres"); set_font("Italic", @@ -452,32 +442,28 @@ void Terminal::update_theme() { set_font( "Regular", "res://addons/godot_xterm/themes/fonts/cousine/cousine_regular.tres"); + + update_size(); } void Terminal::draw_background(int row, int col, Color bgcolor) { - /* Draw the background */ Vector2 background_pos = Vector2(col * cell_size.x, row * cell_size.y); Rect2 background_rect = Rect2(background_pos, cell_size); draw_rect(background_rect, bgcolor); } -void Terminal::draw_foreground(int row, int col, Color fgcolor) { - - struct cell cell = cells[row][col]; - - if (cell.ch == nullptr) - return; // No foreground to draw - +void Terminal::draw_foreground(int row, int col, char *ch, + const tsm_screen_attr *attr, Color fgcolor) { /* Set the font */ Ref fontref = get_font(""); - if (cell.attr.bold && cell.attr.italic) { + if (attr->bold && attr->italic) { fontref = fontmap["Bold Italic"]; - } else if (cell.attr.bold) { + } else if (attr->bold) { fontref = fontmap["Bold"]; - } else if (cell.attr.italic) { + } else if (attr->italic) { fontref = fontmap["Italic"]; } else { fontref = fontmap["Regular"]; @@ -485,65 +471,61 @@ void Terminal::draw_foreground(int row, int col, Color fgcolor) { /* Draw the foreground */ - if (cell.attr.blink) + if (attr->blink) ; // TODO: Handle blink int font_height = fontref.ptr()->get_height(); Vector2 foreground_pos = Vector2(col * cell_size.x, row * cell_size.y + font_height / 1.25); - draw_string(fontref, foreground_pos, cell.ch, fgcolor); + draw_string(fontref, foreground_pos, ch, fgcolor); - if (cell.attr.underline) + if (attr->underline) draw_string(fontref, foreground_pos, "_", fgcolor); } -std::pair Terminal::get_cell_colors(int row, int col) { - struct cell cell = cells[row][col]; +std::pair Terminal::get_cell_colors(const tsm_screen_attr *attr) { Color fgcol, bgcol; float fr = 0, fg = 0, fb = 0, br = 1, bg = 1, bb = 1; /* Get foreground color */ - if (cell.attr.fccode && palette.count(cell.attr.fccode)) { - fgcol = palette[cell.attr.fccode]; + if (attr->fccode && palette.count(attr->fccode)) { + fgcol = palette[attr->fccode]; } else { - fr = (float)cell.attr.fr / 255.0; - fg = (float)cell.attr.fg / 255.0; - fb = (float)cell.attr.fb / 255.0; + fr = (float)attr->fr / 255.0; + fg = (float)attr->fg / 255.0; + fb = (float)attr->fb / 255.0; fgcol = Color(fr, fg, fb); - if (cell.attr.fccode != -1) { - palette.insert( - std::pair(cell.attr.fccode, Color(fr, fg, fb))); + if (attr->fccode != -1) { + palette.insert(std::pair(attr->fccode, Color(fr, fg, fb))); } } /* Get background color */ - if (cell.attr.bccode && palette.count(cell.attr.bccode)) { - bgcol = palette[cell.attr.bccode]; + if (attr->bccode && palette.count(attr->bccode)) { + bgcol = palette[attr->bccode]; } else { - br = (float)cell.attr.br / 255.0; - bg = (float)cell.attr.bg / 255.0; - bb = (float)cell.attr.bb / 255.0; + br = (float)attr->br / 255.0; + bg = (float)attr->bg / 255.0; + bb = (float)attr->bb / 255.0; bgcol = Color(br, bg, bb); - if (cell.attr.bccode != -1) { - palette.insert( - std::pair(cell.attr.bccode, Color(br, bg, bb))); + if (attr->bccode != -1) { + palette.insert(std::pair(attr->bccode, Color(br, bg, bb))); } } - if (cell.attr.inverse) + if (attr->inverse) std::swap(bgcol, fgcol); return std::make_pair(bgcol, fgcol); } -// Recalculates the cell_size and number of cols/rows based on font size and the -// Control's rect_size void Terminal::update_size() { - sleep = true; + // Recalculates the cell_size and number of cols/rows based on font size and + // the Control's rect_size. Ref fontref = fontmap.count("Regular") ? fontmap["Regular"] @@ -557,33 +539,12 @@ void Terminal::update_size() { emit_signal("size_changed", Vector2(cols, rows)); - Cells new_cells = {}; - - for (int x = 0; x < rows; x++) { - Row row(cols); - - for (int y = 0; y < cols; y++) { - if (x < cells.size() && y < cells[x].size()) { - row[y] = cells[x][y]; - } else { - row[y] = empty_cell; - } - } - - new_cells.push_back(row); - } - - cells = new_cells; - tsm_screen_resize(screen, cols, rows); - sleep = false; - framebuffer_age = tsm_screen_draw(screen, text_draw_cb, this); update(); } void Terminal::write(Variant data) { - const char *u8; size_t len; @@ -606,5 +567,6 @@ void Terminal::write(Variant data) { } tsm_vte_input(vte, u8, len); - framebuffer_age = tsm_screen_draw(screen, text_draw_cb, this); + + update(); } diff --git a/addons/godot_xterm/native/src/terminal.h b/addons/godot_xterm/native/src/terminal.h index b815a25..1c8aaee 100644 --- a/addons/godot_xterm/native/src/terminal.h +++ b/addons/godot_xterm/native/src/terminal.h @@ -14,18 +14,6 @@ class Terminal : public Control { GODOT_CLASS(Terminal, Control) public: - struct cell { - char ch[5]; - struct tsm_screen_attr attr; - }; - static const struct cell empty_cell; - -public: - typedef std::vector> Cells; - typedef std::vector Row; - - Cells cells; - Ref input_event_key; protected: @@ -44,11 +32,13 @@ private: std::map> fontmap = {}; void update_size(); - void update_theme(); - std::pair get_cell_colors(int row, int col); + +public: + std::pair get_cell_colors(const tsm_screen_attr *attr); void draw_background(int row, int col, Color bgcol); - void draw_foreground(int row, int col, Color fgcol); + void draw_foreground(int row, int col, char *ch, const tsm_screen_attr *attr, + Color fgcol); public: static void _register_methods(); @@ -64,10 +54,16 @@ public: void write(Variant data); + enum UpdateMode { + DISABLED, + AUTO, + ALL, + ALL_NEXT_FRAME, + }; + int rows; int cols; - - bool sleep; + int update_mode; uint8_t color_palette[TSM_COLOR_NUM][3]; diff --git a/addons/godot_xterm/native/thirdparty/libtsm b/addons/godot_xterm/native/thirdparty/libtsm index 1f3ae2b..1fd9cef 160000 --- a/addons/godot_xterm/native/thirdparty/libtsm +++ b/addons/godot_xterm/native/thirdparty/libtsm @@ -1 +1 @@ -Subproject commit 1f3ae2bc36236136b8ed328b0c64ed954beac33f +Subproject commit 1fd9cef6f2ddef2609d587ea3a5a8eeadb22a2e4 diff --git a/addons/godot_xterm/nodes/terminal/terminal.gd b/addons/godot_xterm/nodes/terminal/terminal.gd new file mode 100644 index 0000000..f370658 --- /dev/null +++ b/addons/godot_xterm/nodes/terminal/terminal.gd @@ -0,0 +1,99 @@ +tool +extends Control + +const DefaultTheme = preload("../../themes/default.tres") + +signal data_sent(data) +signal key_pressed(data, event) +signal size_changed(new_size) + +enum UpdateMode { + DISABLED, + AUTO, + ALL, + ALL_NEXT_FRAME, +} + +export (UpdateMode) var update_mode = UpdateMode.AUTO setget set_update_mode + +var rows: int setget , get_rows # TODO: Show in inspector. +var cols: int setget , get_cols # TODO: Show in inspector. + +var _viewport: Viewport = preload("./viewport.tscn").instance() +var _native_terminal: Control = _viewport.get_node("Terminal") +var _screen := TextureRect.new() +var _visibility_notifier := VisibilityNotifier2D.new() + + +func set_update_mode(value): + update_mode = value + _native_terminal.update_mode = value + + +func get_rows() -> int: + return _native_terminal.rows + + +func get_cols() -> int: + return _native_terminal.cols + + +func write(data) -> void: + assert(data is String or data is PoolByteArray) + _native_terminal.write(data) + + +func _ready(): + if theme: + _native_terminal.theme = theme + + _native_terminal.update_mode = update_mode + _native_terminal.connect("data_sent", self, "_on_data_sent") + _native_terminal.connect("key_pressed", self, "_on_key_pressed") + _native_terminal.connect("size_changed", self, "_on_size_changed") + + _viewport.size = rect_size + _viewport.render_target_update_mode = Viewport.UPDATE_ALWAYS + + _screen.set_anchors_preset(PRESET_WIDE) + _screen.texture = _viewport.get_texture() + + _visibility_notifier.connect("screen_entered", self, "_refresh") + + add_child(_viewport) + add_child(_screen) + add_child(_visibility_notifier) + + _refresh() + + +func _refresh(): + if update_mode == UpdateMode.AUTO: + _native_terminal.update_mode = UpdateMode.ALL_NEXT_FRAME + + +func _gui_input(event): + _native_terminal._gui_input(event) + + +func _notification(what: int) -> void: + match what: + NOTIFICATION_RESIZED: + _viewport.size = rect_size + _visibility_notifier.rect = get_rect() + _refresh() + NOTIFICATION_THEME_CHANGED: + _native_terminal.theme = theme + _refresh() + + +func _on_data_sent(data: PoolByteArray): + emit_signal("data_sent", data) + + +func _on_key_pressed(data: String, event: InputEventKey): + emit_signal("key_pressed", data, event) + + +func _on_size_changed(new_size: Vector2): + emit_signal("size_changed", new_size) diff --git a/addons/godot_xterm/nodes/terminal/viewport.gd b/addons/godot_xterm/nodes/terminal/viewport.gd new file mode 100644 index 0000000..33a83cd --- /dev/null +++ b/addons/godot_xterm/nodes/terminal/viewport.gd @@ -0,0 +1,2 @@ +tool +extends Viewport diff --git a/addons/godot_xterm/nodes/terminal/viewport.tscn b/addons/godot_xterm/nodes/terminal/viewport.tscn new file mode 100644 index 0000000..f6443d5 --- /dev/null +++ b/addons/godot_xterm/nodes/terminal/viewport.tscn @@ -0,0 +1,32 @@ +[gd_scene load_steps=3 format=2] + +[ext_resource path="res://addons/godot_xterm/nodes/terminal/terminal.gdns" type="Script" id=1] + +[sub_resource type="GDScript" id=1] +script/source = "tool +extends Viewport +" + +[node name="Viewport" type="Viewport"] +size = Vector2( 2, 2 ) +own_world = true +transparent_bg = true +handle_input_locally = false +hdr = false +usage = 0 +render_target_v_flip = true +render_target_clear_mode = 1 +gui_snap_controls_to_pixels = false +script = SubResource( 1 ) + +[node name="Terminal" type="Control" parent="."] +anchor_right = 1.0 +anchor_bottom = 1.0 +margin_right = -2.0 +margin_bottom = -2.0 +script = ExtResource( 1 ) +__meta__ = { +"_edit_use_anchors_": false +} +rows = 2 +cols = 1 diff --git a/examples/asciicast/asciicast.tscn b/examples/asciicast/asciicast.tscn index d4aaa43..f89d133 100644 --- a/examples/asciicast/asciicast.tscn +++ b/examples/asciicast/asciicast.tscn @@ -1,20 +1,16 @@ -[gd_scene load_steps=4 format=2] +[gd_scene load_steps=3 format=2] -[ext_resource path="res://addons/godot_xterm/themes/default_dark.tres" type="Theme" id=1] -[ext_resource path="res://addons/godot_xterm/nodes/terminal/terminal.gdns" type="Script" id=4] +[ext_resource path="res://addons/godot_xterm/nodes/terminal/terminal.gd" type="Script" id=1] [ext_resource path="res://examples/asciicast/example.cast" type="Animation" id=6] [node name="Terminal" type="Control"] anchor_right = 1.0 anchor_bottom = 1.0 -focus_mode = 2 -theme = ExtResource( 1 ) -script = ExtResource( 4 ) +focus_mode = 1 +script = ExtResource( 1 ) __meta__ = { "_edit_use_anchors_": false } -rows = 31 -cols = 102 [node name="AnimationPlayer" type="AnimationPlayer" parent="."] autoplay = "example" diff --git a/examples/menu/menu.tscn b/examples/menu/menu.tscn index 0e6b9e5..771deff 100644 --- a/examples/menu/menu.tscn +++ b/examples/menu/menu.tscn @@ -1,8 +1,7 @@ -[gd_scene load_steps=4 format=2] +[gd_scene load_steps=3 format=2] -[ext_resource path="res://addons/godot_xterm/nodes/terminal/terminal.gdns" type="Script" id=1] +[ext_resource path="res://addons/godot_xterm/nodes/terminal/terminal.gd" type="Script" id=1] [ext_resource path="res://examples/menu/menu.gd" type="Script" id=2] -[ext_resource path="res://addons/godot_xterm/themes/default_dark.tres" type="Theme" id=3] [node name="Menu" type="Control"] anchor_right = 1.0 @@ -15,15 +14,11 @@ __meta__ = { [node name="Terminal" type="Control" parent="."] anchor_right = 1.0 anchor_bottom = 1.0 -focus_mode = 2 -size_flags_horizontal = 3 -size_flags_vertical = 3 -theme = ExtResource( 3 ) +rect_pivot_offset = Vector2( -731.582, 67.4799 ) +focus_mode = 1 script = ExtResource( 1 ) __meta__ = { "_edit_use_anchors_": false } -rows = 31 -cols = 102 [connection signal="key_pressed" from="Terminal" to="." method="_on_Terminal_key_pressed"] diff --git a/examples/terminal/terminal.tscn b/examples/terminal/terminal.tscn index 41a2c36..df98ed1 100644 --- a/examples/terminal/terminal.tscn +++ b/examples/terminal/terminal.tscn @@ -1,20 +1,16 @@ -[gd_scene load_steps=4 format=2] +[gd_scene load_steps=3 format=2] -[ext_resource path="res://addons/godot_xterm/nodes/terminal/terminal.gdns" type="Script" id=1] +[ext_resource path="res://addons/godot_xterm/nodes/terminal/terminal.gd" type="Script" id=1] [ext_resource path="res://addons/godot_xterm/nodes/pseudoterminal/pseudoterminal.gdns" type="Script" id=2] -[ext_resource path="res://addons/godot_xterm/themes/default_dark.tres" type="Theme" id=3] [node name="Terminal" type="Control"] anchor_right = 1.0 anchor_bottom = 1.0 -focus_mode = 2 -theme = ExtResource( 3 ) +focus_mode = 1 script = ExtResource( 1 ) __meta__ = { "_edit_use_anchors_": false } -rows = 31 -cols = 102 [node name="Pseudoterminal" type="Node" parent="."] script = ExtResource( 2 ) diff --git a/examples/web_console/web_console.tscn b/examples/web_console/web_console.tscn index 3777e9f..6c3a6fe 100644 --- a/examples/web_console/web_console.tscn +++ b/examples/web_console/web_console.tscn @@ -1,7 +1,6 @@ -[gd_scene load_steps=4 format=2] +[gd_scene load_steps=3 format=2] -[ext_resource path="res://addons/godot_xterm/themes/default_dark.tres" type="Theme" id=1] -[ext_resource path="res://addons/godot_xterm/nodes/terminal/terminal.gdns" type="Script" id=2] +[ext_resource path="res://addons/godot_xterm/nodes/terminal/terminal.gd" type="Script" id=2] [ext_resource path="res://examples/web_console/web_console.gd" type="Script" id=3] [node name="WebConsole" type="Control"] @@ -16,12 +15,9 @@ __meta__ = { anchor_right = 1.0 anchor_bottom = 1.0 focus_mode = 2 -theme = ExtResource( 1 ) script = ExtResource( 2 ) __meta__ = { "_edit_use_anchors_": false } -rows = 31 -cols = 102 [connection signal="key_pressed" from="Terminal" to="." method="_on_Terminal_key_pressed"] diff --git a/test/scenes/basic.gd b/test/scenes/basic.gd new file mode 100644 index 0000000..3621181 --- /dev/null +++ b/test/scenes/basic.gd @@ -0,0 +1,10 @@ +extends Control + +onready var terminal = $Terminal + + +func _ready(): + print("terminal size; rows %d; cols %d;" % [terminal.rows, terminal.cols]) + terminal.write("h") + yield(get_tree().create_timer(1), "timeout") + terminal.write(" i") diff --git a/test/scenes/basic.tscn b/test/scenes/basic.tscn new file mode 100644 index 0000000..54e488d --- /dev/null +++ b/test/scenes/basic.tscn @@ -0,0 +1,29 @@ +[gd_scene load_steps=3 format=2] + +[ext_resource path="res://addons/godot_xterm/nodes/terminal/terminal.gd" type="Script" id=2] +[ext_resource path="res://test/scenes/basic.gd" type="Script" id=3] + +[node name="BasicNewTerm" type="Control"] +margin_right = 43.0 +margin_bottom = 43.0 +script = ExtResource( 3 ) +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="ColorRect" type="ColorRect" parent="."] +margin_right = 40.0 +margin_bottom = 40.0 +color = Color( 0, 1, 0, 1 ) +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Terminal" type="Control" parent="."] +anchor_right = 1.0 +anchor_bottom = 1.0 +focus_mode = 1 +script = ExtResource( 2 ) +__meta__ = { +"_edit_use_anchors_": false +} diff --git a/test/scenes/basic_fullscreen.tscn b/test/scenes/basic_fullscreen.tscn new file mode 100644 index 0000000..a625c73 --- /dev/null +++ b/test/scenes/basic_fullscreen.tscn @@ -0,0 +1,21 @@ +[gd_scene load_steps=3 format=2] + +[ext_resource path="res://addons/godot_xterm/nodes/terminal/terminal.gd" type="Script" id=1] +[ext_resource path="res://test/scenes/basic.gd" type="Script" id=2] + +[node name="BasicNewTerm" type="Control"] +anchor_right = 1.0 +anchor_bottom = 1.0 +script = ExtResource( 2 ) +__meta__ = { +"_edit_use_anchors_": false +} + +[node name="Terminal" type="Control" parent="."] +anchor_right = 1.0 +anchor_bottom = 1.0 +focus_mode = 1 +script = ExtResource( 1 ) +__meta__ = { +"_edit_use_anchors_": false +}