using System; using System.Collections.Generic; using System.Linq; using FlaxEditor; using FlaxEngine; using FlaxEngine.GUI; namespace Cabrito { public abstract class ConsoleScriptBase : Script { public abstract void OnConsoleOpen(); public abstract void OnConsoleClose(); public abstract void SetInput(string text); public abstract void AddLine(string text); } public class ConsoleScript : ConsoleScriptBase { [Limit(5, 720, 1)] public int ConsoleFontSize = 16; [Limit(0.05f, 1.0f, 1)] public float ConsoleHeight = 0.65f; [Limit(0.5f, 4f, 0.05f)] public float LineSpacing { get => lineSpacing; set { lineSpacing = value; if (consoleBox != null) consoleBox.LineSpacing = value; if (consoleInputBox != null) consoleInputBox.LineSpacing = value; RefreshLayout(); } } private float lineSpacing; public FontAsset ConsoleFont; public Texture BackgroundTexture; public Color BackgroundColor; private UIControl rootControl; private ConsoleContentTextBox consoleBox; private ConsoleInputTextBox consoleInputBox; private Image backgroundImage; internal InputEvent consoleInputEvent; public override void OnStart() { Console.Init(); consoleInputEvent = new InputEvent("Console"); consoleInputEvent.Triggered += OnConsoleInputEvent; Vector2 screenSize = Screen.Size; Vector2 consoleSize = new Vector2(screenSize.X, screenSize.Y * ConsoleHeight); FontReference fontReference = new FontReference(ConsoleFont, ConsoleFontSize); Font fontRaw = fontReference.GetFont(); int fontHeight = fontRaw.Height; // root actor which holds all the elements var rootContainerControl = new ContainerControl(0, 0, screenSize.X, screenSize.Y); rootControl = Actor.AddChild(); rootControl.Name = "ConsoleRoot"; rootControl.Control = rootContainerControl; if (backgroundImage == null) { backgroundImage = new Image(0, 0, consoleSize.X, consoleSize.Y); if (BackgroundTexture != null) { backgroundImage.Brush = new TextureBrush(BackgroundTexture); } else { backgroundImage.Brush = new SolidColorBrush(BackgroundColor); backgroundImage.KeepAspectRatio = false; } var locationFix = backgroundImage.Location; var parentControl = rootControl.AddChild(); parentControl.Name = "ConsoleBackground"; parentControl.Control = backgroundImage; backgroundImage.Location = locationFix; // workaround to UIControl.Control overriding the old position backgroundImage.Enabled = false; } // Create a container that keeps the focus in the input box when clicked outside the console window. // The container must be created before the content box so interacting with the console lines wont get // stolen by this container. var containerControl = new ConsoleContainerControl(0, 0, screenSize.X, screenSize.Y); var focusControl = rootControl.AddChild(); focusControl.Name = "ConsoleInputContainer"; focusControl.Control = containerControl; { if (consoleBox == null) { consoleBox = new ConsoleContentTextBox(null, 0, 0, consoleSize.X, consoleSize.Y - fontHeight); consoleBox.Font = fontReference; //consoleBox.HorizontalAlignment = TextAlignment.Near; //consoleBox.VerticalAlignment = TextAlignment.Near; consoleBox.Wrapping = TextWrapping.WrapWords; consoleBox.BackgroundColor = Color.Transparent; consoleBox.BackgroundSelectedColor = Color.Transparent; consoleBox.BackgroundSelectedFlashSpeed = 0; consoleBox.BorderSelectedColor = Color.Transparent; consoleBox.CaretFlashSpeed = 0; consoleBox.LineSpacing = LineSpacing; } var locationFix = consoleBox.Location; var parentControl = rootControl.AddChild(); parentControl.Name = "ConsoleContent"; parentControl.Control = consoleBox; consoleBox.Location = locationFix; // workaround to UIControl.Control overriding the old position } { if (consoleInputBox == null) { consoleInputBox = new ConsoleInputTextBox(consoleBox, 0, consoleSize.Y - fontHeight, consoleSize.X, 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; } containerControl.inputBox = consoleInputBox; var locationFix = consoleInputBox.Location; var parentControl = rootControl.AddChild(); parentControl.Name = "ConsoleInput"; parentControl.Control = consoleInputBox; consoleInputBox.Location = locationFix; // workaround to UIControl.Control overriding the old position } // close instantly var rootlocation = rootControl.Control.Location; rootlocation.Y = -rootControl.Control.Height; rootControl.Control.Location = rootlocation; OnConsoleClose(); Console.RegisterConsoleScript(this); RefreshLayout(); #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) => { };*/ Debug.Logger.LogHandler.SendLog += OnSendLog; Debug.Logger.LogHandler.SendExceptionLog += OnSendExceptionLog; } private void OnSendLog(LogType level, string msg, FlaxEngine.Object obj, string stackTrace) { //Console.Print("[DEBUG] " + msg); } private void OnSendExceptionLog(Exception exception, FlaxEngine.Object obj) { //Console.Print("[EXCEP] " + exception.Message); } public override void OnDestroy() { Console.UnregisterConsoleScript(this); //consoleInputEvent.Triggered -= OnConsoleInputEvent; consoleInputEvent?.Dispose(); consoleBox?.Dispose(); backgroundImage?.DisposeChildren(); backgroundImage?.Dispose(); Debug.Logger.LogHandler.SendLog -= OnSendLog; Debug.Logger.LogHandler.SendExceptionLog -= OnSendExceptionLog; } public void RefreshLayout() { if (consoleBox == null || consoleInputBox == null) return; float fontHeight = consoleBox.GetFontHeight(); Vector2 screenSize = Screen.Size; Vector2 consoleSize = new Vector2(screenSize.X, screenSize.Y * ConsoleHeight); consoleBox.Height = consoleSize.Y - fontHeight; consoleInputBox.Location = new Vector2(0, consoleBox.Height); consoleInputBox.Height = fontHeight; consoleInputBox.ScrollToCaret(); } private void OnConsoleInputEvent() { if (!consoleInputBox.IsFocused) Console.Open(); else Console.Close(); } public override void OnConsoleOpen() { consoleInputBox.Focus(); Parent.As().ReceivesEvents = true; } public override void OnConsoleClose() { consoleInputBox.Defocus(); #if FLAX_EDITOR Editor.Instance.Windows.GameWin.Focus(); #endif Parent.As().ReceivesEvents = false; } public override void OnUpdate() { Profiler.BeginEvent("ConsoleScript_OnUpdate"); base.OnUpdate(); const float consoleSpeed = 3500f; float targetY; if (!Console.IsOpen) targetY = -rootControl.Control.Height; else targetY = 0.0f; Vector2 location = rootControl.Control.Location; if (location.Y != targetY) { if (location.Y > targetY) { location.Y -= Time.UnscaledDeltaTime * consoleSpeed; if (location.Y < targetY) location.Y = targetY; } else if (location.Y < targetY) { location.Y += Time.UnscaledDeltaTime * consoleSpeed; if (location.Y > targetY) location.Y = targetY; } rootControl.Control.Location = location; } Profiler.EndEvent(); } public override void AddLine(string text) { /*if (string.IsNullOrEmpty(consoleBox.Text)) consoleBox.Text += text; else consoleBox.Text += "\n" + text;*/ } public override void SetInput(string text) { consoleInputBox.Text = text; } } }