using System; using System.Collections.Generic; using System.Linq; using FlaxEditor; using FlaxEngine; using FlaxEngine.GUI; namespace Cabrito { public class ConsoleInputTextBox : ConsoleTextBoxBase { public override string TextPrefix { get => Console.LinePrefix; } private ConsoleContentTextBox contentBox; protected override Rectangle TextRectangle => new Rectangle(0, 0, Width, Height); protected override Rectangle TextClipRectangle => new Rectangle(0, 0, Width, Height); public ConsoleInputTextBox() : base() { } public ConsoleInputTextBox(ConsoleContentTextBox contentBox, float x, float y, float width, float height) : base(x, y, width, height) { this.contentBox = contentBox; IsMultiline = true; // Not really but behaves better than single-line box } private bool IsConsoleKeyPressed(KeyboardKeys key = KeyboardKeys.None) { // Ignore any characters generated by the key which opens the console string inputTextLower = Input.InputText.ToLowerInvariant(); IEnumerable consoleKeyMappings; if (key == KeyboardKeys.None) consoleKeyMappings = Input.ActionMappings.Where(x => x.Name == "Console" && x.Key != KeyboardKeys.None); else consoleKeyMappings = Input.ActionMappings.Where(x => x.Name == "Console" && x.Key == key); foreach (var mapping in consoleKeyMappings) { if (inputTextLower.Length > 0) { if ((mapping.Key == KeyboardKeys.Backslash || mapping.Key == KeyboardKeys.BackQuote) && (inputTextLower.Contains('ö') || inputTextLower.Contains('æ') || inputTextLower.Contains('ø'))) { continue; // Scandinavian keyboard layouts } else if (mapping.Key == KeyboardKeys.BackQuote && inputTextLower.Contains('\'')) continue; else if (mapping.Key == KeyboardKeys.Backslash && (inputTextLower.Contains('\\') || inputTextLower.Contains('|'))) { continue; } } if (Input.GetKey(mapping.Key)) return true; } return false; } public override bool OnCharInput(char c) { if (IsConsoleKeyPressed()) return true; return base.OnCharInput(c); } private int inputHistoryIndex = -1; public override bool OnKeyDown(KeyboardKeys key) { bool shiftDown = Root.GetKey(KeyboardKeys.Shift); bool ctrlDown = Root.GetKey(KeyboardKeys.Control); if (IsConsoleKeyPressed(key)) { Clear(); return true; } else if (key == KeyboardKeys.Escape) { Console.Close(); Clear(); return true; } else if (key == KeyboardKeys.Return) { try { Console.Execute(Text, true); inputHistoryIndex = -1; } finally { Clear(); } contentBox.ScrollOffset = 0; return true; } else if (key == KeyboardKeys.ArrowUp) { inputHistoryIndex++; string line = Console.GetBufferHistory(inputHistoryIndex); if (line == null) { inputHistoryIndex--; return true; } SetText(line); SetSelection(TextLength); return true; } else if (key == KeyboardKeys.ArrowDown) { if (inputHistoryIndex > 0) inputHistoryIndex--; string line = Console.GetBufferHistory(inputHistoryIndex); if (line == null) return true; SetText(line); SetSelection(TextLength); return true; } else if (key == KeyboardKeys.PageUp || key == KeyboardKeys.PageDown) { return contentBox.OnKeyDown(key); } return base.OnKeyDown(key); } public override void OnLostFocus() { // Avoids reseting the caret location var oldEditing = _isEditing; _isEditing = false; base.OnLostFocus(); _isEditing = oldEditing; } public override bool OnMouseDown(Vector2 location, MouseButton button) { base.OnMouseDown(location, button); return true; } public override bool OnMouseWheel(Vector2 location, float delta) { return contentBox.OnMouseWheel(location, delta); } public override void Draw() { Profiler.BeginEvent("ConsoleInputTextBoxDraw"); base.Draw(); Profiler.EndEvent(); } } }