mirror of
https://github.com/GrahamKracker/UnityExplorer.git
synced 2025-07-02 11:32:29 +08:00
Only lexer-highlight what is shown in CS console (fix max vert overflow)
This commit is contained in:
@ -6,6 +6,7 @@ using System.Text;
|
|||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityExplorer.UI.IValues;
|
using UnityExplorer.UI.IValues;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using UnityExplorer.UI;
|
||||||
#if CPP
|
#if CPP
|
||||||
using UnhollowerRuntimeLib;
|
using UnhollowerRuntimeLib;
|
||||||
using UnhollowerBaseLib;
|
using UnhollowerBaseLib;
|
||||||
@ -70,6 +71,9 @@ namespace UnityExplorer.Tests
|
|||||||
|
|
||||||
public static TestValueStruct AATestStruct;
|
public static TestValueStruct AATestStruct;
|
||||||
|
|
||||||
|
public static string AAATooLongString = new string('#', UIManager.MAX_INPUTFIELD_CHARS + 2);
|
||||||
|
public static string AAAMaxString = new string('@', UIManager.MAX_INPUTFIELD_CHARS);
|
||||||
|
|
||||||
public static TestEnum AATestEnumOne = TestEnum.Neg50;
|
public static TestEnum AATestEnumOne = TestEnum.Neg50;
|
||||||
public static TestEnum2 AATestEnumTwo = TestEnum2.Max;
|
public static TestEnum2 AATestEnumTwo = TestEnum2.Max;
|
||||||
public static TestFlags AATestFlags = TestFlags.Thirteen;
|
public static TestFlags AATestFlags = TestFlags.Thirteen;
|
||||||
|
@ -61,7 +61,7 @@ The following helper methods are available:
|
|||||||
private static HashSet<string> usingDirectives;
|
private static HashSet<string> usingDirectives;
|
||||||
|
|
||||||
private static CSConsolePanel Panel => UIManager.CSharpConsole;
|
private static CSConsolePanel Panel => UIManager.CSharpConsole;
|
||||||
private static InputField InputField => Panel.InputField.InputField;
|
private static InputFieldRef Input => Panel.Input;
|
||||||
|
|
||||||
// Todo save as config?
|
// Todo save as config?
|
||||||
public static bool EnableCtrlRShortcut { get; private set; } = true;
|
public static bool EnableCtrlRShortcut { get; private set; } = true;
|
||||||
@ -78,7 +78,8 @@ The following helper methods are available:
|
|||||||
Evaluator.Compile("0 == 0");
|
Evaluator.Compile("0 == 0");
|
||||||
|
|
||||||
Panel.OnInputChanged += OnConsoleInputChanged;
|
Panel.OnInputChanged += OnConsoleInputChanged;
|
||||||
// TODO other panel listeners
|
Panel.InputScroll.OnScroll += ForceOnContentChange;
|
||||||
|
// TODO other panel listeners (buttons, etc)
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@ -87,6 +88,123 @@ The following helper methods are available:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Updating and event listeners
|
||||||
|
|
||||||
|
private static readonly KeyCode[] onFocusKeys =
|
||||||
|
{
|
||||||
|
KeyCode.Return, KeyCode.Backspace, KeyCode.UpArrow,
|
||||||
|
KeyCode.DownArrow, KeyCode.LeftArrow, KeyCode.RightArrow
|
||||||
|
};
|
||||||
|
|
||||||
|
public static void Update()
|
||||||
|
{
|
||||||
|
if (EnableCtrlRShortcut)
|
||||||
|
{
|
||||||
|
if ((InputManager.GetKey(KeyCode.LeftControl) || InputManager.GetKey(KeyCode.RightControl))
|
||||||
|
&& InputManager.GetKeyDown(KeyCode.R))
|
||||||
|
{
|
||||||
|
var text = Panel.Input.Text.Trim();
|
||||||
|
if (!string.IsNullOrEmpty(text))
|
||||||
|
{
|
||||||
|
Evaluate(text);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//if (EnableAutoIndent && InputManager.GetKeyDown(KeyCode.Return))
|
||||||
|
// DoAutoIndent();
|
||||||
|
|
||||||
|
//if (EnableAutocompletes && InputField.isFocused)
|
||||||
|
//{
|
||||||
|
// if (InputManager.GetMouseButton(0) || onFocusKeys.Any(it => InputManager.GetKeyDown(it)))
|
||||||
|
// UpdateAutocompletes();
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ForceOnContentChange()
|
||||||
|
{
|
||||||
|
OnConsoleInputChanged(Input.Text);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoked at most once per frame
|
||||||
|
private static void OnConsoleInputChanged(string value)
|
||||||
|
{
|
||||||
|
// todo auto indent? or only on enter?
|
||||||
|
|
||||||
|
// syntax highlight
|
||||||
|
LexerHighlightAndSet(value);
|
||||||
|
|
||||||
|
|
||||||
|
// todo update auto completes
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void LexerHighlightAndSet(string value)
|
||||||
|
{
|
||||||
|
int startLine = 0;
|
||||||
|
int endLine = Input.TextGenerator.lineCount - 1;
|
||||||
|
|
||||||
|
if (Input.Rect.rect.height > Panel.InputScroll.ViewportRect.rect.height)
|
||||||
|
{
|
||||||
|
// Not all text is displayed.
|
||||||
|
// Only syntax highlight what we need to.
|
||||||
|
|
||||||
|
int topLine = -1;
|
||||||
|
int bottomLine = -1;
|
||||||
|
var half = Input.Rect.rect.height * 0.5f;
|
||||||
|
|
||||||
|
var top = Input.Rect.rect.height - Input.Rect.anchoredPosition.y;
|
||||||
|
var bottom = top - Panel.InputScroll.ViewportRect.rect.height;
|
||||||
|
|
||||||
|
for (int i = 0; i < Input.TextGenerator.lineCount; i++)
|
||||||
|
{
|
||||||
|
var line = Input.TextGenerator.lines[i];
|
||||||
|
var pos = line.topY + half;
|
||||||
|
|
||||||
|
if (topLine == -1 && pos <= top)
|
||||||
|
topLine = i;
|
||||||
|
|
||||||
|
if ((pos - line.height) >= bottom)
|
||||||
|
bottomLine = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
startLine = Math.Max(0, topLine - 1);
|
||||||
|
endLine = Math.Min(Input.TextGenerator.lineCount - 1, bottomLine + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int startIdx = Input.TextGenerator.lines[startLine].startCharIdx;
|
||||||
|
int endIdx;
|
||||||
|
if (endLine >= Input.TextGenerator.lineCount - 1)
|
||||||
|
endIdx = value.Length - 1;
|
||||||
|
else
|
||||||
|
endIdx = Math.Min(value.Length - 1, Input.TextGenerator.lines[endLine + 1].startCharIdx);
|
||||||
|
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
for (int i = 0; i < startLine; i++)
|
||||||
|
sb.Append('\n');
|
||||||
|
for (int i = startIdx; i <= endIdx; i++)
|
||||||
|
sb.Append(value[i]);
|
||||||
|
|
||||||
|
Panel.HighlightText.text = Lexer.SyntaxHighlight(sb.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// TODO indenting
|
||||||
|
|
||||||
|
//private static void DoAutoIndent()
|
||||||
|
//{
|
||||||
|
// int caret = Panel.LastCaretPosition;
|
||||||
|
// Panel.InputField.Text = Lexer.AutoIndentOnEnter(InputField.text, ref caret);
|
||||||
|
// InputField.caretPosition = caret;
|
||||||
|
//
|
||||||
|
// Panel.InputText.Rebuild(CanvasUpdate.Prelayout);
|
||||||
|
// InputField.ForceLabelUpdate();
|
||||||
|
// InputField.Rebuild(CanvasUpdate.Prelayout);
|
||||||
|
//
|
||||||
|
// OnConsoleInputChanged(InputField.text);
|
||||||
|
//}
|
||||||
|
|
||||||
#region Evaluating console input
|
#region Evaluating console input
|
||||||
|
|
||||||
public static void ResetConsole(bool logSuccess = true)
|
public static void ResetConsole(bool logSuccess = true)
|
||||||
@ -149,65 +267,5 @@ The following helper methods are available:
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
// Updating and event listeners
|
|
||||||
|
|
||||||
private static readonly KeyCode[] onFocusKeys =
|
|
||||||
{
|
|
||||||
KeyCode.Return, KeyCode.Backspace, KeyCode.UpArrow,
|
|
||||||
KeyCode.DownArrow, KeyCode.LeftArrow, KeyCode.RightArrow
|
|
||||||
};
|
|
||||||
|
|
||||||
public static void Update()
|
|
||||||
{
|
|
||||||
if (EnableCtrlRShortcut)
|
|
||||||
{
|
|
||||||
if ((InputManager.GetKey(KeyCode.LeftControl) || InputManager.GetKey(KeyCode.RightControl))
|
|
||||||
&& InputManager.GetKeyDown(KeyCode.R))
|
|
||||||
{
|
|
||||||
var text = Panel.InputField.Text.Trim();
|
|
||||||
if (!string.IsNullOrEmpty(text))
|
|
||||||
{
|
|
||||||
Evaluate(text);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//if (EnableAutoIndent && InputManager.GetKeyDown(KeyCode.Return))
|
|
||||||
// DoAutoIndent();
|
|
||||||
|
|
||||||
//if (EnableAutocompletes && InputField.isFocused)
|
|
||||||
//{
|
|
||||||
// if (InputManager.GetMouseButton(0) || onFocusKeys.Any(it => InputManager.GetKeyDown(it)))
|
|
||||||
// UpdateAutocompletes();
|
|
||||||
//}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Invoked at most once per frame
|
|
||||||
private static void OnConsoleInputChanged(string input)
|
|
||||||
{
|
|
||||||
// todo update auto completes
|
|
||||||
|
|
||||||
// update syntax highlight
|
|
||||||
Panel.HighlightText.text = Lexer.SyntaxHighlight(input);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO?
|
|
||||||
//private static void DoAutoIndent()
|
|
||||||
//{
|
|
||||||
// int caret = Panel.LastCaretPosition;
|
|
||||||
// Panel.InputField.Text = Lexer.AutoIndentOnEnter(InputField.text, ref caret);
|
|
||||||
// InputField.caretPosition = caret;
|
|
||||||
//
|
|
||||||
// Panel.InputText.Rebuild(CanvasUpdate.Prelayout);
|
|
||||||
// InputField.ForceLabelUpdate();
|
|
||||||
// InputField.Rebuild(CanvasUpdate.Prelayout);
|
|
||||||
//
|
|
||||||
// OnConsoleInputChanged(InputField.text);
|
|
||||||
//}
|
|
||||||
|
|
||||||
// Autocompletes
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ namespace UnityExplorer.UI.IValues
|
|||||||
{
|
{
|
||||||
if (s == null)
|
if (s == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return s.Length >= UIManager.MAX_INPUTFIELD_CHARS;
|
return s.Length >= UIManager.MAX_INPUTFIELD_CHARS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ namespace UnityExplorer.UI
|
|||||||
|
|
||||||
public InputField InputField;
|
public InputField InputField;
|
||||||
public Text PlaceholderText;
|
public Text PlaceholderText;
|
||||||
private readonly RectTransform Rect;
|
public RectTransform Rect;
|
||||||
|
|
||||||
public string Text
|
public string Text
|
||||||
{
|
{
|
||||||
@ -30,6 +30,9 @@ namespace UnityExplorer.UI
|
|||||||
set => InputField.text = value;
|
set => InputField.text = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool ReachedMaxVerts => TextGenerator.vertexCount >= UIManager.MAX_TEXT_VERTS;
|
||||||
|
public TextGenerator TextGenerator => InputField.cachedInputTextGenerator;
|
||||||
|
|
||||||
private bool updatedWanted;
|
private bool updatedWanted;
|
||||||
|
|
||||||
private void OnInputChanged(string value)
|
private void OnInputChanged(string value)
|
||||||
@ -41,7 +44,8 @@ namespace UnityExplorer.UI
|
|||||||
{
|
{
|
||||||
if (updatedWanted)
|
if (updatedWanted)
|
||||||
{
|
{
|
||||||
LayoutRebuilder.ForceRebuildLayoutImmediate(Rect);
|
//LayoutRebuilder.ForceRebuildLayoutImmediate(Rect);
|
||||||
|
LayoutRebuilder.MarkLayoutForRebuild(Rect);
|
||||||
|
|
||||||
OnValueChanged?.Invoke(InputField.text);
|
OnValueChanged?.Invoke(InputField.text);
|
||||||
updatedWanted = false;
|
updatedWanted = false;
|
||||||
|
@ -18,7 +18,8 @@ namespace UnityExplorer.UI.Panels
|
|||||||
public override int MinWidth => 400;
|
public override int MinWidth => 400;
|
||||||
public override int MinHeight => 300;
|
public override int MinHeight => 300;
|
||||||
|
|
||||||
public InputFieldRef InputField { get; private set; }
|
public InputFieldScroller InputScroll { get; private set; }
|
||||||
|
public InputFieldRef Input => InputScroll.InputField;
|
||||||
public Text InputText { get; private set; }
|
public Text InputText { get; private set; }
|
||||||
public Text HighlightText { get; private set; }
|
public Text HighlightText { get; private set; }
|
||||||
|
|
||||||
@ -37,19 +38,20 @@ namespace UnityExplorer.UI.Panels
|
|||||||
|
|
||||||
public void UseSuggestion(string suggestion)
|
public void UseSuggestion(string suggestion)
|
||||||
{
|
{
|
||||||
string input = InputField.Text;
|
string input = Input.Text;
|
||||||
input = input.Insert(LastCaretPosition, suggestion);
|
input = input.Insert(LastCaretPosition, suggestion);
|
||||||
InputField.Text = input;
|
Input.Text = input;
|
||||||
|
|
||||||
m_desiredCaretFix = LastCaretPosition += suggestion.Length;
|
m_desiredCaretFix = LastCaretPosition += suggestion.Length;
|
||||||
|
|
||||||
var color = InputField.InputField.selectionColor;
|
var color = Input.InputField.selectionColor;
|
||||||
color.a = 0f;
|
color.a = 0f;
|
||||||
InputField.InputField.selectionColor = color;
|
Input.InputField.selectionColor = color;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InvokeOnValueChanged(string value)
|
private void InvokeOnValueChanged(string value)
|
||||||
{
|
{
|
||||||
|
// Todo show a label instead of just logging
|
||||||
if (value.Length == UIManager.MAX_INPUTFIELD_CHARS)
|
if (value.Length == UIManager.MAX_INPUTFIELD_CHARS)
|
||||||
ExplorerCore.LogWarning($"Reached maximum InputField character length! ({UIManager.MAX_INPUTFIELD_CHARS})");
|
ExplorerCore.LogWarning($"Reached maximum InputField character length! ({UIManager.MAX_INPUTFIELD_CHARS})");
|
||||||
|
|
||||||
@ -66,23 +68,23 @@ namespace UnityExplorer.UI.Panels
|
|||||||
{
|
{
|
||||||
if (!m_fixWaiting)
|
if (!m_fixWaiting)
|
||||||
{
|
{
|
||||||
EventSystem.current.SetSelectedGameObject(InputField.UIRoot, null);
|
EventSystem.current.SetSelectedGameObject(InputScroll.UIRoot, null);
|
||||||
m_fixWaiting = true;
|
m_fixWaiting = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
InputField.InputField.caretPosition = m_desiredCaretFix;
|
Input.InputField.caretPosition = m_desiredCaretFix;
|
||||||
InputField.InputField.selectionFocusPosition = m_desiredCaretFix;
|
Input.InputField.selectionFocusPosition = m_desiredCaretFix;
|
||||||
var color = InputField.InputField.selectionColor;
|
var color = Input.InputField.selectionColor;
|
||||||
color.a = m_defaultInputFieldAlpha;
|
color.a = m_defaultInputFieldAlpha;
|
||||||
InputField.InputField.selectionColor = color;
|
Input.InputField.selectionColor = color;
|
||||||
|
|
||||||
m_fixWaiting = false;
|
m_fixWaiting = false;
|
||||||
m_desiredCaretFix = -1;
|
m_desiredCaretFix = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (InputField.InputField.caretPosition > 0)
|
else if (Input.InputField.caretPosition > 0)
|
||||||
LastCaretPosition = InputField.InputField.caretPosition;
|
LastCaretPosition = Input.InputField.caretPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Saving
|
// Saving
|
||||||
@ -150,14 +152,14 @@ namespace UnityExplorer.UI.Panels
|
|||||||
int fontSize = 16;
|
int fontSize = 16;
|
||||||
|
|
||||||
var inputObj = UIFactory.CreateSrollInputField(this.content, "ConsoleInput", CSConsole.STARTUP_TEXT, out var inputScroller, fontSize);
|
var inputObj = UIFactory.CreateSrollInputField(this.content, "ConsoleInput", CSConsole.STARTUP_TEXT, out var inputScroller, fontSize);
|
||||||
InputField = inputScroller.InputField;
|
InputScroll = inputScroller;
|
||||||
m_defaultInputFieldAlpha = InputField.InputField.selectionColor.a;
|
m_defaultInputFieldAlpha = Input.InputField.selectionColor.a;
|
||||||
InputField.OnValueChanged += InvokeOnValueChanged;
|
Input.OnValueChanged += InvokeOnValueChanged;
|
||||||
|
|
||||||
var placeHolderText = InputField.PlaceholderText;
|
var placeHolderText = Input.PlaceholderText;
|
||||||
placeHolderText.fontSize = fontSize;
|
placeHolderText.fontSize = fontSize;
|
||||||
|
|
||||||
InputText = InputField.InputField.textComponent;
|
InputText = Input.InputField.textComponent;
|
||||||
InputText.supportRichText = false;
|
InputText.supportRichText = false;
|
||||||
InputText.color = new Color(1, 1, 1, 0.65f);
|
InputText.color = new Color(1, 1, 1, 0.65f);
|
||||||
|
|
||||||
|
@ -58,6 +58,7 @@ namespace UnityExplorer.UI
|
|||||||
internal static readonly Color disabledButtonColor = new Color(0.25f, 0.25f, 0.25f);
|
internal static readonly Color disabledButtonColor = new Color(0.25f, 0.25f, 0.25f);
|
||||||
|
|
||||||
public const int MAX_INPUTFIELD_CHARS = 16000;
|
public const int MAX_INPUTFIELD_CHARS = 16000;
|
||||||
|
public const int MAX_TEXT_VERTS = 65000;
|
||||||
|
|
||||||
public static UIPanel GetPanel(Panels panel)
|
public static UIPanel GetPanel(Panels panel)
|
||||||
{
|
{
|
||||||
|
@ -25,6 +25,8 @@ namespace UnityExplorer.UI.Utility
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Action OnScroll;
|
||||||
|
|
||||||
internal AutoSliderScrollbar Slider;
|
internal AutoSliderScrollbar Slider;
|
||||||
internal InputFieldRef InputField;
|
internal InputFieldRef InputField;
|
||||||
|
|
||||||
@ -52,25 +54,40 @@ namespace UnityExplorer.UI.Utility
|
|||||||
internal bool m_wantJumpToBottom;
|
internal bool m_wantJumpToBottom;
|
||||||
private float m_desiredContentHeight;
|
private float m_desiredContentHeight;
|
||||||
|
|
||||||
|
private float lastContentPosition;
|
||||||
|
private float lastViewportHeight;
|
||||||
|
|
||||||
public override void Update()
|
public override void Update()
|
||||||
{
|
{
|
||||||
|
if (this.ContentRect.localPosition.y != lastContentPosition)
|
||||||
|
{
|
||||||
|
lastContentPosition = ContentRect.localPosition.y;
|
||||||
|
OnScroll?.Invoke();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ViewportRect.rect.height != lastViewportHeight)
|
||||||
|
{
|
||||||
|
lastViewportHeight = ViewportRect.rect.height;
|
||||||
|
m_updateWanted = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (m_updateWanted)
|
if (m_updateWanted)
|
||||||
{
|
{
|
||||||
m_updateWanted = false;
|
m_updateWanted = false;
|
||||||
ProcessInputText();
|
ProcessInputText();
|
||||||
}
|
|
||||||
|
|
||||||
float desiredHeight = Math.Max(m_desiredContentHeight, ViewportRect.rect.height);
|
float desiredHeight = Math.Max(m_desiredContentHeight, ViewportRect.rect.height);
|
||||||
|
|
||||||
if (ContentRect.rect.height < desiredHeight)
|
if (ContentRect.rect.height < desiredHeight)
|
||||||
{
|
{
|
||||||
ContentRect.sizeDelta = new Vector2(0, desiredHeight);
|
ContentRect.sizeDelta = new Vector2(0, desiredHeight);
|
||||||
this.Slider.UpdateSliderHandle();
|
this.Slider.UpdateSliderHandle();
|
||||||
}
|
}
|
||||||
else if (ContentRect.rect.height > desiredHeight)
|
else if (ContentRect.rect.height > desiredHeight)
|
||||||
{
|
{
|
||||||
ContentRect.sizeDelta = new Vector2(0, desiredHeight);
|
ContentRect.sizeDelta = new Vector2(0, desiredHeight);
|
||||||
this.Slider.UpdateSliderHandle();
|
this.Slider.UpdateSliderHandle();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_wantJumpToBottom)
|
if (m_wantJumpToBottom)
|
||||||
@ -100,6 +117,9 @@ namespace UnityExplorer.UI.Utility
|
|||||||
var textGen = InputField.InputField.textComponent.cachedTextGeneratorForLayout;
|
var textGen = InputField.InputField.textComponent.cachedTextGeneratorForLayout;
|
||||||
m_desiredContentHeight = textGen.GetPreferredHeight(m_lastText, texGenSettings) + 10;
|
m_desiredContentHeight = textGen.GetPreferredHeight(m_lastText, texGenSettings) + 10;
|
||||||
|
|
||||||
|
// TODO more intelligent jump.
|
||||||
|
// We can detect if the caret is outside the viewport area.
|
||||||
|
|
||||||
// jump to bottom
|
// jump to bottom
|
||||||
if (InputField.InputField.caretPosition == InputField.Text.Length
|
if (InputField.InputField.caretPosition == InputField.Text.Length
|
||||||
&& InputField.Text.Length > 0
|
&& InputField.Text.Length > 0
|
||||||
|
Reference in New Issue
Block a user