Files
GoakeFlax/Source/Game/Cabrito/Console/ConsoleScript.cs
2021-03-13 23:05:45 +02:00

405 lines
17 KiB
C#

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;
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(new Rectangle(0, 0, screenSize.X, screenSize.Y));
var rootContainerControl = new ContainerControl(new Rectangle());
rootContainerControl.SetAnchorPreset(AnchorPresets.StretchAll, false);
rootControl = Actor.AddChild<UIControl>();
rootControl.Name = "ConsoleRoot";
rootControl.Control = rootContainerControl;
// 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(new Rectangle());
containerControl.SetAnchorPreset(AnchorPresets.StretchAll, false);
/*var focusControl = rootControl.AddChild<UIControl>();
focusControl.Name = "ConsoleInputContainer";
focusControl.Control = containerControl;*/
var focusControl = new UIControl()
{
Parent = rootControl,
Name = "ConsoleInputContainer",
Control = containerControl
};
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<UIControl>();
contentContainerControl.Name = "ContentContainer";
contentContainerControl.Control = contentContainer;
{
if (consoleBox == null)
{
//consoleBox = new ConsoleContentTextBox(null, 0, 0, consoleSize.X, consoleSize.Y - fontHeight);
consoleBox = new ConsoleContentTextBox(null, 0, 0, 0, 0);
consoleBox.SetAnchorPreset(AnchorPresets.HorizontalStretchTop, false);
//consoleBox.AnchorMax = new Vector2(1.0f, ConsoleHeight);
consoleBox.Height = consoleSize.Y - fontHeight;
consoleBox.Font = fontReference;
//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;
consoleBox.LineSpacing = LineSpacing;
}
var locationFix = consoleBox.Location;
var parentControl = contentContainerControl.AddChild<UIControl>();
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 = 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;
}
containerControl.inputBox = consoleInputBox;
var locationFix = consoleInputBox.Location;
var parentControl = contentContainerControl.AddChild<UIControl>();
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 true
//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 += () => { Screen.CursorVisible = true; Screen.CursorLock = CursorLockMode.None; };
Console.OnClose += () => { Screen.CursorVisible = false; Screen.CursorLock = CursorLockMode.Locked; };
}
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();
Debug.Logger.LogHandler.SendLog -= OnSendLog;
Debug.Logger.LogHandler.SendExceptionLog -= OnSendExceptionLog;
}
public void RefreshLayout()
{
if (consoleBox == null || consoleInputBox == null)
return;
//consoleBox.SetAnchorPreset(AnchorPresets.StretchAll, true);
//consoleBox.AnchorMax = new Vector2(1.0f, ConsoleHeight);
Vector2 screenSize = Screen.Size;
Vector2 consoleSize = new Vector2(screenSize.X, screenSize.Y * ConsoleHeight);
//consoleBox.Height = consoleSize.Y - consoleBox.GetFontHeight();
//consoleInputBox.SetAnchorPreset(AnchorPresets.HorizontalStretchTop, true);
//consoleInputBox.Location = new Vector2(0, consoleBox.Bottom);
//Font fontRaw = consoleBox.Font.GetFont();
//consoleBox.Height -= fontRaw.Height;
/*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()
{
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 override void OnConsoleOpen()
{
consoleInputBox.Focus();
Parent.As<UICanvas>().ReceivesEvents = true;
}
public override void OnConsoleClose()
{
consoleInputBox.Defocus();
#if FLAX_EDITOR
Editor.Instance.Windows.GameWin.Focus();
#endif
Parent.As<UICanvas>().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;
}
}
}