NetMaskedTextProvider.cs 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. #nullable enable
  2. using System.ComponentModel;
  3. namespace Terminal.Gui.Views;
  4. /// <summary>
  5. /// .Net MaskedTextProvider Provider for TextValidateField.
  6. /// <para></para>
  7. /// <para>
  8. /// <a
  9. /// href="https://docs.microsoft.com/en-us/dotnet/api/system.componentmodel.maskedtextprovider?view=net-5.0">
  10. /// Wrapper around MaskedTextProvider
  11. /// </a>
  12. /// </para>
  13. /// <para>
  14. /// <a
  15. /// href="https://docs.microsoft.com/en-us/dotnet/api/system.windows.forms.maskedtextbox.mask?view=net-5.0">
  16. /// Masking elements
  17. /// </a>
  18. /// </para>
  19. /// </summary>
  20. public class NetMaskedTextProvider : ITextValidateProvider
  21. {
  22. private MaskedTextProvider? _provider;
  23. /// <summary>Empty Constructor</summary>
  24. public NetMaskedTextProvider (string mask) { Mask = mask; }
  25. /// <summary>Mask property</summary>
  26. public string Mask
  27. {
  28. get => _provider!.Mask;
  29. set
  30. {
  31. string current = _provider != null
  32. ? _provider.ToString (false, false)
  33. : string.Empty;
  34. _provider = new (value == string.Empty ? "&&&&&&" : value);
  35. if (!string.IsNullOrEmpty (current))
  36. {
  37. _provider.Set (current);
  38. }
  39. }
  40. }
  41. /// <inheritdoc/>
  42. public event EventHandler<EventArgs<string>>? TextChanged;
  43. /// <inheritdoc/>
  44. public string Text
  45. {
  46. get => _provider!.ToString ();
  47. set => _provider!.Set (value);
  48. }
  49. /// <inheritdoc/>
  50. public bool IsValid => _provider!.MaskCompleted;
  51. /// <inheritdoc/>
  52. public bool Fixed => true;
  53. /// <inheritdoc/>
  54. public string DisplayText => _provider!.ToDisplayString ();
  55. /// <inheritdoc/>
  56. public int Cursor (int pos)
  57. {
  58. if (pos < 0)
  59. {
  60. return CursorStart ();
  61. }
  62. if (pos > _provider!.Length)
  63. {
  64. return CursorEnd ();
  65. }
  66. int p = _provider.FindEditPositionFrom (pos, false);
  67. if (p == -1)
  68. {
  69. p = _provider.FindEditPositionFrom (pos, true);
  70. }
  71. return p;
  72. }
  73. /// <inheritdoc/>
  74. public int CursorStart ()
  75. {
  76. return _provider!.IsEditPosition (0)
  77. ? 0
  78. : _provider.FindEditPositionFrom (0, true);
  79. }
  80. /// <inheritdoc/>
  81. public int CursorEnd ()
  82. {
  83. return _provider!.IsEditPosition (_provider.Length - 1)
  84. ? _provider.Length - 1
  85. : _provider.FindEditPositionFrom (_provider.Length, false);
  86. }
  87. /// <inheritdoc/>
  88. public int CursorLeft (int pos)
  89. {
  90. int c = _provider!.FindEditPositionFrom (pos - 1, false);
  91. return c == -1 ? pos : c;
  92. }
  93. /// <inheritdoc/>
  94. public int CursorRight (int pos)
  95. {
  96. int c = _provider!.FindEditPositionFrom (pos + 1, true);
  97. return c == -1 ? pos : c;
  98. }
  99. /// <inheritdoc/>
  100. public bool Delete (int pos)
  101. {
  102. string oldValue = Text;
  103. bool result = _provider!.Replace (' ', pos); // .RemoveAt (pos);
  104. if (result)
  105. {
  106. OnTextChanged (new (in oldValue));
  107. }
  108. return result;
  109. }
  110. /// <inheritdoc/>
  111. public bool InsertAt (char ch, int pos)
  112. {
  113. string oldValue = Text;
  114. bool result = _provider!.Replace (ch, pos);
  115. if (result)
  116. {
  117. OnTextChanged (new (in oldValue));
  118. }
  119. return result;
  120. }
  121. /// <inheritdoc/>
  122. public void OnTextChanged (EventArgs<string> args) { TextChanged?.Invoke (this, args); }
  123. }