Files
GoakeFlax/Source/Game/Console/ConsoleScript.cs

350 lines
13 KiB
C#

using System;
using System.Linq;
using FlaxEditor;
using FlaxEditor.Content.Settings;
using FlaxEngine;
using FlaxEngine.Assertions;
using FlaxEngine.GUI;
using Object = FlaxEngine.Object;
namespace Game;
public class ConsoleScript : Script
{
public Color BackgroundColor;
public Texture BackgroundTexture;
public FontAsset ConsoleFont;
[Limit(5, 720)] public int ConsoleFontSize = 16;
[Limit(0.05f, 1.0f)] public float ConsoleHeight = 0.65f;
[Limit(0)] public int ConsoleNotifyLines = 15;
[Limit(0f)] public float ConsoleSpeed = 3500f;
public JsonAssetReference<InputSettings> InputSettingsGameplay;
public JsonAssetReference<InputSettings> InputSettingsMenu;
private ConsoleInputTextBox consoleInputBox;
internal InputEvent consoleInputEvent;
private ConsoleContentTextBox consoleBox;
private ConsoleContentTextBox consoleNotifyBox;
private UIControl rootControl;
private int fontHeight;
public override void OnStart()
{
consoleInputEvent = new InputEvent("Console");
consoleInputEvent.Pressed += OnConsoleInputEvent;
FontReference fontReference = new FontReference(ConsoleFont, ConsoleFontSize);
Font fontRaw = fontReference.GetFont();
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));
ContainerControl rootContainerControl = new ContainerControl(new Rectangle());
rootContainerControl.SetAnchorPreset(AnchorPresets.StretchAll, false);
rootControl = Actor.AddChild<UIControl>();
rootControl.Name = "ConsoleRoot";
rootControl.Control = rootContainerControl;
VerticalPanel contentContainer = new VerticalPanel
{
AutoSize = true,
Margin = Margin.Zero,
Spacing = 0,
Bounds = new Rectangle(),
BackgroundColor = BackgroundColor
};
contentContainer.SetAnchorPreset(AnchorPresets.StretchAll, true);
UIControl contentContainerControl = rootControl.AddChild<UIControl>();
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 Float2(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;
}
Float2 locationFix = consoleBox.Location;
UIControl parentControl = contentContainerControl.AddChild<UIControl>();
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 Float2(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;
consoleNotifyBox.SelectionAllowed = false;
}
Float2 locationFix2 = consoleNotifyBox.Location;
UIControl parentControl2 = Actor.AddChild<UIControl>();
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 Float2(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;
}
Float2 locationFix = consoleInputBox.Location;
UIControl parentControl = contentContainerControl.AddChild<UIControl>();
parentControl.Name = "ConsoleInput";
parentControl.Control = consoleInputBox;
consoleInputBox.Location = locationFix; // workaround to UIControl.Control overriding the old position
}
/*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");*/
//for (int i=0; i<10000; i++)
// Debug.Log("a very very very long long long line in repeat a very very very long long long line in");
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();
OnConsoleClose();
Float2 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, Object obj, string stackTrace)
{
Console.Print("[DEBUG] " + msg);
}
private void OnSendExceptionLog(Exception exception, Object obj)
{
AssertionException assert = exception as AssertionException;
if (assert != null)
{
string[] 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.ToString());
}
}
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)
{
// TODO: Remove when engine has support for binding 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;
if (backquote && Input.InputText.ToLowerInvariant().Contains('\'')) // UK keyboard layouts
return;
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<UICanvas>().ReceivesEvents = true;
Input.SetInputMappingFromSettings(InputSettingsMenu);
}
public void OnConsoleClose()
{
Screen.CursorVisible = false;
Screen.CursorLock = CursorLockMode.Locked;
consoleInputBox.Defocus();
#if FLAX_EDITOR
Editor.Instance.Windows.GameWin.Focus();
#endif
Parent.As<UICanvas>().ReceivesEvents = false;
Input.SetInputMappingFromSettings(InputSettingsGameplay);
}
public override void OnUpdate()
{
#if !USE_EDITOR
consoleNotifyBox.Width = consoleBox.Width;
#endif
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;
Float2 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)
{
if (location.Y < -conHeight * ConsoleHeight + fontHeight)
{
consoleNotifyBox.Visible = true;
consoleInputBox.Visible = false;
}
}
}
}
public void OnPrint(string text)
{
consoleNotifyBox.Height = Math.Min(ConsoleNotifyLines, Console.Lines.Length) * fontHeight;
}
public void SetInput(string text)
{
consoleInputBox.Text = text;
}
}