Godot 4 automatic changes

This commit is contained in:
Daniel Inkpen 2022-11-09 20:57:46 +00:00
parent 8b5caafbc7
commit cdbf3f2adc
75 changed files with 1034 additions and 952 deletions

View file

@ -1,11 +1,11 @@
tool @tool
extends "../../terminal.gd" extends "../../terminal.gd"
signal exited(exit_code, signum) signal exited(exit_code, signum)
var editor_settings: EditorSettings var editor_settings: EditorSettings
onready var pty = $PTY @onready var pty = $PTY
# Sets terminal colors according to a dictionary that maps terminal color names # Sets terminal colors according to a dictionary that maps terminal color names
@ -25,7 +25,7 @@ func _ready():
# Get colors from TextEdit theme. Created using the default (Adaptive) theme # Get colors from TextEdit theme. Created using the default (Adaptive) theme
# for reference, but will probably cause strange results if using another theme # for reference, but will probably cause strange results if using another theme
# better to use a dedicated terminal theme, rather than relying on this. # better to use a dedicated terminal theme, rather than relying checked this.
_set_terminal_colors( _set_terminal_colors(
{ {
"black": "caret_background_color", "black": "caret_background_color",

View file

@ -1,4 +1,4 @@
[gd_resource type="ShortCut" load_steps=2 format=2] [gd_resource type="Shortcut" load_steps=2 format=2]
[sub_resource type="InputEventKey" id=1] [sub_resource type="InputEventKey" id=1]
shift = true shift = true

View file

@ -1,4 +1,4 @@
[gd_resource type="ShortCut" load_steps=2 format=2] [gd_resource type="Shortcut" load_steps=2 format=2]
[sub_resource type="InputEventKey" id=1] [sub_resource type="InputEventKey" id=1]
shift = true shift = true

View file

@ -1,4 +1,4 @@
[gd_resource type="ShortCut" load_steps=2 format=2] [gd_resource type="Shortcut" load_steps=2 format=2]
[sub_resource type="InputEventKey" id=1] [sub_resource type="InputEventKey" id=1]
shift = true shift = true

View file

@ -1,4 +1,4 @@
[gd_resource type="ShortCut" load_steps=2 format=2] [gd_resource type="Shortcut" load_steps=2 format=2]
[sub_resource type="InputEventKey" id=1] [sub_resource type="InputEventKey" id=1]
shift = true shift = true

View file

@ -1,4 +1,4 @@
[gd_resource type="ShortCut" load_steps=2 format=2] [gd_resource type="Shortcut" load_steps=2 format=2]
[sub_resource type="InputEventKey" id=1] [sub_resource type="InputEventKey" id=1]
control = true control = true

View file

@ -1,4 +1,4 @@
[gd_resource type="ShortCut" load_steps=2 format=2] [gd_resource type="Shortcut" load_steps=2 format=2]
[sub_resource type="InputEventKey" id=1] [sub_resource type="InputEventKey" id=1]
control = true control = true

View file

@ -12,48 +12,48 @@ enum CWDType {
### Shortcuts ### ### Shortcuts ###
export(ShortCut) var new_terminal_shortcut = preload("./default_new_terminal_shortcut.tres") @export var new_terminal_shortcut: Shortcut = preload("./default_new_terminal_shortcut.tres")
export(ShortCut) var kill_terminal_shortcut = preload("./default_kill_terminal_shortcut.tres") @export var kill_terminal_shortcut: Shortcut = preload("./default_kill_terminal_shortcut.tres")
export(ShortCut) var copy_shortcut = preload("./default_copy_shortcut.tres") @export var copy_shortcut: Shortcut = preload("./default_copy_shortcut.tres")
export(ShortCut) var paste_shortcut = preload("./default_paste_shortcut.tres") @export var paste_shortcut: Shortcut = preload("./default_paste_shortcut.tres")
export(ShortCut) var next_tab_shortcut = preload("./default_tab_right_shortcut.tres") @export var next_tab_shortcut: Shortcut = preload("./default_tab_right_shortcut.tres")
export(ShortCut) var previous_tab_shortcut = preload("./default_tab_left_shortcut.tres") @export var previous_tab_shortcut: Shortcut = preload("./default_tab_left_shortcut.tres")
### Scroll settings ### ### Scroll settings ###
# The maximum amount of lines the terminal keeps in its buffer. # The maximum amount of lines the terminal keeps in its buffer.
export var scrollback_buffer_lines := 1000 @export var scrollback_buffer_lines := 1000
# If true, mouse wheel up and down can be used to scroll the terminal. # If true, mouse wheel up and down can be used to scroll the terminal.
export var mouse_wheel_scroll := true @export var mouse_wheel_scroll := true
# Whether or not to display scroll bar. # Whether or not to display scroll bar.
export var show_scroll_bar := true @export var show_scroll_bar := true
# Copy/paste settings. # Copy/paste settings.
export var copy_on_selection := false @export var copy_on_selection := false
# Font settings. # Font settings.
export var font_size: int = 14 @export var font_size: int = 14
export var letter_spacing: int = 0 @export var letter_spacing: int = 0
export var line_height: float = 1.2 @export var line_height: float = 1.2
export var ctrl_scroll_to_resize_font := true @export var ctrl_scroll_to_resize_font := true
# Bell settings. # Bell settings.
export var visual_bell := true @export var visual_bell := true
export var audio_bell := true @export var audio_bell := true
export var bell_sound: AudioStream @export var bell_sound: AudioStream
# Exec args. # Exec args.
export(FileType) var file_type := FileType.USE_SHELL_ENV @export var file_type: FileType := FileType.USE_SHELL_ENV
export var custom_file := "/bin/sh" @export var custom_file := "/bin/sh"
export(CWDType) var cwd_type := CWDType.USE_PROJECT_DIRECTORY @export var cwd_type: CWDType := CWDType.USE_PROJECT_DIRECTORY
export var custom_cwd := "" @export var custom_cwd := ""
export var args := PoolStringArray() @export var args := PackedStringArray()
export var use_os_env := true @export var use_os_env := true
export var extra_env := { @export var extra_env := {
TERM = "xterm-256color", TERM = "xterm-256color",
COLORTERM = "truecolor", COLORTERM = "truecolor",
} }

View file

@ -4,7 +4,7 @@
# These snippets are copyright of their authors and released under the MIT license: # These snippets are copyright of their authors and released under the MIT license:
# - Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur (MIT License). # - Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur (MIT License).
# - Copyright (c) 2014-2021 Godot Engine contributors (MIT License). # - Copyright (c) 2014-2021 Godot Engine contributors (MIT License).
tool @tool
extends Control extends Control
const EditorTerminal := preload("./editor_terminal.tscn") const EditorTerminal := preload("./editor_terminal.tscn")
@ -23,23 +23,23 @@ enum TerminalPopupMenuOptions {
} }
# Has access to the EditorSettings singleton so it can dynamically generate the # Has access to the EditorSettings singleton so it can dynamically generate the
# terminal color scheme based on editor theme settings. # terminal color scheme based checked editor theme settings.
var editor_plugin: EditorPlugin var editor_plugin: EditorPlugin
var editor_interface: EditorInterface var editor_interface: EditorInterface
onready var editor_settings: EditorSettings = editor_interface.get_editor_settings() @onready var editor_settings: EditorSettings = editor_interface.get_editor_settings()
onready var tabs: Tabs = $VBoxContainer/TabbarContainer/Tabs @onready var tabs: TabBar = $VBoxContainer/TabbarContainer/TabBar
onready var tabbar_container: HBoxContainer = $VBoxContainer/TabbarContainer @onready var tabbar_container: HBoxContainer = $VBoxContainer/TabbarContainer
onready var add_button: ToolButton = $VBoxContainer/TabbarContainer/Tabs/AddButton @onready var add_button: Button = $VBoxContainer/TabbarContainer/TabBar/AddButton
onready var tab_container: TabContainer = $VBoxContainer/TabContainer @onready var tab_container: TabContainer = $VBoxContainer/TabContainer
onready var terminal_popup_menu: PopupMenu = $VBoxContainer/TerminalPopupMenu @onready var terminal_popup_menu: PopupMenu = $VBoxContainer/TerminalPopupMenu
# Size label. # Size label.
# Used to show the size of the terminal (rows/cols) and panel (pixels) when resized. # Used to show the size of the terminal (rows/cols) and panel (pixels) when resized.
onready var size_label: Label = $SizeLabel @onready var size_label: Label = $SizeLabel
onready var size_label_timer: Timer = $SizeLabel/SizeLabelTimer @onready var size_label_timer: Timer = $SizeLabel/SizeLabelTimer
onready var ready := true @onready var ready := true
var _theme := Theme.new() var _theme := Theme.new()
var _settings: TerminalSettings var _settings: TerminalSettings
@ -47,7 +47,7 @@ var _tab_container_min_size
func _ready(): func _ready():
tab_container.add_stylebox_override("panel", get_stylebox("background", "EditorStyles")) tab_container.add_theme_stylebox_override("panel", get_stylebox("background", "EditorStyles"))
_update_settings() _update_settings()
@ -76,10 +76,10 @@ func _update_settings() -> void:
if editor_interface.has_method("get_editor_scale"): if editor_interface.has_method("get_editor_scale"):
editor_scale = editor_interface.get_editor_scale() editor_scale = editor_interface.get_editor_scale()
rect_min_size = Vector2(0, tabbar_container.rect_size.y + 182) * editor_scale minimum_size = Vector2(0, tabbar_container.size.y + 182) * editor_scale
rect_size.y = 415 size.y = 415
tabs.tab_close_display_policy = Tabs.CLOSE_BUTTON_SHOW_ALWAYS tabs.tab_close_display_policy = TabBar.CLOSE_BUTTON_SHOW_ALWAYS
# Update shortcuts. # Update shortcuts.
if _settings.new_terminal_shortcut: if _settings.new_terminal_shortcut:
@ -104,13 +104,13 @@ func _update_settings() -> void:
func _update_terminal_tabs(): func _update_terminal_tabs():
# Wait a couple of frames to allow everything to resize before updating. # Wait a couple of frames to allow everything to resize before updating.
yield(get_tree(), "idle_frame") await get_tree().idle_frame
yield(get_tree(), "idle_frame") await get_tree().idle_frame
if tabs.get_offset_buttons_visible(): if tabs.get_offset_buttons_visible():
# Move add button to fixed position on the tabbar. # Move add button to fixed position checked the tabbar.
if add_button.get_parent() == tabs: if add_button.get_parent() == tabs:
add_button.rect_position = Vector2.ZERO add_button.position = Vector2.ZERO
tabs.remove_child(add_button) tabs.remove_child(add_button)
tabbar_container.add_child(add_button) tabbar_container.add_child(add_button)
tabbar_container.move_child(add_button, 0) tabbar_container.move_child(add_button, 0)
@ -122,7 +122,7 @@ func _update_terminal_tabs():
var last_tab := Rect2() var last_tab := Rect2()
if tabs.get_tab_count() > 0: if tabs.get_tab_count() > 0:
last_tab = tabs.get_tab_rect(tabs.get_tab_count() - 1) last_tab = tabs.get_tab_rect(tabs.get_tab_count() - 1)
add_button.rect_position = Vector2( add_button.position = Vector2(
last_tab.position.x + last_tab.size.x + 3, last_tab.position.y last_tab.position.x + last_tab.size.x + 3, last_tab.position.y
) )
@ -132,12 +132,12 @@ func _update_terminal_tabs():
func _on_AddButton_pressed(): func _on_AddButton_pressed():
var shell = OS.get_environment("SHELL") if OS.has_environment("SHELL") else "sh" var shell = OS.get_environment("SHELL") if OS.has_environment("SHELL") else "sh"
var terminal := EditorTerminal.instance() var terminal := EditorTerminal.instantiate()
tabs.add_tab(shell.get_file()) tabs.add_tab(shell.get_file())
terminal.editor_settings = editor_settings terminal.editor_settings = editor_settings
terminal.set_anchors_preset(PRESET_WIDE) terminal.set_anchors_preset(PRESET_WIDE)
terminal.connect("gui_input", self, "_on_TabContainer_gui_input") terminal.connect("gui_input",Callable(self,"_on_TabContainer_gui_input"))
terminal.connect("exited", self, "_on_Terminal_exited", [terminal]) terminal.connect("exited",Callable(self,"_on_Terminal_exited").bind(terminal))
tab_container.add_child(terminal) tab_container.add_child(terminal)
terminal.pty.fork(shell) terminal.pty.fork(shell)
terminal.grab_focus() terminal.grab_focus()
@ -172,7 +172,7 @@ func _notification(what):
_update_terminal_tabs() _update_terminal_tabs()
NOTIFICATION_RESIZED: NOTIFICATION_RESIZED:
_update_terminal_tabs() _update_terminal_tabs()
NOTIFICATION_WM_FOCUS_IN: NOTIFICATION_APPLICATION_FOCUS_IN:
_update_terminal_tabs() _update_terminal_tabs()
@ -182,7 +182,7 @@ func _input(event: InputEvent) -> void:
# Global shortcut to open new terminal and make terminal panel visible. # Global shortcut to open new terminal and make terminal panel visible.
if _settings.new_terminal_shortcut and _settings.new_terminal_shortcut.shortcut: if _settings.new_terminal_shortcut and _settings.new_terminal_shortcut.shortcut:
if event.shortcut_match(_settings.new_terminal_shortcut.shortcut): if event.is_match(_settings.new_terminal_shortcut.shortcut):
get_tree().set_input_as_handled() get_tree().set_input_as_handled()
editor_plugin.make_bottom_panel_item_visible(self) editor_plugin.make_bottom_panel_item_visible(self)
_on_AddButton_pressed() _on_AddButton_pressed()
@ -194,38 +194,38 @@ func _input(event: InputEvent) -> void:
): ):
# Kill terminal. # Kill terminal.
if _settings.kill_terminal_shortcut and _settings.kill_terminal_shortcut.shortcut: if _settings.kill_terminal_shortcut and _settings.kill_terminal_shortcut.shortcut:
if event.shortcut_match(_settings.kill_terminal_shortcut.shortcut): if event.is_match(_settings.kill_terminal_shortcut.shortcut):
get_tree().set_input_as_handled() get_tree().set_input_as_handled()
_on_TerminalPopupMenu_id_pressed(TerminalPopupMenuOptions.KILL_TERMINAL) _on_TerminalPopupMenu_id_pressed(TerminalPopupMenuOptions.KILL_TERMINAL)
# Copy. # Copy.
if _settings.copy_shortcut and _settings.copy_shortcut.shortcut: if _settings.copy_shortcut and _settings.copy_shortcut.shortcut:
if event.shortcut_match(_settings.copy_shortcut.shortcut): if event.is_match(_settings.copy_shortcut.shortcut):
get_tree().set_input_as_handled() get_tree().set_input_as_handled()
_on_TerminalPopupMenu_id_pressed(TerminalPopupMenuOptions.COPY) _on_TerminalPopupMenu_id_pressed(TerminalPopupMenuOptions.COPY)
# Paste. # Paste.
if _settings.paste_shortcut and _settings.paste_shortcut.shortcut: if _settings.paste_shortcut and _settings.paste_shortcut.shortcut:
if event.shortcut_match(_settings.paste_shortcut.shortcut): if event.is_match(_settings.paste_shortcut.shortcut):
get_tree().set_input_as_handled() get_tree().set_input_as_handled()
_on_TerminalPopupMenu_id_pressed(TerminalPopupMenuOptions.PASTE) _on_TerminalPopupMenu_id_pressed(TerminalPopupMenuOptions.PASTE)
# Next tab. # Next tab.
if _settings.next_tab_shortcut and _settings.next_tab_shortcut.shortcut: if _settings.next_tab_shortcut and _settings.next_tab_shortcut.shortcut:
if event.shortcut_match(_settings.next_tab_shortcut.shortcut): if event.is_match(_settings.next_tab_shortcut.shortcut):
get_tree().set_input_as_handled() get_tree().set_input_as_handled()
tabs.current_tab = min(tabs.current_tab + 1, tabs.get_tab_count() - 1) tabs.current_tab = min(tabs.current_tab + 1, tabs.get_tab_count() - 1)
# Previous tab. # Previous tab.
if _settings.previous_tab_shortcut and _settings.previous_tab_shortcut.shortcut: if _settings.previous_tab_shortcut and _settings.previous_tab_shortcut.shortcut:
if event.shortcut_match(_settings.previous_tab_shortcut.shortcut): if event.is_match(_settings.previous_tab_shortcut.shortcut):
get_tree().set_input_as_handled() get_tree().set_input_as_handled()
tabs.current_tab = max(tabs.current_tab - 1, 0) tabs.current_tab = max(tabs.current_tab - 1, 0)
func _on_TabContainer_gui_input(event): func _on_TabContainer_gui_input(event):
if event is InputEventMouseButton and event.button_index == BUTTON_RIGHT: if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_RIGHT:
terminal_popup_menu.rect_position = event.global_position terminal_popup_menu.position = event.global_position
terminal_popup_menu.popup() terminal_popup_menu.popup()
@ -243,7 +243,7 @@ func _on_TerminalPopupMenu_id_pressed(id):
for i in OS.clipboard.length(): for i in OS.clipboard.length():
var event = InputEventKey.new() var event = InputEventKey.new()
event.unicode = ord(OS.clipboard[i]) event.unicode = ord(OS.clipboard[i])
event.pressed = true event.button_pressed = true
terminal._gui_input(event) terminal._gui_input(event)
TerminalPopupMenuOptions.COPY_ALL: TerminalPopupMenuOptions.COPY_ALL:
OS.clipboard = terminal.copy_all() OS.clipboard = terminal.copy_all()
@ -262,7 +262,7 @@ func _on_Panel_resized():
if not size_label: if not size_label:
return return
var size = tab_container.rect_size var size = tab_container.size
if tabs.get_tab_count() > 0: if tabs.get_tab_count() > 0:
var terminal = tab_container.get_child(tabs.current_tab) var terminal = tab_container.get_child(tabs.current_tab)
var cols = terminal.get_cols() var cols = terminal.get_cols()

View file

@ -4,7 +4,7 @@
[sub_resource type="Image" id=6] [sub_resource type="Image" id=6]
data = { data = {
"data": PoolByteArray( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ), "data": PackedByteArray( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ),
"format": "LumAlpha8", "format": "LumAlpha8",
"height": 16, "height": 16,
"mipmaps": false, "mipmaps": false,
@ -20,14 +20,14 @@ size = Vector2( 16, 16 )
[sub_resource type="StyleBoxTexture" id=3] [sub_resource type="StyleBoxTexture" id=3]
texture = SubResource( 2 ) texture = SubResource( 2 )
region_rect = Rect2( 0, 0, 16, 16 ) region_rect = Rect2( 0, 0, 16, 16 )
margin_left = 2.0 offset_left = 2.0
margin_right = 2.0 offset_right = 2.0
margin_top = 2.0 offset_top = 2.0
margin_bottom = 2.0 offset_bottom = 2.0
[sub_resource type="Image" id=7] [sub_resource type="Image" id=7]
data = { data = {
"data": PoolByteArray( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 224, 224, 0, 224, 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 224, 224, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 224, 224, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 224, 224, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 224, 224, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 224, 224, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 0, 0, 0, 0, 224, 224, 224, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 0, 0, 0, 0, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 224, 224, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 224, 224, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 224, 224, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 224, 224, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 224, 224, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 224, 224, 0, 224, 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ), "data": PackedByteArray( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 224, 224, 0, 224, 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 224, 224, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 224, 224, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 224, 224, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 224, 224, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 224, 224, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 0, 0, 0, 0, 224, 224, 224, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 0, 0, 0, 0, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 224, 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 224, 224, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 224, 224, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 224, 224, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 224, 224, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 224, 224, 0, 224, 224, 224, 255, 224, 224, 224, 255, 224, 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 224, 224, 0, 224, 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ),
"format": "RGBA8", "format": "RGBA8",
"height": 16, "height": 16,
"mipmaps": false, "mipmaps": false,
@ -43,8 +43,8 @@ size = Vector2( 16, 16 )
[node name="Panel" type="Panel"] [node name="Panel" type="Panel"]
anchor_right = 1.0 anchor_right = 1.0
anchor_bottom = 1.0 anchor_bottom = 1.0
margin_top = -3.0 offset_top = -3.0
rect_min_size = Vector2( 0, 34 ) minimum_size = Vector2( 0, 34 )
custom_styles/panel = SubResource( 3 ) custom_styles/panel = SubResource( 3 )
script = ExtResource( 1 ) script = ExtResource( 1 )
__meta__ = { __meta__ = {
@ -54,48 +54,48 @@ __meta__ = {
[node name="VBoxContainer" type="VBoxContainer" parent="."] [node name="VBoxContainer" type="VBoxContainer" parent="."]
anchor_right = 1.0 anchor_right = 1.0
anchor_bottom = 1.0 anchor_bottom = 1.0
rect_min_size = Vector2( 0, 24 ) minimum_size = Vector2( 0, 24 )
custom_constants/separation = 0 custom_constants/separation = 0
__meta__ = { __meta__ = {
"_edit_use_anchors_": false "_edit_use_anchors_": false
} }
[node name="TabbarContainer" type="HBoxContainer" parent="VBoxContainer"] [node name="TabbarContainer" type="HBoxContainer" parent="VBoxContainer"]
margin_right = 1024.0 offset_right = 1024.0
margin_bottom = 24.0 offset_bottom = 24.0
[node name="Tabs" type="Tabs" parent="VBoxContainer/TabbarContainer"] [node name="TabBar" type="TabBar" parent="VBoxContainer/TabbarContainer"]
margin_right = 1024.0 offset_right = 1024.0
margin_bottom = 24.0 offset_bottom = 24.0
size_flags_horizontal = 3 size_flags_horizontal = 3
tab_align = 0 tab_alignment = 0
tab_close_display_policy = 1 tab_close_display_policy = 1
drag_to_rearrange_enabled = true drag_to_rearrange_enabled = true
__meta__ = { __meta__ = {
"_edit_use_anchors_": false "_edit_use_anchors_": false
} }
[node name="AddButton" type="ToolButton" parent="VBoxContainer/TabbarContainer/Tabs"] [node name="AddButton" type="Button" parent="VBoxContainer/TabbarContainer/TabBar"]
margin_left = 3.0 offset_left = 3.0
margin_right = 31.0 offset_right = 31.0
margin_bottom = 24.0 offset_bottom = 24.0
hint_tooltip = "Add a new scene." tooltip_text = "Add a new scene."
icon = SubResource( 5 ) icon = SubResource( 5 )
__meta__ = { __meta__ = {
"_edit_use_anchors_": false "_edit_use_anchors_": false
} }
[node name="PopupMenu" type="PopupMenu" parent="VBoxContainer/TabbarContainer"] [node name="PopupMenu" type="PopupMenu" parent="VBoxContainer/TabbarContainer"]
margin_left = 906.0 offset_left = 906.0
margin_right = 1024.0 offset_right = 1024.0
margin_bottom = 88.0 offset_bottom = 88.0
items = [ "Kill", null, 0, false, false, 0, 0, null, "", false, "Kill Others", null, 0, false, false, 1, 0, null, "", false, "Kill to the Right", null, 0, false, false, 2, 0, null, "", false, "Kill All", null, 0, false, false, 3, 0, null, "", false ] items = [ "Kill", null, 0, false, false, 0, 0, null, "", false, "Kill Others", null, 0, false, false, 1, 0, null, "", false, "Kill to the Right", null, 0, false, false, 2, 0, null, "", false, "Kill All", null, 0, false, false, 3, 0, null, "", false ]
[node name="TabContainer" type="TabContainer" parent="VBoxContainer"] [node name="TabContainer" type="TabContainer" parent="VBoxContainer"]
margin_top = 24.0 offset_top = 24.0
margin_right = 1024.0 offset_right = 1024.0
margin_bottom = 603.0 offset_bottom = 603.0
rect_clip_content = true clip_contents = true
size_flags_vertical = 3 size_flags_vertical = 3
custom_constants/top_margin = 0 custom_constants/top_margin = 0
custom_constants/side_margin = 0 custom_constants/side_margin = 0
@ -103,8 +103,8 @@ custom_styles/panel = SubResource( 3 )
tabs_visible = false tabs_visible = false
[node name="TerminalPopupMenu" type="PopupMenu" parent="VBoxContainer"] [node name="TerminalPopupMenu" type="PopupMenu" parent="VBoxContainer"]
margin_right = 193.0 offset_right = 193.0
margin_bottom = 160.0 offset_bottom = 160.0
size_flags_horizontal = 0 size_flags_horizontal = 0
size_flags_vertical = 0 size_flags_vertical = 0
items = [ "New Terminal", null, 0, false, false, 0, 0, null, "", false, "", null, 0, false, true, 1, 0, null, "", true, "Copy", null, 0, false, false, 2, 0, null, "", false, "Paste", null, 0, false, false, 3, 0, null, "", false, "Copy All", null, 0, false, false, 4, 0, null, "", false, "", null, 0, false, false, 5, 0, null, "", true, "Clear", null, 0, false, false, 6, 0, null, "", false, "Kill Terminal", null, 0, false, false, 7, 0, null, "", false ] items = [ "New Terminal", null, 0, false, false, 0, 0, null, "", false, "", null, 0, false, true, 1, 0, null, "", true, "Copy", null, 0, false, false, 2, 0, null, "", false, "Paste", null, 0, false, false, 3, 0, null, "", false, "Copy All", null, 0, false, false, 4, 0, null, "", false, "", null, 0, false, false, 5, 0, null, "", true, "Clear", null, 0, false, false, 6, 0, null, "", false, "Kill Terminal", null, 0, false, false, 7, 0, null, "", false ]
@ -118,10 +118,10 @@ anchor_left = 0.5
anchor_top = 0.5 anchor_top = 0.5
anchor_right = 0.5 anchor_right = 0.5
anchor_bottom = 0.5 anchor_bottom = 0.5
margin_left = -52.0 offset_left = -52.0
margin_top = -15.5 offset_top = -15.5
margin_right = 52.0 offset_right = 52.0
margin_bottom = 15.5 offset_bottom = 15.5
text = "Size: %d rows; %d cols text = "Size: %d rows; %d cols
(%d x %d)" (%d x %d)"
align = 1 align = 1
@ -133,10 +133,10 @@ __meta__ = {
show_behind_parent = true show_behind_parent = true
anchor_right = 1.0 anchor_right = 1.0
anchor_bottom = 1.0 anchor_bottom = 1.0
margin_left = -5.0 offset_left = -5.0
margin_top = -5.0 offset_top = -5.0
margin_right = 5.0 offset_right = 5.0
margin_bottom = 5.0 offset_bottom = 5.0
grow_horizontal = 2 grow_horizontal = 2
grow_vertical = 2 grow_vertical = 2
__meta__ = { __meta__ = {
@ -146,10 +146,10 @@ __meta__ = {
[node name="SizeLabelTimer" type="Timer" parent="SizeLabel"] [node name="SizeLabelTimer" type="Timer" parent="SizeLabel"]
[connection signal="resized" from="." to="." method="_on_Panel_resized"] [connection signal="resized" from="." to="." method="_on_Panel_resized"]
[connection signal="reposition_active_tab_request" from="VBoxContainer/TabbarContainer/Tabs" to="." method="_on_Tabs_reposition_active_tab_request"] [connection signal="reposition_active_tab_request" from="VBoxContainer/TabbarContainer/TabBar" to="." method="_on_Tabs_reposition_active_tab_request"]
[connection signal="tab_changed" from="VBoxContainer/TabbarContainer/Tabs" to="." method="_on_Tabs_tab_changed"] [connection signal="tab_changed" from="VBoxContainer/TabbarContainer/TabBar" to="." method="_on_Tabs_tab_changed"]
[connection signal="tab_close" from="VBoxContainer/TabbarContainer/Tabs" to="." method="_on_Tabs_tab_close"] [connection signal="tab_closed" from="VBoxContainer/TabbarContainer/TabBar" to="." method="_on_Tabs_tab_close"]
[connection signal="pressed" from="VBoxContainer/TabbarContainer/Tabs/AddButton" to="." method="_on_AddButton_pressed"] [connection signal="pressed" from="VBoxContainer/TabbarContainer/TabBar/AddButton" to="." method="_on_AddButton_pressed"]
[connection signal="gui_input" from="VBoxContainer/TabContainer" to="." method="_on_TabContainer_gui_input"] [connection signal="gui_input" from="VBoxContainer/TabContainer" to="." method="_on_TabContainer_gui_input"]
[connection signal="id_pressed" from="VBoxContainer/TerminalPopupMenu" to="." method="_on_TerminalPopupMenu_id_pressed"] [connection signal="id_pressed" from="VBoxContainer/TerminalPopupMenu" to="." method="_on_TerminalPopupMenu_id_pressed"]
[connection signal="timeout" from="SizeLabel/SizeLabelTimer" to="." method="_on_SizeLabelTimer_timeout"] [connection signal="timeout" from="SizeLabel/SizeLabelTimer" to="." method="_on_SizeLabelTimer_timeout"]

View file

@ -1,34 +1,34 @@
tool @tool
extends EditorImportPlugin extends EditorImportPlugin
const Asciicast = preload("../resources/asciicast.gd") const Asciicast = preload("../resources/asciicast.gd")
func get_importer_name(): func _get_importer_name():
return "godot_xterm" return "godot_xterm"
func get_visible_name(): func _get_visible_name():
return "asciicast" return "asciicast"
func get_recognized_extensions(): func _get_recognized_extensions():
return ["cast"] return ["cast"]
func get_save_extension(): func _get_save_extension():
return "res" return "res"
func get_resource_type(): func _get_resource_type():
return "Animation" return "Animation"
func get_import_options(preset): func _get_import_options(preset):
return [] return []
func get_preset_count(): func _get_preset_count():
return 0 return 0
@ -45,29 +45,31 @@ func import(source_file, save_path, options, r_platform_variant, r_gen_files):
asciicast.add_track(Animation.TYPE_METHOD, 0) asciicast.add_track(Animation.TYPE_METHOD, 0)
asciicast.track_set_path(0, ".") asciicast.track_set_path(0, ".")
var frame = {"time": 0.0, "data": {"method": "write", "args": [PoolByteArray()]}} var frame = {"time": 0.0, "data": {"method": "write", "args": [PackedByteArray()]}}
while not file.eof_reached(): while not file.eof_reached():
var line = file.get_line() var line = file.get_line()
if line == "": if line == "":
continue continue
var p = JSON.parse(line) var test_json_conv = JSON.new()
test_json_conv.parse(line)
var p = test_json_conv.get_data()
if typeof(p.result) != TYPE_ARRAY: if typeof(p.result) != TYPE_ARRAY:
continue continue
var event_type: String = p.result[1] var event_type: String = p.result[1]
var event_data: PoolByteArray = p.result[2].to_utf8() var event_data: PackedByteArray = p.result[2].to_utf8_buffer()
# Asciicast recordings have a resolution of 0.000001, however animation # Asciicast recordings have a resolution of 0.000001, however animation
# track keys only have a resolution of 0.01, therefore we must combine # track keys only have a resolution of 0.01, therefore we must combine
# events that would occur in the same keyframe, otherwise only the last # events that would occur in the same keyframe, otherwise only the last
# event is inserted and the previous events are overwritten. # event is inserted and the previous events are overwritten.
var time = stepify(p.result[0], 0.01) var time = snapped(p.result[0], 0.01)
if event_type == "o": if event_type == "o":
if time == frame.time: if time == frame.time:
asciicast.track_remove_key_at_position(0, time) asciicast.track_remove_key_at_time(0, time)
frame.data.args[0] = frame.data.args[0] + event_data frame.data.args[0] = frame.data.args[0] + event_data
else: else:
frame.time = time frame.time = time
@ -77,4 +79,4 @@ func import(source_file, save_path, options, r_platform_variant, r_gen_files):
asciicast.length = frame.time asciicast.length = frame.time
return ResourceSaver.save("%s.%s" % [save_path, get_save_extension()], asciicast) return ResourceSaver.save("%s.%s" % [save_path, _get_save_extension()], asciicast)

View file

@ -1,34 +1,34 @@
tool @tool
extends EditorImportPlugin extends EditorImportPlugin
const XrdbTheme := preload("../resources/xrdb_theme.gd") const XrdbTheme := preload("../resources/xrdb_theme.gd")
func get_importer_name(): func _get_importer_name():
return "godot_xterm_xrdb_importer" return "godot_xterm_xrdb_importer"
func get_visible_name(): func _get_visible_name():
return "xrdb_theme" return "xrdb_theme"
func get_recognized_extensions(): func _get_recognized_extensions():
return ["xrdb", "Xresources", "xresources"] return ["xrdb", "Xresources", "xresources"]
func get_save_extension(): func _get_save_extension():
return "res" return "res"
func get_resource_type(): func _get_resource_type():
return "Theme" return "Theme"
func get_import_options(preset): func _get_import_options(preset):
return [] return []
func get_preset_count(): func _get_preset_count():
return 0 return 0
@ -121,4 +121,4 @@ func import(source_file, save_path, options, r_platform_variant, r_gen_files):
"cursor_text_color": "cursor_text_color":
theme.set_color("cursor_text", "Terminal", color) theme.set_color("cursor_text", "Terminal", color)
return ResourceSaver.save("%s.%s" % [save_path, get_save_extension()], theme) return ResourceSaver.save("%s.%s" % [save_path, _get_save_extension()], theme)

View file

@ -1,6 +1,6 @@
# Copyright (c) 2021, Leroy Hopson (MIT License) # Copyright (c) 2021, Leroy Hopson (MIT License)
tool @tool
extends Object extends Object
# Wrapper around libuv utility functions. # Wrapper around libuv utility functions.
# GDNative does not currently support registering static functions so we fake it. # GDNative does not currently support registering static functions so we fake it.
@ -23,9 +23,9 @@ static func get_cwd() -> String:
static func get_windows_build_number() -> int: static func get_windows_build_number() -> int:
assert(OS.get_name() == "Windows", "This function is only supported on Windows.") assert(OS.get_name() == "Windows") #,"This function is only supported checked Windows.")
var release: String = LibuvUtils.new().get_os_release() var release: String = LibuvUtils.new().get_os_release()
assert(false, "Not implemented.") assert(false) #,"Not implemented.")
return 0 return 0
@ -35,4 +35,4 @@ static func kill(pid: int, signum: int):
static func new(): static func new():
assert(false, "Abstract sealed (i.e. static) class should not be instantiated.") assert(false) #,"Abstract sealed (i.e. static) class should not be instantiated.")

View file

@ -1,4 +1,4 @@
tool @tool
extends Node extends Node
signal data_received(data) signal data_received(data)
@ -20,5 +20,5 @@ func _not_implemented() -> int:
if stack.size() >= 2 and "function" in stack[1]: if stack.size() >= 2 and "function" in stack[1]:
method = "%s()" % stack[1].function method = "%s()" % stack[1].function
push_error("Method %s not implemented on the current platform (%s)." % [method, OS.get_name()]) push_error("Method %s not implemented checked the current platform (%s)." % [method, OS.get_name()])
return ERR_METHOD_NOT_FOUND return ERR_METHOD_NOT_FOUND

View file

@ -3,7 +3,7 @@
# Copyright (c) 2016, Daniel Imms (MIT License). # Copyright (c) 2016, Daniel Imms (MIT License).
# Copyright (c) 2018, Microsoft Corporation (MIT License). # Copyright (c) 2018, Microsoft Corporation (MIT License).
# Copyright (c) 2021-2022, Leroy Hopson (MIT License). # Copyright (c) 2021-2022, Leroy Hopson (MIT License).
tool @tool
extends "../pty_native.gd" extends "../pty_native.gd"
const LibuvUtils := preload("../libuv_utils.gd") const LibuvUtils := preload("../libuv_utils.gd")
@ -18,7 +18,7 @@ const DEFAULT_ENV := {TERM = DEFAULT_NAME, COLORTERM = "truecolor"}
const FALLBACK_FILE = "sh" const FALLBACK_FILE = "sh"
## Default messages to indicate PAUSE/RESUME for automatic flow control. ## Default messages to indicate PAUSE/RESUME for automatic flow control.
## To avoid conflicts with rebound XON/XOFF control codes (such as on-my-zsh), ## To avoid conflicts with rebound XON/XOFF control codes (such as checked-my-zsh),
## the sequences can be customized in IPtyForkOptions. ## the sequences can be customized in IPtyForkOptions.
#const FLOW_CONTROL_PAUSE = char(0x13) # defaults to XOFF #const FLOW_CONTROL_PAUSE = char(0x13) # defaults to XOFF
#const FLOW_CONTROL_RESUME = char(0x11) # defaults to XON #const FLOW_CONTROL_RESUME = char(0x11) # defaults to XON
@ -35,7 +35,7 @@ enum Signal {
SIGFPE = 8, # Erroneous arithmetic operation SIGFPE = 8, # Erroneous arithmetic operation
SIGKILL = 9, # Kill (cannot be caught or ignored) SIGKILL = 9, # Kill (cannot be caught or ignored)
SIGSEGV = 11, # Invalid memory reference SIGSEGV = 11, # Invalid memory reference
SIGPIPE = 13, # Write on a pipe with no one to read it SIGPIPE = 13, # Write checked a pipe with no one to read it
SIGALRM = 14, # Alarm clock SIGALRM = 14, # Alarm clock
SIGTERM = 15, # Termination signal SIGTERM = 15, # Termination signal
} }
@ -62,18 +62,18 @@ var uid: int
var gid: int var gid: int
var _fd: int = -1 var _fd: int = -1
var _exit_cb: FuncRef var _exit_cb: Callable
# Writes data to the socket. # Writes data to the socket.
# data: The data to write. # data: The data to write.
func write(data) -> void: func write(data) -> void:
assert( assert(
data is PoolByteArray or data is String, data is PackedByteArray or data is String,
"Invalid type for argument 'data'. Should be of type PoolByteArray or String" "Invalid type for argument 'data'. Should be of type PackedByteArray or String"
) )
if _pipe: if _pipe:
_pipe.write(data if data is PoolByteArray else data.to_utf8()) _pipe.write(data if data is PackedByteArray else data.to_utf8_buffer())
func resize(cols: int, rows: int) -> void: func resize(cols: int, rows: int) -> void:
@ -88,14 +88,14 @@ func kill(signum: int = Signal.SIGHUP) -> void:
LibuvUtils.kill(_pid, signum) LibuvUtils.kill(_pid, signum)
func _parse_env(env: Dictionary = {}) -> PoolStringArray: func _parse_env(env: Dictionary = {}) -> PackedStringArray:
var keys := env.keys() var keys := env.keys()
var pairs := PoolStringArray() var pairs := PackedStringArray()
for key in keys: for key in keys:
var value = env[key] var value = env[key]
var valid = key is String and value is String var valid = key is String and value is String
assert(valid, "Env key/value pairs must be of type String/String.") assert(valid) #,"Env key/value pairs must be of type String/String.")
if not valid: if not valid:
push_warning("Skipping invalid env key/value pair.") push_warning("Skipping invalid env key/value pair.")
@ -113,7 +113,7 @@ func _process(_delta):
func fork( func fork(
file: String = OS.get_environment("SHELL"), file: String = OS.get_environment("SHELL"),
args: PoolStringArray = PoolStringArray(), args: PackedStringArray = PackedStringArray(),
cwd = LibuvUtils.get_cwd(), cwd = LibuvUtils.get_cwd(),
cols: int = DEFAULT_COLS, cols: int = DEFAULT_COLS,
rows: int = DEFAULT_ROWS, rows: int = DEFAULT_ROWS,
@ -122,18 +122,18 @@ func fork(
utf8 = true utf8 = true
) -> int: ) -> int:
# File. # File.
if file.empty(): if file.is_empty():
file = FALLBACK_FILE file = FALLBACK_FILE
# Environment variables. # Environment variables.
# If we are using OS env vars, sanitize them to remove variables that might confuse our terminal. # If we are using OS env vars, sanitize them to remove_at variables that might confuse our terminal.
var final_env := _sanitize_env(LibuvUtils.get_os_environ()) if use_os_env else {} var final_env := _sanitize_env(LibuvUtils.get_os_environ()) if use_os_env else {}
for key in env.keys(): for key in env.keys():
final_env[key] = env[key] final_env[key] = env[key]
var parsed_env: PoolStringArray = _parse_env(final_env) var parsed_env: PackedStringArray = _parse_env(final_env)
# Exit callback. # Exit callback.
_exit_cb = FuncRef.new() _exit_cb = Callable.new()
_exit_cb.set_instance(self) _exit_cb.set_instance(self)
_exit_cb.set_function("_on_exit") _exit_cb.set_function("_on_exit")
@ -157,7 +157,7 @@ func fork(
_pipe.open(_fd) _pipe.open(_fd)
# Must connect to signal AFTER opening, otherwise we will get error ENOTSOCK. # Must connect to signal AFTER opening, otherwise we will get error ENOTSOCK.
_pipe.connect("data_received", self, "_on_pipe_data_received") _pipe.connect("data_received",Callable(self,"_on_pipe_data_received"))
return OK return OK

View file

@ -1,2 +1,2 @@
tool @tool
extends Viewport extends SubViewport

View file

@ -4,10 +4,10 @@
[sub_resource type="GDScript" id=1] [sub_resource type="GDScript" id=1]
script/source = "tool script/source = "tool
extends Viewport extends SubViewport
" "
[node name="Viewport" type="Viewport"] [node name="SubViewport" type="SubViewport"]
size = Vector2( 2, 2 ) size = Vector2( 2, 2 )
own_world = true own_world = true
transparent_bg = true transparent_bg = true
@ -22,8 +22,8 @@ script = SubResource( 1 )
[node name="Terminal" type="Control" parent="."] [node name="Terminal" type="Control" parent="."]
anchor_right = 1.0 anchor_right = 1.0
anchor_bottom = 1.0 anchor_bottom = 1.0
margin_right = -2.0 offset_right = -2.0
margin_bottom = -2.0 offset_bottom = -2.0
script = ExtResource( 1 ) script = ExtResource( 1 )
__meta__ = { __meta__ = {
"_edit_use_anchors_": false "_edit_use_anchors_": false

View file

@ -1,4 +1,4 @@
tool @tool
extends EditorPlugin extends EditorPlugin
var pty_supported := OS.get_name() in ["X11", "Server", "OSX"] var pty_supported := OS.get_name() in ["X11", "Server", "OSX"]
@ -31,7 +31,7 @@ func _enter_tree():
"X11", "Server", "OSX": "X11", "Server", "OSX":
pty_script = load("%s/pty.gd" % base_dir) pty_script = load("%s/pty.gd" % base_dir)
add_custom_type("PTY", "Node", pty_script, pty_icon) add_custom_type("PTY", "Node", pty_script, pty_icon)
terminal_panel = preload("./editor_plugins/terminal/terminal_panel.tscn").instance() terminal_panel = preload("./editor_plugins/terminal/terminal_panel.tscn").instantiate()
terminal_panel.editor_plugin = self terminal_panel.editor_plugin = self
terminal_panel.editor_interface = get_editor_interface() terminal_panel.editor_interface = get_editor_interface()
add_control_to_bottom_panel(terminal_panel, "Terminal") add_control_to_bottom_panel(terminal_panel, "Terminal")

View file

@ -3,7 +3,7 @@
# Copyright (c) 2016, Daniel Imms (MIT License). # Copyright (c) 2016, Daniel Imms (MIT License).
# Copyright (c) 2018, Microsoft Corporation (MIT License). # Copyright (c) 2018, Microsoft Corporation (MIT License).
# Copyright (c) 2021-2022, Leroy Hopson (MIT License). # Copyright (c) 2021-2022, Leroy Hopson (MIT License).
tool @tool
extends Node extends Node
const _LibuvUtils := preload("./nodes/pty/libuv_utils.gd") const _LibuvUtils := preload("./nodes/pty/libuv_utils.gd")
@ -23,23 +23,39 @@ const Signal = _PTYUnix.Signal
signal data_received(data) signal data_received(data)
signal exited(exit_code, signum) signal exited(exit_code, signum)
export(NodePath) var terminal_path := NodePath() setget set_terminal_path @export var terminal_path: NodePath := NodePath() :
get:
return terminal_path # TODOConverter40 Non existent get function
set(mod_value):
mod_value # TODOConverter40 Copy here content of set_terminal_path
var _terminal: _Terminal = null setget _set_terminal var _terminal: _Terminal = null :
get:
return _terminal # TODOConverter40 Non existent get function
set(mod_value):
mod_value # TODOConverter40 Copy here content of _set_terminal
# The column size in characters. # The column size in characters.
export(int) var cols: int = DEFAULT_COLS setget set_cols, get_cols @export var cols: int: int = DEFAULT_COLS :
get:
return cols # TODOConverter40 Copy here content of get_cols
set(mod_value):
mod_value # TODOConverter40 Copy here content of set_cols
# The row size in characters. # The row size in characters.
export(int) var rows: int = DEFAULT_ROWS setget set_rows, get_rows @export var rows: int: int = DEFAULT_ROWS :
get:
return rows # TODOConverter40 Copy here content of get_rows
set(mod_value):
mod_value # TODOConverter40 Copy here content of set_rows
# Environment to be set for the child program. # Environment to be set for the child program.
export(Dictionary) var env := DEFAULT_ENV @export var env: Dictionary := DEFAULT_ENV
# If true the environment variables in the env Dictionary will be merged with # If true the environment variables in the env Dictionary will be merged with
# the environment variables of the operating system (e.g. printenv), with the # the environment variables of the operating system (e.g. printenv), with the
# former taking precedence in the case of conflicts. # former taking precedence in the case of conflicts.
export(bool) var use_os_env := true @export var use_os_env: bool := true
var _cols := DEFAULT_COLS var _cols := DEFAULT_COLS
var _rows := DEFAULT_ROWS var _rows := DEFAULT_ROWS
@ -52,10 +68,10 @@ func _init():
"X11", "Server", "OSX": "X11", "Server", "OSX":
_pty_native = _PTYUnix.new() _pty_native = _PTYUnix.new()
_: _:
push_error("PTY is not support on current platform (%s)." % os_name) push_error("PTY is not support checked current platform (%s)." % os_name)
_pty_native.connect("data_received", self, "_on_pty_native_data_received") _pty_native.connect("data_received",Callable(self,"_on_pty_native_data_received"))
_pty_native.connect("exited", self, "_on_pty_native_exited") _pty_native.connect("exited",Callable(self,"_on_pty_native_exited"))
add_child(_pty_native) add_child(_pty_native)
@ -92,9 +108,9 @@ func _set_terminal(value: _Terminal):
# Disconect the current terminal, if any. # Disconect the current terminal, if any.
if _terminal: if _terminal:
disconnect("data_received", _terminal, "write") disconnect("data_received",Callable(_terminal,"write"))
_terminal.disconnect("data_sent", self, "write") _terminal.disconnect("data_sent",Callable(self,"write"))
_terminal.disconnect("size_changed", self, "resizev") _terminal.disconnect("size_changed",Callable(self,"resizev"))
_terminal = value _terminal = value
@ -103,12 +119,12 @@ func _set_terminal(value: _Terminal):
# Connect the new terminal. # Connect the new terminal.
resize(_terminal.get_cols(), _terminal.get_rows()) resize(_terminal.get_cols(), _terminal.get_rows())
if not _terminal.is_connected("size_changed", self, "resizev"): if not _terminal.is_connected("size_changed",Callable(self,"resizev")):
_terminal.connect("size_changed", self, "resizev") _terminal.connect("size_changed",Callable(self,"resizev"))
if not _terminal.is_connected("data_sent", self, "write"): if not _terminal.is_connected("data_sent",Callable(self,"write")):
_terminal.connect("data_sent", self, "write") _terminal.connect("data_sent",Callable(self,"write"))
if not is_connected("data_received", _terminal, "write"): if not is_connected("data_received",Callable(_terminal,"write")):
connect("data_received", _terminal, "write") connect("data_received",Callable(_terminal,"write"))
# Writes data to the socket. # Writes data to the socket.
@ -138,7 +154,7 @@ func resizev(size: Vector2) -> void:
# Kill the pty. # Kill the pty.
# sigint: The signal to send. By default this is SIGHUP. # sigint: The signal to send. By default this is SIGHUP.
# This is not supported on Windows. # This is not supported checked Windows.
func kill(signum: int = Signal.SIGHUP) -> void: func kill(signum: int = Signal.SIGHUP) -> void:
_pty_native.kill(signum) _pty_native.kill(signum)
@ -153,7 +169,7 @@ func _notification(what: int):
func fork( func fork(
file: String = OS.get_environment("SHELL"), file: String = OS.get_environment("SHELL"),
args: PoolStringArray = PoolStringArray(), args: PackedStringArray = PackedStringArray(),
cwd = _LibuvUtils.get_cwd(), cwd = _LibuvUtils.get_cwd(),
cols: int = _cols, cols: int = _cols,
rows: int = _rows, rows: int = _rows,

View file

@ -3,11 +3,11 @@ extends Animation
signal data_written(data) signal data_written(data)
signal data_read(data) signal data_read(data)
export(int) var version: int = 2 @export var version: int: int = 2
# Initial terminal width (number of columns). # Initial terminal width (number of columns).
export(int) var width: int @export var width: int: int
# Initial terminal height (number of rows). # Initial terminal height (number of rows).
export(int) var height: int @export var height: int: int
func get_class() -> String: func get_class() -> String:
@ -15,7 +15,7 @@ func get_class() -> String:
func is_class(name) -> bool: func is_class(name) -> bool:
return name == get_class() or .is_class(name) return name == get_class() or super.is_class(name)
func _init(): func _init():

View file

@ -6,4 +6,4 @@ func get_class() -> String:
func is_class(name) -> bool: func is_class(name) -> bool:
return name == get_class() or .is_class(name) return name == get_class() or super.is_class(name)

View file

@ -4,7 +4,7 @@
# These snippets are copyright of their authors and released under the MIT license: # These snippets are copyright of their authors and released under the MIT license:
# - Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur (MIT License). # - Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur (MIT License).
# - Copyright (c) 2014-2021 Godot Engine contributors (MIT License). # - Copyright (c) 2014-2021 Godot Engine contributors (MIT License).
tool @tool
extends Control extends Control
signal data_sent(data) signal data_sent(data)
@ -24,28 +24,32 @@ enum SelectionMode {
POINTER, POINTER,
} }
export(UpdateMode) var update_mode = UpdateMode.AUTO setget set_update_mode @export var update_mode: UpdateMode = UpdateMode.AUTO :
get:
return update_mode # TODOConverter40 Non existent get function
set(mod_value):
mod_value # TODOConverter40 Copy here content of set_update_mode
# If true, text in the terminal will be copied to the clipboard when selected. # If true, text in the terminal will be copied to the clipboard when selected.
export(bool) var copy_on_selection @export var copy_on_selection: bool
# Bell # Bell
# If muted, the "bell" signal will not be emitted when the bell "\u0007" character # If muted, the "bell" signal will not be emitted when the bell "\u0007" character
# is written to the terminal. # is written to the terminal.
export var bell_muted := false @export var bell_muted := false
# Amount of time in seconds that must pass before emitting a new "bell" signal. # Amount of time in seconds that must pass before emitting a new "bell" signal.
# This can be useful in cases where the bell character is being written too # This can be useful in cases where the bell character is being written too
# frequently such as `while true; do echo -e "\a"; done`. # frequently such as `while true; do echo -e "\a"; done`.
export var bell_cooldown: float = 0.1 @export var bell_cooldown: float = 0.1
export var blink_on_time: float = 0.6 @export var blink_on_time: float = 0.6
export var blink_off_time: float = 0.3 @export var blink_off_time: float = 0.3
var _cols := 2 var _cols := 2
var _rows := 2 var _rows := 2
var _default_theme: Theme = preload("./themes/default.tres") var _default_theme: Theme = preload("./themes/default.tres")
var _viewport: Viewport = preload("./nodes/terminal/viewport.tscn").instance() var _viewport: SubViewport = preload("./nodes/terminal/viewport.tscn").instantiate()
var _native_terminal: Control = _viewport.get_node("Terminal") var _native_terminal: Control = _viewport.get_node("Terminal")
var _screen := TextureRect.new() var _screen := TextureRect.new()
@ -73,11 +77,11 @@ func get_rows() -> int:
func write(data) -> void: func write(data) -> void:
assert( assert(
data is PoolByteArray or data is String, data is PackedByteArray or data is String,
"Invalid type for argument 'data'. Should be of type PoolByteArray or String." "Invalid type for argument 'data'. Should be of type PackedByteArray or String."
) )
# Will be cleared when _flush() is called after VisualServer emits the "frame_pre_draw" signal. # Will be cleared when _flush() is called after RenderingServer emits the "frame_pre_draw" signal.
_buffer.push_back(data) _buffer.push_back(data)
# Ensure redraw is requested if terminal is visible. # Ensure redraw is requested if terminal is visible.
@ -87,16 +91,16 @@ func write(data) -> void:
func _flush(): func _flush():
for data in _buffer: for data in _buffer:
_native_terminal.write(data if data is PoolByteArray else data.to_utf8()) _native_terminal.write(data if data is PackedByteArray else data.to_utf8_buffer())
_native_terminal.update() _native_terminal.update()
_buffer.clear() _buffer.clear()
func clear() -> void: func clear() -> void:
var initial_size = _native_terminal.rect_size var initial_size = _native_terminal.size
_native_terminal.rect_size.y = _native_terminal.cell_size.y _native_terminal.size.y = _native_terminal.cell_size.y
_native_terminal.clear_sb() _native_terminal.clear_sb()
_native_terminal.rect_size = initial_size _native_terminal.size = initial_size
func copy_selection() -> String: func copy_selection() -> String:
@ -111,22 +115,22 @@ func _ready():
_update_theme() _update_theme()
_native_terminal.update_mode = update_mode _native_terminal.update_mode = update_mode
_native_terminal.connect("data_sent", self, "_on_data_sent") _native_terminal.connect("data_sent",Callable(self,"_on_data_sent"))
_native_terminal.connect("key_pressed", self, "_on_key_pressed") _native_terminal.connect("key_pressed",Callable(self,"_on_key_pressed"))
_native_terminal.connect("size_changed", self, "_on_size_changed") _native_terminal.connect("size_changed",Callable(self,"_on_size_changed"))
_viewport.size = rect_size _viewport.size = size
_viewport.render_target_update_mode = Viewport.UPDATE_ALWAYS _viewport.render_target_update_mode = SubViewport.UPDATE_ALWAYS
_screen.set_anchors_preset(PRESET_WIDE) _screen.set_anchors_preset(PRESET_WIDE)
_screen.texture = _viewport.get_texture() _screen.texture = _viewport.get_texture()
_native_terminal.connect("bell", self, "_on_bell") _native_terminal.connect("bell",Callable(self,"_on_bell"))
_bell_timer.one_shot = true _bell_timer.one_shot = true
add_child(_bell_timer) add_child(_bell_timer)
_selection_timer.wait_time = 0.05 _selection_timer.wait_time = 0.05
_selection_timer.connect("timeout", self, "_on_selection_held") _selection_timer.connect("timeout",Callable(self,"_on_selection_held"))
add_child(_viewport) add_child(_viewport)
add_child(_screen) add_child(_screen)
@ -138,31 +142,31 @@ func _ready():
# we make all the draw_* calls caused by writing. We need to use signals # we make all the draw_* calls caused by writing. We need to use signals
# here rather than yield otherwise we will sometimes get a "Resumed # here rather than yield otherwise we will sometimes get a "Resumed
# function after yield but class instance is gone" error. # function after yield but class instance is gone" error.
VisualServer.connect("frame_pre_draw", self, "_flush") RenderingServer.connect("frame_pre_draw",Callable(self,"_flush"))
func _update_theme(): func _update_theme():
# Themes are not propagated through the Viewport, so in order for theme # Themes are not propagated through the SubViewport, so in order for theme
# inheritance to work we can pass through the theme variables manually. # inheritance to work we can pass through the theme variables manually.
for color in _default_theme.get_color_list("Terminal"): for color in _default_theme.get_color_list("Terminal"):
var c: Color var c: Color
if has_color(color, "Terminal"): if has_theme_color(color, "Terminal"):
c = get_color(color, "Terminal") c = get_color(color, "Terminal")
else: else:
c = _default_theme.get_color(color, "Terminal") c = _default_theme.get_color(color, "Terminal")
_native_terminal.add_color_override(color, c) _native_terminal.add_theme_color_override(color, c)
for font in _default_theme.get_font_list("Terminal"): for font in _default_theme.get_font_list("Terminal"):
var f: Font var f: Font
if has_font(font, "Terminal"): if has_theme_font(font, "Terminal"):
f = get_font(font, "Terminal") f = get_font(font, "Terminal")
elif has_font("regular", "Terminal"): elif has_theme_font("regular", "Terminal"):
f = get_font("regular", "Terminal") f = get_font("regular", "Terminal")
else: else:
if _default_theme.has_font(font, "Terminal"): if _default_theme.has_theme_font(font, "Terminal"):
f = _default_theme.get_font(font, "Terminal") f = _default_theme.get_font(font, "Terminal")
else: else:
f = _default_theme.get_font(font, "regular") f = _default_theme.get_font(font, "regular")
_native_terminal.add_font_override(font, f) _native_terminal.add_theme_font_override(font, f)
_native_terminal._update_theme() _native_terminal._update_theme()
_native_terminal._update_size() _native_terminal._update_size()
@ -180,7 +184,7 @@ func _gui_input(event):
# Return to bottom of scrollback buffer if we scrolled up. Ignore modifier # Return to bottom of scrollback buffer if we scrolled up. Ignore modifier
# keys pressed in isolation or if Ctrl+Shift modifier keys are pressed. # keys pressed in isolation or if Ctrl+Shift modifier keys are pressed.
if ( if (
not event.scancode in [KEY_ALT, KEY_SHIFT, KEY_CONTROL, KEY_META, KEY_MASK_CMD] not event.scancode in [KEY_ALT, KEY_SHIFT, KEY_CTRL, KEY_META, KEY_MASK_CMD]
and not (event.control and event.shift) and not (event.control and event.shift)
): ):
_native_terminal.sb_reset() _native_terminal.sb_reset()
@ -197,7 +201,7 @@ func _handle_mouse_wheel(event: InputEventMouseButton):
if not event or not event.is_pressed(): if not event or not event.is_pressed():
return return
if event.button_index == BUTTON_WHEEL_UP: if event.button_index == MOUSE_BUTTON_WHEEL_UP:
if event.alt: if event.alt:
# Scroll 5 times as fast as normal (like TextEdit). # Scroll 5 times as fast as normal (like TextEdit).
_native_terminal.sb_up(15 * event.factor) _native_terminal.sb_up(15 * event.factor)
@ -205,7 +209,7 @@ func _handle_mouse_wheel(event: InputEventMouseButton):
# Scroll 3 lines. # Scroll 3 lines.
_native_terminal.sb_up(3 * event.factor) _native_terminal.sb_up(3 * event.factor)
if event.button_index == BUTTON_WHEEL_DOWN: if event.button_index == MOUSE_BUTTON_WHEEL_DOWN:
if event.alt: if event.alt:
# Scroll 5 times as fast as normal (like TextEdit). # Scroll 5 times as fast as normal (like TextEdit).
_native_terminal.sb_down(15 * event.factor) _native_terminal.sb_down(15 * event.factor)
@ -216,7 +220,7 @@ func _handle_mouse_wheel(event: InputEventMouseButton):
func _handle_selection(event: InputEventMouse): func _handle_selection(event: InputEventMouse):
if event is InputEventMouseButton: if event is InputEventMouseButton:
if not event or not event.is_pressed() or not event.button_index == BUTTON_LEFT: if not event or not event.is_pressed() or not event.button_index == MOUSE_BUTTON_LEFT:
return return
if _selecting: if _selecting:
@ -230,7 +234,7 @@ func _handle_selection(event: InputEventMouse):
elif event is InputEventMouseMotion: elif event is InputEventMouseMotion:
if ( if (
event.button_mask & BUTTON_MASK_LEFT event.button_mask & MOUSE_BUTTON_MASK_LEFT
and _selecting_mode != SelectionMode.NONE and _selecting_mode != SelectionMode.NONE
and not _selecting and not _selecting
): ):
@ -240,7 +244,7 @@ func _handle_selection(event: InputEventMouse):
func _on_selection_held() -> void: func _on_selection_held() -> void:
if not Input.is_mouse_button_pressed(BUTTON_LEFT) or _selecting_mode == SelectionMode.NONE: if not Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT) or _selecting_mode == SelectionMode.NONE:
if copy_on_selection: if copy_on_selection:
var selection = _native_terminal.copy_selection() var selection = _native_terminal.copy_selection()
OS.set_clipboard(selection) OS.set_clipboard(selection)
@ -255,18 +259,18 @@ func _on_selection_held() -> void:
func _notification(what: int) -> void: func _notification(what: int) -> void:
match what: match what:
NOTIFICATION_RESIZED: NOTIFICATION_RESIZED:
_viewport.size = rect_size _viewport.size = size
_refresh() _refresh()
NOTIFICATION_THEME_CHANGED: NOTIFICATION_THEME_CHANGED:
_update_theme() _update_theme()
_refresh() _refresh()
func _on_data_sent(data: PoolByteArray): func _on_data_sent(data: PackedByteArray):
emit_signal("data_sent", data) emit_signal("data_sent", data)
func _on_key_pressed(data: PoolByteArray, event: InputEventKey): func _on_key_pressed(data: PackedByteArray, event: InputEventKey):
emit_signal("key_pressed", data.get_string_from_utf8(), event) emit_signal("key_pressed", data.get_string_from_utf8(), event)

View file

@ -1,6 +1,6 @@
[gd_resource type="Theme" load_steps=2 format=2] [gd_resource type="Theme" load_steps=2 format=2]
[ext_resource path="res://addons/godot_xterm/themes/fonts/regular.tres" type="DynamicFont" id=1] [ext_resource path="res://addons/godot_xterm/themes/fonts/regular.tres" type="FontFile" id=1]
[resource] [resource]
default_font = ExtResource( 1 ) default_font = ExtResource( 1 )

View file

@ -1,6 +1,6 @@
[gd_resource type="Theme" load_steps=2 format=2] [gd_resource type="Theme" load_steps=2 format=2]
[ext_resource path="res://addons/godot_xterm/themes/fonts/regular.tres" type="DynamicFont" id=4] [ext_resource path="res://addons/godot_xterm/themes/fonts/regular.tres" type="FontFile" id=4]
[resource] [resource]
default_font = ExtResource( 4 ) default_font = ExtResource( 4 )

View file

@ -1,6 +1,6 @@
[gd_resource type="Theme" load_steps=2 format=2] [gd_resource type="Theme" load_steps=2 format=2]
[sub_resource type="DynamicFont" id=1] [sub_resource type="FontFile" id=1]
size = 14 size = 14
extra_spacing_bottom = 1 extra_spacing_bottom = 1

View file

@ -1,6 +1,6 @@
[gd_resource type="DynamicFont" load_steps=2 format=2] [gd_resource type="FontFile" load_steps=2 format=2]
[ext_resource path="res://addons/godot_xterm/themes/fonts/hack/hack_regular-3.003.ttf" type="DynamicFontData" id=4] [ext_resource path="res://addons/godot_xterm/themes/fonts/hack/hack_regular-3.003.ttf" type="FontFile" id=4]
[resource] [resource]
size = 14 size = 14

View file

@ -1,4 +1,4 @@
extends Reference extends RefCounted
# Control Sequence Introducer # Control Sequence Introducer
const CSI = "\u001b[" const CSI = "\u001b["
@ -17,24 +17,24 @@ class ANSIColor:
# colors of the selected terminal theme. Whereas Color will set # colors of the selected terminal theme. Whereas Color will set
# the exact color specified regardless of theme. # the exact color specified regardless of theme.
const black = {fg = 30, bg = 40} const black = {fg = 30, panel = 40}
const red = {fg = 31, bg = 41} const red = {fg = 31, panel = 41}
const green = {fg = 32, bg = 42} const green = {fg = 32, panel = 42}
const yellow = {fg = 33, bg = 43} const yellow = {fg = 33, panel = 43}
const blue = {fg = 34, bg = 44} const blue = {fg = 34, panel = 44}
const magenta = {fg = 35, bg = 45} const magenta = {fg = 35, panel = 45}
const cyan = {fg = 36, bg = 46} const cyan = {fg = 36, panel = 46}
const white = {fg = 37, bg = 47} const white = {fg = 37, panel = 47}
const bright_black = {fg = 90, bg = 100} const bright_black = {fg = 90, panel = 100}
const gray = bright_black const gray = bright_black
const grey = bright_black const grey = bright_black
const bright_red = {fg = 91, bg = 101} const bright_red = {fg = 91, panel = 101}
const bright_green = {fg = 92, bg = 102} const bright_green = {fg = 92, panel = 102}
const bright_yellow = {fg = 93, bg = 103} const bright_yellow = {fg = 93, panel = 103}
const bright_blue = {fg = 94, bg = 104} const bright_blue = {fg = 94, panel = 104}
const bright_magenta = {fg = 95, bg = 105} const bright_magenta = {fg = 95, panel = 105}
const bright_cyan = {fg = 96, bg = 106} const bright_cyan = {fg = 96, panel = 106}
const bright_white = {fg = 97, bg = 107} const bright_white = {fg = 97, panel = 107}
func _init(): func _init():
assert( assert(
@ -46,23 +46,23 @@ class ANSIColor:
var terminal var terminal
func _init(p_terminal: Control) -> void: func _init(p_terminal: Control):
if p_terminal: if p_terminal:
terminal = p_terminal terminal = p_terminal
func write_string(string: String, color: Color = Color.white) -> void: func write_string(string: String, color: Color = Color.WHITE) -> void:
if color: if color:
var fg = "\u001b[38;2;%d;%d;%dm" % [color.r8, color.g8, color.b8] var fg = "\u001b[38;2;%d;%d;%dm" % [color.r8, color.g8, color.b8]
terminal.write(fg.to_utf8()) terminal.write(fg.to_utf8_buffer())
terminal.write(string.to_utf8()) terminal.write(string.to_utf8_buffer())
# Reset color back to default. # Reset color back to default.
terminal.write("\u001b[0m".to_utf8()) terminal.write("\u001b[0m".to_utf8_buffer())
# tput_* functions based on the tput command. # tput_* functions based checked the tput command.
# See: https://man7.org/linux/man-pages/man1/tput.1.html for more info. # See: https://man7.org/linux/man-pages/man1/tput.1.html for more info.
@ -88,8 +88,8 @@ func setaf(color) -> void:
func setab(color) -> void: func setab(color) -> void:
if color is Color: if color is Color:
terminal.write("\u001b[48;2;%d;%d;%dm" % [color.r8, color.g8, color.b8]) terminal.write("\u001b[48;2;%d;%d;%dm" % [color.r8, color.g8, color.b8])
elif "bg" in color and color.bg is int: elif "panel" in color and color.panel is int:
terminal.write("\u001b[%dm" % color.bg) terminal.write("\u001b[%dm" % color.panel)
else: else:
push_error("Invalid color: %s" % color) push_error("Invalid color: %s" % color)

View file

@ -1,8 +1,8 @@
extends Panel extends Panel
onready var _script_list = $ScriptsList @onready var _script_list = $ScriptsList
onready var _nav_container = $VBox/BottomPanel/VBox/HBox/Navigation @onready var _nav_container = $VBox/BottomPanel/VBox/HBox/Node3D
onready var _nav = { @onready var _nav = {
container = _nav_container, container = _nav_container,
prev = _nav_container.get_node("VBox/HBox/Previous"), prev = _nav_container.get_node("VBox/HBox/Previous"),
next = _nav_container.get_node("VBox/HBox/Next"), next = _nav_container.get_node("VBox/HBox/Next"),
@ -11,14 +11,14 @@ onready var _nav = {
run_single = _nav_container.get_node("VBox/HBox/RunSingleScript") run_single = _nav_container.get_node("VBox/HBox/RunSingleScript")
} }
onready var _progress_container = $VBox/BottomPanel/VBox/HBox/Progress @onready var _progress_container = $VBox/BottomPanel/VBox/HBox/Progress
onready var _progress = { @onready var _progress = {
script = _progress_container.get_node("ScriptProgress"), script = _progress_container.get_node("ScriptProgress"),
script_xy = _progress_container.get_node("ScriptProgress/xy"), script_xy = _progress_container.get_node("ScriptProgress/xy"),
test = _progress_container.get_node("TestProgress"), test = _progress_container.get_node("TestProgress"),
test_xy = _progress_container.get_node("TestProgress/xy") test_xy = _progress_container.get_node("TestProgress/xy")
} }
onready var _summary = { @onready var _summary = {
control = $VBox/TitleBar/HBox/Summary, control = $VBox/TitleBar/HBox/Summary,
failing = $VBox/TitleBar/HBox/Summary/Failing, failing = $VBox/TitleBar/HBox/Summary/Failing,
passing = $VBox/TitleBar/HBox/Summary/Passing, passing = $VBox/TitleBar/HBox/Summary/Passing,
@ -27,21 +27,21 @@ onready var _summary = {
pass_count = 0 pass_count = 0
} }
onready var _extras = $ExtraOptions @onready var _extras = $ExtraOptions
onready var _ignore_pauses = $ExtraOptions/IgnorePause @onready var _ignore_pauses = $ExtraOptions/IgnorePause
onready var _continue_button = $VBox/BottomPanel/VBox/HBox/Continue/Continue @onready var _continue_button = $VBox/BottomPanel/VBox/HBox/Continue/Continue
onready var _text_box = $VBox/TextDisplay/RichTextLabel @onready var _text_box = $VBox/TextDisplay/RichTextLabel
onready var _text_box_container = $VBox/TextDisplay @onready var _text_box_container = $VBox/TextDisplay
onready var _log_level_slider = $VBox/BottomPanel/VBox/HBox2/LogLevelSlider @onready var _log_level_slider = $VBox/BottomPanel/VBox/HBox2/LogLevelSlider
onready var _resize_handle = $ResizeHandle @onready var _resize_handle = $ResizeHandle
onready var _current_script = $VBox/BottomPanel/VBox/HBox2/CurrentScriptLabel @onready var _current_script = $VBox/BottomPanel/VBox/HBox2/CurrentScriptLabel
onready var _title_replacement = $VBox/TitleBar/HBox/TitleReplacement @onready var _title_replacement = $VBox/TitleBar/HBox/TitleReplacement
onready var _titlebar = { @onready var _titlebar = {
bar = $VBox/TitleBar, time = $VBox/TitleBar/HBox/Time, label = $VBox/TitleBar/HBox/Title bar = $VBox/TitleBar, time = $VBox/TitleBar/HBox/Time, label = $VBox/TitleBar/HBox/Title
} }
onready var _user_files = $UserFileViewer @onready var _user_files = $UserFileViewer
var _mouse = {down = false, in_title = false, down_pos = null, in_handle = false} var _mouse = {down = false, in_title = false, down_pos = null, in_handle = false}
@ -94,7 +94,7 @@ func elapsed_time_as_str():
func _process(_delta): func _process(_delta):
if _is_running: if _is_running:
_time = OS.get_ticks_msec() - _start_time _time = Time.get_ticks_msec() - _start_time
_titlebar.time.set_text(str("t: ", elapsed_time_as_str())) _titlebar.time.set_text(str("t: ", elapsed_time_as_str()))
@ -106,9 +106,9 @@ func _draw(): # needs get_size()
var grab_line_color = Color(.4, .4, .4) var grab_line_color = Color(.4, .4, .4)
if _resize_handle.visible: if _resize_handle.visible:
for i in range(1, 10): for i in range(1, 10):
var x = rect_size - Vector2(i * line_space, grab_margin) var x = size - Vector2(i * line_space, grab_margin)
var y = rect_size - Vector2(grab_margin, i * line_space) var y = size - Vector2(grab_margin, i * line_space)
draw_line(x, y, grab_line_color, 1, true) draw_line(x,y,grab_line_color,1)
func _on_Maximize_draw(): func _on_Maximize_draw():
@ -213,9 +213,9 @@ func _input(event):
if _mouse.in_handle: if _mouse.in_handle:
if event is InputEventMouseMotion and _mouse.down: if event is InputEventMouseMotion and _mouse.down:
var new_size = rect_size + event.position - _mouse.down_pos var new_size = size + event.position - _mouse.down_pos
var new_mouse_down_pos = event.position var new_mouse_down_pos = event.position
rect_size = new_size size = new_size
_mouse.down_pos = new_mouse_down_pos _mouse.down_pos = new_mouse_down_pos
_pre_maximize_rect = get_rect() _pre_maximize_rect = get_rect()
@ -248,8 +248,8 @@ func _on_Maximize_pressed():
maximize() maximize()
else: else:
compact_mode(false) compact_mode(false)
rect_size = _pre_maximize_rect.size size = _pre_maximize_rect.size
rect_position = _pre_maximize_rect.position position = _pre_maximize_rect.position
func _on_Minimize_pressed(): func _on_Minimize_pressed():
@ -274,7 +274,7 @@ func _on_UserFiles_pressed():
# #################### # ####################
func _run_mode(is_running = true): func _run_mode(is_running = true):
if is_running: if is_running:
_start_time = OS.get_ticks_msec() _start_time = Time.get_ticks_msec()
_time = 0.0 _time = 0.0
clear_summary() clear_summary()
_is_running = is_running _is_running = is_running
@ -373,7 +373,7 @@ func set_log_level(value):
func set_ignore_pause(should): func set_ignore_pause(should):
_ignore_pauses.pressed = should _ignore_pauses.button_pressed = should
func get_ignore_pause(): func get_ignore_pause():
@ -454,17 +454,17 @@ func clear_summary():
func maximize(): func maximize():
if is_inside_tree(): if is_inside_tree():
var vp_size_offset = get_tree().root.get_viewport().get_visible_rect().size var vp_size_offset = get_tree().root.get_viewport().get_visible_rect().size
rect_size = vp_size_offset / get_scale() size = vp_size_offset / get_scale()
set_position(Vector2(0, 0)) set_position(Vector2(0, 0))
func clear_text(): func clear_text():
_text_box.bbcode_text = "" _text_box.text = ""
func scroll_to_bottom(): func scroll_to_bottom():
pass pass
#_text_box.cursor_set_line(_gui.get_text_box().get_line_count()) #_text_box.set_caret_line(_gui.get_text_box().get_line_count())
func _set_font_size_for_rtl(rtl, new_size): func _set_font_size_for_rtl(rtl, new_size):
@ -539,11 +539,11 @@ func compact_mode(should):
_title_replacement.visible = should _title_replacement.visible = should
if should: if should:
rect_min_size = min_sizes.compact minimum_size = min_sizes.compact
rect_size = rect_min_size size = minimum_size
else: else:
rect_min_size = min_sizes.full minimum_size = min_sizes.full
rect_size = min_sizes.full size = min_sizes.full
goto_bottom_right_corner() goto_bottom_right_corner()
@ -553,4 +553,4 @@ func set_script_path(text):
func goto_bottom_right_corner(): func goto_bottom_right_corner():
rect_position = get_tree().root.get_viewport().get_visible_rect().size - rect_size position = get_tree().root.get_viewport().get_visible_rect().size - size

View file

@ -26,15 +26,15 @@ corner_radius_top_left = 20
corner_radius_top_right = 20 corner_radius_top_right = 20
[node name="Gut" type="Panel"] [node name="Gut" type="Panel"]
margin_right = 740.0 offset_right = 740.0
margin_bottom = 300.0 offset_bottom = 300.0
rect_min_size = Vector2( 740, 300 ) minimum_size = Vector2( 740, 300 )
custom_styles/panel = SubResource( 1 ) custom_styles/panel = SubResource( 1 )
script = ExtResource( 1 ) script = ExtResource( 1 )
[node name="UserFileViewer" parent="." instance=ExtResource( 6 )] [node name="UserFileViewer" parent="." instance=ExtResource( 6 )]
margin_top = 388.0 offset_top = 388.0
margin_bottom = 818.0 offset_bottom = 818.0
[node name="VBox" type="VBoxContainer" parent="."] [node name="VBox" type="VBoxContainer" parent="."]
anchor_right = 1.0 anchor_right = 1.0
@ -44,9 +44,9 @@ __meta__ = {
} }
[node name="TitleBar" type="Panel" parent="VBox"] [node name="TitleBar" type="Panel" parent="VBox"]
margin_right = 740.0 offset_right = 740.0
margin_bottom = 30.0 offset_bottom = 30.0
rect_min_size = Vector2( 0, 30 ) minimum_size = Vector2( 0, 30 )
theme = SubResource( 3 ) theme = SubResource( 3 )
__meta__ = { __meta__ = {
"_edit_group_": true, "_edit_group_": true,
@ -61,9 +61,9 @@ __meta__ = {
} }
[node name="Summary" type="Control" parent="VBox/TitleBar/HBox"] [node name="Summary" type="Control" parent="VBox/TitleBar/HBox"]
margin_right = 110.0 offset_right = 110.0
margin_bottom = 30.0 offset_bottom = 30.0
rect_min_size = Vector2( 110, 0 ) minimum_size = Vector2( 110, 0 )
mouse_filter = 2 mouse_filter = 2
__meta__ = { __meta__ = {
"_edit_use_anchors_": false "_edit_use_anchors_": false
@ -71,10 +71,10 @@ __meta__ = {
[node name="Passing" type="Label" parent="VBox/TitleBar/HBox/Summary"] [node name="Passing" type="Label" parent="VBox/TitleBar/HBox/Summary"]
visible = false visible = false
margin_left = 5.0 offset_left = 5.0
margin_top = 7.0 offset_top = 7.0
margin_right = 45.0 offset_right = 45.0
margin_bottom = 21.0 offset_bottom = 21.0
custom_colors/font_color = Color( 0, 0, 0, 1 ) custom_colors/font_color = Color( 0, 0, 0, 1 )
text = "0" text = "0"
align = 1 align = 1
@ -85,20 +85,20 @@ __meta__ = {
[node name="Failing" type="Label" parent="VBox/TitleBar/HBox/Summary"] [node name="Failing" type="Label" parent="VBox/TitleBar/HBox/Summary"]
visible = false visible = false
margin_left = 100.0 offset_left = 100.0
margin_top = 7.0 offset_top = 7.0
margin_right = 140.0 offset_right = 140.0
margin_bottom = 21.0 offset_bottom = 21.0
custom_colors/font_color = Color( 0, 0, 0, 1 ) custom_colors/font_color = Color( 0, 0, 0, 1 )
text = "0" text = "0"
align = 1 align = 1
valign = 1 valign = 1
[node name="AssertCount" type="Label" parent="VBox/TitleBar/HBox/Summary"] [node name="AssertCount" type="Label" parent="VBox/TitleBar/HBox/Summary"]
margin_left = 5.0 offset_left = 5.0
margin_top = 7.0 offset_top = 7.0
margin_right = 165.0 offset_right = 165.0
margin_bottom = 21.0 offset_bottom = 21.0
custom_colors/font_color = Color( 0, 0, 0, 1 ) custom_colors/font_color = Color( 0, 0, 0, 1 )
text = "Assert count" text = "Assert count"
__meta__ = { __meta__ = {
@ -107,18 +107,18 @@ __meta__ = {
[node name="TitleReplacement" type="CenterContainer" parent="VBox/TitleBar/HBox"] [node name="TitleReplacement" type="CenterContainer" parent="VBox/TitleBar/HBox"]
visible = false visible = false
margin_left = 114.0 offset_left = 114.0
margin_right = 352.0 offset_right = 352.0
margin_bottom = 30.0 offset_bottom = 30.0
rect_min_size = Vector2( 5, 0 ) minimum_size = Vector2( 5, 0 )
mouse_filter = 2 mouse_filter = 2
size_flags_horizontal = 3 size_flags_horizontal = 3
size_flags_vertical = 3 size_flags_vertical = 3
[node name="Title" type="Label" parent="VBox/TitleBar/HBox"] [node name="Title" type="Label" parent="VBox/TitleBar/HBox"]
margin_left = 114.0 offset_left = 114.0
margin_right = 598.0 offset_right = 598.0
margin_bottom = 30.0 offset_bottom = 30.0
size_flags_horizontal = 3 size_flags_horizontal = 3
size_flags_vertical = 7 size_flags_vertical = 7
custom_colors/font_color = Color( 0, 0, 0, 1 ) custom_colors/font_color = Color( 0, 0, 0, 1 )
@ -130,10 +130,10 @@ __meta__ = {
} }
[node name="Time" type="Label" parent="VBox/TitleBar/HBox"] [node name="Time" type="Label" parent="VBox/TitleBar/HBox"]
margin_left = 602.0 offset_left = 602.0
margin_top = 8.0 offset_top = 8.0
margin_right = 654.0 offset_right = 654.0
margin_bottom = 22.0 offset_bottom = 22.0
custom_colors/font_color = Color( 0, 0, 0, 1 ) custom_colors/font_color = Color( 0, 0, 0, 1 )
text = "9999.99" text = "9999.99"
valign = 1 valign = 1
@ -142,17 +142,17 @@ __meta__ = {
} }
[node name="CC" type="CenterContainer" parent="VBox/TitleBar/HBox"] [node name="CC" type="CenterContainer" parent="VBox/TitleBar/HBox"]
margin_left = 658.0 offset_left = 658.0
margin_right = 663.0 offset_right = 663.0
margin_bottom = 30.0 offset_bottom = 30.0
rect_min_size = Vector2( 5, 0 ) minimum_size = Vector2( 5, 0 )
mouse_filter = 2 mouse_filter = 2
[node name="Minimize" type="Button" parent="VBox/TitleBar/HBox"] [node name="Minimize" type="Button" parent="VBox/TitleBar/HBox"]
margin_left = 667.0 offset_left = 667.0
margin_right = 697.0 offset_right = 697.0
margin_bottom = 30.0 offset_bottom = 30.0
rect_min_size = Vector2( 30, 0 ) minimum_size = Vector2( 30, 0 )
custom_colors/font_color = Color( 0, 0, 0, 1 ) custom_colors/font_color = Color( 0, 0, 0, 1 )
text = "N" text = "N"
flat = true flat = true
@ -161,10 +161,10 @@ __meta__ = {
} }
[node name="Maximize" type="Button" parent="VBox/TitleBar/HBox"] [node name="Maximize" type="Button" parent="VBox/TitleBar/HBox"]
margin_left = 701.0 offset_left = 701.0
margin_right = 731.0 offset_right = 731.0
margin_bottom = 30.0 offset_bottom = 30.0
rect_min_size = Vector2( 30, 0 ) minimum_size = Vector2( 30, 0 )
custom_colors/font_color = Color( 0, 0, 0, 1 ) custom_colors/font_color = Color( 0, 0, 0, 1 )
text = "X" text = "X"
flat = true flat = true
@ -173,16 +173,16 @@ __meta__ = {
} }
[node name="CC2" type="CenterContainer" parent="VBox/TitleBar/HBox"] [node name="CC2" type="CenterContainer" parent="VBox/TitleBar/HBox"]
margin_left = 735.0 offset_left = 735.0
margin_right = 740.0 offset_right = 740.0
margin_bottom = 30.0 offset_bottom = 30.0
rect_min_size = Vector2( 5, 0 ) minimum_size = Vector2( 5, 0 )
mouse_filter = 2 mouse_filter = 2
[node name="TextDisplay" type="ColorRect" parent="VBox"] [node name="TextDisplay" type="ColorRect" parent="VBox"]
margin_top = 34.0 offset_top = 34.0
margin_right = 740.0 offset_right = 740.0
margin_bottom = 176.0 offset_bottom = 176.0
size_flags_horizontal = 3 size_flags_horizontal = 3
size_flags_vertical = 3 size_flags_vertical = 3
color = Color( 0, 0, 0, 1 ) color = Color( 0, 0, 0, 1 )
@ -193,8 +193,8 @@ __meta__ = {
[node name="RichTextLabel" type="RichTextLabel" parent="VBox/TextDisplay"] [node name="RichTextLabel" type="RichTextLabel" parent="VBox/TextDisplay"]
anchor_right = 1.0 anchor_right = 1.0
anchor_bottom = 1.0 anchor_bottom = 1.0
margin_left = 10.0 offset_left = 10.0
rect_min_size = Vector2( 0, 116 ) minimum_size = Vector2( 0, 116 )
focus_mode = 2 focus_mode = 2
size_flags_horizontal = 3 size_flags_horizontal = 3
size_flags_vertical = 3 size_flags_vertical = 3
@ -209,17 +209,17 @@ __meta__ = {
anchor_top = 1.0 anchor_top = 1.0
anchor_right = 1.0 anchor_right = 1.0
anchor_bottom = 1.0 anchor_bottom = 1.0
margin_top = -25.0 offset_top = -25.0
bbcode_enabled = true bbcode_enabled = true
__meta__ = { __meta__ = {
"_edit_use_anchors_": false "_edit_use_anchors_": false
} }
[node name="BottomPanel" type="ColorRect" parent="VBox"] [node name="BottomPanel" type="ColorRect" parent="VBox"]
margin_top = 180.0 offset_top = 180.0
margin_right = 740.0 offset_right = 740.0
margin_bottom = 300.0 offset_bottom = 300.0
rect_min_size = Vector2( 0, 120 ) minimum_size = Vector2( 0, 120 )
size_flags_horizontal = 9 size_flags_horizontal = 9
size_flags_vertical = 9 size_flags_vertical = 9
color = Color( 1, 1, 1, 0 ) color = Color( 1, 1, 1, 0 )
@ -232,28 +232,28 @@ __meta__ = {
} }
[node name="HBox" type="HBoxContainer" parent="VBox/BottomPanel/VBox"] [node name="HBox" type="HBoxContainer" parent="VBox/BottomPanel/VBox"]
margin_right = 740.0 offset_right = 740.0
margin_bottom = 80.0 offset_bottom = 80.0
size_flags_horizontal = 3 size_flags_horizontal = 3
[node name="CC1" type="CenterContainer" parent="VBox/BottomPanel/VBox/HBox"] [node name="CC1" type="CenterContainer" parent="VBox/BottomPanel/VBox/HBox"]
margin_right = 5.0 offset_right = 5.0
margin_bottom = 80.0 offset_bottom = 80.0
rect_min_size = Vector2( 5, 0 ) minimum_size = Vector2( 5, 0 )
[node name="Progress" type="VBoxContainer" parent="VBox/BottomPanel/VBox/HBox"] [node name="Progress" type="VBoxContainer" parent="VBox/BottomPanel/VBox/HBox"]
margin_left = 9.0 offset_left = 9.0
margin_right = 179.0 offset_right = 179.0
margin_bottom = 80.0 offset_bottom = 80.0
rect_min_size = Vector2( 170, 0 ) minimum_size = Vector2( 170, 0 )
alignment = 1 alignment = 1
[node name="TestProgress" type="ProgressBar" parent="VBox/BottomPanel/VBox/HBox/Progress"] [node name="TestProgress" type="ProgressBar" parent="VBox/BottomPanel/VBox/HBox/Progress"]
margin_top = 11.0 offset_top = 11.0
margin_right = 100.0 offset_right = 100.0
margin_bottom = 36.0 offset_bottom = 36.0
rect_min_size = Vector2( 100, 25 ) minimum_size = Vector2( 100, 25 )
hint_tooltip = "Test progress for the current script." tooltip_text = "Test progress for the current script."
size_flags_horizontal = 0 size_flags_horizontal = 0
step = 1.0 step = 1.0
__meta__ = { __meta__ = {
@ -261,10 +261,10 @@ __meta__ = {
} }
[node name="Label" type="Label" parent="VBox/BottomPanel/VBox/HBox/Progress/TestProgress"] [node name="Label" type="Label" parent="VBox/BottomPanel/VBox/HBox/Progress/TestProgress"]
margin_left = 107.5 offset_left = 107.5
margin_top = 3.0 offset_top = 3.0
margin_right = 172.5 offset_right = 172.5
margin_bottom = 18.0 offset_bottom = 18.0
text = "Tests" text = "Tests"
valign = 1 valign = 1
__meta__ = { __meta__ = {
@ -283,11 +283,11 @@ __meta__ = {
} }
[node name="ScriptProgress" type="ProgressBar" parent="VBox/BottomPanel/VBox/HBox/Progress"] [node name="ScriptProgress" type="ProgressBar" parent="VBox/BottomPanel/VBox/HBox/Progress"]
margin_top = 40.0 offset_top = 40.0
margin_right = 100.0 offset_right = 100.0
margin_bottom = 65.0 offset_bottom = 65.0
rect_min_size = Vector2( 100, 25 ) minimum_size = Vector2( 100, 25 )
hint_tooltip = "Overall progress of executing tests." tooltip_text = "Overall progress of executing tests."
size_flags_horizontal = 0 size_flags_horizontal = 0
step = 1.0 step = 1.0
__meta__ = { __meta__ = {
@ -295,10 +295,10 @@ __meta__ = {
} }
[node name="Label" type="Label" parent="VBox/BottomPanel/VBox/HBox/Progress/ScriptProgress"] [node name="Label" type="Label" parent="VBox/BottomPanel/VBox/HBox/Progress/ScriptProgress"]
margin_left = 107.0 offset_left = 107.0
margin_top = 3.5 offset_top = 3.5
margin_right = 172.0 offset_right = 172.0
margin_bottom = 18.5 offset_bottom = 18.5
text = "Scripts" text = "Scripts"
valign = 1 valign = 1
__meta__ = { __meta__ = {
@ -317,39 +317,39 @@ __meta__ = {
} }
[node name="CenterContainer" type="CenterContainer" parent="VBox/BottomPanel/VBox/HBox/Progress"] [node name="CenterContainer" type="CenterContainer" parent="VBox/BottomPanel/VBox/HBox/Progress"]
margin_top = 69.0 offset_top = 69.0
margin_right = 170.0 offset_right = 170.0
margin_bottom = 69.0 offset_bottom = 69.0
[node name="CC2" type="CenterContainer" parent="VBox/BottomPanel/VBox/HBox"] [node name="CC2" type="CenterContainer" parent="VBox/BottomPanel/VBox/HBox"]
margin_left = 183.0 offset_left = 183.0
margin_right = 226.0 offset_right = 226.0
margin_bottom = 80.0 offset_bottom = 80.0
rect_min_size = Vector2( 5, 0 ) minimum_size = Vector2( 5, 0 )
size_flags_horizontal = 3 size_flags_horizontal = 3
[node name="Navigation" type="Panel" parent="VBox/BottomPanel/VBox/HBox"] [node name="Node3D" type="Panel" parent="VBox/BottomPanel/VBox/HBox"]
self_modulate = Color( 1, 1, 1, 0 ) self_modulate = Color( 1, 1, 1, 0 )
margin_left = 230.0 offset_left = 230.0
margin_right = 580.0 offset_right = 580.0
margin_bottom = 80.0 offset_bottom = 80.0
rect_min_size = Vector2( 350, 80 ) minimum_size = Vector2( 350, 80 )
__meta__ = { __meta__ = {
"_edit_group_": true, "_edit_group_": true,
"_edit_use_anchors_": false "_edit_use_anchors_": false
} }
[node name="VBox" type="VBoxContainer" parent="VBox/BottomPanel/VBox/HBox/Navigation"] [node name="VBox" type="VBoxContainer" parent="VBox/BottomPanel/VBox/HBox/Node3D"]
anchor_right = 1.0 anchor_right = 1.0
anchor_bottom = 1.0 anchor_bottom = 1.0
__meta__ = { __meta__ = {
"_edit_use_anchors_": false "_edit_use_anchors_": false
} }
[node name="CurrentScript" type="Button" parent="VBox/BottomPanel/VBox/HBox/Navigation/VBox"] [node name="CurrentScript" type="Button" parent="VBox/BottomPanel/VBox/HBox/Node3D/VBox"]
margin_right = 350.0 offset_right = 350.0
margin_bottom = 38.0 offset_bottom = 38.0
hint_tooltip = "Select a script to run. You can run just this script, or this script and all scripts after using the run buttons." tooltip_text = "Select a script to run. You can run just this script, or this script and all scripts after using the run buttons."
size_flags_horizontal = 3 size_flags_horizontal = 3
size_flags_vertical = 3 size_flags_vertical = 3
text = "res://test/unit/test_gut.gd" text = "res://test/unit/test_gut.gd"
@ -358,17 +358,17 @@ __meta__ = {
"_edit_use_anchors_": false "_edit_use_anchors_": false
} }
[node name="HBox" type="HBoxContainer" parent="VBox/BottomPanel/VBox/HBox/Navigation/VBox"] [node name="HBox" type="HBoxContainer" parent="VBox/BottomPanel/VBox/HBox/Node3D/VBox"]
margin_top = 42.0 offset_top = 42.0
margin_right = 350.0 offset_right = 350.0
margin_bottom = 80.0 offset_bottom = 80.0
size_flags_horizontal = 3 size_flags_horizontal = 3
size_flags_vertical = 3 size_flags_vertical = 3
[node name="Previous" type="Button" parent="VBox/BottomPanel/VBox/HBox/Navigation/VBox/HBox"] [node name="Previous" type="Button" parent="VBox/BottomPanel/VBox/HBox/Node3D/VBox/HBox"]
margin_right = 84.0 offset_right = 84.0
margin_bottom = 38.0 offset_bottom = 38.0
hint_tooltip = "Previous script in the list." tooltip_text = "Previous script in the list."
size_flags_horizontal = 3 size_flags_horizontal = 3
size_flags_vertical = 3 size_flags_vertical = 3
text = "|<" text = "|<"
@ -376,11 +376,11 @@ __meta__ = {
"_edit_use_anchors_": false "_edit_use_anchors_": false
} }
[node name="Next" type="Button" parent="VBox/BottomPanel/VBox/HBox/Navigation/VBox/HBox"] [node name="Next" type="Button" parent="VBox/BottomPanel/VBox/HBox/Node3D/VBox/HBox"]
margin_left = 88.0 offset_left = 88.0
margin_right = 173.0 offset_right = 173.0
margin_bottom = 38.0 offset_bottom = 38.0
hint_tooltip = "Next script in the list. tooltip_text = "Next script in the list.
" "
size_flags_horizontal = 3 size_flags_horizontal = 3
size_flags_vertical = 3 size_flags_vertical = 3
@ -389,11 +389,11 @@ __meta__ = {
"_edit_use_anchors_": false "_edit_use_anchors_": false
} }
[node name="Run" type="Button" parent="VBox/BottomPanel/VBox/HBox/Navigation/VBox/HBox"] [node name="Run" type="Button" parent="VBox/BottomPanel/VBox/HBox/Node3D/VBox/HBox"]
margin_left = 177.0 offset_left = 177.0
margin_right = 261.0 offset_right = 261.0
margin_bottom = 38.0 offset_bottom = 38.0
hint_tooltip = "Run the currently selected item and all after it." tooltip_text = "Run the currently selected item and all after it."
size_flags_horizontal = 3 size_flags_horizontal = 3
size_flags_vertical = 3 size_flags_vertical = 3
text = ">" text = ">"
@ -401,11 +401,11 @@ __meta__ = {
"_edit_use_anchors_": false "_edit_use_anchors_": false
} }
[node name="RunSingleScript" type="Button" parent="VBox/BottomPanel/VBox/HBox/Navigation/VBox/HBox"] [node name="RunSingleScript" type="Button" parent="VBox/BottomPanel/VBox/HBox/Node3D/VBox/HBox"]
margin_left = 265.0 offset_left = 265.0
margin_right = 350.0 offset_right = 350.0
margin_bottom = 38.0 offset_bottom = 38.0
hint_tooltip = "Run the currently selected item. tooltip_text = "Run the currently selected item.
If the selected item has Inner Test Classes If the selected item has Inner Test Classes
then they will all be run. If the selected item then they will all be run. If the selected item
@ -418,25 +418,25 @@ __meta__ = {
} }
[node name="CC3" type="CenterContainer" parent="VBox/BottomPanel/VBox/HBox"] [node name="CC3" type="CenterContainer" parent="VBox/BottomPanel/VBox/HBox"]
margin_left = 584.0 offset_left = 584.0
margin_right = 627.0 offset_right = 627.0
margin_bottom = 80.0 offset_bottom = 80.0
rect_min_size = Vector2( 5, 0 ) minimum_size = Vector2( 5, 0 )
size_flags_horizontal = 3 size_flags_horizontal = 3
[node name="Continue" type="VBoxContainer" parent="VBox/BottomPanel/VBox/HBox"] [node name="Continue" type="VBoxContainer" parent="VBox/BottomPanel/VBox/HBox"]
self_modulate = Color( 1, 1, 1, 0 ) self_modulate = Color( 1, 1, 1, 0 )
margin_left = 631.0 offset_left = 631.0
margin_right = 731.0 offset_right = 731.0
margin_bottom = 80.0 offset_bottom = 80.0
alignment = 1 alignment = 1
[node name="ShowExtras" type="Button" parent="VBox/BottomPanel/VBox/HBox/Continue"] [node name="ShowExtras" type="Button" parent="VBox/BottomPanel/VBox/HBox/Continue"]
margin_right = 50.0 offset_right = 50.0
margin_bottom = 35.0 offset_bottom = 35.0
rect_min_size = Vector2( 50, 35 ) minimum_size = Vector2( 50, 35 )
rect_pivot_offset = Vector2( 35, 20 ) pivot_offset = Vector2( 35, 20 )
hint_tooltip = "Show/hide additional options." tooltip_text = "Show/hide additional options."
size_flags_horizontal = 0 size_flags_horizontal = 0
toggle_mode = true toggle_mode = true
text = "_" text = "_"
@ -445,11 +445,11 @@ __meta__ = {
} }
[node name="Continue" type="Button" parent="VBox/BottomPanel/VBox/HBox/Continue"] [node name="Continue" type="Button" parent="VBox/BottomPanel/VBox/HBox/Continue"]
margin_top = 39.0 offset_top = 39.0
margin_right = 100.0 offset_right = 100.0
margin_bottom = 79.0 offset_bottom = 79.0
rect_min_size = Vector2( 100, 40 ) minimum_size = Vector2( 100, 40 )
hint_tooltip = "When a pause_before_teardown is encountered this button will be enabled and must be pressed to continue running tests." tooltip_text = "When a pause_before_teardown is encountered this button will be enabled and must be pressed to continue running tests."
disabled = true disabled = true
text = "Continue" text = "Continue"
__meta__ = { __meta__ = {
@ -457,26 +457,26 @@ __meta__ = {
} }
[node name="CC4" type="CenterContainer" parent="VBox/BottomPanel/VBox/HBox"] [node name="CC4" type="CenterContainer" parent="VBox/BottomPanel/VBox/HBox"]
margin_left = 735.0 offset_left = 735.0
margin_right = 740.0 offset_right = 740.0
margin_bottom = 80.0 offset_bottom = 80.0
rect_min_size = Vector2( 5, 0 ) minimum_size = Vector2( 5, 0 )
[node name="HBox2" type="HBoxContainer" parent="VBox/BottomPanel/VBox"] [node name="HBox2" type="HBoxContainer" parent="VBox/BottomPanel/VBox"]
margin_top = 84.0 offset_top = 84.0
margin_right = 740.0 offset_right = 740.0
margin_bottom = 114.0 offset_bottom = 114.0
[node name="CC" type="CenterContainer" parent="VBox/BottomPanel/VBox/HBox2"] [node name="CC" type="CenterContainer" parent="VBox/BottomPanel/VBox/HBox2"]
margin_right = 5.0 offset_right = 5.0
margin_bottom = 30.0 offset_bottom = 30.0
rect_min_size = Vector2( 5, 0 ) minimum_size = Vector2( 5, 0 )
[node name="LogLevelSlider" type="HSlider" parent="VBox/BottomPanel/VBox/HBox2"] [node name="LogLevelSlider" type="HSlider" parent="VBox/BottomPanel/VBox/HBox2"]
margin_left = 9.0 offset_left = 9.0
margin_right = 109.0 offset_right = 109.0
margin_bottom = 30.0 offset_bottom = 30.0
rect_min_size = Vector2( 100, 30 ) minimum_size = Vector2( 100, 30 )
size_flags_vertical = 3 size_flags_vertical = 3
max_value = 2.0 max_value = 2.0
tick_count = 3 tick_count = 3
@ -486,10 +486,10 @@ __meta__ = {
} }
[node name="Label" type="Label" parent="VBox/BottomPanel/VBox/HBox2/LogLevelSlider"] [node name="Label" type="Label" parent="VBox/BottomPanel/VBox/HBox2/LogLevelSlider"]
margin_left = 4.0 offset_left = 4.0
margin_top = -17.0 offset_top = -17.0
margin_right = 85.0 offset_right = 85.0
margin_bottom = 7.0 offset_bottom = 7.0
text = "Log Level" text = "Log Level"
valign = 1 valign = 1
__meta__ = { __meta__ = {
@ -497,16 +497,16 @@ __meta__ = {
} }
[node name="CenterContainer" type="CenterContainer" parent="VBox/BottomPanel/VBox/HBox2"] [node name="CenterContainer" type="CenterContainer" parent="VBox/BottomPanel/VBox/HBox2"]
margin_left = 113.0 offset_left = 113.0
margin_right = 163.0 offset_right = 163.0
margin_bottom = 30.0 offset_bottom = 30.0
rect_min_size = Vector2( 50, 0 ) minimum_size = Vector2( 50, 0 )
[node name="CurrentScriptLabel" type="Label" parent="VBox/BottomPanel/VBox/HBox2"] [node name="CurrentScriptLabel" type="Label" parent="VBox/BottomPanel/VBox/HBox2"]
margin_left = 167.0 offset_left = 167.0
margin_top = 8.0 offset_top = 8.0
margin_right = 740.0 offset_right = 740.0
margin_bottom = 22.0 offset_bottom = 22.0
size_flags_horizontal = 3 size_flags_horizontal = 3
size_flags_vertical = 6 size_flags_vertical = 6
text = "res://test/unit/test_something.gd" text = "res://test/unit/test_something.gd"
@ -517,10 +517,10 @@ __meta__ = {
[node name="ScriptsList" type="ItemList" parent="."] [node name="ScriptsList" type="ItemList" parent="."]
visible = false visible = false
anchor_bottom = 1.0 anchor_bottom = 1.0
margin_left = 179.0 offset_left = 179.0
margin_top = 40.0 offset_top = 40.0
margin_right = 619.0 offset_right = 619.0
margin_bottom = -110.0 offset_bottom = -110.0
allow_reselect = true allow_reselect = true
__meta__ = { __meta__ = {
"_edit_use_anchors_": false "_edit_use_anchors_": false
@ -536,44 +536,44 @@ anchor_left = 1.0
anchor_top = 1.0 anchor_top = 1.0
anchor_right = 1.0 anchor_right = 1.0
anchor_bottom = 1.0 anchor_bottom = 1.0
margin_left = -212.0 offset_left = -212.0
margin_top = -260.0 offset_top = -260.0
margin_right = -2.0 offset_right = -2.0
margin_bottom = -106.0 offset_bottom = -106.0
custom_styles/panel = SubResource( 8 ) custom_styles/panel = SubResource( 8 )
__meta__ = { __meta__ = {
"_edit_use_anchors_": false "_edit_use_anchors_": false
} }
[node name="IgnorePause" type="CheckBox" parent="ExtraOptions"] [node name="IgnorePause" type="CheckBox" parent="ExtraOptions"]
margin_left = 17.5 offset_left = 17.5
margin_top = 4.5 offset_top = 4.5
margin_right = 162.5 offset_right = 162.5
margin_bottom = 29.5 offset_bottom = 29.5
rect_scale = Vector2( 1.2, 1.2 ) scale = Vector2( 1.2, 1.2 )
hint_tooltip = "Ignore all calls to pause_before_teardown." tooltip_text = "Ignore all calls to pause_before_teardown."
text = "Ignore Pauses" text = "Ignore Pauses"
__meta__ = { __meta__ = {
"_edit_use_anchors_": false "_edit_use_anchors_": false
} }
[node name="Copy" type="Button" parent="ExtraOptions"] [node name="Copy" type="Button" parent="ExtraOptions"]
margin_left = 15.0 offset_left = 15.0
margin_top = 40.0 offset_top = 40.0
margin_right = 195.0 offset_right = 195.0
margin_bottom = 80.0 offset_bottom = 80.0
hint_tooltip = "Copy all output to the clipboard." tooltip_text = "Copy all output to the clipboard."
text = "Copy to Clipboard" text = "Copy to Clipboard"
__meta__ = { __meta__ = {
"_edit_use_anchors_": false "_edit_use_anchors_": false
} }
[node name="UserFiles" type="Button" parent="ExtraOptions"] [node name="UserFiles" type="Button" parent="ExtraOptions"]
margin_left = 15.0 offset_left = 15.0
margin_top = 90.0 offset_top = 90.0
margin_right = 195.0 offset_right = 195.0
margin_bottom = 130.0 offset_bottom = 130.0
hint_tooltip = "Copy all output to the clipboard." tooltip_text = "Copy all output to the clipboard."
text = "View User Files" text = "View User Files"
__meta__ = { __meta__ = {
"_edit_use_anchors_": false "_edit_use_anchors_": false
@ -584,8 +584,8 @@ anchor_left = 1.0
anchor_top = 1.0 anchor_top = 1.0
anchor_right = 1.0 anchor_right = 1.0
anchor_bottom = 1.0 anchor_bottom = 1.0
margin_left = -40.0 offset_left = -40.0
margin_top = -40.0 offset_top = -40.0
__meta__ = { __meta__ = {
"_edit_use_anchors_": false "_edit_use_anchors_": false
} }
@ -597,11 +597,11 @@ __meta__ = {
[connection signal="draw" from="VBox/TitleBar/HBox/Maximize" to="." method="_on_Maximize_draw"] [connection signal="draw" from="VBox/TitleBar/HBox/Maximize" to="." method="_on_Maximize_draw"]
[connection signal="pressed" from="VBox/TitleBar/HBox/Maximize" to="." method="_on_Maximize_pressed"] [connection signal="pressed" from="VBox/TitleBar/HBox/Maximize" to="." method="_on_Maximize_pressed"]
[connection signal="gui_input" from="VBox/TextDisplay/RichTextLabel" to="." method="_on_RichTextLabel_gui_input"] [connection signal="gui_input" from="VBox/TextDisplay/RichTextLabel" to="." method="_on_RichTextLabel_gui_input"]
[connection signal="pressed" from="VBox/BottomPanel/VBox/HBox/Navigation/VBox/CurrentScript" to="." method="_on_CurrentScript_pressed"] [connection signal="pressed" from="VBox/BottomPanel/VBox/HBox/Node3D/VBox/CurrentScript" to="." method="_on_CurrentScript_pressed"]
[connection signal="pressed" from="VBox/BottomPanel/VBox/HBox/Navigation/VBox/HBox/Previous" to="." method="_on_Previous_pressed"] [connection signal="pressed" from="VBox/BottomPanel/VBox/HBox/Node3D/VBox/HBox/Previous" to="." method="_on_Previous_pressed"]
[connection signal="pressed" from="VBox/BottomPanel/VBox/HBox/Navigation/VBox/HBox/Next" to="." method="_on_Next_pressed"] [connection signal="pressed" from="VBox/BottomPanel/VBox/HBox/Node3D/VBox/HBox/Next" to="." method="_on_Next_pressed"]
[connection signal="pressed" from="VBox/BottomPanel/VBox/HBox/Navigation/VBox/HBox/Run" to="." method="_on_Run_pressed"] [connection signal="pressed" from="VBox/BottomPanel/VBox/HBox/Node3D/VBox/HBox/Run" to="." method="_on_Run_pressed"]
[connection signal="pressed" from="VBox/BottomPanel/VBox/HBox/Navigation/VBox/HBox/RunSingleScript" to="." method="_on_RunSingleScript_pressed"] [connection signal="pressed" from="VBox/BottomPanel/VBox/HBox/Node3D/VBox/HBox/RunSingleScript" to="." method="_on_RunSingleScript_pressed"]
[connection signal="draw" from="VBox/BottomPanel/VBox/HBox/Continue/ShowExtras" to="." method="_on_ShowExtras_draw"] [connection signal="draw" from="VBox/BottomPanel/VBox/HBox/Continue/ShowExtras" to="." method="_on_ShowExtras_draw"]
[connection signal="toggled" from="VBox/BottomPanel/VBox/HBox/Continue/ShowExtras" to="." method="_on_ShowExtras_toggled"] [connection signal="toggled" from="VBox/BottomPanel/VBox/HBox/Continue/ShowExtras" to="." method="_on_ShowExtras_toggled"]
[connection signal="pressed" from="VBox/BottomPanel/VBox/HBox/Continue/Continue" to="." method="_on_Continue_pressed"] [connection signal="pressed" from="VBox/BottomPanel/VBox/HBox/Continue/Continue" to="." method="_on_Continue_pressed"]

View file

@ -1,6 +1,6 @@
extends WindowDialog extends Window
onready var rtl = $TextDisplay/RichTextLabel @onready var rtl = $TextDisplay/RichTextLabel
var _has_opened_file = false var _has_opened_file = false

View file

@ -2,12 +2,12 @@
[ext_resource path="res://addons/gut/UserFileViewer.gd" type="Script" id=1] [ext_resource path="res://addons/gut/UserFileViewer.gd" type="Script" id=1]
[node name="UserFileViewer" type="WindowDialog"] [node name="UserFileViewer" type="Window"]
margin_top = 20.0 offset_top = 20.0
margin_right = 800.0 offset_right = 800.0
margin_bottom = 450.0 offset_bottom = 450.0
rect_min_size = Vector2( 800, 180 ) minimum_size = Vector2( 800, 180 )
popup_exclusive = true exclusive = true
window_title = "View File" window_title = "View File"
resizable = true resizable = true
script = ExtResource( 1 ) script = ExtResource( 1 )
@ -16,11 +16,11 @@ __meta__ = {
} }
[node name="FileDialog" type="FileDialog" parent="."] [node name="FileDialog" type="FileDialog" parent="."]
margin_right = 416.0 offset_right = 416.0
margin_bottom = 184.0 offset_bottom = 184.0
rect_min_size = Vector2( 400, 140 ) minimum_size = Vector2( 400, 140 )
rect_scale = Vector2( 2, 2 ) scale = Vector2( 2, 2 )
popup_exclusive = true exclusive = true
window_title = "Open a File" window_title = "Open a File"
resizable = true resizable = true
mode = 0 mode = 0
@ -35,9 +35,9 @@ __meta__ = {
[node name="TextDisplay" type="ColorRect" parent="."] [node name="TextDisplay" type="ColorRect" parent="."]
anchor_right = 1.0 anchor_right = 1.0
anchor_bottom = 1.0 anchor_bottom = 1.0
margin_left = 8.0 offset_left = 8.0
margin_right = -10.0 offset_right = -10.0
margin_bottom = -65.0 offset_bottom = -65.0
color = Color( 0.2, 0.188235, 0.188235, 1 ) color = Color( 0.2, 0.188235, 0.188235, 1 )
__meta__ = { __meta__ = {
"_edit_use_anchors_": false "_edit_use_anchors_": false
@ -47,7 +47,7 @@ __meta__ = {
anchor_right = 1.0 anchor_right = 1.0
anchor_bottom = 1.0 anchor_bottom = 1.0
focus_mode = 2 focus_mode = 2
text = "In publishing and graphic design, Lorem ipsum is a placeholder text commonly used to demonstrate the visual form of a document or a typeface without relying on meaningful content. Lorem ipsum may be used before final copy is available, but it may also be used to temporarily replace copy in a process called greeking, which allows designers to consider form without the meaning of the text influencing the design. text = "In publishing and graphic design, Lorem ipsum is a placeholder text commonly used to demonstrate the visual form of a document or a typeface without relying checked meaningful content. Lorem ipsum may be used before final copy is available, but it may also be used to temporarily replace copy in a process called greeking, which allows designers to consider form without the meaning of the text influencing the design.
Lorem ipsum is typically a corrupted version of De finibus bonorum et malorum, a first-century BCE text by the Roman statesman and philosopher Cicero, with words altered, added, and removed to make it nonsensical, improper Latin. Lorem ipsum is typically a corrupted version of De finibus bonorum et malorum, a first-century BCE text by the Roman statesman and philosopher Cicero, with words altered, added, and removed to make it nonsensical, improper Latin.
@ -62,11 +62,11 @@ anchor_left = 1.0
anchor_top = 1.0 anchor_top = 1.0
anchor_right = 1.0 anchor_right = 1.0
anchor_bottom = 1.0 anchor_bottom = 1.0
margin_left = -158.0 offset_left = -158.0
margin_top = -50.0 offset_top = -50.0
margin_right = -84.0 offset_right = -84.0
margin_bottom = -30.0 offset_bottom = -30.0
rect_scale = Vector2( 2, 2 ) scale = Vector2( 2, 2 )
text = "Open File" text = "Open File"
[node name="Home" type="Button" parent="."] [node name="Home" type="Button" parent="."]
@ -74,11 +74,11 @@ anchor_left = 1.0
anchor_top = 1.0 anchor_top = 1.0
anchor_right = 1.0 anchor_right = 1.0
anchor_bottom = 1.0 anchor_bottom = 1.0
margin_left = -478.0 offset_left = -478.0
margin_top = -50.0 offset_top = -50.0
margin_right = -404.0 offset_right = -404.0
margin_bottom = -30.0 offset_bottom = -30.0
rect_scale = Vector2( 2, 2 ) scale = Vector2( 2, 2 )
text = "Home" text = "Home"
__meta__ = { __meta__ = {
"_edit_use_anchors_": false "_edit_use_anchors_": false
@ -87,11 +87,11 @@ __meta__ = {
[node name="Copy" type="Button" parent="."] [node name="Copy" type="Button" parent="."]
anchor_top = 1.0 anchor_top = 1.0
anchor_bottom = 1.0 anchor_bottom = 1.0
margin_left = 160.0 offset_left = 160.0
margin_top = -50.0 offset_top = -50.0
margin_right = 234.0 offset_right = 234.0
margin_bottom = -30.0 offset_bottom = -30.0
rect_scale = Vector2( 2, 2 ) scale = Vector2( 2, 2 )
text = "Copy" text = "Copy"
__meta__ = { __meta__ = {
"_edit_use_anchors_": false "_edit_use_anchors_": false
@ -102,21 +102,21 @@ anchor_left = 1.0
anchor_top = 1.0 anchor_top = 1.0
anchor_right = 1.0 anchor_right = 1.0
anchor_bottom = 1.0 anchor_bottom = 1.0
margin_left = -318.0 offset_left = -318.0
margin_top = -50.0 offset_top = -50.0
margin_right = -244.0 offset_right = -244.0
margin_bottom = -30.0 offset_bottom = -30.0
rect_scale = Vector2( 2, 2 ) scale = Vector2( 2, 2 )
text = "End" text = "End"
[node name="Close" type="Button" parent="."] [node name="Close" type="Button" parent="."]
anchor_top = 1.0 anchor_top = 1.0
anchor_bottom = 1.0 anchor_bottom = 1.0
margin_left = 10.0 offset_left = 10.0
margin_top = -50.0 offset_top = -50.0
margin_right = 80.0 offset_right = 80.0
margin_bottom = -30.0 offset_bottom = -30.0
rect_scale = Vector2( 2, 2 ) scale = Vector2( 2, 2 )
text = "Close" text = "Close"
[connection signal="file_selected" from="FileDialog" to="." method="_on_FileDialog_file_selected"] [connection signal="file_selected" from="FileDialog" to="." method="_on_FileDialog_file_selected"]

View file

@ -34,7 +34,7 @@ var _to_queue_free = []
func add_free(thing): func add_free(thing):
if typeof(thing) == TYPE_OBJECT: if typeof(thing) == TYPE_OBJECT:
if !thing is Reference: if !thing is RefCounted:
_to_free.append(thing) _to_free.append(thing)

View file

@ -1,7 +1,23 @@
var are_equal = null setget set_are_equal, get_are_equal var are_equal = null :
var summary = null setget set_summary, get_summary get:
var max_differences = 30 setget set_max_differences, get_max_differences return are_equal # TODOConverter40 Copy here content of get_are_equal
var differences = {} setget set_differences, get_differences set(mod_value):
mod_value # TODOConverter40 Copy here content of set_are_equal
var summary = null :
get:
return summary # TODOConverter40 Copy here content of get_summary
set(mod_value):
mod_value # TODOConverter40 Copy here content of set_summary
var max_differences = 30 :
get:
return max_differences # TODOConverter40 Copy here content of get_max_differences
set(mod_value):
mod_value # TODOConverter40 Copy here content of set_max_differences
var differences = {} :
get:
return differences # TODOConverter40 Copy here content of get_differences
set(mod_value):
mod_value # TODOConverter40 Copy here content of set_differences
func _block_set(which, val): func _block_set(which, val):

View file

@ -74,7 +74,7 @@ func _invalidate():
differences = null differences = null
func _init(v1, v2, diff_type = DEEP): func _init(v1,v2,diff_type = DEEP):
_value_1 = v1 _value_1 = v1
_value_2 = v2 _value_2 = v2
_diff_type = diff_type _diff_type = diff_type
@ -130,7 +130,7 @@ func _diff_dictionary(d1, d2):
if !d2.has(key): if !d2.has(key):
differences[key] = _compare.simple(d1[key], _compare.MISSING, "key") differences[key] = _compare.simple(d1[key], _compare.MISSING, "key")
else: else:
d2_keys.remove(d2_keys.find(key)) d2_keys.remove_at(d2_keys.find(key))
var result = null var result = null
if _diff_type == DEEP: if _diff_type == DEEP:

View file

@ -120,7 +120,7 @@ class ObjectInfo:
var _singleton_instance = null var _singleton_instance = null
var _singleton_name = null var _singleton_name = null
func _init(path, subpath = null): func _init(path,subpath = null):
_path = path _path = path
if subpath != null: if subpath != null:
_subpaths = Array(subpath.split("/")) _subpaths = Array(subpath.split("/"))
@ -154,7 +154,7 @@ class ObjectInfo:
return _path return _path
func get_subpath(): func get_subpath():
return PoolStringArray(_subpaths).join("/") return "/".join(PackedStringArray(_subpaths))
func has_subpath(): func has_subpath():
return _subpaths.size() != 0 return _subpaths.size() != 0
@ -173,7 +173,7 @@ class ObjectInfo:
var inst = native_class.new() var inst = native_class.new()
_native_class_name = inst.get_class() _native_class_name = inst.get_class()
_path = _native_class_name _path = _native_class_name
if !inst is Reference: if !inst is RefCounted:
inst.free() inst.free()
func get_native_class_name(): func get_native_class_name():
@ -195,7 +195,7 @@ class ObjectInfo:
func get_extends_text(): func get_extends_text():
var extend = null var extend = null
if is_singleton(): if is_singleton():
extend = str("# Double of singleton ", _singleton_name, ", base class is Reference") extend = str("# Double of singleton ", _singleton_name, ", base class is RefCounted")
elif is_native(): elif is_native():
var native = get_native_class_name() var native = get_native_class_name()
if native.begins_with("_"): if native.begins_with("_"):
@ -214,8 +214,8 @@ class ObjectInfo:
return "" return ""
# do not include constants defined in the super class which for # do not include constants defined in the super class which for
# singletons stubs is Reference. # singletons stubs is RefCounted.
var exclude_constants = Array(ClassDB.class_get_integer_constant_list("Reference")) var exclude_constants = Array(ClassDB.class_get_integer_constant_list("RefCounted"))
var text = str("# -----\n# ", _singleton_name, " Constants\n# -----\n") var text = str("# -----\n# ", _singleton_name, " Constants\n# -----\n")
var constants = ClassDB.class_get_integer_constant_list(_singleton_name) var constants = ClassDB.class_get_integer_constant_list(_singleton_name)
for c in constants: for c in constants:
@ -283,17 +283,17 @@ class FileOrString:
func open(path, mode): func open(path, mode):
_path = path _path = path
if _do_file: if _do_file:
return .open(path, mode) return super.open(path, mode)
else: else:
return OK return OK
func close(): func close():
if _do_file: if _do_file:
return .close() return super.close()
func store_string(s): func store_string(s):
if _do_file: if _do_file:
.store_string(s) super.store_string(s)
_contents += s _contents += s
func get_contents(): func get_contents():
@ -326,7 +326,7 @@ class PackedSceneDouble:
_script = obj _script = obj
func instance(edit_state = 0): func instance(edit_state = 0):
var inst = _scene.instance(edit_state) var inst = _scene.instantiate(edit_state)
if _script != null: if _script != null:
inst.set_script(_script) inst.set_script(_script)
return inst return inst
@ -462,7 +462,7 @@ func _double_scene_and_script(scene_info):
var to_return = PackedSceneDouble.new() var to_return = PackedSceneDouble.new()
to_return.load_scene(scene_info.get_path()) to_return.load_scene(scene_info.get_path())
var inst = load(scene_info.get_path()).instance() var inst = load(scene_info.get_path()).instantiate()
var script_path = null var script_path = null
if inst.get_script(): if inst.get_script():
script_path = inst.get_script().get_path() script_path = inst.get_script().get_path()
@ -484,7 +484,7 @@ func _get_methods(object_info):
var script_methods = ScriptMethods.new() var script_methods = ScriptMethods.new()
var methods = obj.get_method_list() var methods = obj.get_method_list()
if !object_info.is_singleton() and !(obj is Reference): if !object_info.is_singleton() and !(obj is RefCounted):
obj.free() obj.free()
# first pass is for local methods only # first pass is for local methods only
@ -723,13 +723,13 @@ func clear_output_directory():
var d = Directory.new() var d = Directory.new()
var result = d.open(_output_dir) var result = d.open(_output_dir)
# BIG GOTCHA HERE. If it cannot open the dir w/ erro 31, then the # BIG GOTCHA HERE. If it cannot open the dir w/ erro 31, then the
# directory becomes res:// and things go on normally and gut clears out # directory becomes res:// and things go checked normally and gut clears out
# out res:// which is SUPER BAD. # out res:// which is SUPER BAD.
if result == OK: if result == OK:
d.list_dir_begin(true) d.list_dir_begin() # TODOGODOT4 fill missing arguments https://github.com/godotengine/godot/pull/40547
var f = d.get_next() var f = d.get_next()
while f != "": while f != "":
d.remove(f) d.remove_at(f)
f = d.get_next() f = d.get_next()
did = true did = true
return did return did
@ -739,7 +739,7 @@ func delete_output_directory():
var did = clear_output_directory() var did = clear_output_directory()
if did: if did:
var d = Directory.new() var d = Directory.new()
d.remove(_output_dir) d.remove_at(_output_dir)
func add_ignored_method(path, method_name): func add_ignored_method(path, method_name):

View file

@ -16,7 +16,7 @@ var _wrote_results = false
# play_custom_scene # play_custom_scene
var _cmdln_mode = false var _cmdln_mode = false
onready var _gut_layer = $GutLayer @onready var _gut_layer = $GutLayer
func _ready(): func _ready():
@ -24,8 +24,8 @@ func _ready():
_gut_config = GutConfig.new() _gut_config = GutConfig.new()
_gut_config.load_options(RUNNER_JSON_PATH) _gut_config.load_options(RUNNER_JSON_PATH)
# The command line will call run_tests on its own. When used from the panel # The command line will call run_tests checked its own. When used from the panel
# we have to kick off the tests ourselves b/c there's no way I know of to # we have to kick unchecked the tests ourselves b/c there's no way I know of to
# interact with the scene that was run via play_custom_scene. # interact with the scene that was run via play_custom_scene.
if !_cmdln_mode: if !_cmdln_mode:
call_deferred("run_tests") call_deferred("run_tests")
@ -58,7 +58,7 @@ func run_tests():
func _write_results(): func _write_results():
# bbcode_text appears to be empty. I'm not 100% sure why. Until that is # text appears to be empty. I'm not 100% sure why. Until that is
# figured out we have to just get the text which stinks. # figured out we have to just get the text which stinks.
var content = _gut.get_gui().get_text_box().text var content = _gut.get_gui().get_text_box().text

View file

@ -35,23 +35,71 @@ extends Control
var _select_script = "" var _select_script = ""
var _tests_like = "" var _tests_like = ""
var _inner_class_name = "" var _inner_class_name = ""
var _should_maximize = false setget set_should_maximize, get_should_maximize var _should_maximize = false :
var _log_level = 1 setget set_log_level, get_log_level get:
var _disable_strict_datatype_checks = false setget disable_strict_datatype_checks, is_strict_datatype_checks_disabled return _should_maximize # TODOConverter40 Copy here content of get_should_maximize
set(mod_value):
mod_value # TODOConverter40 Copy here content of set_should_maximize
var _log_level = 1 :
get:
return _log_level # TODOConverter40 Copy here content of get_log_level
set(mod_value):
mod_value # TODOConverter40 Copy here content of set_log_level
var _disable_strict_datatype_checks = false :
get:
return _disable_strict_datatype_checks # TODOConverter40 Copy here content of is_strict_datatype_checks_disabled
set(mod_value):
mod_value # TODOConverter40 Copy here content of disable_strict_datatype_checks
var _test_prefix = "test_" var _test_prefix = "test_"
var _file_prefix = "test_" var _file_prefix = "test_"
var _file_extension = ".gd" var _file_extension = ".gd"
var _inner_class_prefix = "Test" var _inner_class_prefix = "Test"
var _temp_directory = "user://gut_temp_directory" var _temp_directory = "user://gut_temp_directory"
var _export_path = "" setget set_export_path, get_export_path var _export_path = "" :
var _include_subdirectories = false setget set_include_subdirectories, get_include_subdirectories get:
var _double_strategy = 1 setget set_double_strategy, get_double_strategy return _export_path # TODOConverter40 Copy here content of get_export_path
var _pre_run_script = "" setget set_pre_run_script, get_pre_run_script set(mod_value):
var _post_run_script = "" setget set_post_run_script, get_post_run_script mod_value # TODOConverter40 Copy here content of set_export_path
var _color_output = false setget set_color_output, get_color_output var _include_subdirectories = false :
var _junit_xml_file = "" setget set_junit_xml_file, get_junit_xml_file get:
var _junit_xml_timestamp = false setget set_junit_xml_timestamp, get_junit_xml_timestamp return _include_subdirectories # TODOConverter40 Copy here content of get_include_subdirectories
var _add_children_to = self setget set_add_children_to, get_add_children_to set(mod_value):
mod_value # TODOConverter40 Copy here content of set_include_subdirectories
var _double_strategy = 1 :
get:
return _double_strategy # TODOConverter40 Copy here content of get_double_strategy
set(mod_value):
mod_value # TODOConverter40 Copy here content of set_double_strategy
var _pre_run_script = "" :
get:
return _pre_run_script # TODOConverter40 Copy here content of get_pre_run_script
set(mod_value):
mod_value # TODOConverter40 Copy here content of set_pre_run_script
var _post_run_script = "" :
get:
return _post_run_script # TODOConverter40 Copy here content of get_post_run_script
set(mod_value):
mod_value # TODOConverter40 Copy here content of set_post_run_script
var _color_output = false :
get:
return _color_output # TODOConverter40 Copy here content of get_color_output
set(mod_value):
mod_value # TODOConverter40 Copy here content of set_color_output
var _junit_xml_file = "" :
get:
return _junit_xml_file # TODOConverter40 Copy here content of get_junit_xml_file
set(mod_value):
mod_value # TODOConverter40 Copy here content of set_junit_xml_file
var _junit_xml_timestamp = false :
get:
return _junit_xml_timestamp # TODOConverter40 Copy here content of get_junit_xml_timestamp
set(mod_value):
mod_value # TODOConverter40 Copy here content of set_junit_xml_timestamp
var _add_children_to = self :
get:
return _add_children_to # TODOConverter40 Copy here content of get_add_children_to
set(mod_value):
mod_value # TODOConverter40 Copy here content of set_add_children_to
# -- End Settings -- # -- End Settings --
# ########################### # ###########################
@ -135,14 +183,14 @@ const SIGNAL_STOP_YIELD_BEFORE_TEARDOWN = "stop_yield_before_teardown"
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
var _should_print_versions = true # used to cut down on output in tests. var _should_print_versions = true # used to cut down checked output in tests.
func _init(): func _init():
_before_all_test_obj.name = "before_all" _before_all_test_obj.name = "before_all"
_after_all_test_obj.name = "after_all" _after_all_test_obj.name = "after_all"
# When running tests for GUT itself, _utils has been setup to always return # When running tests for GUT itself, _utils has been setup to always return
# a new logger so this does not set the gut instance on the base logger # a new logger so this does not set the gut instance checked the base logger
# when creating test instances of GUT. # when creating test instances of GUT.
_lgr.set_gut(self) _lgr.set_gut(self)
@ -156,13 +204,13 @@ func _init():
_doubler.set_spy(_spy) _doubler.set_spy(_spy)
_doubler.set_gut(self) _doubler.set_gut(self)
# TODO remove these, universal logger should fix this. # TODO remove_at these, universal logger should fix this.
_doubler.set_logger(_lgr) _doubler.set_logger(_lgr)
_spy.set_logger(_lgr) _spy.set_logger(_lgr)
_stubber.set_logger(_lgr) _stubber.set_logger(_lgr)
_test_collector.set_logger(_lgr) _test_collector.set_logger(_lgr)
_gui = load("res://addons/gut/GutScene.tscn").instance() _gui = load("res://addons/gut/GutScene.tscn").instantiate()
func _physics_process(delta): func _physics_process(delta):
@ -198,7 +246,7 @@ func _ready():
add_child(_yield_timer) add_child(_yield_timer)
_yield_timer.set_one_shot(true) _yield_timer.set_one_shot(true)
_yield_timer.connect("timeout", self, "_yielding_callback") _yield_timer.connect("timeout",Callable(self,"_yielding_callback"))
_setup_gui() _setup_gui()
@ -255,16 +303,16 @@ func _setup_gui():
# This is how we get the size of the control to translate to the gui when # This is how we get the size of the control to translate to the gui when
# the scene is run. This is also another reason why the min_rect_size # the scene is run. This is also another reason why the min_rect_size
# must match between both gut and the gui. # must match between both gut and the gui.
_gui.rect_size = self.rect_size _gui.size = self.size
add_child(_gui) add_child(_gui)
_gui.set_anchor(MARGIN_RIGHT, ANCHOR_END) _gui.set_anchor(MARGIN_RIGHT, ANCHOR_END)
_gui.set_anchor(MARGIN_BOTTOM, ANCHOR_END) _gui.set_anchor(MARGIN_BOTTOM, ANCHOR_END)
_gui.connect("run_single_script", self, "_on_run_one") _gui.connect("run_single_script",Callable(self,"_on_run_one"))
_gui.connect("run_script", self, "_on_new_gui_run_script") _gui.connect("run_script",Callable(self,"_on_new_gui_run_script"))
_gui.connect("end_pause", self, "_on_new_gui_end_pause") _gui.connect("end_pause",Callable(self,"_on_new_gui_end_pause"))
_gui.connect("ignore_pause", self, "_on_new_gui_ignore_pause") _gui.connect("ignore_pause",Callable(self,"_on_new_gui_ignore_pause"))
_gui.connect("log_level_changed", self, "_on_log_level_changed") _gui.connect("log_level_changed",Callable(self,"_on_log_level_changed"))
var _foo = connect("tests_finished", _gui, "end_run") var _foo = connect("tests_finished",Callable(_gui,"end_run"))
func _add_scripts_to_gui(): func _add_scripts_to_gui():
@ -321,8 +369,8 @@ func _on_log_level_changed(value):
# with set_yield_time() # with set_yield_time()
# #
# signal_watcher._on_watched_signal supports up to 9 additional arguments. # signal_watcher._on_watched_signal supports up to 9 additional arguments.
# This is the most number of parameters GUT supports on signals. The comment # This is the most number of parameters GUT supports checked signals. The comment
# on _on_watched_signal explains reasoning. # checked _on_watched_signal explains reasoning.
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
func _yielding_callback( func _yielding_callback(
from_obj = false, from_obj = false,
@ -521,7 +569,7 @@ func _end_run():
# then move the cursor. I found this workaround through trial and error. # then move the cursor. I found this workaround through trial and error.
_yield_between.timer.set_wait_time(0.1) _yield_between.timer.set_wait_time(0.1)
_yield_between.timer.start() _yield_between.timer.start()
yield(_yield_between.timer, "timeout") await _yield_between.timer.timeout
_gui.scroll_to_bottom() _gui.scroll_to_bottom()
_is_running = false _is_running = false
@ -554,7 +602,7 @@ func _export_junit_xml():
if _junit_xml_timestamp: if _junit_xml_timestamp:
var ext = "." + output_file.get_extension() var ext = "." + output_file.get_extension()
output_file = output_file.replace(ext, str("_", OS.get_unix_time(), ext)) output_file = output_file.replace(ext, str("_", Time.get_unix_time_from_system(), ext))
var f_result = exporter.write_file(self, output_file) var f_result = exporter.write_file(self, output_file)
if f_result == OK: if f_result == OK:
@ -592,7 +640,7 @@ func _print_script_heading(script):
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Just gets more logic out of _test_the_scripts. Decides if we should yield after # Just gets more logic out of _test_the_scripts. Decides if we should yield after
# this test based on flags and counters. # this test based checked flags and counters.
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
func _should_yield_now(): func _should_yield_now():
var should = ( var should = (
@ -639,7 +687,7 @@ func _wait_for_done(result):
var print_after = 3 var print_after = 3
# callback method sets waiting to false. # callback method sets waiting to false.
result.connect(COMPLETED, self, "_on_test_script_yield_completed") result.connect(COMPLETED,Callable(self,"_on_test_script_yield_completed"))
if !_was_yield_method_called: if !_was_yield_method_called:
_lgr.log("-- Yield detected, waiting --", _lgr.fmts.yellow) _lgr.log("-- Yield detected, waiting --", _lgr.fmts.yellow)
@ -652,7 +700,7 @@ func _wait_for_done(result):
iter_counter += 1 iter_counter += 1
_lgr.yield_text("waiting" + dots) _lgr.yield_text("waiting" + dots)
_wait_timer.start() _wait_timer.start()
yield(_wait_timer, "timeout") await _wait_timer.timeout
dots += "." dots += "."
if dots.length() > 5: if dots.length() > 5:
dots = "" dots = ""
@ -690,7 +738,7 @@ func _call_deprecated_script_method(script, method, alt):
func _get_indexes_matching_script_name(name): func _get_indexes_matching_script_name(name):
var indexes = [] # empty runs all var indexes = [] # empty runs all
for i in range(_test_collector.scripts.size()): for i in range(_test_collector.scripts.size()):
if _test_collector.scripts[i].get_filename().find(name) != -1: if _test_collector.scripts[i].get_scene_file_path().find(name) != -1:
indexes.append(i) indexes.append(i)
return indexes return indexes
@ -714,8 +762,8 @@ func _run_parameterized_test(test_script, test_name):
_lgr.warn("Test did not assert") _lgr.warn("Test did not assert")
if _is_function_state(script_result): if _is_function_state(script_result):
# _run_tests does _wait_for_done so just wait on it to complete # _run_tests does _wait_for_done so just wait checked it to complete
yield(script_result, COMPLETED) await script_result.COMPLETED
if _parameter_handler == null: if _parameter_handler == null:
_lgr.error( _lgr.error(
@ -737,8 +785,8 @@ func _run_parameterized_test(test_script, test_name):
var cur_assert_count = _current_test.assert_count var cur_assert_count = _current_test.assert_count
script_result = _run_test(test_script, test_name) script_result = _run_test(test_script, test_name)
if _is_function_state(script_result): if _is_function_state(script_result):
# _run_tests does _wait_for_done so just wait on it to complete # _run_tests does _wait_for_done so just wait checked it to complete
yield(script_result, COMPLETED) await script_result.COMPLETED
if _current_test.assert_count == cur_assert_count and !_current_test.pending: if _current_test.assert_count == cur_assert_count and !_current_test.pending:
_lgr.warn("Test did not assert") _lgr.warn("Test did not assert")
@ -758,7 +806,7 @@ func _run_test(script_inst, test_name):
_call_deprecated_script_method(script_inst, "setup", "before_each") _call_deprecated_script_method(script_inst, "setup", "before_each")
var before_each_result = script_inst.before_each() var before_each_result = script_inst.before_each()
if _is_function_state(before_each_result): if _is_function_state(before_each_result):
yield(_wait_for_done(before_each_result), COMPLETED) await _wait_for_done(before_each_result).COMPLETED
# When the script yields it will return a GDScriptFunctionState object # When the script yields it will return a GDScriptFunctionState object
script_result = script_inst.call(test_name) script_result = script_inst.call(test_name)
@ -770,13 +818,13 @@ func _run_test(script_inst, test_name):
# possible since we only know what the yield was for except when yield_for # possible since we only know what the yield was for except when yield_for
# and yield_to are used. # and yield_to are used.
if _is_function_state(script_result): if _is_function_state(script_result):
yield(_wait_for_done(script_result), COMPLETED) await _wait_for_done(script_result).COMPLETED
# if the test called pause_before_teardown then yield until # if the test called pause_before_teardown then yield until
# the continue button is pressed. # the continue button is pressed.
if _pause_before_teardown and !_ignore_pause_before_teardown: if _pause_before_teardown and !_ignore_pause_before_teardown:
_gui.pause() _gui.pause()
yield(_wait_for_continue_button(), SIGNAL_STOP_YIELD_BEFORE_TEARDOWN) await _wait_for_continue_button().SIGNAL_STOP_YIELD_BEFORE_TEARDOWN
script_inst.clear_signal_watcher() script_inst.clear_signal_watcher()
@ -784,7 +832,7 @@ func _run_test(script_inst, test_name):
_call_deprecated_script_method(script_inst, "teardown", "after_each") _call_deprecated_script_method(script_inst, "teardown", "after_each")
var after_each_result = script_inst.after_each() var after_each_result = script_inst.after_each()
if _is_function_state(after_each_result): if _is_function_state(after_each_result):
yield(_wait_for_done(after_each_result), COMPLETED) await _wait_for_done(after_each_result).COMPLETED
# Free up everything in the _autofree. Yield for a bit if we # Free up everything in the _autofree. Yield for a bit if we
# have anything with a queue_free so that they have time to # have anything with a queue_free so that they have time to
@ -792,7 +840,7 @@ func _run_test(script_inst, test_name):
var aqf_count = _autofree.get_queue_free_count() var aqf_count = _autofree.get_queue_free_count()
_autofree.free_all() _autofree.free_all()
if aqf_count > 0: if aqf_count > 0:
yield(_do_yield_between(), "timeout") await _do_yield_between().timeout
test_summary.orphans = _orphan_counter.get_counter("test") test_summary.orphans = _orphan_counter.get_counter("test")
if _log_level > 0: if _log_level > 0:
@ -802,7 +850,7 @@ func _run_test(script_inst, test_name):
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Calls after_all on the passed in test script and takes care of settings so all # Calls after_all checked the passed in test script and takes care of settings so all
# logger output appears indented and with a proper heading # logger output appears indented and with a proper heading
# #
# Calls both pre-all-tests methods until prerun_setup is removed # Calls both pre-all-tests methods until prerun_setup is removed
@ -819,14 +867,14 @@ func _call_before_all(test_script):
var result = test_script.before_all() var result = test_script.before_all()
if _is_function_state(result): if _is_function_state(result):
yield(_wait_for_done(result), COMPLETED) await _wait_for_done(result).COMPLETED
_lgr.dec_indent() _lgr.dec_indent()
_current_test = null _current_test = null
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Calls after_all on the passed in test script and takes care of settings so all # Calls after_all checked the passed in test script and takes care of settings so all
# logger output appears indented and with a proper heading # logger output appears indented and with a proper heading
# #
# Calls both post-all-tests methods until postrun_teardown is removed. # Calls both post-all-tests methods until postrun_teardown is removed.
@ -843,7 +891,7 @@ func _call_after_all(test_script):
var result = test_script.after_all() var result = test_script.after_all()
if _is_function_state(result): if _is_function_state(result):
yield(_wait_for_done(result), COMPLETED) await _wait_for_done(result).COMPLETED
_lgr.dec_indent() _lgr.dec_indent()
_current_test = null _current_test = null
@ -902,7 +950,7 @@ func _test_the_scripts(indexes = []):
# yield between test scripts so things paint # yield between test scripts so things paint
if _yield_between.should: if _yield_between.should:
yield(_do_yield_between(), "timeout") await _do_yield_between().timeout
# !!! # !!!
# Hack so there isn't another indent to this monster of a method. if # Hack so there isn't another indent to this monster of a method. if
@ -915,7 +963,7 @@ func _test_the_scripts(indexes = []):
var before_all_result = _call_before_all(test_script) var before_all_result = _call_before_all(test_script)
if _is_function_state(before_all_result): if _is_function_state(before_all_result):
# _call_before_all calls _wait for done, just wait for that to finish # _call_before_all calls _wait for done, just wait for that to finish
yield(before_all_result, COMPLETED) await before_all_result.COMPLETED
_gui.set_progress_test_max(the_script.tests.size()) # New way _gui.set_progress_test_max(the_script.tests.size()) # New way
@ -933,7 +981,7 @@ func _test_the_scripts(indexes = []):
): ):
# yield so things paint # yield so things paint
if _should_yield_now(): if _should_yield_now():
yield(_do_yield_between(), "timeout") await _do_yield_between().timeout
if _current_test.arg_count > 1: if _current_test.arg_count > 1:
_lgr.error( _lgr.error(
@ -952,7 +1000,7 @@ func _test_the_scripts(indexes = []):
if _is_function_state(script_result): if _is_function_state(script_result):
# _run_test calls _wait for done, just wait for that to finish # _run_test calls _wait for done, just wait for that to finish
yield(script_result, COMPLETED) await script_result.COMPLETED
if _current_test.assert_count == 0 and !_current_test.pending: if _current_test.assert_count == 0 and !_current_test.pending:
_lgr.warn("Test did not assert") _lgr.warn("Test did not assert")
@ -968,13 +1016,13 @@ func _test_the_scripts(indexes = []):
var after_all_result = _call_after_all(test_script) var after_all_result = _call_after_all(test_script)
if _is_function_state(after_all_result): if _is_function_state(after_all_result):
# _call_after_all calls _wait for done, just wait for that to finish # _call_after_all calls _wait for done, just wait for that to finish
yield(after_all_result, COMPLETED) await after_all_result.COMPLETED
_log_test_children_warning(test_script) _log_test_children_warning(test_script)
# This might end up being very resource intensive if the scripts # This might end up being very resource intensive if the scripts
# don't clean up after themselves. Might have to consolidate output # don't clean up after themselves. Might have to consolidate output
# into some other structure and kill the script objects with # into some other structure and kill the script objects with
# test_script.free() instead of remove child. # test_script.free() instead of remove_at child.
_add_children_to.remove_child(test_script) _add_children_to.remove_child(test_script)
_lgr.set_indent_level(0) _lgr.set_indent_level(0)
@ -1061,7 +1109,7 @@ func _get_files(path, prefix, suffix):
var d = Directory.new() var d = Directory.new()
d.open(path) d.open(path)
# true parameter tells list_dir_begin not to include "." and ".." directories. # true parameter tells list_dir_begin not to include "." and ".." directories.
d.list_dir_begin(true) d.list_dir_begin() # TODOGODOT4 fill missing arguments https://github.com/godotengine/godot/pull/40547
# Traversing a directory is kinda odd. You have to start the process of listing # Traversing a directory is kinda odd. You have to start the process of listing
# the contents of a directory with list_dir_begin then use get_next until it # the contents of a directory with list_dir_begin then use get_next until it
@ -1098,7 +1146,7 @@ func _get_files(path, prefix, suffix):
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Conditionally prints the text to the console/results variable based on the # Conditionally prints the text to the console/results variable based checked the
# current log level and what level is passed in. Whenever currently in a test, # current log level and what level is passed in. Whenever currently in a test,
# the text will be indented under the test. It can be further indented if # the text will be indented under the test. It can be further indented if
# desired. # desired.
@ -1287,7 +1335,7 @@ func is_strict_datatype_checks_disabled():
# you want to watch a test play out onscreen or inspect results. # you want to watch a test play out onscreen or inspect results.
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
func end_yielded_test(): func end_yielded_test():
_lgr.deprecated("end_yielded_test is no longer necessary, you can remove it.") _lgr.deprecated("end_yielded_test is no longer necessary, you can remove_at it.")
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
@ -1385,7 +1433,7 @@ func pause_before_teardown():
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# For batch processing purposes, you may want to ignore any calls to # For batch processing purposes, you may want to ignore any calls to
# pause_before_teardown that you forgot to remove. # pause_before_teardown that you forgot to remove_at.
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
func set_ignore_pause_before_teardown(should_ignore): func set_ignore_pause_before_teardown(should_ignore):
_ignore_pause_before_teardown = should_ignore _ignore_pause_before_teardown = should_ignore
@ -1413,7 +1461,7 @@ func get_yield_between_tests():
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Call _process or _fixed_process, if they exist, on obj and all it's children # Call _process or _fixed_process, if they exist, checked obj and all it's children
# and their children and so and so forth. Delta will be passed through to all # and their children and so and so forth. Delta will be passed through to all
# the _process or _fixed_process methods. # the _process or _fixed_process methods.
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
@ -1431,10 +1479,10 @@ func simulate(obj, times, delta):
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Starts an internal timer with a timeout of the passed in time. A 'timeout' # Starts an internal timer with a timeout of the passed in time. A 'timeout'
# signal will be sent when the timer ends. Returns itself so that it can be # signal will be sent when the timer ends. Returns itself so that it can be
# used in a call to yield...cutting down on lines of code. # used in a call to yield...cutting down checked lines of code.
# #
# Example, yield to the Gut object for 10 seconds: # Example, yield to the Gut object for 10 seconds:
# yield(gut.set_yield_time(10), 'timeout') # await gut.set_yield_time(10).timeout
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
func set_yield_time(time, text = ""): func set_yield_time(time, text = ""):
_yield_timer.set_wait_time(time) _yield_timer.set_wait_time(time)
@ -1474,7 +1522,7 @@ func set_yield_frames(frames, text = ""):
# number of seconds, whichever comes first. # number of seconds, whichever comes first.
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
func set_yield_signal_or_time(obj, signal_name, max_wait, text = ""): func set_yield_signal_or_time(obj, signal_name, max_wait, text = ""):
obj.connect(signal_name, self, "_yielding_callback", [true]) obj.connect(signal_name,Callable(self,"_yielding_callback").bind(true))
_yielding_to.obj = obj _yielding_to.obj = obj
_yielding_to.signal_name = signal_name _yielding_to.signal_name = signal_name
@ -1518,7 +1566,7 @@ func file_delete(path):
var d = Directory.new() var d = Directory.new()
var result = d.open(path.get_base_dir()) var result = d.open(path.get_base_dir())
if result == OK: if result == OK:
d.remove(path) d.remove_at(path)
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
@ -1527,7 +1575,7 @@ func file_delete(path):
func is_file_empty(path): func is_file_empty(path):
var f = File.new() var f = File.new()
f.open(path, f.READ) f.open(path, f.READ)
var empty = f.get_len() == 0 var empty = f.get_length() == 0
f.close() f.close()
return empty return empty
@ -1552,14 +1600,14 @@ func directory_delete_files(path):
# Traversing a directory is kinda odd. You have to start the process of listing # Traversing a directory is kinda odd. You have to start the process of listing
# the contents of a directory with list_dir_begin then use get_next until it # the contents of a directory with list_dir_begin then use get_next until it
# returns an empty string. Then I guess you should end it. # returns an empty string. Then I guess you should end it.
d.list_dir_begin() d.list_dir_begin() # TODOGODOT4 fill missing arguments https://github.com/godotengine/godot/pull/40547
var thing = d.get_next() # could be a dir or a file or something else maybe? var thing = d.get_next() # could be a dir or a file or something else maybe?
var full_path = "" var full_path = ""
while thing != "": while thing != "":
full_path = path + "/" + thing full_path = path + "/" + thing
#file_exists returns fasle for directories #file_exists returns fasle for directories
if d.file_exists(full_path): if d.file_exists(full_path):
d.remove(full_path) d.remove_at(full_path)
thing = d.get_next() thing = d.get_next()
d.list_dir_end() d.list_dir_end()

View file

@ -122,7 +122,7 @@ class OptionResolver:
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Here starts the actual script that uses the Options class to kick off Gut # Here starts the actual script that uses the Options class to kick unchecked Gut
# and run your tests. # and run your tests.
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
var _utils = load("res://addons/gut/utils.gd").get_instance() var _utils = load("res://addons/gut/utils.gd").get_instance()
@ -284,24 +284,24 @@ func _print_gutconfigs(values):
var header = """Here is a sample of a full .gutconfig.json file. var header = """Here is a sample of a full .gutconfig.json file.
You do not need to specify all values in your own file. The values supplied in You do not need to specify all values in your own file. The values supplied in
this sample are what would be used if you ran gut w/o the -gprint_gutconfig_sample this sample are what would be used if you ran gut w/o the -gprint_gutconfig_sample
option (option priority: command-line, .gutconfig, default).""" option (option priority: command-line, super.gutconfig, default)."""
print("\n", header.replace("\n", " "), "\n\n") print("\n", header.replace("\n", " "), "\n\n")
var resolved = values var resolved = values
# remove some options that don't make sense to be in config # remove_at some options that don't make sense to be in config
resolved.erase("config_file") resolved.erase("config_file")
resolved.erase("show_help") resolved.erase("show_help")
print( print(
"Here's a config with all the properties set based off of your current command and config." "Here's a config with all the properties set based unchecked of your current command and config."
) )
print(JSON.print(resolved, " ")) print(JSON.stringify(resolved, " "))
for key in resolved: for key in resolved:
resolved[key] = null resolved[key] = null
print("\n\nAnd here's an empty config for you fill in what you want.") print("\n\nAnd here's an empty config for you fill in what you want.")
print(JSON.print(resolved, " ")) print(JSON.stringify(resolved, " "))
# parse options and run Gut # parse options and run Gut
@ -332,7 +332,7 @@ func _run_gut():
( (
"All command line options and where they are specified. " "All command line options and where they are specified. "
+ 'The "final" value shows which value will actually be used ' + 'The "final" value shows which value will actually be used '
+ "based on order of precedence (default < .gutconfig < cmd line)." + "based checked order of precedence (default < super.gutconfig < cmd line)."
+ "\n" + "\n"
) )
) )
@ -345,7 +345,7 @@ func _run_gut():
_final_opts = opt_resolver.get_resolved_values() _final_opts = opt_resolver.get_resolved_values()
_gut_config.options = _final_opts _gut_config.options = _final_opts
var runner = GutRunner.instance() var runner = GutRunner.instantiate()
runner.set_cmdln_mode(true) runner.set_cmdln_mode(true)
runner.set_gut_config(_gut_config) runner.set_gut_config(_gut_config)

View file

@ -2,7 +2,7 @@ var Gut = load("res://addons/gut/gut.gd")
# Do not want a ref to _utils here due to use by editor plugin. # Do not want a ref to _utils here due to use by editor plugin.
# _utils needs to be split so that constants and what not do not # _utils needs to be split so that constants and what not do not
# have to rely on the weird singleton thing I made. # have to rely checked the weird singleton thing I made.
enum DOUBLE_STRATEGY { FULL, PARTIAL } enum DOUBLE_STRATEGY { FULL, PARTIAL }
var valid_fonts = ["AnonymousPro", "CourierPro", "LobsterTwo", "Default"] var valid_fonts = ["AnonymousPro", "CourierPro", "LobsterTwo", "Default"]
@ -68,7 +68,9 @@ func _load_options_from_config_file(file_path, into):
var json = f.get_as_text() var json = f.get_as_text()
f.close() f.close()
var results = JSON.parse(json) var test_json_conv = JSON.new()
test_json_conv.parse(json)
var results = test_json_conv.get_data()
# SHORTCIRCUIT # SHORTCIRCUIT
if results.error != OK: if results.error != OK:
print("\n\n", "!! ERROR parsing file: ", file_path) print("\n\n", "!! ERROR parsing file: ", file_path)
@ -87,7 +89,7 @@ func _load_options_from_config_file(file_path, into):
func write_options(path): func write_options(path):
var content = JSON.print(options, " ") var content = JSON.stringify(options, " ")
var f = File.new() var f = File.new()
var result = f.open(path, f.WRITE) var result = f.open(path, f.WRITE)

View file

@ -48,7 +48,7 @@
static func _to_scancode(which): static func _to_scancode(which):
var key_code = which var key_code = which
if typeof(key_code) == TYPE_STRING: if typeof(key_code) == TYPE_STRING:
key_code = key_code.to_upper().to_ascii()[0] key_code = key_code.to_upper().to_ascii_buffer()[0]
return key_code return key_code
@ -57,7 +57,7 @@ static func new_mouse_button_event(position, global_position, pressed, button_in
event.position = position event.position = position
if global_position != null: if global_position != null:
event.global_position = global_position event.global_position = global_position
event.pressed = pressed event.button_pressed = pressed
event.button_index = button_index event.button_index = button_index
return event return event
@ -66,14 +66,14 @@ static func new_mouse_button_event(position, global_position, pressed, button_in
static func key_up(which): static func key_up(which):
var event = InputEventKey.new() var event = InputEventKey.new()
event.scancode = _to_scancode(which) event.scancode = _to_scancode(which)
event.pressed = false event.button_pressed = false
return event return event
static func key_down(which): static func key_down(which):
var event = InputEventKey.new() var event = InputEventKey.new()
event.scancode = _to_scancode(which) event.scancode = _to_scancode(which)
event.pressed = true event.button_pressed = true
return event return event
@ -88,33 +88,33 @@ static func action_down(which, strength = 1.0):
var event = InputEventAction.new() var event = InputEventAction.new()
event.action = which event.action = which
event.strength = strength event.strength = strength
event.pressed = true event.button_pressed = true
return event return event
static func mouse_left_button_down(position, global_position = null): static func mouse_left_button_down(position, global_position = null):
var event = new_mouse_button_event(position, global_position, true, BUTTON_LEFT) var event = new_mouse_button_event(position, global_position, true, MOUSE_BUTTON_LEFT)
return event return event
static func mouse_left_button_up(position, global_position = null): static func mouse_left_button_up(position, global_position = null):
var event = new_mouse_button_event(position, global_position, false, BUTTON_LEFT) var event = new_mouse_button_event(position, global_position, false, MOUSE_BUTTON_LEFT)
return event return event
static func mouse_double_click(position, global_position = null): static func mouse_double_click(position, global_position = null):
var event = new_mouse_button_event(position, global_position, false, BUTTON_LEFT) var event = new_mouse_button_event(position, global_position, false, MOUSE_BUTTON_LEFT)
event.doubleclick = true event.doubleclick = true
return event return event
static func mouse_right_button_down(position, global_position = null): static func mouse_right_button_down(position, global_position = null):
var event = new_mouse_button_event(position, global_position, true, BUTTON_RIGHT) var event = new_mouse_button_event(position, global_position, true, MOUSE_BUTTON_RIGHT)
return event return event
static func mouse_right_button_up(position, global_position = null): static func mouse_right_button_up(position, global_position = null):
var event = new_mouse_button_event(position, global_position, false, BUTTON_RIGHT) var event = new_mouse_button_event(position, global_position, false, MOUSE_BUTTON_RIGHT)
return event return event

View file

@ -71,7 +71,7 @@ class InputQueueItem:
if _waited_frames >= frame_delay: if _waited_frames >= frame_delay:
emit_signal("event_ready") emit_signal("event_ready")
func _init(t_delay, f_delay): func _init(t_delay,f_delay):
time_delay = t_delay time_delay = t_delay
frame_delay = f_delay frame_delay = f_delay
_is_ready = time_delay == 0 and frame_delay == 0 _is_ready = time_delay == 0 and frame_delay == 0
@ -90,7 +90,7 @@ class InputQueueItem:
_delay_started = true _delay_started = true
if time_delay > 0: if time_delay > 0:
var t = _delay_timer(time_delay) var t = _delay_timer(time_delay)
t.connect("timeout", self, "_on_time_timeout") t.connect("timeout",Callable(self,"_on_time_timeout"))
# ############################################################################## # ##############################################################################
@ -99,7 +99,7 @@ class InputQueueItem:
var _utils = load("res://addons/gut/utils.gd").get_instance() var _utils = load("res://addons/gut/utils.gd").get_instance()
var InputFactory = load("res://addons/gut/input_factory.gd") var InputFactory = load("res://addons/gut/input_factory.gd")
const INPUT_WARN = "If using Input as a reciever it will not respond to *_down events until a *_up event is recieved. Call the appropriate *_up event or use .hold_for(...) to automatically release after some duration." const INPUT_WARN = "If using Input as a reciever it will not respond to *_down events until a *_up event is recieved. Call the appropriate *_up event or use super.hold_for(...) to automatically release after some duration."
var _lgr = _utils.get_logger() var _lgr = _utils.get_logger()
var _receivers = [] var _receivers = []
@ -197,7 +197,7 @@ func _on_queue_item_ready(item):
func _add_queue_item(item): func _add_queue_item(item):
item.connect("event_ready", self, "_on_queue_item_ready", [item]) item.connect("event_ready",Callable(self,"_on_queue_item_ready").bind(item))
_next_queue_item = item _next_queue_item = item
_input_queue.append(item) _input_queue.append(item)
Engine.get_main_loop().root.add_child(item) Engine.get_main_loop().root.add_child(item)
@ -344,7 +344,7 @@ func release_all():
for key in _pressed_mouse_buttons: for key in _pressed_mouse_buttons:
var event = _pressed_mouse_buttons[key].duplicate() var event = _pressed_mouse_buttons[key].duplicate()
if event.pressed: if event.pressed:
event.pressed = false event.button_pressed = false
_send_event(event) _send_event(event)
_pressed_mouse_buttons.clear() _pressed_mouse_buttons.clear()
@ -352,7 +352,7 @@ func release_all():
func hold_for(duration): func hold_for(duration):
if _last_event != null and _last_event.pressed: if _last_event != null and _last_event.pressed:
var next_event = _last_event.duplicate() var next_event = _last_event.duplicate()
next_event.pressed = false next_event.button_pressed = false
wait(duration) wait(duration)
send_event(next_event) send_event(next_event)
return self return self

View file

@ -90,7 +90,7 @@ func _init():
_printers.console = _utils.Printers.ConsolePrinter.new() _printers.console = _utils.Printers.ConsolePrinter.new()
# There were some problems in the timing of disabling this at the right # There were some problems in the timing of disabling this at the right
# time in gut_cmdln so it is disabled by default. This is enabled # time in gut_cmdln so it is disabled by default. This is enabled
# by plugin_control.gd based on settings. # by plugin_control.gd based checked settings.
_printers.console.set_disabled(true) _printers.console.set_disabled(true)

View file

@ -2,13 +2,13 @@ class CallParameters:
var p_name = null var p_name = null
var default = null var default = null
func _init(n, d): func _init(n,d):
p_name = n p_name = n
default = d default = d
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# This class will generate method declaration lines based on method meta # This class will generate method declaration lines based checked method meta
# data. It will create defaults that match the method data. # data. It will create defaults that match the method data.
# #
# -------------------- # --------------------
@ -43,7 +43,7 @@ const PARAM_PREFIX = "p_"
# TYPE_NIL = 0 — Variable is of type nil (only applied for null). # TYPE_NIL = 0 — Variable is of type nil (only applied for null).
# TYPE_BOOL = 1 — Variable is of type bool. # TYPE_BOOL = 1 — Variable is of type bool.
# TYPE_INT = 2 — Variable is of type int. # TYPE_INT = 2 — Variable is of type int.
# TYPE_REAL = 3 — Variable is of type float/real. # TYPE_FLOAT = 3 — Variable is of type float/real.
# TYPE_STRING = 4 — Variable is of type String. # TYPE_STRING = 4 — Variable is of type String.
# TYPE_VECTOR2 = 5 — Variable is of type Vector2. # TYPE_VECTOR2 = 5 — Variable is of type Vector2.
# TYPE_RECT2 = 6 — Variable is of type Rect2. # TYPE_RECT2 = 6 — Variable is of type Rect2.
@ -52,22 +52,22 @@ const PARAM_PREFIX = "p_"
# TYPE_OBJECT = 17 — Variable is of type Object. # TYPE_OBJECT = 17 — Variable is of type Object.
# TYPE_DICTIONARY = 18 — Variable is of type Dictionary. # TYPE_DICTIONARY = 18 — Variable is of type Dictionary.
# TYPE_ARRAY = 19 — Variable is of type Array. # TYPE_ARRAY = 19 — Variable is of type Array.
# TYPE_VECTOR2_ARRAY = 24 — Variable is of type PoolVector2Array. # TYPE_PACKED_VECTOR2_ARRAY = 24 — Variable is of type PackedVector2Array.
# TYPE_TRANSFORM = 13 — Variable is of type Transform. # TYPE_TRANSFORM3D = 13 — Variable is of type Transform3D.
# TYPE_TRANSFORM2D = 8 — Variable is of type Transform2D. # TYPE_TRANSFORM2D = 8 — Variable is of type Transform2D.
# TYPE_RID = 16 — Variable is of type RID. # TYPE_RID = 16 — Variable is of type RID.
# TYPE_INT_ARRAY = 21 — Variable is of type PoolIntArray. # TYPE_PACKED_INT32_ARRAY = 21 — Variable is of type PackedInt32Array.
# TYPE_REAL_ARRAY = 22 — Variable is of type PoolRealArray. # TYPE_PACKED_FLOAT32_ARRAY = 22 — Variable is of type PackedFloat32Array.
# TYPE_PLANE = 9 — Variable is of type Plane. # TYPE_PLANE = 9 — Variable is of type Plane.
# TYPE_QUAT = 10 — Variable is of type Quat. # TYPE_QUATERNION = 10 — Variable is of type Quaternion.
# TYPE_AABB = 11 — Variable is of type AABB. # TYPE_AABB = 11 — Variable is of type AABB.
# TYPE_BASIS = 12 — Variable is of type Basis. # TYPE_BASIS = 12 — Variable is of type Basis.
# TYPE_NODE_PATH = 15 — Variable is of type NodePath. # TYPE_NODE_PATH = 15 — Variable is of type NodePath.
# TYPE_RAW_ARRAY = 20 — Variable is of type PoolByteArray. # TYPE_PACKED_BYTE_ARRAY = 20 — Variable is of type PackedByteArray.
# TYPE_STRING_ARRAY = 23 — Variable is of type PoolStringArray. # TYPE_PACKED_STRING_ARRAY = 23 — Variable is of type PackedStringArray.
# TYPE_VECTOR3_ARRAY = 25 — Variable is of type PoolVector3Array. # TYPE_PACKED_VECTOR3_ARRAY = 25 — Variable is of type PackedVector3Array.
# TYPE_COLOR_ARRAY = 26 — Variable is of type PoolColorArray. # TYPE_PACKED_COLOR_ARRAY = 26 — Variable is of type PackedColorArray.
# TYPE_MAX = 27 — Marker for end of type constants. # TYPE_MAX = 27 — Marker for end of type constants.
# ------------------------------------------------------ # ------------------------------------------------------
var _supported_defaults = [] var _supported_defaults = []
@ -81,12 +81,12 @@ func _init():
_supported_defaults[TYPE_NIL] = "" _supported_defaults[TYPE_NIL] = ""
_supported_defaults[TYPE_BOOL] = "" _supported_defaults[TYPE_BOOL] = ""
_supported_defaults[TYPE_INT] = "" _supported_defaults[TYPE_INT] = ""
_supported_defaults[TYPE_REAL] = "" _supported_defaults[TYPE_FLOAT] = ""
_supported_defaults[TYPE_OBJECT] = "" _supported_defaults[TYPE_OBJECT] = ""
_supported_defaults[TYPE_ARRAY] = "" _supported_defaults[TYPE_ARRAY] = ""
_supported_defaults[TYPE_STRING] = "" _supported_defaults[TYPE_STRING] = ""
_supported_defaults[TYPE_DICTIONARY] = "" _supported_defaults[TYPE_DICTIONARY] = ""
_supported_defaults[TYPE_VECTOR2_ARRAY] = "" _supported_defaults[TYPE_PACKED_VECTOR2_ARRAY] = ""
_supported_defaults[TYPE_RID] = "" _supported_defaults[TYPE_RID] = ""
# These require a prefix for whatever default is provided # These require a prefix for whatever default is provided
@ -95,9 +95,9 @@ func _init():
_supported_defaults[TYPE_VECTOR3] = "Vector3" _supported_defaults[TYPE_VECTOR3] = "Vector3"
_supported_defaults[TYPE_COLOR] = "Color" _supported_defaults[TYPE_COLOR] = "Color"
_supported_defaults[TYPE_TRANSFORM2D] = "Transform2D" _supported_defaults[TYPE_TRANSFORM2D] = "Transform2D"
_supported_defaults[TYPE_TRANSFORM] = "Transform" _supported_defaults[TYPE_TRANSFORM3D] = "Transform3D"
_supported_defaults[TYPE_INT_ARRAY] = "PoolIntArray" _supported_defaults[TYPE_PACKED_INT32_ARRAY] = "PackedInt32Array"
_supported_defaults[TYPE_REAL_ARRAY] = "PoolRealArray" _supported_defaults[TYPE_PACKED_FLOAT32_ARRAY] = "PackedFloat32Array"
# ############### # ###############
@ -146,7 +146,7 @@ func _make_arg_array(method_meta, override_size):
_supported_defaults[t], _supported_defaults[t],
str(method_meta.default_args[dflt_idx]).to_lower() str(method_meta.default_args[dflt_idx]).to_lower()
) )
elif t == TYPE_TRANSFORM: elif t == TYPE_TRANSFORM3D:
#value will be 4 Vector3 and look like: 1, 0, 0, 0, 1, 0, 0, 0, 1 - 0, 0, 0 #value will be 4 Vector3 and look like: 1, 0, 0, 0, 1, 0, 0, 0, 1 - 0, 0, 0
var sections = str(method_meta.default_args[dflt_idx]).split("-") var sections = str(method_meta.default_args[dflt_idx]).split("-")
var vecs = sections[0].split(",") var vecs = sections[0].split(",")
@ -167,7 +167,7 @@ func _make_arg_array(method_meta, override_size):
dflt_text = str(_supported_defaults[t], "(", vectors, ")") dflt_text = str(_supported_defaults[t], "(", vectors, ")")
elif t == TYPE_RID: elif t == TYPE_RID:
dflt_text = str(_supported_defaults[t], "null") dflt_text = str(_supported_defaults[t], "null")
elif t in [TYPE_REAL_ARRAY, TYPE_INT_ARRAY]: elif t in [TYPE_PACKED_FLOAT32_ARRAY, TYPE_PACKED_INT32_ARRAY]:
dflt_text = str(_supported_defaults[t], "()") dflt_text = str(_supported_defaults[t], "()")
# Everything else puts the prefix (if one is there) form _supported_defaults # Everything else puts the prefix (if one is there) form _supported_defaults
@ -253,7 +253,7 @@ func _get_spy_call_parameters_text(args):
# ############### # ###############
# Creates a delceration for a function based off of function metadata. All # Creates a delceration for a function based unchecked of function metadata. All
# types whose defaults are supported will have their values. If a datatype # types whose defaults are supported will have their values. If a datatype
# is not supported and the parameter has a default, a warning message will be # is not supported and the parameter has a default, a warning message will be
# printed and the declaration will return null. # printed and the declaration will return null.

View file

@ -40,7 +40,7 @@
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
# Parses the command line arguments supplied into an array that can then be # Parses the command line arguments supplied into an array that can then be
# examined and parsed based on how the gut options work. # examined and parsed based checked how the gut options work.
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
class CmdLineParser: class CmdLineParser:
var _used_options = [] var _used_options = []
@ -94,7 +94,7 @@ class CmdLineParser:
var opt_loc = find_option(option) var opt_loc = find_option(option)
if opt_loc != -1: if opt_loc != -1:
to_return = _parse_array_value(_opts[opt_loc]) to_return = _parse_array_value(_opts[opt_loc])
_opts.remove(opt_loc) _opts.remove_at(opt_loc)
return to_return return to_return
@ -107,7 +107,7 @@ class CmdLineParser:
var opt_loc = find_option(option) var opt_loc = find_option(option)
if opt_loc != -1: if opt_loc != -1:
to_return = _parse_option_value(_opts[opt_loc]) to_return = _parse_option_value(_opts[opt_loc])
_opts.remove(opt_loc) _opts.remove_at(opt_loc)
return to_return return to_return
@ -128,14 +128,14 @@ class CmdLineParser:
var script_option = to_return.find("-s") var script_option = to_return.find("-s")
if script_option != -1: if script_option != -1:
to_return.remove(script_option + 1) to_return.remove_at(script_option + 1)
to_return.remove(script_option) to_return.remove_at(script_option)
while _used_options.size() > 0: while _used_options.size() > 0:
var index = to_return.find(_used_options[0].split("=")[0]) var index = to_return.find(_used_options[0].split("=")[0])
if index != -1: if index != -1:
to_return.remove(index) to_return.remove_at(index)
_used_options.remove(0) _used_options.remove_at(0)
return to_return return to_return
@ -149,7 +149,7 @@ class Option:
var default = null var default = null
var description = "" var description = ""
func _init(name, default_value, desc = ""): func _init(name,default_value,desc = ""):
option_name = name option_name = name
default = default_value default = default_value
description = desc description = desc

View file

@ -30,84 +30,84 @@
# through the editor and delays the creation of the GUT instance until # through the editor and delays the creation of the GUT instance until
# Engine.get_main_loop() works as expected. # Engine.get_main_loop() works as expected.
# ############################################################################## # ##############################################################################
tool @tool
extends Control extends Control
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# GUT Settings # GUT Settings
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
export(String, "AnonymousPro", "CourierPrime", "LobsterTwo", "Default") var _font_name = "AnonymousPro" @export var _font_name = "AnonymousPro" # (String, "AnonymousPro", "CourierPrime", "LobsterTwo", "Default")
export(int) var _font_size = 20 @export var _font_size: int = 20
export(Color) var _font_color = Color(.8, .8, .8, 1) @export var _font_color: Color = Color(.8, .8, .8, 1)
export(Color) var _background_color = Color(.15, .15, .15, 1) @export var _background_color: Color = Color(.15, .15, .15, 1)
# Enable/Disable coloring of output. # Enable/Disable coloring of output.
export(bool) var _color_output = true @export var _color_output: bool = true
# The full/partial name of a script to select upon startup # The full/partial name of a script to select upon startup
export(String) var _select_script = "" @export var _select_script: String = ""
# The full/partial name of a test. All tests that contain the string will be # The full/partial name of a test. All tests that contain the string will be
# run # run
export(String) var _tests_like = "" @export var _tests_like: String = ""
# The full/partial name of an Inner Class to be run. All Inner Classes that # The full/partial name of an Inner Class to be run. All Inner Classes that
# contain the string will be run. # contain the string will be run.
export(String) var _inner_class_name = "" @export var _inner_class_name: String = ""
# Start running tests when the scene finishes loading # Start running tests when the scene finishes loading
export var _run_on_load = false @export var _run_on_load = false
# Maximize the GUT control on startup # Maximize the GUT control checked startup
export var _should_maximize = false @export var _should_maximize = false
# Print output to the consol as well # Print output to the consol as well
export var _should_print_to_console = true @export var _should_print_to_console = true
# Display orphan counts at the end of tests/scripts. # Display orphan counts at the end of tests/scripts.
export var _show_orphans = true @export var _show_orphans = true
# The log level. # The log level.
export(int, "Fail/Errors", "Errors/Warnings/Test Names", "Everything") var _log_level = 1 @export var _log_level = 1 # (int, "Fail/Errors", "Errors/Warnings/Test Names", "Everything")
# When enabled GUT will yield between tests to give the GUI time to paint. # When enabled GUT will yield between tests to give the GUI time to paint.
# Disabling this can make the program appear to hang and can have some # Disabling this can make the program appear to hang and can have some
# unwanted consequences with the timing of freeing objects # unwanted consequences with the timing of freeing objects
export var _yield_between_tests = true @export var _yield_between_tests = true
# When GUT compares values it first checks the types to prevent runtime errors. # When GUT compares values it first checks the types to prevent runtime errors.
# This behavior can be disabled if desired. This flag was added early in # This behavior can be disabled if desired. This flag was added early in
# development to prevent any breaking changes and will likely be removed in # development to prevent any breaking changes and will likely be removed in
# the future. # the future.
export var _disable_strict_datatype_checks = false @export var _disable_strict_datatype_checks = false
# The prefix used to find test methods. # The prefix used to find test methods.
export var _test_prefix = "test_" @export var _test_prefix = "test_"
# The prefix used to find test scripts. # The prefix used to find test scripts.
export var _file_prefix = "test_" @export var _file_prefix = "test_"
# The file extension for test scripts (I don't think you can change this and # The file extension for test scripts (I don't think you can change this and
# everythign work). # everythign work).
export var _file_extension = ".gd" @export var _file_extension = ".gd"
# The prefix used to find Inner Test Classes. # The prefix used to find Inner Test Classes.
export var _inner_class_prefix = "Test" @export var _inner_class_prefix = "Test"
# The directory GUT will use to write any temporary files. This isn't used # The directory GUT will use to write any temporary files. This isn't used
# much anymore since there was a change to the double creation implementation. # much anymore since there was a change to the double creation implementation.
# This will be removed in a later release. # This will be removed in a later release.
export(String) var _temp_directory = "user://gut_temp_directory" @export var _temp_directory: String = "user://gut_temp_directory"
# The path and filename for exported test information. # The path and filename for exported test information.
export(String) var _export_path = "" @export var _export_path: String = ""
# When enabled, any directory added will also include its subdirectories when # When enabled, any directory added will also include its subdirectories when
# GUT looks for test scripts. # GUT looks for test scripts.
export var _include_subdirectories = false @export var _include_subdirectories = false
# Allow user to add test directories via editor. This is done with strings # Allow user to add test directories via editor. This is done with strings
# instead of an array because the interface for editing arrays is really # instead of an array because the interface for editing arrays is really
# cumbersome and complicates testing because arrays set through the editor # cumbersome and complicates testing because arrays set through the editor
# apply to ALL instances. This also allows the user to use the built in # apply to ALL instances. This also allows the user to use the built in
# dialog to pick a directory. # dialog to pick a directory.
export(String, DIR) var _directory1 = "" @export var _directory1 = "" # (String, DIR)
export(String, DIR) var _directory2 = "" @export var _directory2 = "" # (String, DIR)
export(String, DIR) var _directory3 = "" @export var _directory3 = "" # (String, DIR)
export(String, DIR) var _directory4 = "" @export var _directory4 = "" # (String, DIR)
export(String, DIR) var _directory5 = "" @export var _directory5 = "" # (String, DIR)
export(String, DIR) var _directory6 = "" @export var _directory6 = "" # (String, DIR)
# Must match the types in _utils for double strategy # Must match the types in _utils for double strategy
export(int, "FULL", "PARTIAL") var _double_strategy = 1 @export var _double_strategy = 1 # (int, "FULL", "PARTIAL")
# Path and filename to the script to run before all tests are run. # Path3D and filename to the script to run before all tests are run.
export(String, FILE) var _pre_run_script = "" @export var _pre_run_script = "" # (String, FILE)
# Path and filename to the script to run after all tests are run. # Path3D and filename to the script to run after all tests are run.
export(String, FILE) var _post_run_script = "" @export var _post_run_script = "" # (String, FILE)
# Path to the file that gut will export results to in the junit xml format # Path3D to the file that gut will export results to in the junit xml format
export(String, FILE) var _junit_xml_file = "" @export var _junit_xml_file = "" # (String, FILE)
# Flag to include a timestamp in the filename of _junit_xml_file # Flag to include a timestamp in the filename of _junit_xml_file
export(bool) var _junit_xml_timestamp = false @export var _junit_xml_timestamp: bool = false
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
@ -130,7 +130,7 @@ var _placeholder = null
func _init(): func _init():
# This min size has to be what the min size of the GutScene's min size is # This min size has to be what the min size of the GutScene's min size is
# but it has to be set here and not inferred i think. # but it has to be set here and not inferred i think.
rect_min_size = Vector2(740, 250) minimum_size = Vector2(740, 250)
func _ready(): func _ready():
@ -138,18 +138,18 @@ func _ready():
# Engine.get_main_loop() is populated and the psuedo singleton utils.gd # Engine.get_main_loop() is populated and the psuedo singleton utils.gd
# can be setup correctly. # can be setup correctly.
if Engine.editor_hint: if Engine.editor_hint:
_placeholder = load("res://addons/gut/GutScene.tscn").instance() _placeholder = load("res://addons/gut/GutScene.tscn").instantiate()
call_deferred("add_child", _placeholder) call_deferred("add_child", _placeholder)
_placeholder.rect_size = rect_size _placeholder.size = size
else: else:
call_deferred("_setup_gut") call_deferred("_setup_gut")
connect("resized", self, "_on_resized") connect("resized",Callable(self,"_on_resized"))
func _on_resized(): func _on_resized():
if _placeholder != null: if _placeholder != null:
_placeholder.rect_size = rect_size _placeholder.size = size
# Templates can be missing if tests are exported and the export config for the # Templates can be missing if tests are exported and the export config for the
@ -176,7 +176,7 @@ func _setup_gut():
_lgr = _utils.get_logger() _lgr = _utils.get_logger()
_gut = load("res://addons/gut/gut.gd").new() _gut = load("res://addons/gut/gut.gd").new()
_gut.connect("tests_finished", self, "_on_tests_finished") _gut.connect("tests_finished",Callable(self,"_on_tests_finished"))
if !_check_for_templates(): if !_check_for_templates():
return return
@ -228,7 +228,7 @@ func _setup_gut():
_gut.get_gui().set_font(_font_name) _gut.get_gui().set_font(_font_name)
_gut.get_gui().set_default_font_color(_font_color) _gut.get_gui().set_default_font_color(_font_color)
_gut.get_gui().set_background_color(_background_color) _gut.get_gui().set_background_color(_background_color)
_gut.get_gui().rect_size = rect_size _gut.get_gui().size = size
emit_signal("gut_ready") emit_signal("gut_ready")
if _run_on_load: if _run_on_load:
@ -244,7 +244,7 @@ func _is_ready_to_go(action):
str( str(
"GUT is not ready for ", "GUT is not ready for ",
action, action,
" yet. Perform actions on GUT in/after the gut_ready signal." " yet. Perform actions checked GUT in/after the gut_ready signal."
) )
) )
return _gut != null return _gut != null

View file

@ -49,7 +49,7 @@ class GutGuiPrinter:
extends Printer extends Printer
var _gut = null var _gut = null
var _colors = {red = Color.red, yellow = Color.yellow, green = Color.green} var _colors = {red = Color.RED, yellow = Color.YELLOW, green = Color.GREEN}
func _init(): func _init():
_printer_name = "gui" _printer_name = "gui"
@ -122,7 +122,7 @@ class ConsolePrinter:
class TerminalPrinter: class TerminalPrinter:
extends Printer extends Printer
var escape = PoolByteArray([0x1b]).get_string_from_ascii() var escape = PackedByteArray([0x1b]).get_string_from_ascii()
var cmd_colors = { var cmd_colors = {
red = escape + "[31m", red = escape + "[31m",
yellow = escape + "[33m", yellow = escape + "[33m",

View file

@ -94,7 +94,7 @@ func get_results_dictionary(gut, include_scripts = true):
func write_json_file(gut, path): func write_json_file(gut, path):
var dict = get_results_dictionary(gut) var dict = get_results_dictionary(gut)
var json = JSON.print(dict, " ") var json = JSON.stringify(dict, " ")
var f_result = _utils.write_file(path, json) var f_result = _utils.write_file(path, json)
if f_result != OK: if f_result != OK:
@ -106,7 +106,7 @@ func write_json_file(gut, path):
func write_summary_file(gut, path): func write_summary_file(gut, path):
var dict = get_results_dictionary(gut, false) var dict = get_results_dictionary(gut, false)
var json = JSON.print(dict, " ") var json = JSON.stringify(dict, " ")
var f_result = _utils.write_file(path, json) var f_result = _utils.write_file(path, json)
if f_result != OK: if f_result != OK:

View file

@ -25,7 +25,7 @@
# ############################################################################## # ##############################################################################
# Some arbitrary string that should never show up by accident. If it does, then # Some arbitrary string that should never show up by accident. If it does, then
# shame on you. # shame checked you.
const ARG_NOT_SET = "_*_argument_*_is_*_not_set_*_" const ARG_NOT_SET = "_*_argument_*_is_*_not_set_*_"
# This hash holds the objects that are being watched, the signals that are being # This hash holds the objects that are being watched, the signals that are being
@ -46,11 +46,11 @@ const ARG_NOT_SET = "_*_argument_*_is_*_not_set_*_"
# } # }
# #
# In this sample: # In this sample:
# - signal1 on the ref1 object was emitted 3 times and each time, zero # - signal1 checked the ref1 object was emitted 3 times and each time, zero
# parameters were passed. # parameters were passed.
# - signal3 on ref1 was emitted once and passed a single parameter # - signal3 checked ref1 was emitted once and passed a single parameter
# - some_signal on ref2 was never emitted. # - some_signal checked ref2 was never emitted.
# - other_signal on ref2 was emitted 3 times, each time with 3 parameters. # - other_signal checked ref2 was emitted 3 times, each time with 3 parameters.
var _watched_signals = {} var _watched_signals = {}
var _utils = load("res://addons/gut/utils.gd").get_instance() var _utils = load("res://addons/gut/utils.gd").get_instance()
@ -64,7 +64,7 @@ func _add_watched_signal(obj, name):
_watched_signals[obj] = {name: []} _watched_signals[obj] = {name: []}
else: else:
_watched_signals[obj][name] = [] _watched_signals[obj][name] = []
obj.connect(name, self, "_on_watched_signal", [obj, name]) obj.connect(name,Callable(self,"_on_watched_signal").bind(obj, name))
# This handles all the signals that are watched. It supports up to 9 parameters # This handles all the signals that are watched. It supports up to 9 parameters
@ -73,7 +73,7 @@ func _add_watched_signal(obj, name):
# parameters when dynamically calling a method via call (per the Godot # parameters when dynamically calling a method via call (per the Godot
# documentation, i.e. some_object.call('some_method', 1, 2, 3...)). # documentation, i.e. some_object.call('some_method', 1, 2, 3...)).
# #
# Based on the documentation of emit_signal, it appears you can only pass up # Based checked the documentation of emit_signal, it appears you can only pass up
# to 4 parameters when firing a signal. I haven't verified this, but this should # to 4 parameters when firing a signal. I haven't verified this, but this should
# future proof this some if the value ever grows. # future proof this some if the value ever grows.
func _on_watched_signal( func _on_watched_signal(
@ -91,13 +91,13 @@ func _on_watched_signal(
): ):
var args = [arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11] var args = [arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11]
# strip off any unused vars. # strip unchecked any unused vars.
var idx = args.size() - 1 var idx = args.size() - 1
while str(args[idx]) == ARG_NOT_SET: while str(args[idx]) == ARG_NOT_SET:
args.remove(idx) args.remove_at(idx)
idx -= 1 idx -= 1
# retrieve object and signal name from the array and remove them. These # retrieve object and signal name from the array and remove_at them. These
# will always be at the end since they are added when the connect happens. # will always be at the end since they are added when the connect happens.
var signal_name = args[args.size() - 1] var signal_name = args[args.size() - 1]
args.pop_back() args.pop_back()
@ -172,7 +172,7 @@ func clear():
for obj in _watched_signals: for obj in _watched_signals:
if _utils.is_not_freed(obj): if _utils.is_not_freed(obj):
for signal_name in _watched_signals[obj]: for signal_name in _watched_signals[obj]:
obj.disconnect(signal_name, self, "_on_watched_signal") obj.disconnect(signal_name,Callable(self,"_on_watched_signal"))
_watched_signals.clear() _watched_signals.clear()

View file

@ -10,37 +10,37 @@ func _init_types_dictionary():
types[TYPE_NIL] = "TYPE_NIL" types[TYPE_NIL] = "TYPE_NIL"
types[TYPE_BOOL] = "Bool" types[TYPE_BOOL] = "Bool"
types[TYPE_INT] = "Int" types[TYPE_INT] = "Int"
types[TYPE_REAL] = "Float/Real" types[TYPE_FLOAT] = "Float/Real"
types[TYPE_STRING] = "String" types[TYPE_STRING] = "String"
types[TYPE_VECTOR2] = "Vector2" types[TYPE_VECTOR2] = "Vector2"
types[TYPE_RECT2] = "Rect2" types[TYPE_RECT2] = "Rect2"
types[TYPE_VECTOR3] = "Vector3" types[TYPE_VECTOR3] = "Vector3"
#types[8] = 'Matrix32' #types[8] = 'Matrix32'
types[TYPE_PLANE] = "Plane" types[TYPE_PLANE] = "Plane"
types[TYPE_QUAT] = "QUAT" types[TYPE_QUATERNION] = "QUAT"
types[TYPE_AABB] = "AABB" types[TYPE_AABB] = "AABB"
#types[12] = 'Matrix3' #types[12] = 'Matrix3'
types[TYPE_TRANSFORM] = "Transform" types[TYPE_TRANSFORM3D] = "Transform3D"
types[TYPE_COLOR] = "Color" types[TYPE_COLOR] = "Color"
#types[15] = 'Image' #types[15] = 'Image'
types[TYPE_NODE_PATH] = "Node Path" types[TYPE_NODE_PATH] = "Node Path3D"
types[TYPE_RID] = "RID" types[TYPE_RID] = "RID"
types[TYPE_OBJECT] = "TYPE_OBJECT" types[TYPE_OBJECT] = "TYPE_OBJECT"
#types[19] = 'TYPE_INPUT_EVENT' #types[19] = 'TYPE_INPUT_EVENT'
types[TYPE_DICTIONARY] = "Dictionary" types[TYPE_DICTIONARY] = "Dictionary"
types[TYPE_ARRAY] = "Array" types[TYPE_ARRAY] = "Array"
types[TYPE_RAW_ARRAY] = "TYPE_RAW_ARRAY" types[TYPE_PACKED_BYTE_ARRAY] = "TYPE_PACKED_BYTE_ARRAY"
types[TYPE_INT_ARRAY] = "TYPE_INT_ARRAY" types[TYPE_PACKED_INT32_ARRAY] = "TYPE_PACKED_INT32_ARRAY"
types[TYPE_REAL_ARRAY] = "TYPE_REAL_ARRAY" types[TYPE_PACKED_FLOAT32_ARRAY] = "TYPE_PACKED_FLOAT32_ARRAY"
types[TYPE_STRING_ARRAY] = "TYPE_STRING_ARRAY" types[TYPE_PACKED_STRING_ARRAY] = "TYPE_PACKED_STRING_ARRAY"
types[TYPE_VECTOR2_ARRAY] = "TYPE_VECTOR2_ARRAY" types[TYPE_PACKED_VECTOR2_ARRAY] = "TYPE_PACKED_VECTOR2_ARRAY"
types[TYPE_VECTOR3_ARRAY] = "TYPE_VECTOR3_ARRAY" types[TYPE_PACKED_VECTOR3_ARRAY] = "TYPE_PACKED_VECTOR3_ARRAY"
types[TYPE_COLOR_ARRAY] = "TYPE_COLOR_ARRAY" types[TYPE_PACKED_COLOR_ARRAY] = "TYPE_PACKED_COLOR_ARRAY"
types[TYPE_MAX] = "TYPE_MAX" types[TYPE_MAX] = "TYPE_MAX"
# Types to not be formatted when using _str # Types to not be formatted when using _str
var _str_ignore_types = [TYPE_INT, TYPE_REAL, TYPE_STRING, TYPE_NIL, TYPE_BOOL] var _str_ignore_types = [TYPE_INT, TYPE_FLOAT, TYPE_STRING, TYPE_NIL, TYPE_BOOL]
func _init(): func _init():
@ -82,10 +82,10 @@ func _get_obj_filename(thing):
pass pass
elif NativeScriptClass != null and thing.get_script() is NativeScriptClass: elif NativeScriptClass != null and thing.get_script() is NativeScriptClass:
# Work with GDNative scripts: # Work with GDNative scripts:
# inst2dict fails with "Not a script with an instance" on GDNative script instances # inst_to_dict fails with "Not a script with an instance" checked GDNative script instances
filename = _get_filename(thing.get_script().resource_path) filename = _get_filename(thing.get_script().resource_path)
elif !_utils.is_native_class(thing): elif !_utils.is_native_class(thing):
var dict = inst2dict(thing) var dict = inst_to_dict(thing)
filename = _get_filename(dict["@path"]) filename = _get_filename(dict["@path"])
if dict["@subpath"] != "": if dict["@subpath"] != "":
filename += str("/", dict["@subpath"]) filename += str("/", dict["@subpath"])
@ -108,7 +108,7 @@ func type2str(thing):
# will pass typeof(thing) == TYPE_OBJECT check so this has to be # will pass typeof(thing) == TYPE_OBJECT check so this has to be
# before that. # before that.
str_thing = str(null) str_thing = str(null)
elif typeof(thing) == TYPE_REAL: elif typeof(thing) == TYPE_FLOAT:
if !"." in str_thing: if !"." in str_thing:
str_thing += ".0" str_thing += ".0"
elif typeof(thing) == TYPE_STRING: elif typeof(thing) == TYPE_STRING:

View file

@ -1,7 +1,7 @@
var return_val = null var return_val = null
var stub_target = null var stub_target = null
var target_subpath = null var target_subpath = null
# the parameter values to match method call on. # the parameter values to match method call checked.
var parameters = null var parameters = null
var stub_method = null var stub_method = null
var call_super = false var call_super = false
@ -25,7 +25,7 @@ var _parameter_override_only = true
const NOT_SET = "|_1_this_is_not_set_1_|" const NOT_SET = "|_1_this_is_not_set_1_|"
func _init(target = null, method = null, subpath = null): func _init(target = null,method = null,subpath = null):
stub_target = target stub_target = target
stub_method = method stub_method = method
target_subpath = subpath target_subpath = subpath
@ -64,7 +64,7 @@ func when_passed(
var idx = 0 var idx = 0
while idx < parameters.size(): while idx < parameters.size():
if str(parameters[idx]) == NOT_SET: if str(parameters[idx]) == NOT_SET:
parameters.remove(idx) parameters.remove_at(idx)
else: else:
idx += 1 idx += 1
return self return self

View file

@ -28,7 +28,7 @@ func _make_key_from_metadata(doubled):
return to_return return to_return
# Creates they key for the returns hash based on the type of object passed in # Creates they key for the returns hash based checked the type of object passed in
# obj could be a string of a path to a script with an optional subpath or # obj could be a string of a path to a script with an optional subpath or
# it could be an instance of a doubled object. # it could be an instance of a doubled object.
func _make_key_from_variant(obj, subpath = null): func _make_key_from_variant(obj, subpath = null):

View file

@ -62,7 +62,7 @@ class DoubleInfo:
# (object_to_double, subpath) # (object_to_double, subpath)
# (object_to_double, strategy) # (object_to_double, strategy)
# (object_to_double, subpath, strategy) # (object_to_double, subpath, strategy)
func _init(thing, p2 = null, p3 = null): func _init(thing,p2 = null,p3 = null):
strategy = p2 strategy = p2
# short-circuit and ensure that is_valid # short-circuit and ensure that is_valid
@ -218,7 +218,7 @@ func _do_datatypes_match__fail_if_not(got, expected, text):
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Create a string that lists all the methods that were called on an spied # Create a string that lists all the methods that were called checked an spied
# instance. # instance.
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
func _get_desc_of_calls_to_instance(inst): func _get_desc_of_calls_to_instance(inst):
@ -226,9 +226,9 @@ func _get_desc_of_calls_to_instance(inst):
var calls = gut.get_spy().get_call_list_as_string(inst) var calls = gut.get_spy().get_call_list_as_string(inst)
# indent all the calls # indent all the calls
calls = BULLET + calls.replace("\n", "\n" + BULLET) calls = BULLET + calls.replace("\n", "\n" + BULLET)
# remove trailing newline and bullet # remove_at trailing newline and bullet
calls = calls.substr(0, calls.length() - BULLET.length() - 1) calls = calls.substr(0, calls.length() - BULLET.length() - 1)
return "Calls made on " + str(inst) + "\n" + calls return "Calls made checked " + str(inst) + "\n" + calls
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
@ -282,7 +282,7 @@ func _fail_if_parameters_not_array(parameters):
func _create_obj_from_type(type): func _create_obj_from_type(type):
var obj = null var obj = null
if type.is_class("PackedScene"): if type.is_class("PackedScene"):
obj = type.instance() obj = type.instantiate()
add_child(obj) add_child(obj)
else: else:
obj = type.new() obj = type.new()
@ -678,8 +678,8 @@ func assert_get_set_methods(obj, property, default, set_to):
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
func assert_accessors(obj, property, default, set_to): func assert_accessors(obj, property, default, set_to):
var fail_count = _summary.failed var fail_count = _summary.failed
var get_func = "get_" + property var get()_func = "get_" + property
var set_func = "set_" + property var set()_func = "set_" + property
if obj.has_method("is_" + property): if obj.has_method("is_" + property):
get_func = "is_" + property get_func = "is_" + property
@ -699,7 +699,7 @@ func assert_accessors(obj, property, default, set_to):
# from passed object. Returns null if not found. # from passed object. Returns null if not found.
# If provided, property_usage constrains the type of property returned by # If provided, property_usage constrains the type of property returned by
# passing either: # passing either:
# EDITOR_PROPERTY for properties defined as: export(int) var some_value # EDITOR_PROPERTY for properties defined as: export var some_value: int
# VARIABLE_PROPERTY for properties defined as: var another_value # VARIABLE_PROPERTY for properties defined as: var another_value
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
func _find_object_property(obj, property_name, property_usage = null): func _find_object_property(obj, property_name, property_usage = null):
@ -707,7 +707,7 @@ func _find_object_property(obj, property_name, property_usage = null):
var found = false var found = false
var properties = obj.get_property_list() var properties = obj.get_property_list()
while !found and !properties.empty(): while !found and !properties.is_empty():
var property = properties.pop_back() var property = properties.pop_back()
if property["name"] == property_name: if property["name"] == property_name:
if property_usage == null or property["usage"] == property_usage: if property_usage == null or property["usage"] == property_usage:
@ -747,12 +747,12 @@ func _can_make_signal_assertions(object, signal_name):
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Check if an object is connected to a signal on another object. Returns True # Check if an object is connected to a signal checked another object. Returns True
# if it is and false otherwise # if it is and false otherwise
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
func _is_connected(signaler_obj, connect_to_obj, signal_name, method_name = ""): func _is_connected(signaler_obj, connect_to_obj, signal_name, method_name = ""):
if method_name != "": if method_name != "":
return signaler_obj.is_connected(signal_name, connect_to_obj, method_name) return signaler_obj.is_connected(signal_name,Callable(connect_to_obj,method_name))
else: else:
var connections = signaler_obj.get_signal_connection_list(signal_name) var connections = signaler_obj.get_signal_connection_list(signal_name)
for conn in connections: for conn in connections:
@ -770,10 +770,10 @@ func watch_signals(object):
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Asserts that an object is connected to a signal on another object # Asserts that an object is connected to a signal checked another object
# #
# This will fail with specific messages if the target object is not connected # This will fail with specific messages if the target object is not connected
# to the specified signal on the source object. # to the specified signal checked the source object.
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
func assert_connected(signaler_obj, connect_to_obj, signal_name, method_name = ""): func assert_connected(signaler_obj, connect_to_obj, signal_name, method_name = ""):
pass pass
@ -785,7 +785,7 @@ func assert_connected(signaler_obj, connect_to_obj, signal_name, method_name = "
_str(signaler_obj), _str(signaler_obj),
" to be connected to signal: [", " to be connected to signal: [",
signal_name, signal_name,
"] on ", "] checked ",
_str(connect_to_obj), _str(connect_to_obj),
method_disp method_disp
) )
@ -796,10 +796,10 @@ func assert_connected(signaler_obj, connect_to_obj, signal_name, method_name = "
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Asserts that an object is not connected to a signal on another object # Asserts that an object is not connected to a signal checked another object
# #
# This will fail with specific messages if the target object is connected # This will fail with specific messages if the target object is connected
# to the specified signal on the source object. # to the specified signal checked the source object.
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
func assert_not_connected(signaler_obj, connect_to_obj, signal_name, method_name = ""): func assert_not_connected(signaler_obj, connect_to_obj, signal_name, method_name = ""):
var method_disp = "" var method_disp = ""
@ -810,7 +810,7 @@ func assert_not_connected(signaler_obj, connect_to_obj, signal_name, method_name
_str(signaler_obj), _str(signaler_obj),
" to not be connected to signal: [", " to not be connected to signal: [",
signal_name, signal_name,
"] on ", "] checked ",
_str(connect_to_obj), _str(connect_to_obj),
method_disp method_disp
) )
@ -1116,21 +1116,21 @@ func assert_string_ends_with(text, search, match_case = true):
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Assert that a method was called on an instance of a doubled class. If # Assert that a method was called checked an instance of a doubled class. If
# parameters are supplied then the params passed in when called must match. # parameters are supplied then the params passed in when called must match.
# TODO make 3rd parameter "param_or_text" and add fourth parameter of "text" and # TODO make 3rd parameter "param_or_text" and add fourth parameter of "text" and
# then work some magic so this can have a "text" parameter without being # then work some magic so this can have a "text" parameter without being
# annoying. # annoying.
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
func assert_called(inst, method_name, parameters = null): func assert_called(inst, method_name, parameters = null):
var disp = str("Expected [", method_name, "] to have been called on ", _str(inst)) var disp = str("Expected [", method_name, "] to have been called checked ", _str(inst))
if _fail_if_parameters_not_array(parameters): if _fail_if_parameters_not_array(parameters):
return return
if !_utils.is_double(inst): if !_utils.is_double(inst):
_fail( _fail(
"You must pass a doubled instance to assert_called. Check the wiki for info on using double." "You must pass a doubled instance to assert_called. Check the wiki for info checked using double."
) )
else: else:
if gut.get_spy().was_called(inst, method_name, parameters): if gut.get_spy().was_called(inst, method_name, parameters):
@ -1142,19 +1142,19 @@ func assert_called(inst, method_name, parameters = null):
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Assert that a method was not called on an instance of a doubled class. If # Assert that a method was not called checked an instance of a doubled class. If
# parameters are specified then this will only fail if it finds a call that was # parameters are specified then this will only fail if it finds a call that was
# sent matching parameters. # sent matching parameters.
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
func assert_not_called(inst, method_name, parameters = null): func assert_not_called(inst, method_name, parameters = null):
var disp = str("Expected [", method_name, "] to NOT have been called on ", _str(inst)) var disp = str("Expected [", method_name, "] to NOT have been called checked ", _str(inst))
if _fail_if_parameters_not_array(parameters): if _fail_if_parameters_not_array(parameters):
return return
if !_utils.is_double(inst): if !_utils.is_double(inst):
_fail( _fail(
"You must pass a doubled instance to assert_not_called. Check the wiki for info on using double." "You must pass a doubled instance to assert_not_called. Check the wiki for info checked using double."
) )
else: else:
if gut.get_spy().was_called(inst, method_name, parameters): if gut.get_spy().was_called(inst, method_name, parameters):
@ -1166,7 +1166,7 @@ func assert_not_called(inst, method_name, parameters = null):
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Assert that a method on an instance of a doubled class was called a number # Assert that a method checked an instance of a doubled class was called a number
# of times. If parameters are specified then only calls with matching # of times. If parameters are specified then only calls with matching
# parameter values will be counted. # parameter values will be counted.
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
@ -1179,12 +1179,12 @@ func assert_call_count(inst, method_name, expected_count, parameters = null):
var param_text = "" var param_text = ""
if parameters: if parameters:
param_text = " with parameters " + str(parameters) param_text = " with parameters " + str(parameters)
var disp = "Expected [%s] on %s to be called [%s] times%s. It was called [%s] times." var disp = "Expected [%s] checked %s to be called [%s] times%s. It was called [%s] times."
disp = disp % [method_name, _str(inst), expected_count, param_text, count] disp = disp % [method_name, _str(inst), expected_count, param_text, count]
if !_utils.is_double(inst): if !_utils.is_double(inst):
_fail( _fail(
"You must pass a doubled instance to assert_call_count. Check the wiki for info on using double." "You must pass a doubled instance to assert_call_count. Check the wiki for info checked using double."
) )
else: else:
if count == expected_count: if count == expected_count:
@ -1498,7 +1498,7 @@ func yield_frames(frames, msg = ""):
# not make assertions after a yield. # not make assertions after a yield.
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
func end_test(): func end_test():
_lgr.deprecated("end_test is no longer necessary, you can remove it.") _lgr.deprecated("end_test is no longer necessary, you can remove_at it.")
#gut.end_yielded_test() #gut.end_yielded_test()
@ -1678,7 +1678,7 @@ func ignore_method_when_doubling(thing, method_name):
var path = double_info.path var path = double_info.path
if double_info.is_scene(): if double_info.is_scene():
var inst = thing.instance() var inst = thing.instantiate()
if inst.get_script(): if inst.get_script():
path = inst.get_script().get_path() path = inst.get_script().get_path()
@ -1698,7 +1698,7 @@ func ignore_method_when_doubling(thing, method_name):
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
func stub(thing, p2, p3 = null): func stub(thing, p2, p3 = null):
if _utils.is_instance(thing) and !_utils.is_double(thing): if _utils.is_instance(thing) and !_utils.is_double(thing):
_lgr.error(str("You cannot use stub on ", _str(thing), " because it is not a double.")) _lgr.error(str("You cannot use stub checked ", _str(thing), " because it is not a double."))
return _utils.StubParams.new() return _utils.StubParams.new()
var method_name = p2 var method_name = p2
@ -1791,7 +1791,7 @@ func autofree(thing):
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Works the same as autofree except queue_free will be called on the object # Works the same as autofree except queue_free will be called checked the object
# instead. This also imparts a brief pause after the test finishes so that # instead. This also imparts a brief pause after the test finishes so that
# the queued object has time to free. # the queued object has time to free.
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
@ -1807,7 +1807,7 @@ func add_child_autofree(node, legible_unique_name = false):
gut.get_autofree().add_free(node) gut.get_autofree().add_free(node)
# Explicitly calling super here b/c add_child MIGHT change and I don't want # Explicitly calling super here b/c add_child MIGHT change and I don't want
# a bug sneaking its way in here. # a bug sneaking its way in here.
.add_child(node, legible_unique_name) super.add_child(node, legible_unique_name)
return node return node
@ -1818,7 +1818,7 @@ func add_child_autoqfree(node, legible_unique_name = false):
gut.get_autofree().add_queue_free(node) gut.get_autofree().add_queue_free(node)
# Explicitly calling super here b/c add_child MIGHT change and I don't want # Explicitly calling super here b/c add_child MIGHT change and I don't want
# a bug sneaking its way in here. # a bug sneaking its way in here.
.add_child(node, legible_unique_name) super.add_child(node, legible_unique_name)
return node return node
@ -1869,7 +1869,7 @@ func fail_test(text):
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Peforms a deep compare on both values, a CompareResult instnace is returned. # Peforms a deep compare checked both values, a CompareResult instnace is returned.
# The optional max_differences paramter sets the max_differences to be displayed. # The optional max_differences paramter sets the max_differences to be displayed.
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
func compare_deep(v1, v2, max_differences = null): func compare_deep(v1, v2, max_differences = null):
@ -1880,7 +1880,7 @@ func compare_deep(v1, v2, max_differences = null):
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Peforms a shallow compare on both values, a CompareResult instnace is returned. # Peforms a shallow compare checked both values, a CompareResult instnace is returned.
# The optional max_differences paramter sets the max_differences to be displayed. # The optional max_differences paramter sets the max_differences to be displayed.
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
func compare_shallow(v1, v2, max_differences = null): func compare_shallow(v1, v2, max_differences = null):

View file

@ -31,7 +31,7 @@ class TestScript:
var _utils = null var _utils = null
var _lgr = null var _lgr = null
func _init(utils = null, logger = null): func _init(utils = null,logger = null):
_utils = utils _utils = utils
_lgr = logger _lgr = logger
@ -60,7 +60,7 @@ class TestScript:
return to_return return to_return
func get_filename_and_inner(): func get_filename_and_inner():
var to_return = get_filename() var to_return = get_scene_file_path()
if inner_class_name != null: if inner_class_name != null:
to_return += "." + inner_class_name to_return += "." + inner_class_name
return to_return return to_return
@ -71,7 +71,7 @@ class TestScript:
to_return += "." + inner_class_name to_return += "." + inner_class_name
return to_return return to_return
func get_filename(): func get_scene_file_path():
return path.get_file() return path.get_file()
func has_inner_class(): func has_inner_class():

View file

@ -108,7 +108,7 @@ var req_godot = [3, 2, 0]
# Used for doing file manipulation stuff so as to not keep making File instances. # Used for doing file manipulation stuff so as to not keep making File instances.
# could be a bit of overkill but who cares. # could be a bit of overkill but who cares.
var _file_checker = File.new() var _file_checker = File.new()
# Online fetch of the latest version available on github # Online fetch of the latest version available checked github
var latest_version = null var latest_version = null
var should_display_latest_version = false var should_display_latest_version = false
@ -135,7 +135,7 @@ func _http_request_latest_version() -> void:
var http_request = HTTPRequest.new() var http_request = HTTPRequest.new()
http_request.name = "http_request" http_request.name = "http_request"
add_child(http_request) add_child(http_request)
http_request.connect("request_completed", self, "_on_http_request_latest_version_completed") http_request.connect("request_completed",Callable(self,"_on_http_request_latest_version_completed"))
# Perform a GET request. The URL below returns JSON as of writing. # Perform a GET request. The URL below returns JSON as of writing.
var error = http_request.request("https://api.github.com/repos/bitwes/Gut/releases/latest") var error = http_request.request("https://api.github.com/repos/bitwes/Gut/releases/latest")
@ -144,7 +144,9 @@ func _on_http_request_latest_version_completed(result, response_code, headers, b
if not result == HTTPRequest.RESULT_SUCCESS: if not result == HTTPRequest.RESULT_SUCCESS:
return return
var response = parse_json(body.get_string_from_utf8()) var test_json_conv = JSON.new()
test_json_conv.parse(body.get_string_from_utf8())
var response = test_json_conv.get_data()
# Will print the user agent string used by the HTTPRequest node (as recognized by httpbin.org). # Will print the user agent string used by the HTTPRequest node (as recognized by httpbin.org).
if response: if response:
if response.get("html_url"): if response.get("html_url"):
@ -176,7 +178,7 @@ func get_version_text():
# Returns a nice string for erroring out when we have a bad Godot version. # Returns a nice string for erroring out when we have a bad Godot version.
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
func get_bad_version_text(): func get_bad_version_text():
var ver = PoolStringArray(req_godot).join(".") var ver = ".".join(PackedStringArray(req_godot))
var info = Engine.get_version_info() var info = Engine.get_version_info()
var gd_version = str(info.major, ".", info.minor, ".", info.patch) var gd_version = str(info.major, ".", info.minor, ".", info.patch)
return ( return (
@ -278,7 +280,7 @@ func is_gdscript(obj):
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Returns an array of values by calling get(property) on each element in source # Returns an array of values by calling get(property) checked each element in source
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
func extract_property_from_array(source, property): func extract_property_from_array(source, property):
var to_return = [] var to_return = []
@ -323,7 +325,7 @@ func get_native_class_name(thing):
if is_native_class(thing): if is_native_class(thing):
var newone = thing.new() var newone = thing.new()
to_return = newone.get_class() to_return = newone.get_class()
if !newone is Reference: if !newone is RefCounted:
newone.free() newone.free()
return to_return return to_return
@ -352,7 +354,7 @@ func get_file_as_text(path):
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# Loops through an array of things and calls a method or checks a property on # Loops through an array of things and calls a method or checks a property checked
# each element until it finds the returned value. The item in the array is # each element until it finds the returned value. The item in the array is
# returned or null if it is not found. # returned or null if it is not found.
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
@ -383,7 +385,7 @@ func are_datatypes_same(got, expected):
func pretty_print(dict): func pretty_print(dict):
print(str(JSON.print(dict, " "))) print(str(JSON.stringify(dict, " ")))
func get_script_text(obj): func get_script_text(obj):

View file

@ -1,6 +1,6 @@
[gd_resource type="Environment" load_steps=2 format=2] [gd_resource type="Environment" load_steps=2 format=2]
[sub_resource type="ProceduralSky" id=1] [sub_resource type="Sky" id=1]
[resource] [resource]
background_mode = 2 background_mode = 2

View file

@ -1,4 +1,4 @@
tool @tool
extends Control extends Control
# This scene demonstrates how we can control the Terminal node directly by # This scene demonstrates how we can control the Terminal node directly by
# sending and receiving strings and ANSI escape sequences to the terminal # sending and receiving strings and ANSI escape sequences to the terminal
@ -38,15 +38,15 @@ var row: int
var menu_start_row: int var menu_start_row: int
var offset: int var offset: int
onready var tput = TPut.new($Terminal) @onready var tput = TPut.new($Terminal)
func _ready(): func _ready():
if not $Terminal.is_connected("key_pressed", self, "_on_Terminal_key_pressed"): if not $Terminal.is_connected("key_pressed",Callable(self,"_on_Terminal_key_pressed")):
# warning-ignore:return_value_discarded # warning-ignore:return_value_discarded
$Terminal.connect("key_pressed", self, "_on_Terminal_key_pressed") $Terminal.connect("key_pressed",Callable(self,"_on_Terminal_key_pressed"))
# warning-ignore:return_value_discarded # warning-ignore:return_value_discarded
$Terminal.connect("size_changed", self, "draw_all") $Terminal.connect("size_changed",Callable(self,"draw_all"))
$Terminal.grab_focus() $Terminal.grab_focus()
draw_all() draw_all()
@ -132,12 +132,12 @@ func _on_Terminal_key_pressed(data: String, event: InputEventKey) -> void:
match item.name: match item.name:
"Asciicast": "Asciicast":
var scene = item.scene.instance() var scene = item.scene.instantiate()
var animation_player: AnimationPlayer = scene.get_node("AnimationPlayer") var animation_player: AnimationPlayer = scene.get_node("AnimationPlayer")
scene.connect("key_pressed", self, "_on_Asciicast_key_pressed", [animation_player]) scene.connect("key_pressed",Callable(self,"_on_Asciicast_key_pressed").bind(animation_player))
add_child(scene) add_child(scene)
scene.grab_focus() scene.grab_focus()
yield(animation_player, "animation_finished") await animation_player.animation_finished
remove_child(scene) remove_child(scene)
$Terminal.grab_focus() $Terminal.grab_focus()
scene.queue_free() scene.queue_free()
@ -148,15 +148,15 @@ func _on_Terminal_key_pressed(data: String, event: InputEventKey) -> void:
( (
"Psuedoterminal node currently" "Psuedoterminal node currently"
+ " uses pty.h but needs to use either winpty or conpty" + " uses pty.h but needs to use either winpty or conpty"
+ " to work on Windows." + " to work checked Windows."
), ),
"Terminal not Supported on Windows" "Terminal not Supported checked Windows"
) )
var scene = item.scene.instance() var scene = item.scene.instantiate()
var pty = scene if OS.has_feature("JavaScript") else scene.get_node("PTY") var pty = scene if OS.has_feature("JavaScript") else scene.get_node("PTY")
add_child(scene) add_child(scene)
scene.grab_focus() scene.grab_focus()
yield(pty, "exited") await pty.exited
$Terminal.grab_focus() $Terminal.grab_focus()
scene.queue_free() scene.queue_free()
"Exit": "Exit":

View file

@ -20,14 +20,14 @@ shader_type canvas_item;
// - If you are using this shader as an overlay, and want the shader to affect the nodes below in the Scene hierarchy, // - If you are using this shader as an overlay, and want the shader to affect the nodes below in the Scene hierarchy,
// set 'overlay' to true (checked in the inspector). // set 'overlay' to true (checked in the inspector).
// On Mac there is potentially a bug causing this to not work properly. If that is the case and you want to use the shader as an overlay // On Mac there is potentially a bug causing this to not work properly. If that is the case and you want to use the shader as an overlay
// change all \"overlay ? SCREEN_TEXTURE : TEXTURE\" to only \"SCREEN_TEXTURE\" on lines 129-140, and \"vec2 uv = overlay ? warp(SCREEN_UV) : warp(UV);\" // change all \"overlay ? SCREEN_TEXTURE : TEXTURE\" to only \"SCREEN_TEXTURE\" checked lines 129-140, and \"vec2 uv = overlay ? warp(SCREEN_UV) : warp(UV);\"
// to \"vec2 uv = warp(SCREEN_UV);\" on line 98. // to \"vec2 uv = warp(SCREEN_UV);\" checked line 98.
uniform bool overlay = false; uniform bool overlay = false;
uniform float scanlines_opacity : hint_range(0.0, 1.0) = 0.4; uniform float scanlines_opacity : hint_range(0.0, 1.0) = 0.4;
uniform float scanlines_width : hint_range(0.0, 0.5) = 0.25; uniform float scanlines_width : hint_range(0.0, 0.5) = 0.25;
uniform float grille_opacity : hint_range(0.0, 1.0) = 0.3; uniform float grille_opacity : hint_range(0.0, 1.0) = 0.3;
uniform vec2 resolution = vec2(640.0, 480.0); // Set the number of rows and columns the texture will be divided in. Scanlines and grille will make a square based on these values uniform vec2 resolution = vec2(640.0, 480.0); // Set the number of rows and columns the texture will be divided in. Scanlines and grille will make a square based checked these values
uniform bool pixelate = true; // Fill each square (\"pixel\") with a sampled color, creating a pixel look and a more accurate representation of how a CRT monitor would work. uniform bool pixelate = true; // Fill each square (\"pixel\") with a sampled color, creating a pixel look and a more accurate representation of how a CRT monitor would work.
@ -42,7 +42,7 @@ uniform float noise_speed = 5.0; // There is a movement in the noise pattern tha
uniform float static_noise_intensity : hint_range(0.0, 1.0) = 0.06; uniform float static_noise_intensity : hint_range(0.0, 1.0) = 0.06;
uniform float aberration : hint_range(-1.0, 1.0) = 0.03; // Chromatic aberration, a distortion on each color channel. uniform float aberration : hint_range(-1.0, 1.0) = 0.03; // Chromatic aberration, a distortion checked each color channel.
uniform float brightness = 1.4; // When adding scanline gaps and grille the image can get very dark. Brightness tries to compensate for that. uniform float brightness = 1.4; // When adding scanline gaps and grille the image can get very dark. Brightness tries to compensate for that.
uniform bool discolor = true; // Add a discolor effect simulating a VHS uniform bool discolor = true; // Add a discolor effect simulating a VHS
@ -107,7 +107,7 @@ void fragment()
float time = roll ? TIME : 0.0; float time = roll ? TIME : 0.0;
// Pixelate the texture based on the given resolution. // Pixelate the texture based checked the given resolution.
if (pixelate) if (pixelate)
{ {
text_uv = ceil(uv * resolution) / resolution; text_uv = ceil(uv * resolution) / resolution;
@ -174,7 +174,7 @@ void fragment()
text.g = clamp(g * brightness, 0.0, 1.0); text.g = clamp(g * brightness, 0.0, 1.0);
text.b = clamp(b * brightness, 0.0, 1.0); text.b = clamp(b * brightness, 0.0, 1.0);
// Scanlines are the horizontal lines that make up the image on a CRT monitor. // Scanlines are the horizontal lines that make up the image checked a CRT monitor.
// Here we are actual setting the black gap between each line, which I guess is not the right definition of the word, but you get the idea // Here we are actual setting the black gap between each line, which I guess is not the right definition of the word, but you get the idea
float scanlines = 0.5; float scanlines = 0.5;
if (scanlines_opacity > 0.0) if (scanlines_opacity > 0.0)
@ -190,13 +190,13 @@ void fragment()
// Generate a noise pattern that is very stretched horizontally, and animate it with noise_speed // Generate a noise pattern that is very stretched horizontally, and animate it with noise_speed
float noise = smoothstep(0.4, 0.5, noise(uv * vec2(2.0, 200.0) + vec2(10.0, (TIME * (noise_speed))) ) ); float noise = smoothstep(0.4, 0.5, noise(uv * vec2(2.0, 200.0) + vec2(10.0, (TIME * (noise_speed))) ) );
// We use roll_line (set above) to define how big the noise should be vertically (multiplying cuts off all black parts). // We use roll_line (set above) to define how big the noise should be vertically (multiplying cuts unchecked all black parts).
// We also add in some basic noise with random() to break up the noise pattern above. The noise is sized according to // We also add in some basic noise with random() to break up the noise pattern above. The noise is sized according to
// the resolution value set in the inspector. If you don't like this look you can // the resolution value set in the inspector. If you don't like this look you can
// change \"ceil(uv * resolution) / resolution\" to only \"uv\" to make it less pixelated. Or multiply resolution with som value // change \"ceil(uv * resolution) / resolution\" to only \"uv\" to make it less pixelated. Or multiply resolution with som value
// greater than 1.0 to make them smaller. // greater than 1.0 to make them smaller.
roll_line *= noise * scanlines * clamp(random((ceil(uv * resolution) / resolution) + vec2(TIME * 0.8, 0.0)).x + 0.8, 0.0, 1.0); roll_line *= noise * scanlines * clamp(random((ceil(uv * resolution) / resolution) + vec2(TIME * 0.8, 0.0)).x + 0.8, 0.0, 1.0);
// Add it to the texture based on noise_opacity // Add it to the texture based checked noise_opacity
text.rgb = clamp(mix(text.rgb, text.rgb + roll_line, noise_opacity), vec3(0.0), vec3(1.0)); text.rgb = clamp(mix(text.rgb, text.rgb + roll_line, noise_opacity), vec3(0.0), vec3(1.0));
} }
@ -210,7 +210,7 @@ void fragment()
// Also apply the vignette // Also apply the vignette
text.rgb *= border(uv); text.rgb *= border(uv);
text.rgb *= vignette(uv); text.rgb *= vignette(uv);
// Hides the black border and make that area transparent. Good if you want to add the the texture on top an image of a TV or monitor. // Hides the black border and make that area transparent. Good if you want to add the the texture checked top an image of a TV or monitor.
if (clip_warp) if (clip_warp)
{ {
text.a = border(uv); text.a = border(uv);
@ -283,8 +283,8 @@ __meta__ = {
} }
[node name="Menu" parent="." instance=ExtResource( 1 )] [node name="Menu" parent="." instance=ExtResource( 1 )]
margin_left = 30.0 offset_left = 30.0
margin_top = 30.0 offset_top = 30.0
[node name="CanvasLayer" type="CanvasLayer" parent="."] [node name="CanvasLayer" type="CanvasLayer" parent="."]

View file

@ -1,9 +1,9 @@
extends "res://addons/godot_xterm/terminal.gd" extends "res://addons/godot_xterm/terminal.gd"
export(String) var exec_path := "bash" @export var exec_path: String := "bash"
export(String) var socat_path := "socat" # E.g. /usr/bin/socat @export var socat_path: String := "socat" # E.g. /usr/bin/socat
export(int) var port := 2023 @export var port: int := 2023
export(bool) var verbose := false @export var verbose: bool := false
var _timeout = 30 var _timeout = 30
var _pid: int var _pid: int
@ -31,7 +31,7 @@ func _process(delta):
StreamPeerTCP.STATUS_CONNECTED: StreamPeerTCP.STATUS_CONNECTED:
var avail = _stream.get_available_bytes() var avail = _stream.get_available_bytes()
var data = PoolByteArray() var data = PackedByteArray()
for i in range(avail): for i in range(avail):
data.append(_stream.get_u8()) data.append(_stream.get_u8())
call_deferred("write", data) call_deferred("write", data)

View file

@ -1,6 +1,6 @@
extends "res://addons/godot_xterm/terminal.gd" extends "res://addons/godot_xterm/terminal.gd"
onready var pty = $PTY @onready var pty = $PTY
func _ready(): func _ready():

View file

@ -7,8 +7,8 @@ signal exited(status)
var line := "" var line := ""
var _tput var _tput
onready var terminal = $Terminal @onready var terminal = $Terminal
onready var _has_js: bool = OS.has_feature("JavaScript") @onready var _has_js: bool = OS.has_feature("JavaScript")
func prompt(prompt: String): func prompt(prompt: String):
@ -42,7 +42,7 @@ func _on_Terminal_key_pressed(_data, event: InputEventKey):
if not event: if not event:
return return
# For some reason, data String is malformed on HTML5, so only use event.unicode. # For some reason, data String is malformed checked HTML5, so only use event.unicode.
var data = char(event.unicode) var data = char(event.unicode)
match event.scancode: match event.scancode:

View file

@ -1,14 +1,6 @@
; Engine configuration file. ; Project was converted by built-in tool to Godot 4.0
; It's best edited using the editor UI and not directly, config_version=5
; since the parameters that go here are not all obvious. _global_script_classes=[{
;
; Format:
; [section] ; section goes between []
; param=value ; assign values to parameters
config_version=4
_global_script_classes=[ {
"base": "Reference", "base": "Reference",
"class": "GutHookScript", "class": "GutHookScript",
"language": "GDScript", "language": "GDScript",
@ -18,7 +10,7 @@ _global_script_classes=[ {
"class": "GutTest", "class": "GutTest",
"language": "GDScript", "language": "GDScript",
"path": "res://addons/gut/test.gd" "path": "res://addons/gut/test.gd"
} ] }]
_global_script_class_icons={ _global_script_class_icons={
"GutHookScript": "", "GutHookScript": "",
"GutTest": "" "GutTest": ""
@ -36,7 +28,7 @@ window/vsync/use_vsync=false
[editor_plugins] [editor_plugins]
enabled=PoolStringArray( "res://addons/godot_xterm/plugin.cfg" ) enabled=PackedStringArray("res://addons/godot_xterm/plugin.cfg")
[rendering] [rendering]

View file

@ -7,7 +7,7 @@ var terminal: Terminal
func before_each(): func before_each():
terminal = Terminal.new() terminal = Terminal.new()
terminal.rect_size = Vector2(400, 200) terminal.size = Vector2(400, 200)
add_child_autofree(terminal) add_child_autofree(terminal)
@ -18,7 +18,7 @@ func test_bell() -> void:
terminal.write("\a") terminal.write("\a")
terminal.write("\u0007") terminal.write("\u0007")
terminal.write("'Ask not for whom the \a tolls; it tolls for thee' - John Donne") terminal.write("'Ask not for whom the \a tolls; it tolls for thee' - John Donne")
yield(yield_to(terminal, "bell", 5), YIELD) await yield_to(terminal, "bell", 5).YIELD
assert_signal_emit_count(terminal, "bell", 5) assert_signal_emit_count(terminal, "bell", 5)
@ -27,15 +27,15 @@ func test_bell_cooldown() -> void:
terminal.bell_cooldown = 0.5 terminal.bell_cooldown = 0.5
terminal.write("\a") terminal.write("\a")
terminal.write("\a") terminal.write("\a")
yield(yield_for(1), YIELD) await yield_for(1).YIELD
terminal.write("\a") terminal.write("\a")
yield(yield_to(terminal, "bell", 5), YIELD) await yield_to(terminal, "bell", 5).YIELD
assert_signal_emit_count(terminal, "bell", 2) assert_signal_emit_count(terminal, "bell", 2)
func test_writing_random_data_to_terminal_does_not_crash_application(): func test_writing_random_data_to_terminal_does_not_crash_application():
add_child_autofree(preload("res://test/scenes/write_random.tscn").instance()) add_child_autofree(preload("res://test/scenes/write_random.tscn").instantiate())
yield(yield_frames(5, "Writing random data to terminal"), YIELD) await yield_frames(5, "Writing random data to terminal").YIELD
assert_true(true, "Expected no crash when writing random data to terminal.") assert_true(true, "Expected no crash when writing random data to terminal.")
@ -71,16 +71,16 @@ class TestTheme:
func _get_pixelv(src: Vector2) -> Color: func _get_pixelv(src: Vector2) -> Color:
var screen := get_tree().root.get_texture().get_data() var screen := get_tree().root.get_texture().get_data()
screen.lock() false # screen.lock() # TODOConverter40, Image no longer requires locking, `false` helps to not break one line if/else, so it can freely be removed
screen.flip_y() screen.flip_y()
var pixel := screen.get_pixelv(src) var pixel := screen.get_pixelv(src)
screen.unlock() false # screen.unlock() # TODOConverter40, Image no longer requires locking, `false` helps to not break one line if/else, so it can freely be removed
return pixel return pixel
func _check_colors(theme: Theme): func _check_colors(theme: Theme):
var cell_size := Vector2( var cell_size := Vector2(
int(terminal.rect_size.x / terminal.get_cols()), int(terminal.size.x / terminal.get_cols()),
int(terminal.rect_size.y / terminal.get_rows()) int(terminal.size.y / terminal.get_rows())
) )
var src := cell_size / 2 var src := cell_size / 2
@ -96,61 +96,61 @@ class TestTheme:
src += Vector2(cell_size.x, 0) src += Vector2(cell_size.x, 0)
func before_each(): func before_each():
terminal = autofree(TestScene.instance()) terminal = autofree(TestScene.instantiate())
yield(yield_frames(1), YIELD) await yield_frames(1).YIELD
func test_terminal_display_colors_from_default_theme(): func test_terminal_display_colors_from_default_theme():
terminal.theme = null terminal.theme = null
add_child(terminal) add_child(terminal)
yield(yield_to(terminal, "theme_changed", 5), YIELD) await yield_to(terminal, "theme_changed", 5).YIELD
_check_colors(default_theme) _check_colors(default_theme)
func test_terminal_displays_colors_from_theme(): func test_terminal_displays_colors_from_theme():
terminal.theme = alt_theme terminal.theme = alt_theme
add_child(terminal) add_child(terminal)
yield(yield_to(terminal, "theme_changed", 5), YIELD) await yield_to(terminal, "theme_changed", 5).YIELD
_check_colors(alt_theme) _check_colors(alt_theme)
func test_visible_characters_still_displayed_after_resize_with_default_theme(): func test_visible_characters_still_displayed_after_resize_with_default_theme():
terminal.theme = null terminal.theme = null
add_child(terminal) add_child(terminal)
yield(yield_frames(1), YIELD) await yield_frames(1).YIELD
OS.window_size += Vector2(1, 0) OS.window_size += Vector2(1, 0)
yield(yield_to(terminal, "size_changed", 5), YIELD) await yield_to(terminal, "size_changed", 5).YIELD
_check_colors(default_theme) _check_colors(default_theme)
func test_visible_characters_still_displayed_after_resize_with_custom_theme(): func test_visible_characters_still_displayed_after_resize_with_custom_theme():
# Issue 57: https://github.com/lihop/godot-xterm/issues/57 # Issue 57: https://github.com/lihop/godot-xterm/issues/57
terminal.theme = alt_theme terminal.theme = alt_theme
add_child(terminal) add_child(terminal)
yield(yield_to(terminal, "theme_changed", 5), YIELD) await yield_to(terminal, "theme_changed", 5).YIELD
OS.window_size += Vector2(1, 0) OS.window_size += Vector2(1, 0)
yield(yield_to(terminal, "size_changed", 5), YIELD) await yield_to(terminal, "size_changed", 5).YIELD
_check_colors(alt_theme) _check_colors(alt_theme)
func test_updates_colors_after_theme_set(): func test_updates_colors_after_theme_set():
# Issue 58: https://github.com/lihop/godot-xterm/issues/58 # Issue 58: https://github.com/lihop/godot-xterm/issues/58
terminal.theme = null terminal.theme = null
add_child(terminal) add_child(terminal)
yield(yield_frames(1), YIELD) await yield_frames(1).YIELD
terminal.theme = alt_theme terminal.theme = alt_theme
yield(yield_to(terminal, "theme_changed", 50), YIELD) await yield_to(terminal, "theme_changed", 50).YIELD
_check_colors(alt_theme) _check_colors(alt_theme)
func test_updates_colors_after_theme_unset(): func test_updates_colors_after_theme_unset():
# Issue 58: https://github.com/lihop/godot-xterm/issues/58 # Issue 58: https://github.com/lihop/godot-xterm/issues/58
terminal.theme = alt_theme terminal.theme = alt_theme
add_child(terminal) add_child(terminal)
yield(yield_to(terminal, "theme_changed", 5), YIELD) await yield_to(terminal, "theme_changed", 5).YIELD
terminal.theme = null terminal.theme = null
yield(yield_to(terminal, "theme_changed", 5), YIELD) await yield_to(terminal, "theme_changed", 5).YIELD
_check_colors(default_theme) _check_colors(default_theme)
func test_updates_colors_after_theme_changed(): func test_updates_colors_after_theme_changed():
# Issue 58: https://github.com/lihop/godot-xterm/issues/58 # Issue 58: https://github.com/lihop/godot-xterm/issues/58
terminal.theme = alt_theme terminal.theme = alt_theme
add_child(terminal) add_child(terminal)
yield(yield_to(terminal, "theme_changed", 5), YIELD) await yield_to(terminal, "theme_changed", 5).YIELD
terminal.theme = default_theme terminal.theme = default_theme
yield(yield_to(terminal, "theme_changed", 5), YIELD) await yield_to(terminal, "theme_changed", 5).YIELD
_check_colors(default_theme) _check_colors(default_theme)

View file

@ -26,8 +26,8 @@ func test_fork_succeeds():
func test_fork_has_output(): func test_fork_has_output():
pty.call_deferred("fork", "exit") pty.call_deferred("fork", "exit")
yield(yield_to(pty, "data_received", 1), YIELD) await yield_to(pty, "data_received", 1).YIELD
var expected := PoolByteArray( var expected := PackedByteArray(
[ [
101, 101,
120, 120,
@ -124,20 +124,20 @@ func test_closes_pty_on_exit():
pty.fork("sleep", ["1000"]) pty.fork("sleep", ["1000"])
remove_child(pty) remove_child(pty)
pty.free() pty.free()
yield(yield_for(1), YIELD) await yield_for(1).YIELD
var new_num_pts = helper._get_pts().size() var new_num_pts = helper._get_pts().size()
assert_eq(new_num_pts, num_pts) assert_eq(new_num_pts, num_pts)
func test_emits_exited_signal_when_child_process_exits(): func test_emits_exited_signal_when_child_process_exits():
pty.call_deferred("fork", "exit") pty.call_deferred("fork", "exit")
yield(yield_to(pty, "exited", 1), YIELD) await yield_to(pty, "exited", 1).YIELD
assert_signal_emitted(pty, "exited") assert_signal_emitted(pty, "exited")
class Helper: class Helper:
static func _get_pts() -> Array: static func _get_pts() -> Array:
assert(false, "Abstract method") assert(false) #,"Abstract method")
return [] return []
static func _get_winsize(fd: int) -> Dictionary: static func _get_winsize(fd: int) -> Dictionary:
@ -161,9 +161,9 @@ class Helper:
true, true,
output output
) )
assert(exit_code == 0, "Failed to run python command for this test.") assert(exit_code == 0) #,"Failed to run python command for this test.")
var size = str2var("Vector2" + output[0].strip_edges()) var size = str_to_var("Vector2" + output[0].strip_edges())
return {rows = int(size.x), cols = int(size.y)} return {rows = int(size.x), cols = int(size.y)}
@ -186,7 +186,7 @@ class TestPTYSize:
regex.compile(".*rows (?<rows>[0-9]+).*columns (?<columns>[0-9]+).*") regex.compile(".*rows (?<rows>[0-9]+).*columns (?<columns>[0-9]+).*")
func before_each(): func before_each():
scene = add_child_autofree(preload("res://test/scenes/pty_and_terminal.tscn").instance()) scene = add_child_autofree(preload("res://test/scenes/pty_and_terminal.tscn").instantiate())
func test_correct_stty_reports_correct_size(): func test_correct_stty_reports_correct_size():
for s in [ for s in [
@ -198,14 +198,14 @@ class TestPTYSize:
"PTYCousinAbove2", "PTYCousinAbove2",
"PTYCousinBelow2" "PTYCousinBelow2"
]: ]:
pty = scene.get_node(s).find_node("PTY") pty = scene.get_node(s).find_child("PTY")
terminal = scene.get_node(s).find_node("Terminal") terminal = scene.get_node(s).find_child("Terminal")
pty.call_deferred("fork", OS.get_environment("SHELL")) pty.call_deferred("fork", OS.get_environment("SHELL"))
pty.call_deferred("write", "stty -a | head -n1\n") pty.call_deferred("write", "stty -a | head -n1\n")
var output := "" var output := ""
while not "rows" in output and not "columns" in output: while not "rows" in output and not "columns" in output:
output = (yield(pty, "data_received")).get_string_from_utf8() output = (await pty.data_received).get_string_from_utf8()
var regex_match = regex.search(output) var regex_match = regex.search(output)
var stty_rows = int(regex_match.get_string("rows")) var stty_rows = int(regex_match.get_string("rows"))
var stty_cols = int(regex_match.get_string("columns")) var stty_cols = int(regex_match.get_string("columns"))
@ -228,14 +228,14 @@ class LinuxHelper:
static func _get_pts() -> Array: static func _get_pts() -> Array:
var dir := Directory.new() var dir := Directory.new()
if dir.open("/dev/pts") != OK or dir.list_dir_begin(true, true) != OK: if dir.open("/dev/pts") != OK or dir.list_dir_begin() != OK:# TODOGODOT4 fill missing arguments https://github.com/godotengine/godot/pull/40547
assert(false, "Could not open /dev/pts.") assert(false) #,"Could not open /dev/pts.")
var pts := [] var pts := []
var file_name: String = dir.get_next() var file_name: String = dir.get_next()
while file_name != "": while file_name != "":
if file_name.is_valid_integer(): if file_name.is_valid_int():
pts.append("/dev/pts/%s" % file_name) pts.append("/dev/pts/%s" % file_name)
file_name = dir.get_next() file_name = dir.get_next()
@ -249,5 +249,5 @@ class MacOSHelper:
# TODO: Implement for macOS. # TODO: Implement for macOS.
# On macOS there is no /dev/pts directory, rather new ptys are created # On macOS there is no /dev/pts directory, rather new ptys are created
# under /dev/ttysXYZ. # under /dev/ttysXYZ.
assert(false, "Not implemented") assert(false) #,"Not implemented")
return [] return []

View file

@ -1,10 +1,10 @@
extends Control extends Control
onready var terminal = $Terminal @onready var terminal = $Terminal
func _ready(): func _ready():
print("terminal size; rows %d; cols %d;" % [terminal.get_rows(), terminal.get_cols()]) print("terminal size; rows %d; cols %d;" % [terminal.get_rows(), terminal.get_cols()])
terminal.write("h") terminal.write("h")
yield(get_tree().create_timer(1), "timeout") await get_tree().create_timer(1).timeout
terminal.write(" i") terminal.write(" i")

View file

@ -4,16 +4,16 @@
[ext_resource path="res://test/scenes/basic.gd" type="Script" id=3] [ext_resource path="res://test/scenes/basic.gd" type="Script" id=3]
[node name="BasicNewTerm" type="Control"] [node name="BasicNewTerm" type="Control"]
margin_right = 43.0 offset_right = 43.0
margin_bottom = 43.0 offset_bottom = 43.0
script = ExtResource( 3 ) script = ExtResource( 3 )
__meta__ = { __meta__ = {
"_edit_use_anchors_": false "_edit_use_anchors_": false
} }
[node name="ColorRect" type="ColorRect" parent="."] [node name="ColorRect" type="ColorRect" parent="."]
margin_right = 40.0 offset_right = 40.0
margin_bottom = 40.0 offset_bottom = 40.0
color = Color( 0, 1, 0, 1 ) color = Color( 0, 1, 0, 1 )
__meta__ = { __meta__ = {
"_edit_use_anchors_": false "_edit_use_anchors_": false

View file

@ -7,44 +7,44 @@ anchor_right = 1.0
anchor_bottom = 1.0 anchor_bottom = 1.0
[node name="HBoxContainer" type="HBoxContainer" parent="."] [node name="HBoxContainer" type="HBoxContainer" parent="."]
margin_right = 1024.0 offset_right = 1024.0
margin_bottom = 600.0 offset_bottom = 600.0
size_flags_horizontal = 3 size_flags_horizontal = 3
[node name="TextEdit" type="TextEdit" parent="HBoxContainer"] [node name="TextEdit" type="TextEdit" parent="HBoxContainer"]
margin_right = 338.0 offset_right = 338.0
margin_bottom = 600.0 offset_bottom = 600.0
size_flags_horizontal = 3 size_flags_horizontal = 3
[node name="VBoxContainer" type="VBoxContainer" parent="HBoxContainer"] [node name="VBoxContainer" type="VBoxContainer" parent="HBoxContainer"]
margin_left = 342.0 offset_left = 342.0
margin_right = 681.0 offset_right = 681.0
margin_bottom = 600.0 offset_bottom = 600.0
size_flags_horizontal = 3 size_flags_horizontal = 3
[node name="TextEdit3" type="TextEdit" parent="HBoxContainer/VBoxContainer"] [node name="TextEdit3" type="TextEdit" parent="HBoxContainer/VBoxContainer"]
margin_right = 339.0 offset_right = 339.0
margin_bottom = 197.0 offset_bottom = 197.0
size_flags_vertical = 3 size_flags_vertical = 3
[node name="Terminal" type="Control" parent="HBoxContainer/VBoxContainer"] [node name="Terminal" type="Control" parent="HBoxContainer/VBoxContainer"]
margin_top = 201.0 offset_top = 201.0
margin_right = 339.0 offset_right = 339.0
margin_bottom = 398.0 offset_bottom = 398.0
focus_mode = 2 focus_mode = 2
size_flags_vertical = 3 size_flags_vertical = 3
script = ExtResource( 1 ) script = ExtResource( 1 )
[node name="TextEdit2" type="TextEdit" parent="HBoxContainer/VBoxContainer"] [node name="TextEdit2" type="TextEdit" parent="HBoxContainer/VBoxContainer"]
margin_top = 402.0 offset_top = 402.0
margin_right = 339.0 offset_right = 339.0
margin_bottom = 600.0 offset_bottom = 600.0
size_flags_vertical = 3 size_flags_vertical = 3
[node name="TextEdit2" type="TextEdit" parent="HBoxContainer"] [node name="TextEdit2" type="TextEdit" parent="HBoxContainer"]
margin_left = 685.0 offset_left = 685.0
margin_right = 1024.0 offset_right = 1024.0
margin_bottom = 600.0 offset_bottom = 600.0
size_flags_horizontal = 3 size_flags_horizontal = 3
[connection signal="data_sent" from="HBoxContainer/VBoxContainer/Terminal" to="HBoxContainer/VBoxContainer/Terminal" method="write"] [connection signal="data_sent" from="HBoxContainer/VBoxContainer/Terminal" to="HBoxContainer/VBoxContainer/Terminal" method="write"]

View file

@ -1,4 +1,4 @@
tool @tool
extends "res://addons/godot_xterm/terminal.gd" extends "res://addons/godot_xterm/terminal.gd"
signal theme_changed signal theme_changed
@ -27,7 +27,7 @@ func _ready():
func _notification(what): func _notification(what):
._notification(what) super._notification(what)
match what: match what:
NOTIFICATION_THEME_CHANGED: NOTIFICATION_THEME_CHANGED:
call_deferred("emit_signal", "theme_changed") call_deferred("emit_signal", "theme_changed")

View file

@ -12,7 +12,7 @@ func _ready():
func _process(_delta): func _process(_delta):
for _i in range(4096): for _i in range(4096):
write(PoolByteArray([rng.randi() % 256])) write(PackedByteArray([rng.randi() % 256]))
" "
[node name="Terminal" type="Control"] [node name="Terminal" type="Control"]

View file

@ -21,18 +21,18 @@ class TestMultipleInputs:
func press_key(scancode: int, unicode := 0) -> void: func press_key(scancode: int, unicode := 0) -> void:
var key_down = InputEventKey.new() var key_down = InputEventKey.new()
key_down.scancode = scancode key_down.scancode = scancode
key_down.pressed = true key_down.button_pressed = true
Input.parse_input_event(key_down) Input.parse_input_event(key_down)
yield(get_tree().create_timer(0.1), "timeout") await get_tree().create_timer(0.1).timeout
var key_up = InputEventKey.new() var key_up = InputEventKey.new()
key_up.scancode = scancode key_up.scancode = scancode
key_up.pressed = false key_up.button_pressed = false
Input.parse_input_event(key_up) Input.parse_input_event(key_up)
func before_each(): func before_each():
var scene := preload("../scenes/multiple_inputs.tscn").instance() var scene := preload("../scenes/multiple_inputs.tscn").instantiate()
add_child_autofree(scene) add_child_autofree(scene)
terminal = scene.find_node("Terminal") terminal = scene.find_child("Terminal")
terminal.grab_focus() terminal.grab_focus()
func test_terminal_keeps_focus_when_certain_keys_pressed(): func test_terminal_keeps_focus_when_certain_keys_pressed():

View file

@ -1,9 +1,9 @@
[gd_resource type="Theme" load_steps=5 format=2] [gd_resource type="Theme" load_steps=5 format=2]
[ext_resource path="res://themes/fonts/bold_italic.tres" type="DynamicFont" id=2] [ext_resource path="res://themes/fonts/bold_italic.tres" type="FontFile" id=2]
[ext_resource path="res://themes/fonts/italic.tres" type="DynamicFont" id=3] [ext_resource path="res://themes/fonts/italic.tres" type="FontFile" id=3]
[ext_resource path="res://themes/fonts/bold.tres" type="DynamicFont" id=4] [ext_resource path="res://themes/fonts/bold.tres" type="FontFile" id=4]
[ext_resource path="res://themes/fonts/regular.tres" type="DynamicFont" id=5] [ext_resource path="res://themes/fonts/regular.tres" type="FontFile" id=5]
[resource] [resource]
Terminal/colors/background = Color( 0.12549, 0.145098, 0.192157, 1 ) Terminal/colors/background = Color( 0.12549, 0.145098, 0.192157, 1 )

View file

@ -1,10 +1,10 @@
[gd_resource type="DynamicFont" load_steps=6 format=2] [gd_resource type="FontFile" load_steps=6 format=2]
[ext_resource path="res://themes/fonts/hack/hack_bold-3.003.ttf" type="DynamicFontData" id=1] [ext_resource path="res://themes/fonts/hack/hack_bold-3.003.ttf" type="FontFile" id=1]
[ext_resource path="res://themes/fonts/nerd_fonts/symbols_2048_em_nerd_font_complete-2.1.0.ttf" type="DynamicFontData" id=2] [ext_resource path="res://themes/fonts/nerd_fonts/symbols_2048_em_nerd_font_complete-2.1.0.ttf" type="FontFile" id=2]
[ext_resource path="res://themes/fonts/noto_color_emoji/noto_color_emoji-20201206-phase3.ttf" type="DynamicFontData" id=3] [ext_resource path="res://themes/fonts/noto_color_emoji/noto_color_emoji-20201206-phase3.ttf" type="FontFile" id=3]
[ext_resource path="res://themes/fonts/unifont/unifont-13.0.06.ttf" type="DynamicFontData" id=4] [ext_resource path="res://themes/fonts/unifont/unifont-13.0.06.ttf" type="FontFile" id=4]
[ext_resource path="res://themes/fonts/unifont/unifont_upper-13.0.06.ttf" type="DynamicFontData" id=5] [ext_resource path="res://themes/fonts/unifont/unifont_upper-13.0.06.ttf" type="FontFile" id=5]
[resource] [resource]
size = 14 size = 14

View file

@ -1,10 +1,10 @@
[gd_resource type="DynamicFont" load_steps=6 format=2] [gd_resource type="FontFile" load_steps=6 format=2]
[ext_resource path="res://themes/fonts/nerd_fonts/symbols_2048_em_nerd_font_complete-2.1.0.ttf" type="DynamicFontData" id=1] [ext_resource path="res://themes/fonts/nerd_fonts/symbols_2048_em_nerd_font_complete-2.1.0.ttf" type="FontFile" id=1]
[ext_resource path="res://themes/fonts/hack/hack_bold_italic-3.003.ttf" type="DynamicFontData" id=2] [ext_resource path="res://themes/fonts/hack/hack_bold_italic-3.003.ttf" type="FontFile" id=2]
[ext_resource path="res://themes/fonts/noto_color_emoji/noto_color_emoji-20201206-phase3.ttf" type="DynamicFontData" id=3] [ext_resource path="res://themes/fonts/noto_color_emoji/noto_color_emoji-20201206-phase3.ttf" type="FontFile" id=3]
[ext_resource path="res://themes/fonts/unifont/unifont-13.0.06.ttf" type="DynamicFontData" id=4] [ext_resource path="res://themes/fonts/unifont/unifont-13.0.06.ttf" type="FontFile" id=4]
[ext_resource path="res://themes/fonts/unifont/unifont_upper-13.0.06.ttf" type="DynamicFontData" id=5] [ext_resource path="res://themes/fonts/unifont/unifont_upper-13.0.06.ttf" type="FontFile" id=5]
[resource] [resource]
size = 14 size = 14

View file

@ -1,10 +1,10 @@
[gd_resource type="DynamicFont" load_steps=6 format=2] [gd_resource type="FontFile" load_steps=6 format=2]
[ext_resource path="res://themes/fonts/nerd_fonts/symbols_2048_em_nerd_font_complete-2.1.0.ttf" type="DynamicFontData" id=1] [ext_resource path="res://themes/fonts/nerd_fonts/symbols_2048_em_nerd_font_complete-2.1.0.ttf" type="FontFile" id=1]
[ext_resource path="res://themes/fonts/noto_color_emoji/noto_color_emoji-20201206-phase3.ttf" type="DynamicFontData" id=2] [ext_resource path="res://themes/fonts/noto_color_emoji/noto_color_emoji-20201206-phase3.ttf" type="FontFile" id=2]
[ext_resource path="res://themes/fonts/unifont/unifont-13.0.06.ttf" type="DynamicFontData" id=3] [ext_resource path="res://themes/fonts/unifont/unifont-13.0.06.ttf" type="FontFile" id=3]
[ext_resource path="res://themes/fonts/hack/hack_italic-3.003.ttf" type="DynamicFontData" id=4] [ext_resource path="res://themes/fonts/hack/hack_italic-3.003.ttf" type="FontFile" id=4]
[ext_resource path="res://themes/fonts/unifont/unifont_upper-13.0.06.ttf" type="DynamicFontData" id=5] [ext_resource path="res://themes/fonts/unifont/unifont_upper-13.0.06.ttf" type="FontFile" id=5]
[resource] [resource]
size = 14 size = 14

View file

@ -1,10 +1,10 @@
[gd_resource type="DynamicFont" load_steps=6 format=2] [gd_resource type="FontFile" load_steps=6 format=2]
[ext_resource path="res://themes/fonts/unifont/unifont_upper-13.0.06.ttf" type="DynamicFontData" id=1] [ext_resource path="res://themes/fonts/unifont/unifont_upper-13.0.06.ttf" type="FontFile" id=1]
[ext_resource path="res://themes/fonts/unifont/unifont-13.0.06.ttf" type="DynamicFontData" id=2] [ext_resource path="res://themes/fonts/unifont/unifont-13.0.06.ttf" type="FontFile" id=2]
[ext_resource path="res://themes/fonts/noto_color_emoji/noto_color_emoji-20201206-phase3.ttf" type="DynamicFontData" id=3] [ext_resource path="res://themes/fonts/noto_color_emoji/noto_color_emoji-20201206-phase3.ttf" type="FontFile" id=3]
[ext_resource path="res://addons/godot_xterm/themes/fonts/hack/hack_regular-3.003.ttf" type="DynamicFontData" id=4] [ext_resource path="res://addons/godot_xterm/themes/fonts/hack/hack_regular-3.003.ttf" type="FontFile" id=4]
[ext_resource path="res://themes/fonts/nerd_fonts/symbols_2048_em_nerd_font_complete-2.1.0.ttf" type="DynamicFontData" id=5] [ext_resource path="res://themes/fonts/nerd_fonts/symbols_2048_em_nerd_font_complete-2.1.0.ttf" type="FontFile" id=5]
[resource] [resource]
size = 14 size = 14

View file

@ -1,9 +1,9 @@
[gd_resource type="Theme" load_steps=4 format=2] [gd_resource type="Theme" load_steps=4 format=2]
[ext_resource path="res://addons/godot_xterm/resources/xrdb_theme.gd" type="Script" id=1] [ext_resource path="res://addons/godot_xterm/resources/xrdb_theme.gd" type="Script" id=1]
[ext_resource path="res://addons/godot_xterm/themes/fonts/hack/hack_regular-3.003.ttf" type="DynamicFontData" id=2] [ext_resource path="res://addons/godot_xterm/themes/fonts/hack/hack_regular-3.003.ttf" type="FontFile" id=2]
[sub_resource type="DynamicFont" id=1] [sub_resource type="FontFile" id=1]
size = 39 size = 39
extra_spacing_bottom = 1 extra_spacing_bottom = 1
font_data = ExtResource( 2 ) font_data = ExtResource( 2 )