105 lines
3.4 KiB
GDScript
105 lines
3.4 KiB
GDScript
@tool
|
|
extends SelectableContainer
|
|
|
|
signal command_requested(session_id: String, command: String)
|
|
|
|
@onready var tabs: TabContainer = %Tabs
|
|
|
|
func _ready() -> void:
|
|
super._ready()
|
|
_refresh_header()
|
|
if Engine.is_editor_hint():
|
|
return
|
|
tabs.get_tab_bar().focus_mode = Control.FOCUS_NONE
|
|
tabs.get_tab_bar().gui_input.connect(func(event: InputEvent) -> void:
|
|
if event is InputEventMouseButton and event.pressed: activate()
|
|
)
|
|
tabs.tab_changed.connect(func(_index: int) -> void:
|
|
_last_focus = null
|
|
activate()
|
|
)
|
|
for page in _pages():
|
|
page.command_submitted.connect(_route_command.bind(page.session_id))
|
|
page.focus_requested.connect(activate)
|
|
|
|
func _pages() -> Array[Control]:
|
|
var result: Array[Control] = []
|
|
var node := get_node_or_null("%Tabs")
|
|
if node != null:
|
|
for child in node.get_children():
|
|
if child.has_method("submit_command"): result.append(child)
|
|
return result
|
|
|
|
func get_focus_shortcuts() -> Array[Key]:
|
|
var keys: Array[Key] = []
|
|
for page in _pages():
|
|
if page.shortcut != KEY_NONE: keys.append(page.shortcut)
|
|
return keys
|
|
|
|
func _refresh_header() -> void:
|
|
super._refresh_header()
|
|
var node := get_node_or_null("%Tabs") as TabContainer
|
|
if node == null:
|
|
return
|
|
var seen: Dictionary = {}
|
|
for index in range(node.get_tab_count()):
|
|
var page := node.get_tab_control(index)
|
|
if not page.has_method("submit_command"): continue
|
|
var key: Key = page.shortcut
|
|
var available := is_shortcut_available(key) and not seen.has(key)
|
|
var caption: String = page.tab_label
|
|
if key != KEY_NONE:
|
|
caption += " · " + OS.get_keycode_string(key) + (" (in use)" if not available else "")
|
|
seen[key] = true
|
|
node.set_tab_title(index, caption)
|
|
node.set_tab_tooltip(index, "Focus " + page.tab_label if available else "Shortcut already used by another panel or tab")
|
|
|
|
func activate() -> void:
|
|
super.activate()
|
|
if is_active:
|
|
var page := tabs.get_current_tab_control()
|
|
if page != null:
|
|
var target: Control = page.preferred_input()
|
|
if target.is_visible_in_tree(): target.grab_focus()
|
|
|
|
func activate_shortcut(key: Key) -> void:
|
|
for index in range(tabs.get_tab_count()):
|
|
if tabs.get_tab_control(index).shortcut == key:
|
|
tabs.current_tab = index
|
|
_last_focus = null
|
|
activate()
|
|
return
|
|
|
|
func _input(event: InputEvent) -> void:
|
|
if not Engine.is_editor_hint() and is_active and event is InputEventKey:
|
|
if event.ctrl_pressed and not event.alt_pressed and not event.meta_pressed and event.keycode in [KEY_TAB, KEY_L]:
|
|
get_viewport().set_input_as_handled()
|
|
if event.pressed and not event.echo:
|
|
if event.keycode == KEY_TAB:
|
|
tabs.current_tab = wrapi(tabs.current_tab + (-1 if event.shift_pressed else 1), 0, tabs.get_tab_count())
|
|
else:
|
|
tabs.get_current_tab_control().clear_output()
|
|
return
|
|
super._input(event)
|
|
|
|
func session(id: String) -> Control:
|
|
for page in _pages():
|
|
if page.session_id == id: return page
|
|
return null
|
|
|
|
func append_output(id: String, text: String) -> void:
|
|
var page := session(id)
|
|
if page != null: page.append_output(text)
|
|
|
|
func set_connection(id: String, connected: bool, message: String = "") -> void:
|
|
var page := session(id)
|
|
if page != null: page.set_connection(connected, message)
|
|
|
|
func _route_command(command: String, id: String) -> void:
|
|
var page := session(id)
|
|
if page == null: return
|
|
if not page.connected or command_requested.get_connections().is_empty():
|
|
page.append_output("Not connected; command was not sent.\n")
|
|
else:
|
|
command_requested.emit(id, command)
|