@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)