using System; using System.Collections.Generic; using System.Linq; using FlaxEditor; using FlaxEngine; using FlaxEngine.Assertions; using FlaxEngine.GUI; namespace Cabrito { public class ConsoleScript : Script { [Limit(5, 720, 1)] public int ConsoleFontSize = 16; [Limit(0.05f, 1.0f, 1)] public float ConsoleHeight = 0.65f; [Limit(0)] public int ConsoleNotifyLines = 3; [Limit(0f)] public float ConsoleSpeed = 3500f; public FontAsset ConsoleFont; public Texture BackgroundTexture; public Color BackgroundColor; private UIControl rootControl; private ConsoleContentTextBox consoleBox; private ConsoleInputTextBox consoleInputBox; private ConsoleContentTextBox consoleNotifyBox; internal InputEvent consoleInputEvent; public override void OnStart() { consoleInputEvent = new InputEvent("Console"); consoleInputEvent.Triggered += OnConsoleInputEvent; FontReference fontReference = new FontReference(ConsoleFont, ConsoleFontSize); Font fontRaw = fontReference.GetFont(); int fontHeight = (int) (fontRaw.Height / Platform.DpiScale); // root actor which holds all the elements //var rootContainerControl = new ContainerControl(new Rectangle(0, 0, screenSize.X, screenSize.Y)); var rootContainerControl = new ContainerControl(new Rectangle()); rootContainerControl.SetAnchorPreset(AnchorPresets.StretchAll, false); rootControl = Actor.AddChild(); rootControl.Name = "ConsoleRoot"; rootControl.Control = rootContainerControl; var contentContainer = new VerticalPanel() { AutoSize = true, Margin = Margin.Zero, Spacing = 0, Bounds = new Rectangle(), BackgroundColor = BackgroundColor }; contentContainer.SetAnchorPreset(AnchorPresets.StretchAll, true); var contentContainerControl = rootControl.AddChild(); contentContainerControl.Name = "ContentContainer"; contentContainerControl.Control = contentContainer; { if (consoleBox == null) { //consoleBox = new ConsoleContentTextBox(null, 0, 0, consoleSize.X, consoleSize.Y - fontHeight); consoleBox = new ConsoleContentTextBox(fontReference, null, 0, 0, 0, 0); consoleBox.SetAnchorPreset(AnchorPresets.HorizontalStretchTop, true); //consoleBox.AnchorMax = new Vector2(1.0f, ConsoleHeight); //consoleBox.Height = consoleSize.Y - fontHeight; //consoleBox.HorizontalAlignment = TextAlignment.Near; //consoleBox.VerticalAlignment = TextAlignment.Near; consoleBox.HeightMultiplier = ConsoleHeight; consoleBox.Wrapping = TextWrapping.WrapWords; consoleBox.BackgroundColor = Color.Transparent; consoleBox.BackgroundSelectedColor = Color.Transparent; consoleBox.BackgroundSelectedFlashSpeed = 0; consoleBox.BorderSelectedColor = Color.Transparent; consoleBox.CaretFlashSpeed = 0; } var locationFix = consoleBox.Location; var parentControl = contentContainerControl.AddChild(); parentControl.Name = "ConsoleContent"; parentControl.Control = consoleBox; consoleBox.Location = locationFix; // workaround to UIControl.Control overriding the old position if (consoleNotifyBox == null) { //consoleBox = new ConsoleContentTextBox(null, 0, 0, consoleSize.X, consoleSize.Y - fontHeight); consoleNotifyBox = new ConsoleContentTextBox(fontReference, null, 0, 0, 0, 0); consoleNotifyBox.HeightMultiplier = 0; consoleNotifyBox.Height = ConsoleNotifyLines * fontHeight; consoleNotifyBox.SetAnchorPreset(AnchorPresets.HorizontalStretchTop, true); //consoleBox.AnchorMax = new Vector2(1.0f, ConsoleHeight); //consoleBox.HorizontalAlignment = TextAlignment.Near; //consoleBox.VerticalAlignment = TextAlignment.Near; //consoleNotifyBox.HeightMultiplier = ConsoleHeight; consoleNotifyBox.Wrapping = TextWrapping.WrapWords; consoleNotifyBox.BackgroundColor = Color.Transparent; consoleNotifyBox.BackgroundSelectedColor = Color.Transparent; consoleNotifyBox.BackgroundSelectedFlashSpeed = 0; consoleNotifyBox.BorderSelectedColor = Color.Transparent; consoleNotifyBox.CaretFlashSpeed = 0; } var locationFix2 = consoleNotifyBox.Location; var parentControl2 = Actor.AddChild(); parentControl2.Name = "ConsoleNotifyContent"; parentControl2.Control = consoleNotifyBox; consoleNotifyBox.Location = locationFix2; // workaround to UIControl.Control overriding the old position } { if (consoleInputBox == null) { //consoleInputBox = new ConsoleInputTextBox(consoleBox, 0, consoleSize.Y - fontHeight, consoleSize.X, fontHeight); consoleInputBox = new ConsoleInputTextBox(consoleBox, 0, 0, 0, 0); consoleInputBox.SetAnchorPreset(AnchorPresets.HorizontalStretchTop, false); //consoleInputBox.Location = new Vector2(0, consoleSize.Y - fontHeight); consoleInputBox.Height = fontHeight; consoleInputBox.Font = fontReference; consoleBox.inputBox = consoleInputBox; consoleInputBox.Wrapping = TextWrapping.WrapWords; consoleInputBox.BackgroundColor = Color.Transparent; consoleInputBox.BackgroundSelectedColor = Color.Transparent; consoleInputBox.BackgroundSelectedFlashSpeed = 0; consoleInputBox.BorderSelectedColor = Color.Transparent; consoleInputBox.CaretFlashSpeed = 0; } var locationFix = consoleInputBox.Location; var parentControl = contentContainerControl.AddChild(); parentControl.Name = "ConsoleInput"; parentControl.Control = consoleInputBox; consoleInputBox.Location = locationFix; // workaround to UIControl.Control overriding the old position } #if false //for (int i = 0; i < 10; i++) { string[] teststr = { /* "...loading 'scripts/devilpunch.shader'", "...loading 'scripts/mkoxide.shader'", "...loading 'scripts/cpm22.shader'", "...loading 'scripts/cpm27.shader'", "...loading 'scripts/island.shader'", "...loading 'scripts/noodtex3.shader'", "...loading 'scripts/nood_cosdglass.shader'", "...loading 'scripts/nood_fog_1000.shader'", "...loading 'scripts/nood_lightbeams.shader'", "...loading 'scripts/nood_nightsky_nolight.shader'", "Rescanning shaders", @"Raw input type 0: [0] \\?\HID#VID_046D&PID_C231#2&229a2ea&0&0000#", @"Raw input type 0: [18] \\?\HID#VID_046D&PID_C539&MI_01&Col01#8&24523410&0&0000#", @"Raw input type 0: [19] \\?\HID#VID_28DE&PID_1102&MI_01#8&2fb9bb60&0&0000#", @"Raw input type 0: [20] \\?\HID#VID_04D9&PID_A131&MI_02&Col01#8&197f95af&0&0000#", "Raw input: initialized with 5 mice and 0 keyboards", "WASAPI: overriding channels", "WASAPI: 2 channel 32bit 48000khz non-exclusive", "WASAPI: requested periodicity: 128, default: 480, min: 128, max: 480, step: 16", "WASAPI: Low latency mode enabled", "WASAPI: buffer size: 280", "OpenGL renderer initialized", "video restart took 0.291480 seconds", "main thread video restart took 0.291798 secs", "[------ Goake Initialized ------]", "Initializing menu.dat", "Couldn't load sound/ambience/water1.wav", "Couldn't load sound/ambience/wind2.wav", "Couldn't load sound/misc/menu2.wav", "Couldn't load sound/misc/menu3.wav", "]cl_maxfps 120", "a very very very long long long line in repeat a very very very long long long line in repeat a very very very long long long line in repeat a very very very long long long line in repeat a very very very long long long line in repeat a very very very long long long line in repeat" */ "Warning: Unsupported entity field 'light'", "Warning: Unsupported entity field '_keeplights'", "Warning: Unsupported entity field 'light'", "Warning: Unsupported entity field '_keeplights'", "Warning: Unsupported entity field 'light'", "Warning: Unsupported entity field '_keeplights'", "Warning: Unsupported entity field 'light'", "Warning: Unsupported entity field '_keeplights'", "maps/aerowalk.bsp: Using lightmap format E5BGR9_UF", "maps/devbox.bsp: Using lightmap format E5BGR9_UF", "what", "Game mode changed to: Free For All", "what", "641 additional FS searches", "fixangle frame: 1427", "Couldn't load sound/ambience/wind2.wav", "Couldn't load sound/ambience/water1.wav" }; foreach (var l in teststr) Console.Print(l); } #endif /*FlaxEditor.Editor.Options.OptionsChanged += (FlaxEditor.Options.EditorOptions options) => { };*/ /*Console.Print("normal line"); Console.Print( "a very very very long long long line in repeat a very very very long long long line in repeat 1 a very very ver" + "y long long long line in repeat a very very very 2 long long long line in repeat a very very very 3 long long" + " long line in repeat a very very very long long long 4 line in repeat"); Console.Print("another normal line");*/ Debug.Logger.LogHandler.SendLog += OnSendLog; Debug.Logger.LogHandler.SendExceptionLog += OnSendExceptionLog; Console.OnOpen += OnConsoleOpen; Console.OnClose += OnConsoleClose; Console.OnPrint += OnPrint; // hide console by default, and close it instantly Console.Close(); var rootlocation = rootControl.Control.Location; rootlocation.Y = -rootControl.Control.Height; rootControl.Control.Location = rootlocation; Console.Print("Renderer: " + GPUDevice.Instance.RendererType); } private void OnSendLog(LogType level, string msg, FlaxEngine.Object obj, string stackTrace) { Console.Print("[DEBUG] " + msg); } private void OnSendExceptionLog(Exception exception, FlaxEngine.Object obj) { AssertionException assert = exception as AssertionException; if (assert != null) { var assertLines = assert.Message.Split('\n'); if (assertLines.Length > 2) Console.Print("Assert Failure: " + assertLines[2]); else Console.Print("Assert Failure: " + assert.Message); } else Console.Print("[EXCEP] " + exception.Message); } public override void OnDestroy() { base.OnDestroy(); //consoleInputEvent.Triggered -= OnConsoleInputEvent; consoleInputEvent?.Dispose(); consoleBox?.Dispose(); consoleNotifyBox?.Dispose(); Console.OnOpen -= OnConsoleOpen; Console.OnClose -= OnConsoleClose; Console.OnPrint -= OnPrint; Debug.Logger.LogHandler.SendLog -= OnSendLog; Debug.Logger.LogHandler.SendExceptionLog -= OnSendExceptionLog; } private void OnConsoleInputEvent() { string currentInput = Input.InputText; if (Input.InputText.Length > 0) { // Really need rawinput support with separate ActionConfig.RawKey values, bound to physical keys/scancode instead of virtual ones var consoleKeys = Input.ActionMappings.Where(x => x.Name == "Console" && x.Key != KeyboardKeys.None); bool backslash = consoleKeys.Any(x => x.Key == KeyboardKeys.Backslash); bool backquote = consoleKeys.Any(x => x.Key == KeyboardKeys.BackQuote); // Workaround to only trigger Console key from key bound to left side of 1 (tilde/backquote/backslash key) if ((backslash || backquote) && (Input.InputText.ToLowerInvariant().Contains('ö') || Input.InputText.ToLowerInvariant().Contains('æ') || Input.InputText.ToLowerInvariant().Contains('ø'))) // Scandinavian keyboard layouts { return; } else if (backquote && Input.InputText.ToLowerInvariant().Contains('\'')) // UK keyboard layouts return; else if (backslash && (Input.InputText.ToLowerInvariant().Contains('\\') || Input.InputText.ToLowerInvariant() .Contains('|'))) // US/International keyboard layouts return; } if (!consoleInputBox.IsFocused) Console.Open(); else Console.Close(); } public void OnConsoleOpen() { Screen.CursorVisible = true; Screen.CursorLock = CursorLockMode.None; consoleInputBox.Focus(); Parent.As().ReceivesEvents = true; } public void OnConsoleClose() { Screen.CursorVisible = false; Screen.CursorLock = CursorLockMode.Locked; consoleInputBox.Defocus(); #if FLAX_EDITOR Editor.Instance.Windows.GameWin.Focus(); #endif Parent.As().ReceivesEvents = false; } public override void OnUpdate() { base.OnUpdate(); if (!Console.IsOpen && Input.GetAction("ClearConsole")) Console.Clear(); float targetY; float conHeight = rootControl.Control.Height /*/ Platform.DpiScale*/; if (!Console.IsOpen) targetY = -conHeight; else targetY = 0.0f; Vector2 location = rootControl.Control.Location; if (location.Y != targetY) { if (location.Y > targetY) { // closing location.Y -= Time.UnscaledDeltaTime * ConsoleSpeed; if (location.Y < targetY) location.Y = targetY; if (location.Y < targetY * ConsoleHeight) location.Y = targetY; } else if (location.Y < targetY) { // opening if (location.Y < -conHeight * ConsoleHeight) location.Y = -conHeight * ConsoleHeight; location.Y += Time.UnscaledDeltaTime * ConsoleSpeed; if (location.Y > targetY) location.Y = targetY; } rootControl.Control.Location = location; if (Console.IsOpen) { consoleNotifyBox.Visible = false; consoleInputBox.Visible = true; } else if (!Console.IsOpen) { int fontHeight = (int) (consoleNotifyBox.FontHeight / Platform.DpiScale); if (location.Y < (-conHeight * ConsoleHeight) + fontHeight) { consoleNotifyBox.Visible = true; consoleInputBox.Visible = false; } } } } public void OnPrint(string text) { int fontHeight = (int) (consoleNotifyBox.FontHeight / Platform.DpiScale); consoleNotifyBox.Height = Math.Min(ConsoleNotifyLines, Console.Lines.Count) * fontHeight; } public void SetInput(string text) { consoleInputBox.Text = text; } } }