This commit is contained in:
GoaLitiuM
2021-02-28 21:55:41 +02:00
parent deae939fef
commit edb2180c65
6 changed files with 223 additions and 128 deletions

View File

@@ -75,6 +75,7 @@ namespace Cabrito
{
public int lineIndex;
public int lineOffset;
public int lineLength;
}
private void CalculateVisibleLines(IReadOnlyCollection<string> lines, out int firstVisibleLine, out int lastVisibleLine, out LineInfo[] wrappedLines)
@@ -92,19 +93,23 @@ namespace Cabrito
int lineMaxLines = (int)(Height / (font.Height / Platform.DpiScale)); // number of fully visible lines
int numLines = 0;
int lineIndex = lines.Count - 1;
List<LineInfo> lineInfos = new List<LineInfo>(lineMaxLines);
List<LineInfo> lineInfos = new List<LineInfo>(lineMaxLines+1);
foreach (string line in lines.Reverse())
{
int numChars = 0;
int startIndex = lineInfos.Count;
while (numChars < line.Length)
{
LineInfo li = new LineInfo();
li.lineIndex = lineIndex;
li.lineOffset = numChars;
li.lineLength = Math.Min(line.Length - numChars, lineMaxChars);
lineInfos.Add(li);
numChars += lineMaxChars;
}
if (lineInfos.Count - startIndex > 1)
lineInfos.Reverse(startIndex, lineInfos.Count - startIndex);
numLines++;
lineIndex--;
@@ -200,6 +205,7 @@ namespace Cabrito
float lineHeight = font.Height / Platform.DpiScale;
float accumHeight = wrappedLines.Length * lineHeight;
// selection in line-space, wrapping ignored
int selectionLeftLine = selectionStartLine;
int selectionLeftChar = selectionStartChar;
int selectionRightLine = selectionEndLine;
@@ -223,29 +229,35 @@ namespace Cabrito
TextLayoutOptions layout = _layout;
layout.Bounds.Y -= accumHeight - Height;
for (int i = startLine; i < lastLine; i++)
//for (int i = startLine; i < lastLine; i++)
foreach (LineInfo li in wrappedLines)
{
string line = lines.ElementAt(i);
var lineIndex = li.lineIndex;
string fullLine = lines.ElementAt(lineIndex);
string line = fullLine.Substring(li.lineOffset, li.lineLength);
int leftChar = selectionLeftChar;
int rightChar = selectionRightChar;
Rectangle selectionRect = new Rectangle(layout.Bounds.X, layout.Bounds.Y, 0f, 0f);
// apply selection
if (i >= selectionLeftLine && i <= selectionRightLine)
if (lineIndex >= selectionLeftLine && lineIndex <= selectionRightLine)
{
if (i > selectionLeftLine && i < selectionRightLine)
if (lineIndex > selectionLeftLine && lineIndex < selectionRightLine)
{
// whole line is selected
Vector2 lineSize = font.MeasureText(line);
selectionRect.Width = lineSize.X;
selectionRect.Height = lineSize.Y;
}
else if (i == selectionLeftLine)
else if (lineIndex == selectionLeftLine)
{
if (i < selectionRightLine)
if (lineIndex < selectionRightLine)
{
// right side of the line is selected
Vector2 leftSize = font.MeasureText(line.Substring(0, selectionLeftChar));
Vector2 rightSize = font.MeasureText(line.Substring(selectionLeftChar));
Vector2 leftSize = font.MeasureText(fullLine.Substring(0, leftChar));
Vector2 rightSize = font.MeasureText(fullLine.Substring(leftChar));
selectionRect.X += leftSize.X;
selectionRect.Width = rightSize.X;
selectionRect.Height = rightSize.Y;
@@ -253,25 +265,25 @@ namespace Cabrito
//int diff = line.Length - selectionLeftChar;
//line = line.Substring(0, selectionLeftChar) + (diff > 0 ? new string('X', diff) : "");
}
else if (i == selectionRightLine)
else if (lineIndex == selectionRightLine && leftChar != rightChar)
{
// selecting middle of the one line
Vector2 lineSize = font.MeasureText(line);
Vector2 leftSize = font.MeasureText(line.Substring(0, selectionLeftChar));
Vector2 rightSize = font.MeasureText(line.Substring(selectionRightChar));
Vector2 lineSize = font.MeasureText(fullLine);
Vector2 leftSize = font.MeasureText(fullLine.Substring(0, leftChar));
Vector2 midSize = font.MeasureText(fullLine.Substring(leftChar, rightChar-leftChar));
selectionRect.X += leftSize.X;
selectionRect.Width = lineSize.X - (leftSize.X + rightSize.Y);
selectionRect.Width = midSize.X;
selectionRect.Height = lineSize.Y;
//int diff = selectionRightChar - selectionLeftChar;
//line = line.Substring(0, selectionLeftChar) + (diff > 0 ? new string('X', diff) : "") + line.Substring(selectionRightChar);
}
}
else if (i == selectionRightLine)
else if (lineIndex == selectionRightLine)
{
// left side of the line is selected
Vector2 leftSize = font.MeasureText(line.Substring(0, selectionRightChar));
Vector2 leftSize = font.MeasureText(fullLine.Substring(0, rightChar));
selectionRect.Width = leftSize.X;
selectionRect.Height = leftSize.Y;
@@ -290,9 +302,10 @@ namespace Cabrito
{
TextLayoutOptions layout = _layout;
layout.Bounds.Y -= accumHeight - Height;
for (int i = startLine; i < lastLine; i++)
{
string line = lines.ElementAt(i);
foreach (LineInfo li in wrappedLines)
{
var lineIndex = li.lineIndex;
string line = lines.ElementAt(lineIndex).Substring(li.lineOffset, li.lineLength);
Render2D.DrawText(font, line, TextColor, ref layout);
layout.Bounds.Y += lineHeight;
}
@@ -369,7 +382,7 @@ namespace Cabrito
return false;
hitLine = wrappedLines[hitWrappedLine].lineIndex;
string line = lines.ElementAt(hitLine);
string line = lines.ElementAt(hitLine).Substring(wrappedLines[hitWrappedLine].lineOffset, wrappedLines[hitWrappedLine].lineLength);
layout.Bounds.Y = top + ((hitWrappedLine) * lineHeight);
layout.Bounds.Height = top + 9999;//(visibleHeight / Platform.DpiScale);
@@ -379,8 +392,9 @@ namespace Cabrito
}*/
hitChar = font.HitTestText(line, location, ref layout);
hitChar += wrappedLines[hitWrappedLine].lineOffset;
FlaxEngine.Debug.Log(string.Format("hit line {0}/{1}, max lines {2}", hitWrappedLine, wrappedLines.Length, lineMaxLines));
//FlaxEngine.Debug.Log(string.Format("hit line {0}/{1}, char {2}", hitWrappedLine, wrappedLines.Length, hitChar));
return true;
}
@@ -389,6 +403,20 @@ namespace Cabrito
return HitTestText(location + _viewOffset);
}*/
public override bool OnKeyDown(KeyboardKeys key)
{
bool shiftDown = Root.GetKey(KeyboardKeys.Shift);
bool ctrlDown = Root.GetKey(KeyboardKeys.Control);
if ((shiftDown && key == KeyboardKeys.Delete) || (ctrlDown && key == KeyboardKeys.Insert) || (ctrlDown && key == KeyboardKeys.C) || (ctrlDown && key == KeyboardKeys.X))
{
Copy();
return true;
}
//else if (ctrlDown && key == KeyboardKeys.A)
// SelectAll();
return base.OnKeyDown(key);
}
public override bool OnMouseDown(Vector2 location, MouseButton button)
{
@@ -414,6 +442,7 @@ namespace Cabrito
selectionStartChar = hitChar;
selectionEndLine = hitLine;
selectionEndChar = hitChar;
FlaxEngine.Debug.Log(string.Format("start line {0} char {1}", hitLine, hitChar));
}
else
throw new Exception("no???");
@@ -446,126 +475,96 @@ namespace Cabrito
{
selectionEndLine = hitLine;
selectionEndChar = hitChar;
FlaxEngine.Debug.Log(string.Format("end line {0} char {1}", hitLine, hitChar));
}
}
}
/// <inheritdoc />
public override bool OnMouseUp(Vector2 location, MouseButton button)
{
if (button == MouseButton.Left)
{
OnSelectingEnd();
Focus(inputBox);
return true;
}
return false;
}
}
#if false
public class ConsoleContentTextBox_Old : ConsoleTextBoxBase
{
[HideInEditor]
public ConsoleInputTextBox inputBox;
private string _textCache;
private long _textCacheLines;
public override string Text
protected void Copy()
{
get
if (!selectionActive)
return;
// selection in line-space, wrapping ignored
int selectionLeftLine = selectionStartLine;
int selectionLeftChar = selectionStartChar;
int selectionRightLine = selectionEndLine;
int selectionRightChar = selectionEndChar;
if (selectionLeftLine > selectionRightLine || (selectionLeftLine == selectionRightLine && selectionLeftChar > selectionRightChar))
{
var lines = Console.GetLines();
if (_textCache == null || _textCacheLines != lines.Count)
selectionLeftLine = selectionEndLine;
selectionLeftChar = selectionEndChar;
selectionRightLine = selectionStartLine;
selectionRightChar = selectionStartChar;
}
var lines = Console.GetLines();
CalculateVisibleLines(lines, out int startLine, out int lastLine, out LineInfo[] wrappedLines);
StringBuilder selectedText = new StringBuilder();
int lastLineIndex = -1;
foreach (LineInfo li in wrappedLines)
{
var lineIndex = li.lineIndex;
if (lineIndex < selectionLeftLine || lineIndex > selectionRightLine)
continue;
if (lastLineIndex != lineIndex && lastLineIndex != -1)
selectedText.AppendLine();
lastLineIndex = lineIndex;
string fullLine = lines.ElementAt(lineIndex);
string line = fullLine.Substring(li.lineOffset, li.lineLength);
int leftChar = selectionLeftChar;
int rightChar = selectionRightChar;
if (lineIndex >= selectionLeftLine && lineIndex <= selectionRightLine)
{
//Deselect();
//ResetViewOffset();
_textCache = string.Join("\n", lines);
_textCacheLines = lines.Count;
OnTextChanged();
if (lineIndex > selectionLeftLine && lineIndex < selectionRightLine)
{
// whole line is selected
selectedText.Append(line);
}
else if (lineIndex == selectionLeftLine)
{
if (lineIndex < selectionRightLine)
{
// right side of the line is selected
selectedText.Append(fullLine.Substring(leftChar));
}
else if (lineIndex == selectionRightLine && leftChar != rightChar)
{
// selecting middle of the one line
selectedText.Append(fullLine.Substring(leftChar, rightChar - leftChar));
}
}
else if (lineIndex == selectionRightLine)
{
// left side of the line is selected
selectedText.Append(fullLine.Substring(0, rightChar));
}
}
return _textCache;
}
set => _textCache = value;
if (selectedText.Length > 0)
Clipboard.Text = selectedText.ToString();
}
public ConsoleContentTextBox_Old(ConsoleInputTextBox inputBox, float x, float y, float width, float height) : base(x, y, width, height)
{
this.inputBox = inputBox;
Height = height;
IsMultiline = true;
IsReadOnly = true;
CaretColor = new Color(0f, 0f, 0f, 0f);
AutoFocus = false;
}
public override void OnGotFocus()
{
base.OnGotFocus();
}
public override void OnLostFocus()
{
ClearSelection();
base.OnLostFocus();
}
protected override void OnTextChanged()
{
base.OnTextChanged();
ScrollToEnd();
}
public override bool OnKeyDown(KeyboardKeys key)
{
bool ret;
switch (key)
{
case KeyboardKeys.Escape:
ret = true; // disable text restoration
break;
case KeyboardKeys.Home:
case KeyboardKeys.End:
// TODO: scroll top and scroll bottom
ret = true;
break;
case KeyboardKeys.ArrowUp:
case KeyboardKeys.ArrowDown:
case KeyboardKeys.ArrowLeft:
case KeyboardKeys.ArrowRight:
ret = true; // input box has priority
break;
case KeyboardKeys.PageUp:
case KeyboardKeys.PageDown:
return true;
default:
ret = base.OnKeyDown(key);
break;
}
if (inputBox == null)
return ret;
return inputBox.OnKeyDown(key);
}
public override void OnKeyUp(KeyboardKeys key)
{
base.OnKeyUp(key);
if (inputBox != null)
inputBox.OnKeyUp(key);
}
public override bool OnCharInput(char c)
{
if (inputBox == null)
return base.OnCharInput(c);
Focus(inputBox);
return inputBox.OnCharInput(c);
}
}
#endif
}