// SpatialShellTerminal.cs — the terminal panel: a command line inside VR. // // A TextMeshPro input field + output log. Typing a command and submitting it // sends the text to the backend shell and prints the returned output. This is // the "terminal" element of the spatial OS. // // Setup: attach to a GameObject with a TMP_InputField (input) and a TMP_Text // (output) as children, and a reference to the XrosClient. Wire the input // field's OnSubmit event to Submit(), or call Submit() from your own handler. using System.Collections.Generic; using Newtonsoft.Json.Linq; using TMPro; using UnityEngine; public class SpatialShellTerminal : MonoBehaviour { public XrosClient client; public TMP_InputField input; public TMP_Text output; [Tooltip("Maximum number of output lines kept in the log.")] public int maxLines = 200; private readonly List history = new List(); private int historyIndex = -1; private void OnEnable() { if (client != null) client.OnMessage += HandleMessage; } private void OnDisable() { if (client != null) client.OnMessage -= HandleMessage; } private void HandleMessage(JObject msg) { // Only the terminal cares about "output" (command results). if (msg["op"]?.ToString() == "output") { Append(msg["text"]?.ToString() ?? ""); } } public void Submit() { if (string.IsNullOrWhiteSpace(input.text)) return; string line = input.text.Trim(); history.Add(line); historyIndex = history.Count; Append("> " + line); input.text = ""; input.ActivateInputField(); client?.SendCommand(line); } public void ScrollHistory(int direction) { if (history.Count == 0) return; historyIndex = Mathf.Clamp(historyIndex + direction, 0, history.Count); input.text = historyIndex < history.Count ? history[historyIndex] : ""; input.caretPosition = input.text.Length; } private void Append(string line) { output.text += line + "\n"; // Trim old lines to keep the log bounded. var lines = output.text.Split('\n'); if (lines.Length > maxLines) { var kept = new string[maxLines]; System.Array.Copy(lines, lines.Length - maxLines, kept, 0, maxLines); output.text = string.Join("\n", kept); } } }