Reformat codef

This commit is contained in:
GoaLitiuM
2021-06-28 16:22:20 +03:00
parent c7369d94b5
commit 6c5965e959
19 changed files with 2964 additions and 2926 deletions

View File

@@ -7,349 +7,363 @@ using FlaxEngine.Assertions;
namespace Cabrito
{
public class ConsoleLine
{
public string content;
public class ConsoleLine
{
public string content;
internal ConsoleLine(string line)
{
content = line;
}
internal ConsoleLine(string line)
{
content = line;
}
public static implicit operator string(ConsoleLine line) => line.content;
public static explicit operator ConsoleLine(string line) => new ConsoleLine(line);
public static implicit operator string(ConsoleLine line) => line.content;
public static explicit operator ConsoleLine(string line) => new ConsoleLine(line);
public override string ToString() => content.ToString();
}
public override string ToString() => content.ToString();
}
public static class Console
{
private static ConsoleInstance instance;
public static void Init()
{
Destroy();
instance = new ConsoleInstance();
}
public static class Console
{
private static ConsoleInstance instance;
private static void Destroy()
{
if (instance != null)
{
instance.Dispose();
instance = null;
FlaxEngine.Debug.Log("Console.Destroy");
}
}
public static void Init()
{
Destroy();
instance = new ConsoleInstance();
}
// Returns if Console window open right now.
public static bool IsOpen => instance.IsOpen;
private static void Destroy()
{
if (instance != null)
{
instance.Dispose();
instance = null;
FlaxEngine.Debug.Log("Console.Destroy");
}
}
// For debugging only: Returns true when Console was not closed during the same frame.
// Needed when Escape-key both closes the console and exits the game.
public static bool IsSafeToQuit => instance.IsSafeToQuit;
// Returns if Console window open right now.
public static bool IsOpen => instance.IsOpen;
// Called when Console is opened.
public static Action OnOpen
{
get { return instance.OnOpen; }
set { instance.OnOpen = value; }
}
// For debugging only: Returns true when Console was not closed during the same frame.
// Needed when Escape-key both closes the console and exits the game.
public static bool IsSafeToQuit => instance.IsSafeToQuit;
// Called when Console is closed.
public static Action OnClose
{
get { return instance.OnClose; }
set { instance.OnClose = value; }
}
// Called when Console is opened.
public static Action OnOpen
{
get { return instance.OnOpen; }
set { instance.OnOpen = value; }
}
// Called when a line of text was printed in Console.
public static Action<string> OnPrint
{
get { return instance.OnPrint; }
set { instance.OnPrint = value; }
}
// Called when Console is closed.
public static Action OnClose
{
get { return instance.OnClose; }
set { instance.OnClose = value; }
}
public static bool ShowExecutedLines => instance.ShowExecutedLines;
public static string LinePrefix => instance.LinePrefix;
// Called when a line of text was printed in Console.
public static Action<string> OnPrint
{
get { return instance.OnPrint; }
set { instance.OnPrint = value; }
}
public static IReadOnlyCollection<ConsoleLine> Lines => instance.Lines;
public static bool ShowExecutedLines => instance.ShowExecutedLines;
public static string LinePrefix => instance.LinePrefix;
// Echoes text to Console
public static void Print(string text) => instance.Print(text);
public static IReadOnlyCollection<ConsoleLine> Lines => instance.Lines;
// Echoes warning text to Console
public static void PrintWarning(string text) => instance.PrintWarning(text);
// Echoes text to Console
public static void Print(string text) => instance.Print(text);
// Echoes error text to Console
public static void PrintError(string text) => instance.PrintError(text);
// Echoes warning text to Console
public static void PrintWarning(string text) => instance.PrintWarning(text);
// Echoes developer/debug text to Console
public static void PrintDebug(string text) => instance.PrintDebug(text);
// Echoes error text to Console
public static void PrintError(string text) => instance.PrintError(text);
// Opens the Console
public static void Open() => instance.Open();
// Echoes developer/debug text to Console
public static void PrintDebug(string text) => instance.PrintDebug(text);
// Closes the Console
public static void Close() => instance.Close();
// Opens the Console
public static void Open() => instance.Open();
// Clears the content of the Console
public static void Clear() => instance.Clear();
// Closes the Console
public static void Close() => instance.Close();
public static void Execute(string str) => instance.Execute(str);
// Clears the content of the Console
public static void Clear() => instance.Clear();
public static string GetVariable(string variableName) => instance.GetVariable(variableName);
}
public static void Execute(string str) => instance.Execute(str);
public class ConsoleInstance : IDisposable
{
public bool IsOpen { get; internal set; } = true;
public static string GetVariable(string variableName) => instance.GetVariable(variableName);
}
public bool IsSafeToQuit { get { return stopwatch.Elapsed.TotalSeconds > 0.1; } }
private Stopwatch stopwatch = Stopwatch.StartNew();
public class ConsoleInstance : IDisposable
{
public bool IsOpen { get; internal set; } = true;
public Action OnOpen;
public Action OnClose;
public Action<string> OnPrint;
public bool ShowExecutedLines = true;
public string LinePrefix { get; internal set; } = "]";
public bool IsSafeToQuit
{
get { return stopwatch.Elapsed.TotalSeconds > 0.1; }
}
//private static List<string> consoleLines = new List<string>();
private List<ConsoleLine> consoleLines = new List<ConsoleLine>();
private Dictionary<string, ConsoleCommand> consoleCommands = new Dictionary<string, ConsoleCommand>();
private Dictionary<string, ConsoleVariable> consoleVariables = new Dictionary<string, ConsoleVariable>();
private Stopwatch stopwatch = Stopwatch.StartNew();
// Initializes the Console system.
public ConsoleInstance()
{
AppDomain currentDomain = AppDomain.CurrentDomain;
Assembly[] assemblies = currentDomain.GetAssemblies();
public Action OnOpen;
public Action OnClose;
public Action<string> OnPrint;
foreach (var assembly in assemblies)
{
// Skip common assemblies
var assemblyName = assembly.GetName().Name;
if (assemblyName == "System" ||
assemblyName.StartsWith("System.") ||
assemblyName.StartsWith("Mono.") ||
assemblyName == "mscorlib" ||
assemblyName == "Newtonsoft.Json" ||
assemblyName.StartsWith("FlaxEngine."))
{
continue;
}
public bool ShowExecutedLines = true;
public string LinePrefix { get; internal set; } = "]";
foreach (var type in assembly.GetTypes())
{
Dictionary<string, ConsoleCommand> cmdParsed = new Dictionary<string, ConsoleCommand>();
Dictionary<string, List<MethodInfo>> cmdMethods = new Dictionary<string, List<MethodInfo>>();
//private static List<string> consoleLines = new List<string>();
private List<ConsoleLine> consoleLines = new List<ConsoleLine>();
private Dictionary<string, ConsoleCommand> consoleCommands = new Dictionary<string, ConsoleCommand>();
private Dictionary<string, ConsoleVariable> consoleVariables = new Dictionary<string, ConsoleVariable>();
foreach (MethodInfo method in type.GetMethods())
{
if (!method.IsStatic)
continue;
// Initializes the Console system.
public ConsoleInstance()
{
AppDomain currentDomain = AppDomain.CurrentDomain;
Assembly[] assemblies = currentDomain.GetAssemblies();
Attribute[] attributes = Attribute.GetCustomAttributes(method);
foreach (var assembly in assemblies)
{
// Skip common assemblies
var assemblyName = assembly.GetName().Name;
if (assemblyName == "System" ||
assemblyName.StartsWith("System.") ||
assemblyName.StartsWith("Mono.") ||
assemblyName == "mscorlib" ||
assemblyName == "Newtonsoft.Json" ||
assemblyName.StartsWith("FlaxEngine."))
{
continue;
}
foreach (Attribute attr in attributes)
{
if (attr is ConsoleCommandAttribute cmdAttribute)
{
//Console.Print("found cmd '" + cmdAttribute.name + "' bound to field '" + method.Name + "'");
foreach (var type in assembly.GetTypes())
{
Dictionary<string, ConsoleCommand> cmdParsed = new Dictionary<string, ConsoleCommand>();
Dictionary<string, List<MethodInfo>> cmdMethods = new Dictionary<string, List<MethodInfo>>();
// Defer constructing the command until we have parsed all the methods for it in this assembly.
foreach (MethodInfo method in type.GetMethods())
{
if (!method.IsStatic)
continue;
List<MethodInfo> methods;
if (!cmdMethods.TryGetValue(cmdAttribute.name, out methods))
{
methods = new List<MethodInfo>();
cmdMethods.Add(cmdAttribute.name, methods);
}
methods.Add(method);
Attribute[] attributes = Attribute.GetCustomAttributes(method);
ConsoleCommand cmd = new ConsoleCommand(cmdAttribute.name, null);
if (!cmdParsed.ContainsKey(cmdAttribute.name))
cmdParsed.Add(cmdAttribute.name, cmd);
foreach (var alias in cmdAttribute.aliases)
{
if (!cmdParsed.ContainsKey(alias))
cmdParsed.Add(alias, cmd);
foreach (Attribute attr in attributes)
{
if (attr is ConsoleCommandAttribute cmdAttribute)
{
//Console.Print("found cmd '" + cmdAttribute.name + "' bound to field '" + method.Name + "'");
List<MethodInfo> aliasMethods;
if (!cmdMethods.TryGetValue(alias, out aliasMethods))
{
aliasMethods = new List<MethodInfo>();
cmdMethods.Add(alias, aliasMethods);
}
aliasMethods.Add(method);
}
}
}
}
// Defer constructing the command until we have parsed all the methods for it in this assembly.
foreach (var kv in cmdParsed)
{
var methods = cmdMethods[kv.Key];
var definition = kv.Value;
List<MethodInfo> methods;
if (!cmdMethods.TryGetValue(cmdAttribute.name, out methods))
{
methods = new List<MethodInfo>();
cmdMethods.Add(cmdAttribute.name, methods);
}
ConsoleCommand cmd = new ConsoleCommand(definition.name, methods.ToArray());
consoleCommands.Add(kv.Key, cmd);
}
methods.Add(method);
foreach (FieldInfo field in type.GetFields())
{
if (!field.IsStatic)
continue;
ConsoleCommand cmd = new ConsoleCommand(cmdAttribute.name, null);
if (!cmdParsed.ContainsKey(cmdAttribute.name))
cmdParsed.Add(cmdAttribute.name, cmd);
foreach (var alias in cmdAttribute.aliases)
{
if (!cmdParsed.ContainsKey(alias))
cmdParsed.Add(alias, cmd);
Attribute[] attributes = Attribute.GetCustomAttributes(field);
List<MethodInfo> aliasMethods;
if (!cmdMethods.TryGetValue(alias, out aliasMethods))
{
aliasMethods = new List<MethodInfo>();
cmdMethods.Add(alias, aliasMethods);
}
foreach (Attribute attr in attributes)
{
if (attr is ConsoleVariableAttribute cvarAttribute)
{
//Console.Print("found cvar '" + cvarAttribute.name + "' bound to field '" + field.Name + "'");
consoleVariables.Add(cvarAttribute.name, new ConsoleVariable(cvarAttribute.name, cvarAttribute.flags, field));
foreach (var alias in cvarAttribute.aliases)
consoleVariables.Add(alias, new ConsoleVariable(cvarAttribute.name, cvarAttribute.flags | ConsoleFlags.NoSerialize, field));
}
}
}
aliasMethods.Add(method);
}
}
}
}
foreach (PropertyInfo prop in type.GetProperties())
{
MethodInfo getter = prop.GetGetMethod();
MethodInfo setter = prop.GetSetMethod();
if (getter == null || setter == null || !getter.IsStatic || !setter.IsStatic)
continue;
foreach (var kv in cmdParsed)
{
var methods = cmdMethods[kv.Key];
var definition = kv.Value;
Attribute[] attributes = Attribute.GetCustomAttributes(prop);
ConsoleCommand cmd = new ConsoleCommand(definition.name, methods.ToArray());
consoleCommands.Add(kv.Key, cmd);
}
foreach (Attribute attr in attributes)
{
if (attr is ConsoleVariableAttribute cvarAttribute)
{
//Console.Print("found cvar '" + cvarAttribute.name + "' bound to field '" + field.Name + "'");
consoleVariables.Add(cvarAttribute.name, new ConsoleVariable(cvarAttribute.name, cvarAttribute.flags, getter, setter));
foreach (var alias in cvarAttribute.aliases)
consoleVariables.Add(alias, new ConsoleVariable(cvarAttribute.name, cvarAttribute.flags | ConsoleFlags.NoSerialize, getter, setter));
}
}
}
}
}
}
foreach (FieldInfo field in type.GetFields())
{
if (!field.IsStatic)
continue;
public void Dispose()
{
}
Attribute[] attributes = Attribute.GetCustomAttributes(field);
public IReadOnlyCollection<ConsoleLine> Lines
{
get => consoleLines.AsReadOnly();
}
foreach (Attribute attr in attributes)
{
if (attr is ConsoleVariableAttribute cvarAttribute)
{
//Console.Print("found cvar '" + cvarAttribute.name + "' bound to field '" + field.Name + "'");
consoleVariables.Add(cvarAttribute.name,
new ConsoleVariable(cvarAttribute.name, cvarAttribute.flags, field));
foreach (var alias in cvarAttribute.aliases)
consoleVariables.Add(alias,
new ConsoleVariable(cvarAttribute.name,
cvarAttribute.flags | ConsoleFlags.NoSerialize, field));
}
}
}
// Echoes text to Console
public void Print(string text)
{
ConsoleLine line = new ConsoleLine(text);
consoleLines.Add(line);
OnPrint?.Invoke(text);
}
foreach (PropertyInfo prop in type.GetProperties())
{
MethodInfo getter = prop.GetGetMethod();
MethodInfo setter = prop.GetSetMethod();
if (getter == null || setter == null || !getter.IsStatic || !setter.IsStatic)
continue;
// Echoes warning text to Console
public void PrintWarning(string text)
{
ConsoleLine line = new ConsoleLine(text);
consoleLines.Add(line);
OnPrint?.Invoke(text);
}
Attribute[] attributes = Attribute.GetCustomAttributes(prop);
// Echoes error text to Console
public void PrintError(string text)
{
ConsoleLine line = new ConsoleLine(text);
consoleLines.Add(line);
OnPrint?.Invoke(text);
}
foreach (Attribute attr in attributes)
{
if (attr is ConsoleVariableAttribute cvarAttribute)
{
//Console.Print("found cvar '" + cvarAttribute.name + "' bound to field '" + field.Name + "'");
consoleVariables.Add(cvarAttribute.name,
new ConsoleVariable(cvarAttribute.name, cvarAttribute.flags, getter, setter));
foreach (var alias in cvarAttribute.aliases)
consoleVariables.Add(alias,
new ConsoleVariable(cvarAttribute.name,
cvarAttribute.flags | ConsoleFlags.NoSerialize, getter, setter));
}
}
}
}
}
}
// Echoes developer/debug text to Console
public void PrintDebug(string text)
{
ConsoleLine line = new ConsoleLine(text);
consoleLines.Add(line);
OnPrint?.Invoke(text);
}
public void Dispose()
{
}
// Opens the Console
public void Open()
{
if (IsOpen)
return;
public IReadOnlyCollection<ConsoleLine> Lines
{
get => consoleLines.AsReadOnly();
}
IsOpen = true;
OnOpen?.Invoke();
}
// Echoes text to Console
public void Print(string text)
{
ConsoleLine line = new ConsoleLine(text);
consoleLines.Add(line);
OnPrint?.Invoke(text);
}
// Closes the Console
public void Close()
{
if (!IsOpen)
return;
// Echoes warning text to Console
public void PrintWarning(string text)
{
ConsoleLine line = new ConsoleLine(text);
consoleLines.Add(line);
OnPrint?.Invoke(text);
}
IsOpen = false;
OnClose?.Invoke();
// Echoes error text to Console
public void PrintError(string text)
{
ConsoleLine line = new ConsoleLine(text);
consoleLines.Add(line);
OnPrint?.Invoke(text);
}
stopwatch.Restart();
}
// Echoes developer/debug text to Console
public void PrintDebug(string text)
{
ConsoleLine line = new ConsoleLine(text);
consoleLines.Add(line);
OnPrint?.Invoke(text);
}
// Clears the content of the Console
public void Clear()
{
consoleLines.Clear();
}
// Opens the Console
public void Open()
{
if (IsOpen)
return;
public void Execute(string str)
{
str = str.Trim();
IsOpen = true;
OnOpen?.Invoke();
}
if (ShowExecutedLines)
Console.Print(LinePrefix + str);
// Closes the Console
public void Close()
{
if (!IsOpen)
return;
string[] strs = str.Split(' ');
string execute = strs[0];
string executeLower = execute.ToLowerInvariant();
string value = strs.Length > 1 ? str.Substring(execute.Length + 1) : null;
IsOpen = false;
OnClose?.Invoke();
//Console.PrintDebug("Executed '" + execute + "' with params: '" + value + "'");
stopwatch.Restart();
}
if (consoleCommands.TryGetValue(executeLower, out ConsoleCommand cmd))
{
string[] values = strs.Skip(1).ToArray();
if (values.Length > 0)
cmd.Invoke(values);
else
cmd.Invoke();
//Console.Print("Command bound to '" + execute + "' is '" + cmd.method.Name + "'");
}
else if (consoleVariables.TryGetValue(executeLower, out ConsoleVariable cvar))
{
if (value != null)
cvar.SetValue(value);
// Clears the content of the Console
public void Clear()
{
consoleLines.Clear();
}
Console.Print("'" + execute + "' is '" + cvar.GetValueString() + "'");
}
else
Console.Print("Unknown command '" + execute + "'");
}
public void Execute(string str)
{
str = str.Trim();
public string GetVariable(string variableName)
{
if (consoleVariables.TryGetValue(variableName, out ConsoleVariable cvar))
{
string value = cvar.GetValueString();
return value;
}
return null;
}
}
}
if (ShowExecutedLines)
Console.Print(LinePrefix + str);
string[] strs = str.Split(' ');
string execute = strs[0];
string executeLower = execute.ToLowerInvariant();
string value = strs.Length > 1 ? str.Substring(execute.Length + 1) : null;
//Console.PrintDebug("Executed '" + execute + "' with params: '" + value + "'");
if (consoleCommands.TryGetValue(executeLower, out ConsoleCommand cmd))
{
string[] values = strs.Skip(1).ToArray();
if (values.Length > 0)
cmd.Invoke(values);
else
cmd.Invoke();
//Console.Print("Command bound to '" + execute + "' is '" + cmd.method.Name + "'");
}
else if (consoleVariables.TryGetValue(executeLower, out ConsoleVariable cvar))
{
if (value != null)
cvar.SetValue(value);
Console.Print("'" + execute + "' is '" + cvar.GetValueString() + "'");
}
else
Console.Print("Unknown command '" + execute + "'");
}
public string GetVariable(string variableName)
{
if (consoleVariables.TryGetValue(variableName, out ConsoleVariable cvar))
{
string value = cvar.GetValueString();
return value;
}
return null;
}
}
}

View File

@@ -6,54 +6,54 @@ using System.Threading.Tasks;
namespace Cabrito
{
[AttributeUsage(AttributeTargets.All)]
public abstract class ConsoleBaseAttribute : Attribute
{
internal string name;
[AttributeUsage(AttributeTargets.All)]
public abstract class ConsoleBaseAttribute : Attribute
{
internal string name;
// Additional aliases for this command, these should only be used with user interaction.
// Commands such as 'cvarlist' should not list these in order to avoid clutter.
internal string[] aliases = new string[0];
// Additional aliases for this command, these should only be used with user interaction.
// Commands such as 'cvarlist' should not list these in order to avoid clutter.
internal string[] aliases = new string[0];
public ConsoleFlags flags { get; private set; }
public ConsoleFlags flags { get; private set; }
public ConsoleBaseAttribute(string name)
{
this.name = name.ToLowerInvariant();
}
public ConsoleBaseAttribute(string name)
{
this.name = name.ToLowerInvariant();
}
public ConsoleBaseAttribute(params string[] names)
{
this.name = names[0].ToLowerInvariant();
aliases = new List<string>(names).Skip(1).Select(x => x.ToLowerInvariant()).ToArray();
}
}
public ConsoleBaseAttribute(params string[] names)
{
this.name = names[0].ToLowerInvariant();
aliases = new List<string>(names).Skip(1).Select(x => x.ToLowerInvariant()).ToArray();
}
}
[AttributeUsage(AttributeTargets.All)]
public class ConsoleVariableAttribute : ConsoleBaseAttribute
{
public ConsoleVariableAttribute(string name) : base(name)
{
}
}
[AttributeUsage(AttributeTargets.All)]
public class ConsoleVariableAttribute : ConsoleBaseAttribute
{
public ConsoleVariableAttribute(string name) : base(name)
{
}
}
[AttributeUsage(AttributeTargets.All)]
public class ConsoleCommandAttribute : ConsoleBaseAttribute
{
/// <summary>
/// Registers a command to Console system.
/// </summary>
/// <param name="name">Name used for calling this command.</param>
public ConsoleCommandAttribute(string name) : base(name)
{
}
[AttributeUsage(AttributeTargets.All)]
public class ConsoleCommandAttribute : ConsoleBaseAttribute
{
/// <summary>
/// Registers a command to Console system.
/// </summary>
/// <param name="name">Name used for calling this command.</param>
public ConsoleCommandAttribute(string name) : base(name)
{
}
/// <summary>
/// Registers a command to Console system.
/// </summary>
/// <param name="names">Names used for calling this command. First name is the main name for this command, rest of the names are aliases.</param>
public ConsoleCommandAttribute(params string[] names) : base(names)
{
}
}
}
/// <summary>
/// Registers a command to Console system.
/// </summary>
/// <param name="names">Names used for calling this command. First name is the main name for this command, rest of the names are aliases.</param>
public ConsoleCommandAttribute(params string[] names) : base(names)
{
}
}
}

View File

@@ -7,74 +7,75 @@ using System.Threading.Tasks;
namespace Cabrito
{
internal struct ConsoleCommand
{
public string name { get; private set; }
internal struct ConsoleCommand
{
public string name { get; private set; }
private MethodInfo[] methods;
private MethodInfo[] methods;
public ConsoleCommand(string name, MethodInfo[] method)
{
this.name = name;
this.methods = method;
}
public ConsoleCommand(string name, MethodInfo[] method)
{
this.name = name;
this.methods = method;
}
public void Invoke()
{
foreach (var method in methods)
{
var methodParameters = method.GetParameters();
if (methodParameters.Length != 0)
continue;
public void Invoke()
{
foreach (var method in methods)
{
var methodParameters = method.GetParameters();
if (methodParameters.Length != 0)
continue;
method.Invoke(null, null);
return;
}
method.Invoke(null, null);
return;
}
throw new Exception("Unexpected number of parameters.");
}
throw new Exception("Unexpected number of parameters.");
}
public void Invoke(string[] parameters)
{
MethodInfo match = null;
foreach (var method in methods)
{
var methodParameters = method.GetParameters();
if (methodParameters.Length == 1 && methodParameters[0].ParameterType == typeof(string[]))
{
match = method;
continue;
}
else if (methodParameters.Length != parameters.Length)
continue;
public void Invoke(string[] parameters)
{
MethodInfo match = null;
foreach (var method in methods)
{
var methodParameters = method.GetParameters();
if (methodParameters.Length == 1 && methodParameters[0].ParameterType == typeof(string[]))
{
match = method;
continue;
}
else if (methodParameters.Length != parameters.Length)
continue;
// TODO: try to parse string parameters to needed types first,
// may require finding the exact match first instead of first matching one.
for (int i = 0; i < methodParameters.Length; i++)
//if (methodParameters[i].ParameterType != parameters[i].GetType())
if (methodParameters[i].ParameterType != typeof(string))
continue;
// TODO: try to parse string parameters to needed types first,
// may require finding the exact match first instead of first matching one.
for (int i = 0; i < methodParameters.Length; i++)
//if (methodParameters[i].ParameterType != parameters[i].GetType())
if (methodParameters[i].ParameterType != typeof(string))
continue;
if (match != null)
{
// Prefer exact number of parameters over string[] match
if (methodParameters.Length != parameters.Length)
continue;
}
match = method;
}
if (match != null)
{
// Prefer exact number of parameters over string[] match
if (methodParameters.Length != parameters.Length)
continue;
}
if (match != null)
{
if (match.GetParameters().Length == 1 && match.GetParameters()[0].ParameterType == typeof(string[]))
match.Invoke(null, new object[] { parameters });
else
match.Invoke(null, parameters);
match = method;
}
return;
}
if (match != null)
{
if (match.GetParameters().Length == 1 && match.GetParameters()[0].ParameterType == typeof(string[]))
match.Invoke(null, new object[] {parameters});
else
match.Invoke(null, parameters);
throw new Exception("Unexpected number of parameters.");
}
}
}
return;
}
throw new Exception("Unexpected number of parameters.");
}
}
}

View File

@@ -7,35 +7,33 @@ using FlaxEngine.GUI;
namespace Cabrito
{
// Container that keeps the focus on the input box
public class ConsoleContainerControl : ContainerControl
{
[HideInEditor]
public ConsoleInputTextBox inputBox;
// Container that keeps the focus on the input box
public class ConsoleContainerControl : ContainerControl
{
[HideInEditor] public ConsoleInputTextBox inputBox;
public ConsoleContainerControl() : base()
{
public ConsoleContainerControl() : base()
{
}
}
public ConsoleContainerControl(float x, float y, float width, float height) : base(x, y, width, height)
{
}
public ConsoleContainerControl(float x, float y, float width, float height) : base(x, y, width, height)
{
}
public ConsoleContainerControl(Rectangle bounds) : base(bounds)
{
}
public ConsoleContainerControl(Rectangle bounds) : base(bounds)
{
}
public override void OnGotFocus()
{
base.OnGotFocus();
if (inputBox != null)
Focus(inputBox);
}
public override void OnGotFocus()
{
base.OnGotFocus();
if (inputBox != null)
Focus(inputBox);
}
public override void OnLostFocus()
{
base.OnLostFocus();
}
}
}
public override void OnLostFocus()
{
base.OnLostFocus();
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -7,138 +7,142 @@ using FlaxEngine.GUI;
namespace Cabrito
{
public class ConsoleInputTextBox : ConsoleTextBoxBase
{
public override string TextPrefix { get => Console.LinePrefix; }
public class ConsoleInputTextBox : ConsoleTextBoxBase
{
public override string TextPrefix
{
get => Console.LinePrefix;
}
private ConsoleContentTextBox contentBox;
private ConsoleContentTextBox contentBox;
protected override Rectangle TextRectangle => new Rectangle(0, 0, Width, Height);
protected override Rectangle TextClipRectangle => new Rectangle(0, 0, Width, Height);
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() : 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
}
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();
private bool IsConsoleKeyPressed(KeyboardKeys key = KeyboardKeys.None)
{
// Ignore any characters generated by the key which opens the console
string inputTextLower = Input.InputText.ToLowerInvariant();
IEnumerable<ActionConfig> 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;
}
}
IEnumerable<ActionConfig> 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;
}
if (Input.GetKey(mapping.Key))
return true;
}
return false;
}
return false;
}
public override bool OnCharInput(char c)
{
if (IsConsoleKeyPressed())
return true;
public override bool OnCharInput(char c)
{
if (IsConsoleKeyPressed())
return true;
return base.OnCharInput(c);
}
return base.OnCharInput(c);
}
public override bool OnKeyDown(KeyboardKeys key)
{
bool shiftDown = Root.GetKey(KeyboardKeys.Shift);
bool ctrlDown = Root.GetKey(KeyboardKeys.Control);
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);
}
finally
{
Clear();
}
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);
}
finally
{
Clear();
}
contentBox.ScrollOffset = 0;
return true;
}
else if (key == KeyboardKeys.ArrowUp || key == KeyboardKeys.ArrowDown)
{
// TODO: implement input history
return true;
}
else if (key == KeyboardKeys.PageUp || key == KeyboardKeys.PageDown)
{
return contentBox.OnKeyDown(key);
}
contentBox.ScrollOffset = 0;
return true;
}
else if (key == KeyboardKeys.ArrowUp || key == KeyboardKeys.ArrowDown)
{
// TODO: implement input history
return true;
}
else if (key == KeyboardKeys.PageUp || key == KeyboardKeys.PageDown)
{
return contentBox.OnKeyDown(key);
}
return base.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 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 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 bool OnMouseWheel(Vector2 location, float delta)
{
return contentBox.OnMouseWheel(location, delta);
}
public override void Draw()
{
Profiler.BeginEvent("ConsoleInputTextBoxDraw");
base.Draw();
Profiler.EndEvent();
}
}
}
public override void Draw()
{
Profiler.BeginEvent("ConsoleInputTextBoxDraw");
base.Draw();
Profiler.EndEvent();
}
}
}

View File

@@ -5,29 +5,29 @@ using Console = Cabrito.Console;
namespace Game
{
public class ConsolePlugin : GamePlugin
{
public override void Initialize()
{
Console.Init();
base.Initialize();
public class ConsolePlugin : GamePlugin
{
public override void Initialize()
{
Console.Init();
base.Initialize();
Console.Print("ConsolePlugin initialize");
}
Console.Print("ConsolePlugin initialize");
}
public override void Deinitialize()
{
base.Deinitialize();
FlaxEngine.Debug.Log("ConsolePlugin Deinitialize");
}
public override void Deinitialize()
{
base.Deinitialize();
FlaxEngine.Debug.Log("ConsolePlugin Deinitialize");
}
public override PluginDescription Description => new PluginDescription()
{
Author = "Ari Vuollet",
Name = "Console",
Description = "Quake-like console",
Version = Version.Parse("0.1.0"),
IsAlpha = true,
};
}
}
public override PluginDescription Description => new PluginDescription()
{
Author = "Ari Vuollet",
Name = "Console",
Description = "Quake-like console",
Version = Version.Parse("0.1.0"),
IsAlpha = true,
};
}
}

View File

@@ -7,173 +7,167 @@ using FlaxEngine.GUI;
namespace Cabrito
{
public class ConsoleScript : Script
{
[Limit(5, 720, 1)]
public int ConsoleFontSize = 16;
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.05f, 1.0f, 1)] public float ConsoleHeight = 0.65f;
[Limit(0)]
public int ConsoleNotifyLines = 3;
[Limit(0)] public int ConsoleNotifyLines = 3;
[Limit(0f)]
public float ConsoleSpeed = 3500f;
[Limit(0f)] public float ConsoleSpeed = 3500f;
public FontAsset ConsoleFont;
public FontAsset ConsoleFont;
public Texture BackgroundTexture;
public Texture BackgroundTexture;
public Color BackgroundColor;
public Color BackgroundColor;
private UIControl rootControl;
private ConsoleContentTextBox consoleBox;
private ConsoleInputTextBox consoleInputBox;
private ConsoleContentTextBox consoleNotifyBox;
private UIControl rootControl;
private ConsoleContentTextBox consoleBox;
private ConsoleInputTextBox consoleInputBox;
private ConsoleContentTextBox consoleNotifyBox;
internal InputEvent consoleInputEvent;
internal InputEvent consoleInputEvent;
public override void OnStart()
{
Console.Print("ConsoleScript OnStart");
consoleInputEvent = new InputEvent("Console");
consoleInputEvent.Triggered += OnConsoleInputEvent;
public override void OnStart()
{
Console.Print("ConsoleScript OnStart");
consoleInputEvent = new InputEvent("Console");
consoleInputEvent.Triggered += OnConsoleInputEvent;
Vector2 screenSize = Screen.Size;
Vector2 consoleSize = new Vector2(screenSize.X, screenSize.Y * ConsoleHeight);
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 = (int)(fontRaw.Height / Platform.DpiScale);
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);
// 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;
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
};
// 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 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;
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, true);
//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;
}
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 (consoleNotifyBox == null)
{
//consoleBox = new ConsoleContentTextBox(null, 0, 0, consoleSize.X, consoleSize.Y - fontHeight);
consoleNotifyBox = new ConsoleContentTextBox(null, 0, 0, 0, 0);
consoleNotifyBox.HeightMultiplier = 0;
consoleNotifyBox.Height = ConsoleNotifyLines * fontHeight;
consoleNotifyBox.SetAnchorPreset(AnchorPresets.HorizontalStretchTop, true);
//consoleBox.AnchorMax = new Vector2(1.0f, ConsoleHeight);
consoleNotifyBox.Font = fontReference;
//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<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 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;
{
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, true);
//consoleBox.AnchorMax = new Vector2(1.0f, ConsoleHeight);
//consoleBox.Height = consoleSize.Y - fontHeight;
consoleBox.Font = fontReference;
var locationFix = consoleInputBox.Location;
var parentControl = contentContainerControl.AddChild<UIControl>();
parentControl.Name = "ConsoleInput";
parentControl.Control = consoleInputBox;
//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;
}
consoleInputBox.Location = locationFix; // workaround to UIControl.Control overriding the old position
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 (consoleNotifyBox == null)
{
//consoleBox = new ConsoleContentTextBox(null, 0, 0, consoleSize.X, consoleSize.Y - fontHeight);
consoleNotifyBox = new ConsoleContentTextBox(null, 0, 0, 0, 0);
consoleNotifyBox.HeightMultiplier = 0;
consoleNotifyBox.Height = ConsoleNotifyLines * fontHeight;
consoleNotifyBox.SetAnchorPreset(AnchorPresets.HorizontalStretchTop, true);
//consoleBox.AnchorMax = new Vector2(1.0f, ConsoleHeight);
consoleNotifyBox.Font = fontReference;
//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<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 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
}
#if false
//for (int i = 0; i < 10; i++)
@@ -236,176 +230,178 @@ namespace Cabrito
Console.Print(l);
}
#endif
/*FlaxEditor.Editor.Options.OptionsChanged += (FlaxEditor.Options.EditorOptions options) =>
{
/*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");*/
/*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;
Debug.Logger.LogHandler.SendLog += OnSendLog;
Debug.Logger.LogHandler.SendExceptionLog += OnSendExceptionLog;
Console.OnOpen += OnConsoleOpen;
Console.OnClose += OnConsoleClose;
Console.OnPrint += OnPrint;
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;
}
// hide console by default, and close it instantly
Console.Close();
var rootlocation = rootControl.Control.Location;
rootlocation.Y = -rootControl.Control.Height;
rootControl.Control.Location = rootlocation;
}
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);
}
private void OnSendLog(LogType level, string msg, FlaxEngine.Object obj, string stackTrace)
{
Console.Print("[DEBUG] " + msg);
}
public override void OnDestroy()
{
//consoleInputEvent.Triggered -= OnConsoleInputEvent;
consoleInputEvent?.Dispose();
consoleBox?.Dispose();
consoleNotifyBox?.Dispose();
private void OnSendExceptionLog(Exception exception, FlaxEngine.Object obj)
{
Console.Print("[EXCEP] " + exception.Message);
}
Console.OnOpen -= OnConsoleOpen;
Console.OnClose -= OnConsoleClose;
Console.OnPrint -= OnPrint;
public override void OnDestroy()
{
//consoleInputEvent.Triggered -= OnConsoleInputEvent;
consoleInputEvent?.Dispose();
consoleBox?.Dispose();
consoleNotifyBox?.Dispose();
Debug.Logger.LogHandler.SendLog -= OnSendLog;
Debug.Logger.LogHandler.SendExceptionLog -= OnSendExceptionLog;
}
Console.OnOpen -= OnConsoleOpen;
Console.OnClose -= OnConsoleClose;
Console.OnPrint -= OnPrint;
private void OnConsoleInputEvent()
{
string currentInput = Input.InputText;
Debug.Logger.LogHandler.SendLog -= OnSendLog;
Debug.Logger.LogHandler.SendExceptionLog -= OnSendExceptionLog;
}
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);
private void OnConsoleInputEvent()
{
string currentInput = Input.InputText;
// 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 (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);
if (!consoleInputBox.IsFocused)
Console.Open();
else
Console.Close();
}
// 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;
}
public void OnConsoleOpen()
{
Screen.CursorVisible = true;
Screen.CursorLock = CursorLockMode.None;
if (!consoleInputBox.IsFocused)
Console.Open();
else
Console.Close();
}
consoleInputBox.Focus();
Parent.As<UICanvas>().ReceivesEvents = true;
}
public void OnConsoleOpen()
{
Screen.CursorVisible = true;
Screen.CursorLock = CursorLockMode.None;
public void OnConsoleClose()
{
Console.Print("closed console");
Screen.CursorVisible = false;
Screen.CursorLock = CursorLockMode.Locked;
consoleInputBox.Focus();
Parent.As<UICanvas>().ReceivesEvents = true;
}
consoleInputBox.Defocus();
public void OnConsoleClose()
{
Console.Print("closed console");
Screen.CursorVisible = false;
Screen.CursorLock = CursorLockMode.Locked;
consoleInputBox.Defocus();
#if FLAX_EDITOR
Editor.Instance.Windows.GameWin.Focus();
Editor.Instance.Windows.GameWin.Focus();
#endif
Parent.As<UICanvas>().ReceivesEvents = false;
}
Parent.As<UICanvas>().ReceivesEvents = false;
}
public override void OnUpdate()
{
base.OnUpdate();
public override void OnUpdate()
{
base.OnUpdate();
if (!Console.IsOpen && Input.GetAction("ClearConsole"))
Console.Clear();
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;
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;
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;
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;
}
location.Y += Time.UnscaledDeltaTime * ConsoleSpeed;
if (location.Y > targetY)
location.Y = targetY;
}
rootControl.Control.Location = location;
rootControl.Control.Location = location;
if (Console.IsOpen)
{
consoleNotifyBox.Visible = false;
consoleInputBox.Visible = true;
}
else if (!Console.IsOpen)
{
int fontHeight = (int)(consoleNotifyBox.Font.GetFont().Height / Platform.DpiScale);
if (location.Y < (-conHeight * ConsoleHeight) + fontHeight)
{
consoleNotifyBox.Visible = true;
consoleInputBox.Visible = false;
}
}
}
}
if (Console.IsOpen)
{
consoleNotifyBox.Visible = false;
consoleInputBox.Visible = true;
}
else if (!Console.IsOpen)
{
int fontHeight = (int) (consoleNotifyBox.Font.GetFont().Height / Platform.DpiScale);
if (location.Y < (-conHeight * ConsoleHeight) + fontHeight)
{
consoleNotifyBox.Visible = true;
consoleInputBox.Visible = false;
}
}
}
}
public void OnPrint(string text)
{
int fontHeight = (int)(consoleNotifyBox.Font.GetFont().Height / Platform.DpiScale);
consoleNotifyBox.Height = Math.Min(ConsoleNotifyLines, Console.Lines.Count) * fontHeight;
}
public void OnPrint(string text)
{
int fontHeight = (int) (consoleNotifyBox.Font.GetFont().Height / Platform.DpiScale);
consoleNotifyBox.Height = Math.Min(ConsoleNotifyLines, Console.Lines.Count) * fontHeight;
}
public void SetInput(string text)
{
consoleInputBox.Text = text;
}
}
}
public void SetInput(string text)
{
consoleInputBox.Text = text;
}
}
}

View File

@@ -7,389 +7,392 @@ using FlaxEngine.GUI;
namespace Cabrito
{
// Mostly based on TextBox
public class ConsoleTextBoxBase : TextBoxBase
{
protected TextLayoutOptions _layout;
// Mostly based on TextBox
public class ConsoleTextBoxBase : TextBoxBase
{
protected TextLayoutOptions _layout;
/// <summary>
/// Gets or sets the text wrapping within the control bounds.
/// </summary>
[EditorDisplay("Style"), EditorOrder(2000), Tooltip("The text wrapping within the control bounds.")]
public TextWrapping Wrapping
{
get => _layout.TextWrapping;
set => _layout.TextWrapping = value;
}
/// <summary>
/// Gets or sets the text wrapping within the control bounds.
/// </summary>
[EditorDisplay("Style"), EditorOrder(2000), Tooltip("The text wrapping within the control bounds.")]
public TextWrapping Wrapping
{
get => _layout.TextWrapping;
set => _layout.TextWrapping = value;
}
/// <summary>
/// Gets or sets the font.
/// </summary>
[EditorDisplay("Style"), EditorOrder(2000)]
public FontReference Font { get; set; }
/// <summary>
/// Gets or sets the font.
/// </summary>
[EditorDisplay("Style"), EditorOrder(2000)]
public FontReference Font { get; set; }
/// <summary>
/// Gets or sets the color of the text.
/// </summary>
[EditorDisplay("Style"), EditorOrder(2000), Tooltip("The color of the text.")]
public Color TextColor { get; set; }
/// <summary>
/// Gets or sets the color of the text.
/// </summary>
[EditorDisplay("Style"), EditorOrder(2000), Tooltip("The color of the text.")]
public Color TextColor { get; set; }
/// <summary>
/// Gets or sets the color of the selection (Transparent if not used).
/// </summary>
[EditorDisplay("Style"), EditorOrder(2000), Tooltip("The color of the selection (Transparent if not used).")]
public Color SelectionColor { get; set; }
/// <summary>
/// Gets or sets the color of the selection (Transparent if not used).
/// </summary>
[EditorDisplay("Style"), EditorOrder(2000), Tooltip("The color of the selection (Transparent if not used).")]
public Color SelectionColor { get; set; }
[HideInEditor]
public virtual string TextPrefix { get; set; } = "";
[HideInEditor] public virtual string TextPrefix { get; set; } = "";
//[HideInEditor]
//public override string Text => _text;
//[HideInEditor]
//public override string Text => _text;
public ConsoleTextBoxBase() : base()
{
public ConsoleTextBoxBase() : base()
{
}
}
public ConsoleTextBoxBase(float x, float y, float width, float height) : base(false, x, y, width)
{
Height = height;
public ConsoleTextBoxBase(float x, float y, float width, float height) : base(false, x, y, width)
{
Height = height;
IsReadOnly = false;
CaretColor = new Color(1f, 1f, 1f, 1f);
AutoFocus = true;
IsReadOnly = false;
CaretColor = new Color(1f, 1f, 1f, 1f);
AutoFocus = true;
_layout = TextLayoutOptions.Default;
_layout.VerticalAlignment = IsMultiline ? TextAlignment.Near : TextAlignment.Center;
_layout.TextWrapping = TextWrapping.NoWrap;
_layout.Bounds = new Rectangle(0, 0, Width, Height);//new Rectangle(DefaultMargin, 1, Width - 2 * DefaultMargin, Height - 2);
_layout = TextLayoutOptions.Default;
_layout.VerticalAlignment = IsMultiline ? TextAlignment.Near : TextAlignment.Center;
_layout.TextWrapping = TextWrapping.NoWrap;
_layout.Bounds =
new Rectangle(0, 0, Width,
Height); //new Rectangle(DefaultMargin, 1, Width - 2 * DefaultMargin, Height - 2);
#if FLAX_EDITOR
var style = Style.Current;
if (style.FontMedium != null)
Font = new FontReference(style.FontMedium);
TextColor = style.Foreground;
SelectionColor = style.BackgroundSelected;
var style = Style.Current;
if (style.FontMedium != null)
Font = new FontReference(style.FontMedium);
TextColor = style.Foreground;
SelectionColor = style.BackgroundSelected;
#endif
}
}
/*protected override void SetText(string value)
{
// Prevent from null problems
if (value == null)
value = string.Empty;
/*protected override void SetText(string value)
{
// Prevent from null problems
if (value == null)
value = string.Empty;
// Filter text
if (value.IndexOf('\r') != -1)
value = value.Replace("\r", "");
// Filter text
if (value.IndexOf('\r') != -1)
value = value.Replace("\r", "");
// Clamp length
if (value.Length > MaxLength)
value = value.Substring(0, MaxLength);
// Clamp length
if (value.Length > MaxLength)
value = value.Substring(0, MaxLength);
// Ensure to use only single line
if (_isMultiline == false && value.Length > 0)
{
// Extract only the first line
value = value.GetLines()[0];
}
// Ensure to use only single line
if (_isMultiline == false && value.Length > 0)
{
// Extract only the first line
value = value.GetLines()[0];
}
if (Text != value)
{
Deselect();
ResetViewOffset();
if (Text != value)
{
Deselect();
ResetViewOffset();
Text = value;
Text = value;
OnTextChanged();
}
}*/
OnTextChanged();
}
}*/
public int GetFontHeight()
{
var font = Font.GetFont();
if (font == null)
return (int)Height;
public int GetFontHeight()
{
var font = Font.GetFont();
if (font == null)
return (int) Height;
return (int)Mathf.Round(font.Height * Scale.Y);
}
return (int) Mathf.Round(font.Height * Scale.Y);
}
public override void Clear()
{
// Can't clear the text while user is editing it...
var oldEditing = _isEditing;
_isEditing = false;
base.Clear();
_isEditing = oldEditing;
}
public override void Clear()
{
// Can't clear the text while user is editing it...
var oldEditing = _isEditing;
_isEditing = false;
base.Clear();
_isEditing = oldEditing;
}
public override void ResetViewOffset()
{
TargetViewOffset = new Vector2(0, 0);
}
public override void ResetViewOffset()
{
TargetViewOffset = new Vector2(0, 0);
}
/*public void ScrollToEnd()
{
float maxY = TextSize.Y - Height;
float spacing = GetRealLineSpacing();
maxY += spacing;
/*public void ScrollToEnd()
{
float maxY = TextSize.Y - Height;
float spacing = GetRealLineSpacing();
maxY += spacing;
TargetViewOffset = new Vector2(0, Math.Max(0, maxY));
}*/
TargetViewOffset = new Vector2(0, Math.Max(0, maxY));
}*/
public override void ScrollToCaret()
{
if (Text.Length == 0)
return;
public override void ScrollToCaret()
{
if (Text.Length == 0)
return;
Rectangle caretBounds = CaretBounds;
Rectangle caretBounds = CaretBounds;
float maxY = TextSize.Y - Height;
float maxY = TextSize.Y - Height;
Vector2 newLocation = CaretBounds.Location;
TargetViewOffset = Vector2.Clamp(newLocation, new Vector2(0, 0), new Vector2(_targetViewOffset.X, maxY));
}
Vector2 newLocation = CaretBounds.Location;
TargetViewOffset = Vector2.Clamp(newLocation, new Vector2(0, 0), new Vector2(_targetViewOffset.X, maxY));
}
/*const bool smoothScrolling = false;
/*const bool smoothScrolling = false;
public override bool OnMouseWheel(Vector2 location, float delta)
{
if (!IsMultiline || Text.Length == 0)
return false;
public override bool OnMouseWheel(Vector2 location, float delta)
{
if (!IsMultiline || Text.Length == 0)
return false;
if (!smoothScrolling)
delta = GetFontHeight() * Math.Sign(delta) * 3;
else
delta *= 30;
float maxY = TextSize.Y - Height;
float offset = GetRealLineSpacing();
maxY += offset;
TargetViewOffset = Vector2.Clamp(_targetViewOffset - new Vector2(0, delta), new Vector2(0, offset), new Vector2(_targetViewOffset.X, maxY));
return true;
}*/
if (!smoothScrolling)
delta = GetFontHeight() * Math.Sign(delta) * 3;
else
delta *= 30;
public override Vector2 GetTextSize()
{
var font = Font.GetFont();
if (font == null)
return Vector2.Zero;
float maxY = TextSize.Y - Height;
float offset = GetRealLineSpacing();
maxY += offset;
TargetViewOffset = Vector2.Clamp(_targetViewOffset - new Vector2(0, delta), new Vector2(0, offset), new Vector2(_targetViewOffset.X, maxY));
return true;
}*/
return font.MeasureText(Text, ref _layout);
}
public override Vector2 GetTextSize()
{
var font = Font.GetFont();
if (font == null)
return Vector2.Zero;
public override Vector2 GetCharPosition(int index, out float height)
{
var font = Font.GetFont();
if (font == null)
{
height = Height;
return Vector2.Zero;
}
return font.MeasureText(Text, ref _layout);
}
height = GetFontHeight();
return font.GetCharPosition(Text, index, ref _layout);
}
public override Vector2 GetCharPosition(int index, out float height)
{
var font = Font.GetFont();
if (font == null)
{
height = Height;
return Vector2.Zero;
}
public override int HitTestText(Vector2 location)
{
var font = Font.GetFont();
if (font == null)
return 0;
height = GetFontHeight();
return font.GetCharPosition(Text, index, ref _layout);
}
if (TextPrefix != "")
{
var prefixSize = font.MeasureText(TextPrefix);
location.X -= prefixSize.X;
}
public override int HitTestText(Vector2 location)
{
var font = Font.GetFont();
if (font == null)
return 0;
return font.HitTestText(Text, location, ref _layout);
}
if (TextPrefix != "")
{
var prefixSize = font.MeasureText(TextPrefix);
location.X -= prefixSize.X;
}
protected override void OnIsMultilineChanged()
{
base.OnIsMultilineChanged();
return font.HitTestText(Text, location, ref _layout);
}
_layout.VerticalAlignment = IsMultiline ? TextAlignment.Near : TextAlignment.Center;
}
protected override void OnIsMultilineChanged()
{
base.OnIsMultilineChanged();
public override bool OnKeyDown(KeyboardKeys key)
{
bool shiftDown = Root.GetKey(KeyboardKeys.Shift);
bool ctrlDown = Root.GetKey(KeyboardKeys.Control);
_layout.VerticalAlignment = IsMultiline ? TextAlignment.Near : TextAlignment.Center;
}
if (shiftDown && key == KeyboardKeys.Delete)
Cut();
else if (ctrlDown && key == KeyboardKeys.Insert)
Copy();
else if (shiftDown && key == KeyboardKeys.Insert)
Paste();
if (shiftDown && key == KeyboardKeys.Home)
{
if (!IsReadOnly)
SetSelection(_selectionStart, 0);
return true;
}
else if (shiftDown && key == KeyboardKeys.End)
{
if (!IsReadOnly)
SetSelection(_selectionStart, TextLength);
return true;
}
return base.OnKeyDown(key);
}
public override bool OnKeyDown(KeyboardKeys key)
{
bool shiftDown = Root.GetKey(KeyboardKeys.Shift);
bool ctrlDown = Root.GetKey(KeyboardKeys.Control);
bool doubleClicked = false;
System.Diagnostics.Stopwatch lastDoubleClick = new System.Diagnostics.Stopwatch();
Vector2 lastDoubleClickLocation = new Vector2(0, 0);
if (shiftDown && key == KeyboardKeys.Delete)
Cut();
else if (ctrlDown && key == KeyboardKeys.Insert)
Copy();
else if (shiftDown && key == KeyboardKeys.Insert)
Paste();
if (shiftDown && key == KeyboardKeys.Home)
{
if (!IsReadOnly)
SetSelection(_selectionStart, 0);
return true;
}
else if (shiftDown && key == KeyboardKeys.End)
{
if (!IsReadOnly)
SetSelection(_selectionStart, TextLength);
return true;
}
public override bool OnMouseDown(Vector2 location, MouseButton button)
{
if (doubleClicked && lastDoubleClick.Elapsed.TotalSeconds < 0.5 && location == lastDoubleClickLocation) // Windows defaults to 500ms window
{
doubleClicked = false;
if (OnMouseTripleClick(location, button))
return true;
}
return base.OnKeyDown(key);
}
return base.OnMouseDown(location, button);
}
bool doubleClicked = false;
System.Diagnostics.Stopwatch lastDoubleClick = new System.Diagnostics.Stopwatch();
Vector2 lastDoubleClickLocation = new Vector2(0, 0);
public override bool OnMouseDown(Vector2 location, MouseButton button)
{
if (doubleClicked && lastDoubleClick.Elapsed.TotalSeconds < 0.5 &&
location == lastDoubleClickLocation) // Windows defaults to 500ms window
{
doubleClicked = false;
if (OnMouseTripleClick(location, button))
return true;
}
return base.OnMouseDown(location, button);
}
public override bool OnMouseDoubleClick(Vector2 location, MouseButton button)
{
doubleClicked = true;
lastDoubleClick.Restart();
lastDoubleClickLocation = location;
public override bool OnMouseDoubleClick(Vector2 location, MouseButton button)
{
doubleClicked = true;
lastDoubleClick.Restart();
lastDoubleClickLocation = location;
return base.OnMouseDoubleClick(location, button);
}
return base.OnMouseDoubleClick(location, button);
}
public bool OnMouseTripleClick(Vector2 location, MouseButton button)
{
if (!IsMultiline)
SelectAll();
else
{
// TODO: select the line
SelectAll();
}
return true;
}
public bool OnMouseTripleClick(Vector2 location, MouseButton button)
{
if (!IsMultiline)
SelectAll();
else
{
// TODO: select the line
SelectAll();
}
protected override void OnSizeChanged()
{
base.OnSizeChanged();
return true;
}
_layout.Bounds = TextRectangle;
}
protected override void OnSizeChanged()
{
base.OnSizeChanged();
public override void Draw()
{
// Cache data
var rect = new Rectangle(Vector2.Zero, Size);
var font = Font.GetFont();
if (!font)
return;
_layout.Bounds = TextRectangle;
}
// Background
Color backColor = BackgroundColor;
if (IsMouseOver)
backColor = BackgroundSelectedColor;
if (backColor.A > 0.0f)
Render2D.FillRectangle(rect, backColor);
public override void Draw()
{
// Cache data
var rect = new Rectangle(Vector2.Zero, Size);
var font = Font.GetFont();
if (!font)
return;
Color borderColor = IsFocused ? BorderSelectedColor : BorderColor;
if (borderColor.A > 0.0f)
Render2D.DrawRectangle(rect, borderColor);
// Background
Color backColor = BackgroundColor;
if (IsMouseOver)
backColor = BackgroundSelectedColor;
if (backColor.A > 0.0f)
Render2D.FillRectangle(rect, backColor);
//string text = TextPrefix + Text;
string text = TextPrefix + Text;
Color borderColor = IsFocused ? BorderSelectedColor : BorderColor;
if (borderColor.A > 0.0f)
Render2D.DrawRectangle(rect, borderColor);
if (text.Length == 0)
return;
//string text = TextPrefix + Text;
string text = TextPrefix + Text;
// Apply view offset and clip mask
Render2D.PushClip(TextClipRectangle);
bool useViewOffset = !_viewOffset.IsZero;
if (useViewOffset)
Render2D.PushTransform(Matrix3x3.Translation2D(-_viewOffset));
if (text.Length == 0)
return;
// Check if any text is selected to draw selection
if (HasSelection)
{
Vector2 leftEdge = font.GetCharPosition(text, SelectionLeft + TextPrefix.Length, ref _layout);
Vector2 rightEdge = font.GetCharPosition(text, SelectionRight + TextPrefix.Length, ref _layout);
float fontHeight = GetFontHeight();
// Apply view offset and clip mask
Render2D.PushClip(TextClipRectangle);
bool useViewOffset = !_viewOffset.IsZero;
if (useViewOffset)
Render2D.PushTransform(Matrix3x3.Translation2D(-_viewOffset));
// Draw selection background
float alpha = Mathf.Min(1.0f, Mathf.Cos(_animateTime * BackgroundSelectedFlashSpeed) * 0.5f + 1.3f);
alpha = alpha * alpha;
Color selectionColor = SelectionColor * alpha;
// Check if any text is selected to draw selection
if (HasSelection)
{
Vector2 leftEdge = font.GetCharPosition(text, SelectionLeft + TextPrefix.Length, ref _layout);
Vector2 rightEdge = font.GetCharPosition(text, SelectionRight + TextPrefix.Length, ref _layout);
float fontHeight = GetFontHeight();
int selectedLinesCount = 1 + Mathf.FloorToInt((rightEdge.Y - leftEdge.Y) / fontHeight);
if (selectedLinesCount == 1) // Selected is part of single line
{
Rectangle r1 = new Rectangle(leftEdge.X, leftEdge.Y, rightEdge.X - leftEdge.X, fontHeight);
Render2D.FillRectangle(r1, selectionColor);
}
else // Selected is more than one line
{
float leftMargin = _layout.Bounds.Location.X;
Rectangle r1 = new Rectangle(leftEdge.X, leftEdge.Y, 1000000000, fontHeight);
Render2D.FillRectangle(r1, selectionColor);
// Draw selection background
float alpha = Mathf.Min(1.0f, Mathf.Cos(_animateTime * BackgroundSelectedFlashSpeed) * 0.5f + 1.3f);
alpha = alpha * alpha;
Color selectionColor = SelectionColor * alpha;
for (int i = 3; i <= selectedLinesCount; i++)
{
leftEdge.Y += fontHeight;
Rectangle r = new Rectangle(leftMargin, leftEdge.Y, 1000000000, fontHeight);
Render2D.FillRectangle(r, selectionColor);
}
int selectedLinesCount = 1 + Mathf.FloorToInt((rightEdge.Y - leftEdge.Y) / fontHeight);
if (selectedLinesCount == 1) // Selected is part of single line
{
Rectangle r1 = new Rectangle(leftEdge.X, leftEdge.Y, rightEdge.X - leftEdge.X, fontHeight);
Render2D.FillRectangle(r1, selectionColor);
}
else // Selected is more than one line
{
float leftMargin = _layout.Bounds.Location.X;
Rectangle r1 = new Rectangle(leftEdge.X, leftEdge.Y, 1000000000, fontHeight);
Render2D.FillRectangle(r1, selectionColor);
Rectangle r2 = new Rectangle(leftMargin, rightEdge.Y, rightEdge.X - leftMargin, fontHeight);
Render2D.FillRectangle(r2, selectionColor);
}
}
for (int i = 3; i <= selectedLinesCount; i++)
{
leftEdge.Y += fontHeight;
Rectangle r = new Rectangle(leftMargin, leftEdge.Y, 1000000000, fontHeight);
Render2D.FillRectangle(r, selectionColor);
}
Render2D.DrawText(font, text, TextColor, ref _layout);
Rectangle r2 = new Rectangle(leftMargin, rightEdge.Y, rightEdge.X - leftMargin, fontHeight);
Render2D.FillRectangle(r2, selectionColor);
}
}
if (CaretPosition > -1)
{
var prefixSize = TextPrefix != "" ? font.MeasureText(TextPrefix) : new Vector2();
var caretBounds = CaretBounds;
caretBounds.X += prefixSize.X;
Render2D.DrawText(font, text, TextColor, ref _layout);
float alpha = Mathf.Saturate(Mathf.Cos(_animateTime * CaretFlashSpeed) * 0.5f + 0.7f);
alpha = alpha * alpha * alpha * alpha * alpha * alpha;
Render2D.FillRectangle(caretBounds, CaretColor * alpha);
}
if (CaretPosition > -1)
{
var prefixSize = TextPrefix != "" ? font.MeasureText(TextPrefix) : new Vector2();
var caretBounds = CaretBounds;
caretBounds.X += prefixSize.X;
// Restore rendering state
if (useViewOffset)
Render2D.PopTransform();
Render2D.PopClip();
}
float alpha = Mathf.Saturate(Mathf.Cos(_animateTime * CaretFlashSpeed) * 0.5f + 0.7f);
alpha = alpha * alpha * alpha * alpha * alpha * alpha;
Render2D.FillRectangle(caretBounds, CaretColor * alpha);
}
public override void Paste()
{
if (IsReadOnly)
return;
// Restore rendering state
if (useViewOffset)
Render2D.PopTransform();
Render2D.PopClip();
}
var clipboardText = Clipboard.Text;
// Handle newlines in clipboard text
if (!string.IsNullOrEmpty(clipboardText))
{
// TODO: probably better to just split these lines and parse each line separately
clipboardText = clipboardText.Replace("\r\n", "");
clipboardText = clipboardText.Replace("\n", "");
}
public override void Paste()
{
if (IsReadOnly)
return;
if (!string.IsNullOrEmpty(clipboardText))
{
var right = SelectionRight;
Insert(clipboardText);
SetSelection(Mathf.Max(right, 0) + clipboardText.Length);
}
}
}
}
var clipboardText = Clipboard.Text;
// Handle newlines in clipboard text
if (!string.IsNullOrEmpty(clipboardText))
{
// TODO: probably better to just split these lines and parse each line separately
clipboardText = clipboardText.Replace("\r\n", "");
clipboardText = clipboardText.Replace("\n", "");
}
if (!string.IsNullOrEmpty(clipboardText))
{
var right = SelectionRight;
Insert(clipboardText);
SetSelection(Mathf.Max(right, 0) + clipboardText.Length);
}
}
}
}

View File

@@ -7,69 +7,69 @@ using System.Threading.Tasks;
namespace Cabrito
{
[Flags]
public enum ConsoleFlags
{
NoSerialize = 1, // Value does not persist
[Flags]
public enum ConsoleFlags
{
NoSerialize = 1, // Value does not persist
Alias = NoSerialize,
}
Alias = NoSerialize,
}
internal struct ConsoleVariable
{
public string name { get; private set; }
public ConsoleFlags flags { get; private set; }
internal struct ConsoleVariable
{
public string name { get; private set; }
public ConsoleFlags flags { get; private set; }
private FieldInfo field;
private MethodInfo getter;
private MethodInfo setter;
private FieldInfo field;
private MethodInfo getter;
private MethodInfo setter;
public ConsoleVariable(string name, ConsoleFlags flags, FieldInfo field)
{
this.name = name;
this.flags = flags;
this.field = field;
this.getter = null;
this.setter = null;
}
public ConsoleVariable(string name, ConsoleFlags flags, FieldInfo field)
{
this.name = name;
this.flags = flags;
this.field = field;
this.getter = null;
this.setter = null;
}
public ConsoleVariable(string name, ConsoleFlags flags, MethodInfo getter, MethodInfo setter)
{
this.name = name;
this.flags = flags;
this.field = null;
this.getter = getter;
this.setter = setter;
}
public ConsoleVariable(string name, ConsoleFlags flags, MethodInfo getter, MethodInfo setter)
{
this.name = name;
this.flags = flags;
this.field = null;
this.getter = getter;
this.setter = setter;
}
public string GetValueString()
{
var type = field != null ? field.FieldType : getter.ReturnType;
if (type == typeof(string))
{
if (field != null)
return (string)field.GetValue(null);
else if (setter != null)
return (string)getter.Invoke(null, null);
}
else
throw new Exception("cvar is not type of string");
public string GetValueString()
{
var type = field != null ? field.FieldType : getter.ReturnType;
if (type == typeof(string))
{
if (field != null)
return (string) field.GetValue(null);
else if (setter != null)
return (string) getter.Invoke(null, null);
}
else
throw new Exception("cvar is not type of string");
throw new Exception("GetValueString no field or getter specified");
}
throw new Exception("GetValueString no field or getter specified");
}
public void SetValue(string value)
{
var type = field != null ? field.FieldType : getter.ReturnType;
if (type == typeof(string))
{
if (field != null)
field.SetValue(null, value);
else if (setter != null)
setter.Invoke(null, new object[] { value });
}
else
throw new Exception("Unsupported type for SetValue: " + type.Name);
}
}
}
public void SetValue(string value)
{
var type = field != null ? field.FieldType : getter.ReturnType;
if (type == typeof(string))
{
if (field != null)
field.SetValue(null, value);
else if (setter != null)
setter.Invoke(null, new object[] {value});
}
else
throw new Exception("Unsupported type for SetValue: " + type.Name);
}
}
}