Added console panel with device and host console, logs and domain console.
This commit is contained in:
1 parent
6038b816b7
commit
b98ed82619
17 files changed
+551
-22
No files matched your search
@@ -0,0 +1,106 @@
|
||||
@tool
|
||||
extends VBoxContainer
|
||||
|
||||
signal command_submitted(command: String)
|
||||
signal focus_requested
|
||||
|
||||
@export var session_id := "rov"
|
||||
@export var tab_label := "ROV"
|
||||
@export var shortcut: Key = KEY_F5
|
||||
@export var prompt := "rov $"
|
||||
@export var read_only := false
|
||||
@export var introduction := "ROV shell disconnected."
|
||||
@export var max_scrollback_characters := 128000
|
||||
var connected := false
|
||||
var _buffer := ""
|
||||
var _history: Array[String] = []
|
||||
var _history_index := 0
|
||||
var _draft := ""
|
||||
|
||||
@onready var output: RichTextLabel = $Output
|
||||
@onready var command_input: LineEdit = $Input/Command
|
||||
@onready var filter_input: LineEdit = $Filter/Text
|
||||
|
||||
func _ready() -> void:
|
||||
$Input.visible = not read_only
|
||||
$Filter.visible = read_only
|
||||
$Input/Prompt.text = prompt
|
||||
_buffer = introduction + "\n"
|
||||
output.text = _buffer
|
||||
if Engine.is_editor_hint():
|
||||
return
|
||||
command_input.text_submitted.connect(submit_command)
|
||||
command_input.gui_input.connect(_history_input)
|
||||
filter_input.text_changed.connect(func(_text: String) -> void: _render_output())
|
||||
$Status/Clear.pressed.connect(clear_output)
|
||||
$Status/Follow.toggled.connect(func(enabled: bool) -> void:
|
||||
output.scroll_following = enabled
|
||||
if enabled: output.scroll_to_line(maxi(output.get_line_count() - 1, 0))
|
||||
)
|
||||
for control in [output, command_input, filter_input, $Status/Clear, $Status/Follow]:
|
||||
control.gui_input.connect(func(event: InputEvent) -> void:
|
||||
if event is InputEventMouseButton and event.pressed:
|
||||
focus_requested.emit()
|
||||
)
|
||||
|
||||
func preferred_input() -> Control:
|
||||
return filter_input if read_only else command_input
|
||||
|
||||
func set_connection(value: bool, message: String = "") -> void:
|
||||
connected = value
|
||||
$Status/Connection.text = message if not message.is_empty() else ("Connected" if value else "Not connected")
|
||||
|
||||
func submit_command(command: String) -> bool:
|
||||
if read_only or command.strip_edges().is_empty():
|
||||
return false
|
||||
if _history.is_empty() or _history.back() != command:
|
||||
_history.append(command)
|
||||
if _history.size() > 200: _history.pop_front()
|
||||
_history_index = _history.size()
|
||||
_draft = ""
|
||||
append_output(prompt + " " + command + "\n")
|
||||
command_input.clear()
|
||||
command_submitted.emit(command)
|
||||
return true
|
||||
|
||||
func append_output(text: String) -> void:
|
||||
_buffer += text
|
||||
var truncated := _buffer.length() > max_scrollback_characters
|
||||
if truncated:
|
||||
_buffer = _buffer.right(max_scrollback_characters)
|
||||
var newline := _buffer.find("\n")
|
||||
if newline >= 0 and newline < _buffer.length() - 1:
|
||||
_buffer = _buffer.substr(newline + 1)
|
||||
if truncated or (read_only and not filter_input.text.is_empty()):
|
||||
_render_output()
|
||||
else:
|
||||
output.add_text(text)
|
||||
|
||||
func clear_output() -> void:
|
||||
_buffer = ""
|
||||
output.clear()
|
||||
|
||||
func _render_output() -> void:
|
||||
var scroll := output.get_v_scroll_bar().value
|
||||
if read_only and not filter_input.text.is_empty():
|
||||
var matches := PackedStringArray()
|
||||
for line in _buffer.split("\n"):
|
||||
if line.to_lower().contains(filter_input.text.to_lower()):
|
||||
matches.append(line)
|
||||
output.text = "\n".join(matches)
|
||||
else:
|
||||
output.text = _buffer
|
||||
if not $Status/Follow.button_pressed:
|
||||
output.get_v_scroll_bar().set_deferred("value", scroll)
|
||||
|
||||
func _history_input(event: InputEvent) -> void:
|
||||
if not event is InputEventKey or not event.pressed or event.ctrl_pressed or event.alt_pressed or event.meta_pressed:
|
||||
return
|
||||
if event.keycode not in [KEY_UP, KEY_DOWN] or _history.is_empty():
|
||||
return
|
||||
if _history_index == _history.size():
|
||||
_draft = command_input.text
|
||||
_history_index = clampi(_history_index + (-1 if event.keycode == KEY_UP else 1), 0, _history.size())
|
||||
command_input.text = _draft if _history_index == _history.size() else _history[_history_index]
|
||||
command_input.caret_column = command_input.text.length()
|
||||
command_input.accept_event()
|
||||
Reference in new issue
Block a user