src/common/details/console/gui/controls/EditBoxControl.cs (378 lines of code) (raw):
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE.md file in the project root for full license information.
//
using System;
namespace Azure.AI.Details.Common.CLI.ConsoleGui
{
public class EditBoxControl : ScrollingControl
{
public EditBoxControl(Window? parent, Rect rect, Colors color, string? text, int uiMaxTextLengthParam, string? picture, string? pszBorder, bool fEnabled = true) :
base(parent, rect, color, pszBorder, fEnabled)
{
uiMaxTextLength = uiMaxTextLengthParam;
_text = text ?? string.Empty;
_picture = picture;
cursor.Save();
}
#region text, rows, and columns
public string GetText() { return _text; }
public override int GetNumRows()
{
return 0;
}
public override int GetNumColumns()
{
return GetText().Length + 1;
}
#endregion
#region open, close, focus
public override bool Open()
{
if (base.Open())
{
DisplayText();
return true;
}
return false;
}
public override bool Close()
{
cursor.Restore();
return base.Close();
}
public override bool SetFocus()
{
if (base.SetFocus())
{
DisplayText();
DisplayCursor();
return true;
}
return false;
}
public override void KillFocus()
{
base.KillFocus();
Home();
DisplayText();
DisplayCursor();
}
#endregion
#region selection and offset
protected override bool SetRowOffset(int ui)
{
return false;
}
protected override bool SetColumnOffset(int ui)
{
if (base.SetColumnOffset(ui))
{
DisplayText();
DisplayCursor();
return true;
}
return false;
}
protected override bool SetSelectedColumn(int ui, int width = 1)
{
if (IsPosValid(ui) && base.SetSelectedColumn(ui, width))
{
DisplayText();
DisplayCursor();
return true;
}
return false;
}
#endregion
#region processing keys
public override bool ProcessKey(ConsoleKeyInfo key)
{
bool fProcessedKey = false;
cursor.Hide();
switch (key.Key)
{
case ConsoleKey.Home:
if (!key.IsShift() && !key.IsCtrl() && !key.IsAlt())
{
Home();
fProcessedKey = true;
}
break;
case ConsoleKey.End:
if (!key.IsShift() && !key.IsCtrl() && !key.IsAlt())
{
End();
fProcessedKey = true;
}
break;
case ConsoleKey.UpArrow:
case ConsoleKey.LeftArrow:
if (!key.IsShift() && !key.IsCtrl() && !key.IsAlt())
{
Left();
fProcessedKey = true;
}
break;
case ConsoleKey.DownArrow:
case ConsoleKey.RightArrow:
if (!key.IsShift() && !key.IsCtrl() && !key.IsAlt())
{
Right();
fProcessedKey = true;
}
break;
case ConsoleKey.Backspace:
if (!key.IsShift() && !key.IsCtrl() && !key.IsAlt())
{
BackSpace();
fProcessedKey = true;
}
break;
case ConsoleKey.Insert:
if (!key.IsShift() && !key.IsCtrl() && !key.IsAlt())
{
Insert();
fProcessedKey = true;
}
break;
case ConsoleKey.Delete:
if (!key.IsShift() && !key.IsCtrl() && !key.IsAlt())
{
Delete();
fProcessedKey = true;
}
break;
case ConsoleKey.Escape:
case ConsoleKey.Enter:
case ConsoleKey.PageDown:
case ConsoleKey.PageUp:
case ConsoleKey.F1:
case ConsoleKey.F2:
case ConsoleKey.F3:
case ConsoleKey.F4:
case ConsoleKey.F5:
case ConsoleKey.F6:
case ConsoleKey.F7:
case ConsoleKey.F8:
case ConsoleKey.F9:
case ConsoleKey.F10:
case ConsoleKey.F11:
case ConsoleKey.F12:
case ConsoleKey.Tab:
break;
default:
if (key.IsAscii())
{
TypeChar(key.KeyChar);
fProcessedKey = true;
}
break;
}
DisplayCursor();
return fProcessedKey;
}
public bool Home()
{
bool fSuccess = true;
int ui = 0;
int uiMaxPos = GetText().Length;
for (; !IsPosValid(ui); ui++)
if (ui >= uiMaxPos)
{
fSuccess = false;
break;
}
if (fSuccess)
SetSelectedColumn(ui);
return fSuccess;
}
public bool End()
{
bool fSuccess = true;
int ui = GetText().Length;
if (ui >= uiMaxTextLength)
ui = uiMaxTextLength - 1;
for (; !IsPosValid(ui); ui--)
if (ui == 0)
{
fSuccess = false;
break;
}
if (fSuccess)
SetSelectedColumn(ui);
return fSuccess;
}
public bool Left()
{
bool fSuccess = true;
int ui = SelectedColumn;
do
{
if (ui == 0)
{
fSuccess = false;
break;
}
}
while (!IsPosValid(--ui));
if (fSuccess)
SetSelectedColumn(ui);
return fSuccess;
}
public bool Right()
{
bool fSuccess = true;
int ui = SelectedColumn;
int uiMaxPos = GetText().Length;
if (uiMaxPos >= uiMaxTextLength)
uiMaxPos = uiMaxTextLength - 1;
do
{
if (ui >= uiMaxPos)
{
fSuccess = false;
break;
}
}
while (!IsPosValid(++ui));
if (fSuccess)
SetSelectedColumn(ui);
return fSuccess;
}
public bool BackSpace()
{
bool fSuccess;
if ((fSuccess = Left()) != false)
Delete();
return fSuccess;
}
public bool Delete()
{
bool fSuccess;
if (SelectedColumn < GetText().Length)
{
fSuccess = true;
if (_picture == null)
{
_text = _text.Remove(SelectedColumn, 1);
}
else
{
int ui;
for (ui = SelectedColumn + 1; ui < _text.Length && IsPosValid(ui) && IsCharValid(_text[ui], ui - 1); ui++)
{
_text = _text.Insert(ui, _text[ui].ToString()).Remove(ui - 1, 1);
}
if (ui == _text.Length)
{
_text = _text.Remove(ui - 1);
}
else
{
_text = _text.Insert(ui - 1, " ").Remove(ui, 1);
}
}
DisplayText();
}
else
fSuccess = false;
return fSuccess;
}
public bool Insert()
{
fInsertMode = !fInsertMode;
DisplayCursor();
return true;
}
public bool TypeChar(char ch)
{
return fInsertMode ? InsertChar(ch) : TypeOverChar(ch);
}
#endregion
#region cursor
public void DisplayCursor()
{
if (IsFocus())
{
cursor.SetPosition(ClientRect.X + SelectedColumn - ColumnOffset, ClientRect.Y);
cursor.Show();
if (fInsertMode)
cursor.SetBoxShape();
else
cursor.SetLineShape();
}
else
{
HideCursor();
}
}
public void HideCursor()
{
cursor.Hide();
}
#endregion
#region private methods
private void DisplayText()
{
Screen.Current.SetColors(Colors);
WriteClientText(0, 0, _text.Substring(ColumnOffset), ClientRect.Width);
}
private bool IsPosValid(int uiPos)
{
return uiPos < uiMaxTextLength &&
uiPos <= GetText().Length &&
(_picture == null ||
_picture == "@#" ||
_picture == "@A" ||
(uiPos < _picture.Length &&
(_picture[uiPos] == '#' ||
_picture[uiPos] == 'A')));
}
private bool IsCharValid(char ch, int uiPos)
{
return IsPosValid(uiPos) &&
(_picture == null ||
((char.IsLetter(ch) && (_picture == "@A" || _picture[uiPos] == 'A')) ||
(char.IsDigit(ch) && (_picture == "@#" || _picture[uiPos] == '#'))));
}
private bool InsertChar(char ch)
{
bool fSuccess;
if ((fSuccess = IsCharValid(ch, SelectedColumn)) != false)
{
// insert the char
_text = _text.Insert(SelectedColumn, ch.ToString());
// check to make sure the rest of the characters are in valid spots
for (int i = SelectedColumn + 1; i < _text.Length; i++)
{
if (!IsCharValid(_text[i], i))
{
// truncate at the first one that's not valid
_text = _text.Remove(i);
break;
}
}
// dipsplay the text
DisplayText();
// move to the right since we're done
Right();
}
return fSuccess;
}
private bool TypeOverChar(char ch)
{
bool fSuccess;
if ((fSuccess = IsCharValid(ch, SelectedColumn)) != false)
{
// make space if needed
if (SelectedColumn == _text.Length)
{
_text = _text.Insert(SelectedColumn, " ");
}
// insert the new character
_text = _text.Remove(SelectedColumn, 1).Insert(SelectedColumn, ch.ToString());
// display the text
DisplayText();
// move to the right
Right();
}
return fSuccess;
}
#endregion
#region private data
string _text;
int uiMaxTextLength;
string? _picture;
Cursor cursor = new Cursor();
static bool fInsertMode = false;
#endregion
}
}