Button.cs 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. namespace Terminal {
  5. /// <summary>
  6. /// Button view
  7. /// </summary>
  8. /// <remarks>
  9. /// Provides a button that can be clicked, or pressed with
  10. /// the enter key and processes hotkeys (the first uppercase
  11. /// letter in the button becomes the hotkey).
  12. /// </remarks>
  13. public class Button : View {
  14. string text;
  15. string shown_text;
  16. char hot_key;
  17. int hot_pos = -1;
  18. bool is_default;
  19. /// <summary>
  20. /// Clicked event, raised when the button is clicked.
  21. /// </summary>
  22. /// <remarks>
  23. /// Client code can hook up to this event, it is
  24. /// raised when the button is activated either with
  25. /// the mouse or the keyboard.
  26. /// </remarks>
  27. public event EventHandler Clicked;
  28. /// <summary>
  29. /// Public constructor, creates a button based on
  30. /// the given text at position 0,0
  31. /// </summary>
  32. /// <remarks>
  33. /// The size of the button is computed based on the
  34. /// text length. This button is not a default button.
  35. /// </remarks>
  36. public Button (string s) : this (0, 0, s) { }
  37. /// <summary>
  38. /// Public constructor, creates a button based on
  39. /// the given text.
  40. /// </summary>
  41. /// <remarks>
  42. /// If the value for is_default is true, a special
  43. /// decoration is used, and the enter key on a
  44. /// dialog would implicitly activate this button.
  45. /// </remarks>
  46. public Button (string s, bool is_default) : this (0, 0, s, is_default) { }
  47. /// <summary>
  48. /// Public constructor, creates a button based on
  49. /// the given text at the given position.
  50. /// </summary>
  51. /// <remarks>
  52. /// The size of the button is computed based on the
  53. /// text length. This button is not a default button.
  54. /// </remarks>
  55. public Button (int x, int y, string s) : this (x, y, s, false) { }
  56. /// <summary>
  57. /// The text displayed by this widget.
  58. /// </summary>
  59. public string Text {
  60. get {
  61. return text;
  62. }
  63. set {
  64. text = value;
  65. if (is_default)
  66. shown_text = "[< " + value + " >]";
  67. else
  68. shown_text = "[ " + value + " ]";
  69. hot_pos = -1;
  70. hot_key = (char)0;
  71. int i = 0;
  72. foreach (char c in shown_text) {
  73. if (Char.IsUpper (c)) {
  74. hot_key = c;
  75. hot_pos = i;
  76. break;
  77. }
  78. i++;
  79. }
  80. }
  81. }
  82. /// <summary>
  83. /// Public constructor, creates a button based on
  84. /// the given text at the given position.
  85. /// </summary>
  86. /// <remarks>
  87. /// If the value for is_default is true, a special
  88. /// decoration is used, and the enter key on a
  89. /// dialog would implicitly activate this button.
  90. /// </remarks>
  91. public Button (int x, int y, string s, bool is_default)
  92. : base (new Rect (x, y, s.Length + 4 + (is_default ? 2 : 0), 1))
  93. {
  94. CanFocus = true;
  95. this.is_default = is_default;
  96. Text = s;
  97. }
  98. public override void Redraw (Rect region)
  99. {
  100. Driver.SetAttribute (HasFocus ? Colors.Base.Focus : Colors.Base.Normal);
  101. Move (0, 0);
  102. Driver.AddStr (shown_text);
  103. if (hot_pos != -1) {
  104. Move (hot_pos, 0);
  105. Driver.SetAttribute (HasFocus ? Colors.Base.HotFocus : Colors.Base.HotNormal);
  106. Driver.AddCh (hot_key);
  107. }
  108. }
  109. public override void PositionCursor ()
  110. {
  111. Move (hot_pos, 0);
  112. }
  113. bool CheckKey (KeyEvent key)
  114. {
  115. if (Char.ToUpper ((char)key.KeyValue) == hot_key) {
  116. this.SuperView.SetFocus (this);
  117. if (Clicked != null)
  118. Clicked (this, EventArgs.Empty);
  119. return true;
  120. }
  121. return false;
  122. }
  123. public override bool ProcessHotKey (KeyEvent kb)
  124. {
  125. if (kb.IsAlt)
  126. return CheckKey (kb);
  127. return false;
  128. }
  129. public override bool ProcessColdKey (KeyEvent kb)
  130. {
  131. if (is_default && kb.KeyValue == '\n') {
  132. if (Clicked != null)
  133. Clicked (this, EventArgs.Empty);
  134. return true;
  135. }
  136. return CheckKey (kb);
  137. }
  138. public override bool ProcessKey (KeyEvent kb)
  139. {
  140. var c = kb.KeyValue;
  141. if (c == '\n' || c == ' ' || Char.ToUpper ((char)c) == hot_key) {
  142. if (Clicked != null)
  143. Clicked (this, EventArgs.Empty);
  144. return true;
  145. }
  146. return false;
  147. }
  148. #if false
  149. public override void ProcessMouse (Curses.MouseEvent ev)
  150. {
  151. if ((ev.ButtonState & Curses.Event.Button1Clicked) != 0) {
  152. Container.SetFocus (this);
  153. Container.Redraw ();
  154. if (Clicked != null)
  155. Clicked (this, EventArgs.Empty);
  156. }
  157. }
  158. #endif
  159. }
  160. }