Add a Type (= General, Filename, Integer) to TextFieldWidget.

This commit is contained in:
Paul Chote
2018-04-28 16:28:37 +00:00
committed by reaperrr
parent df8e2f4be4
commit 59c2a9e4da

View File

@@ -11,17 +11,28 @@
using System; using System;
using System.Drawing; using System.Drawing;
using System.IO;
using System.Linq;
using OpenRA.Widgets; using OpenRA.Widgets;
namespace OpenRA.Mods.Common.Widgets namespace OpenRA.Mods.Common.Widgets
{ {
public enum TextFieldType { General, Filename, Integer }
public class TextFieldWidget : Widget public class TextFieldWidget : Widget
{ {
string text = ""; string text = "";
public string Text public string Text
{ {
get { return text; } get
set { text = value ?? ""; CursorPosition = CursorPosition.Clamp(0, text.Length); } {
return text;
}
set
{
text = RemoveInvalidCharacters(value ?? "");
CursorPosition = CursorPosition.Clamp(0, text.Length);
}
} }
public int MaxLength = 0; public int MaxLength = 0;
@@ -31,6 +42,24 @@ namespace OpenRA.Mods.Common.Widgets
public bool Disabled = false; public bool Disabled = false;
TextFieldType type = TextFieldType.General;
public TextFieldType Type
{
get
{
return type;
}
set
{
type = value;
// Revalidate text
text = RemoveInvalidCharacters(text);
CursorPosition = CursorPosition.Clamp(0, text.Length);
}
}
public Func<bool> OnEnterKey = () => false; public Func<bool> OnEnterKey = () => false;
public Func<bool> OnTabKey = () => false; public Func<bool> OnTabKey = () => false;
public Func<bool> OnEscKey = () => false; public Func<bool> OnEscKey = () => false;
@@ -61,6 +90,7 @@ namespace OpenRA.Mods.Common.Widgets
{ {
Text = widget.Text; Text = widget.Text;
MaxLength = widget.MaxLength; MaxLength = widget.MaxLength;
Type = widget.Type;
Font = widget.Font; Font = widget.Font;
TextColor = widget.TextColor; TextColor = widget.TextColor;
TextColorDisabled = widget.TextColorDisabled; TextColorDisabled = widget.TextColorDisabled;
@@ -162,6 +192,28 @@ namespace OpenRA.Mods.Common.Widgets
return CursorPosition + trimmedSpaces + nextWhitespace; return CursorPosition + trimmedSpaces + nextWhitespace;
} }
string RemoveInvalidCharacters(string input)
{
switch (Type)
{
case TextFieldType.Filename:
{
var invalidIndex = -1;
var invalidChars = Path.GetInvalidFileNameChars();
while ((invalidIndex = input.IndexOfAny(invalidChars)) != -1)
input = input.Remove(invalidIndex, 1);
return input;
}
case TextFieldType.Integer:
return new string(input.Where(c => char.IsDigit(c)).ToArray());
default:
return input;
}
}
public override bool HandleKeyPress(KeyInput e) public override bool HandleKeyPress(KeyInput e)
{ {
if (IsDisabled() || e.Event == KeyInputEvent.Up) if (IsDisabled() || e.Event == KeyInputEvent.Up)
@@ -263,7 +315,10 @@ namespace OpenRA.Mods.Common.Widgets
case Keycode.D: case Keycode.D:
if (e.Modifiers.HasModifier(Modifiers.Ctrl) && CursorPosition < Text.Length) if (e.Modifiers.HasModifier(Modifiers.Ctrl) && CursorPosition < Text.Length)
{ {
Text = Text.Remove(CursorPosition, 1); // Write directly to the Text backing field to avoid unnecessary validation
text = text.Remove(CursorPosition, 1);
CursorPosition = CursorPosition.Clamp(0, text.Length);
OnTextEdited(); OnTextEdited();
} }
@@ -274,7 +329,10 @@ namespace OpenRA.Mods.Common.Widgets
ResetBlinkCycle(); ResetBlinkCycle();
if (e.Modifiers.HasModifier(Modifiers.Ctrl) && CursorPosition < Text.Length) if (e.Modifiers.HasModifier(Modifiers.Ctrl) && CursorPosition < Text.Length)
{ {
Text = Text.Remove(CursorPosition); // Write directly to the Text backing field to avoid unnecessary validation
text = text.Remove(CursorPosition);
CursorPosition = CursorPosition.Clamp(0, text.Length);
OnTextEdited(); OnTextEdited();
} }
@@ -285,7 +343,8 @@ namespace OpenRA.Mods.Common.Widgets
ResetBlinkCycle(); ResetBlinkCycle();
if (!isOSX && e.Modifiers.HasModifier(Modifiers.Ctrl) && CursorPosition > 0) if (!isOSX && e.Modifiers.HasModifier(Modifiers.Ctrl) && CursorPosition > 0)
{ {
Text = Text.Substring(CursorPosition); // Write directly to the Text backing field to avoid unnecessary validation
text = text.Substring(CursorPosition);
CursorPosition = 0; CursorPosition = 0;
ClearSelection(); ClearSelection();
OnTextEdited(); OnTextEdited();
@@ -326,13 +385,15 @@ namespace OpenRA.Mods.Common.Widgets
RemoveSelectedText(); RemoveSelectedText();
else if (CursorPosition < Text.Length) else if (CursorPosition < Text.Length)
{ {
// Write directly to the Text backing field to avoid unnecessary validation
if ((!isOSX && e.Modifiers.HasModifier(Modifiers.Ctrl)) || (isOSX && e.Modifiers.HasModifier(Modifiers.Alt))) if ((!isOSX && e.Modifiers.HasModifier(Modifiers.Ctrl)) || (isOSX && e.Modifiers.HasModifier(Modifiers.Alt)))
Text = Text.Substring(0, CursorPosition) + Text.Substring(GetNextWhitespaceIndex()); text = text.Substring(0, CursorPosition) + text.Substring(GetNextWhitespaceIndex());
else if (isOSX && e.Modifiers.HasModifier(Modifiers.Meta)) else if (isOSX && e.Modifiers.HasModifier(Modifiers.Meta))
Text = Text.Remove(CursorPosition); text = text.Remove(CursorPosition);
else else
Text = Text.Remove(CursorPosition, 1); text = text.Remove(CursorPosition, 1);
CursorPosition = CursorPosition.Clamp(0, text.Length);
OnTextEdited(); OnTextEdited();
} }
@@ -345,21 +406,22 @@ namespace OpenRA.Mods.Common.Widgets
RemoveSelectedText(); RemoveSelectedText();
else if (CursorPosition > 0) else if (CursorPosition > 0)
{ {
// Write directly to the Text backing field to avoid unnecessary validation
if ((!isOSX && e.Modifiers.HasModifier(Modifiers.Ctrl)) || (isOSX && e.Modifiers.HasModifier(Modifiers.Alt))) if ((!isOSX && e.Modifiers.HasModifier(Modifiers.Ctrl)) || (isOSX && e.Modifiers.HasModifier(Modifiers.Alt)))
{ {
var prevWhitespace = GetPrevWhitespaceIndex(); var prevWhitespace = GetPrevWhitespaceIndex();
Text = Text.Substring(0, prevWhitespace) + Text.Substring(CursorPosition); text = text.Substring(0, prevWhitespace) + text.Substring(CursorPosition);
CursorPosition = prevWhitespace; CursorPosition = prevWhitespace;
} }
else if (isOSX && e.Modifiers.HasModifier(Modifiers.Meta)) else if (isOSX && e.Modifiers.HasModifier(Modifiers.Meta))
{ {
Text = Text.Substring(CursorPosition); text = text.Substring(CursorPosition);
CursorPosition = 0; CursorPosition = 0;
} }
else else
{ {
CursorPosition--; CursorPosition--;
Text = Text.Remove(CursorPosition, 1); text = text.Remove(CursorPosition, 1);
} }
OnTextEdited(); OnTextEdited();
@@ -404,24 +466,30 @@ namespace OpenRA.Mods.Common.Widgets
return true; return true;
} }
public override bool HandleTextInput(string text) public override bool HandleTextInput(string input)
{ {
if (!HasKeyboardFocus || IsDisabled()) if (!HasKeyboardFocus || IsDisabled())
return false; return false;
// Validate input
input = RemoveInvalidCharacters(input);
if (input.Length == 0)
return true;
if (selectionStartIndex != -1) if (selectionStartIndex != -1)
RemoveSelectedText(); RemoveSelectedText();
if (MaxLength > 0 && Text.Length >= MaxLength) if (MaxLength > 0 && Text.Length >= MaxLength)
return true; return true;
var pasteLength = text.Length; var pasteLength = input.Length;
// Truncate the pasted string if the total length (current + paste) is greater than the maximum. // Truncate the pasted string if the total length (current + paste) is greater than the maximum.
if (MaxLength > 0 && MaxLength > Text.Length) if (MaxLength > 0 && MaxLength > Text.Length)
pasteLength = Math.Min(text.Length, MaxLength - Text.Length); pasteLength = Math.Min(input.Length, MaxLength - Text.Length);
Text = Text.Insert(CursorPosition, text.Substring(0, pasteLength)); // Write directly to the Text backing field to avoid repeating the invalid character validation
text = text.Insert(CursorPosition, input.Substring(0, pasteLength));
CursorPosition += pasteLength; CursorPosition += pasteLength;
ClearSelection(); ClearSelection();
OnTextEdited(); OnTextEdited();
@@ -453,7 +521,9 @@ namespace OpenRA.Mods.Common.Widgets
{ {
var lowestIndex = selectionStartIndex < selectionEndIndex ? selectionStartIndex : selectionEndIndex; var lowestIndex = selectionStartIndex < selectionEndIndex ? selectionStartIndex : selectionEndIndex;
var highestIndex = selectionStartIndex < selectionEndIndex ? selectionEndIndex : selectionStartIndex; var highestIndex = selectionStartIndex < selectionEndIndex ? selectionEndIndex : selectionStartIndex;
Text = Text.Remove(lowestIndex, highestIndex - lowestIndex);
// Write directly to the Text backing field to avoid unnecessary validation
text = text.Remove(lowestIndex, highestIndex - lowestIndex);
ClearSelection(); ClearSelection();