using System.Text.RegularExpressions; using Cogwheel; using ImGuiNET; using Raylib_cs; namespace RaylibCogwheel; public class RaylibCogwheelConsole : ICogwheelConsole { public string OpeningMessage { get; set; } = "===========================\n" + "| COGWHEEL RAYLIB CONSOLE |\n" + "==========================="; public bool IsRunning { get; set; } public CommandsManager CommandsManager { get; set; } public bool IsOpen { get; set; } = false; private string _input = string.Empty; private string _output = string.Empty; private int _output_buffer_size = 1000; //private List _history = new(); private bool _scrollToBottom = false; private string hint = ""; public void Initialize(CommandsManager commandsManager) { COGWHEEL.RegisterObject(this); CommandsManager = commandsManager; Write(OpeningMessage); } public void Log(string message) { WriteColor("[INFO] " + message, new Color(0, 200, 255, 255)); } public void LogError(string message) { WriteColor("[COGWHEEL ERROR] " + message, new Color(255, 0, 0, 255)); // Red color } public void LogWarning(string message) { WriteColor("[COGWHEEL WARNING] " + message, new Color(255, 255, 0, 255)); // Yellow color } public void WriteColor(string message, Color color) { string colorCode = $"{color.R},{color.G},{color.B},{color.A}"; _output += $"[Color={colorCode}]{message}[/Color]\n"; TrimOutputBuffer(); } public void Write(string message) { _output += message + "\n"; TrimOutputBuffer(); } public void ClearConsole() { _output = string.Empty; } public void Exit() { Raylib.CloseWindow(); } public void ToggleConsole() { IsOpen = !IsOpen; } public void Update() { if (Raylib.IsKeyPressed(KeyboardKey.Grave)) { ToggleConsole(); } if (CommandsManager.CurrentContext != null && hint != CommandsManager.CurrentContext.GetType().FullName) { hint = CommandsManager.CurrentContext.GetType().FullName; } } public void Draw() { if (!IsOpen) return; ImGui.SetNextWindowSize(new System.Numerics.Vector2(Raylib.GetScreenWidth(), (float)(Raylib.GetScreenHeight() * 0.75)), ImGuiCond.Always); ImGui.SetNextWindowPos(new System.Numerics.Vector2(0, 0), ImGuiCond.Always); if (ImGui.Begin("Cogwheel Console", ImGuiWindowFlags.NoResize | ImGuiWindowFlags.NoMove | ImGuiWindowFlags.NoCollapse | ImGuiWindowFlags.NoTitleBar)) { // Display the output text in a scrollable region ImGui.BeginChild("ScrollingRegion", new System.Numerics.Vector2(0, -ImGui.GetTextLineHeightWithSpacing() - 10), ImGuiChildFlags.None); // Split the output into lines var lines = _output.Split('\n'); var regex = new Regex(@"\[Color=(\d+),(\d+),(\d+),(\d+)\](.*?)\[/Color\]", RegexOptions.Compiled); foreach (var line in lines) { var matches = regex.Matches(line); int lastIndex = 0; foreach (Match match in matches) { // Add text before the color tag if (match.Index > lastIndex) { ImGui.PushStyleColor(ImGuiCol.Text, new System.Numerics.Vector4(1.0f, 1.0f, 1.0f, 1.0f)); // White for normal text ImGui.TextUnformatted(line.Substring(lastIndex, match.Index - lastIndex)); ImGui.PopStyleColor(); } // Set the color for the text inside the color tags var color = new System.Numerics.Vector4( float.Parse(match.Groups[1].Value) / 255.0f, float.Parse(match.Groups[2].Value) / 255.0f, float.Parse(match.Groups[3].Value) / 255.0f, float.Parse(match.Groups[4].Value) / 255.0f ); ImGui.PushStyleColor(ImGuiCol.Text, color); ImGui.TextUnformatted(match.Groups[5].Value); ImGui.PopStyleColor(); lastIndex = match.Index + match.Length; } // Add remaining text after the last color tag if (lastIndex < line.Length) { ImGui.PushStyleColor(ImGuiCol.Text, new System.Numerics.Vector4(1.0f, 1.0f, 1.0f, 1.0f)); // White for normal text ImGui.TextUnformatted(line.Substring(lastIndex)); ImGui.PopStyleColor(); } } if (_scrollToBottom) { ImGui.SetScrollHereY(1.0f); _scrollToBottom = false; } ImGui.EndChild(); ImGui.Separator(); ImGui.SetKeyboardFocusHere(); ImGui.PushStyleColor(ImGuiCol.FrameBg, new System.Numerics.Vector4(0, 0, 0, 1)); ImGui.PushItemWidth(-1); ImGui.InputText("", ref _input, 256, ImGuiInputTextFlags.EnterReturnsTrue); ImGui.PopItemWidth(); ImGui.PopStyleColor(); if (_input != "" && ImGui.IsKeyPressed(ImGuiKey.Enter)) { ProcessInput(_input); _input = string.Empty; _scrollToBottom = true; } } } private void ProcessInput(string input) { Write("\n" + "> " + input + "\n"); COGWHEEL.RunCommand(input); } private void TrimOutputBuffer() { var lines = _output.Split('\n'); if (lines.Length > _output_buffer_size) { _output = string.Join("\n", lines.Skip(lines.Length - _output_buffer_size)); } } }