/cui/container.d

http://github.com/wilkie/djehuty · D · 320 lines · 228 code · 68 blank · 24 comment · 42 complexity · 8518bff37a0494e0cb85e93b184fbca8 MD5 · raw file

  1. /*
  2. * container.d
  3. *
  4. * This module implements a widget container for CuiWidget.
  5. *
  6. * Author: Dave Wilkinson
  7. * Originated: August 20th 2009
  8. *
  9. */
  10. module cui.container;
  11. import cui.widget;
  12. import djehuty;
  13. private import io.console;
  14. class CuiContainer : CuiWidget {
  15. this(uint x, uint y, uint width, uint height) {
  16. _name = "";
  17. super(x,y,width,height);
  18. }
  19. override void onInit() {
  20. _inited = true;
  21. CuiWidget c = _firstControl;
  22. if (c is null) { return; }
  23. do {
  24. c = c._prevControl;
  25. c.onInit();
  26. //if ()
  27. //c.onDraw();
  28. } while (c !is _firstControl)
  29. }
  30. override void onGotFocus() {
  31. if (_focusedControl is null) {
  32. CuiWidget c = _firstControl;
  33. if (c is null) { return; }
  34. do {
  35. c = c._prevControl;
  36. if (c.isTabStop()) {
  37. _focusedControl = c;
  38. _focusedControl.onGotFocus();
  39. break;
  40. }
  41. } while (c !is _firstControl);
  42. }
  43. else {
  44. _focusedControl.onGotFocus();
  45. }
  46. }
  47. override void onLostFocus() {
  48. if (_focusedControl !is null) {
  49. _focusedControl.onLostFocus();
  50. }
  51. }
  52. override void onDraw() {
  53. // Go through child widget list and draw each one
  54. Console.position(0,0);
  55. CuiWidget c = _firstControl;
  56. io.console.Console.clipSave();
  57. if (c !is null) {
  58. do {
  59. c = c._prevControl;
  60. io.console.Console.clipSave();
  61. this.widgetClippingContext = c;
  62. c.onDraw();
  63. io.console.Console.clipRestore();
  64. io.console.Console.clipRect(_base_x + this.left + c.left, _base_y + this.top + c.top, _base_x + this.left + c.left + c.width, _base_y + this.top + c.top + c.height);
  65. } while(c !is _firstControl);
  66. }
  67. // Should clear the rest of the space not used by a widget
  68. static string spaces = " ";
  69. Console.backcolor = Color.Gray;
  70. for (uint i; i < this.height; i++) {
  71. Console.position(0,i);
  72. io.console.Console.backcolor = Color.Black;
  73. uint numSpaces = this.width;
  74. do {
  75. uint pad = spaces.length;
  76. if (numSpaces < pad) {
  77. pad = numSpaces;
  78. }
  79. io.console.Console.put(spaces[0..pad]);
  80. numSpaces -= pad;
  81. } while (numSpaces > 0)
  82. }
  83. io.console.Console.clipRestore();
  84. }
  85. override void onKeyDown(Key key) {
  86. if (_focusedControl !is null) {
  87. _focusedControl.onKeyDown(key);
  88. }
  89. }
  90. override void onKeyChar(dchar chr) {
  91. if (_focusedControl !is null) {
  92. _focusedControl.onKeyChar(chr);
  93. }
  94. }
  95. override void onPrimaryMouseDown() {
  96. if (_focusedControl !is null) {
  97. _focusedControl.onPrimaryMouseDown();
  98. }
  99. }
  100. override void onSecondaryMouseDown() {
  101. if (_focusedControl !is null) {
  102. _focusedControl.onSecondaryMouseDown();
  103. }
  104. }
  105. override void onTertiaryMouseDown() {
  106. if (_focusedControl !is null) {
  107. _focusedControl.onTertiaryMouseDown();
  108. }
  109. }
  110. override void onPrimaryMouseUp() {
  111. if (_focusedControl !is null) {
  112. _focusedControl.onPrimaryMouseUp();
  113. }
  114. }
  115. override void onSecondaryMouseUp() {
  116. if (_focusedControl !is null) {
  117. _focusedControl.onSecondaryMouseUp();
  118. }
  119. }
  120. override void onTertiaryMouseUp() {
  121. if (_focusedControl !is null) {
  122. _focusedControl.onTertiaryMouseUp();
  123. }
  124. }
  125. override void onMouseWheelY(int amount) {
  126. if (_focusedControl !is null) {
  127. _focusedControl.onMouseWheelY(amount);
  128. }
  129. }
  130. override void onMouseWheelX(int amount) {
  131. if (_focusedControl !is null) {
  132. _focusedControl.onMouseWheelX(amount);
  133. }
  134. }
  135. override void onMouseMove() {
  136. if (_focusedControl !is null) {
  137. _focusedControl.onMouseMove();
  138. }
  139. }
  140. override void push(Dispatcher dsp) {
  141. if (cast(CuiWidget)dsp) {
  142. // do not add a control that is already part of another window
  143. CuiWidget control = cast(CuiWidget)dsp;
  144. if (control._nextControl !is null) {
  145. return;
  146. }
  147. // add to the control linked list
  148. if (_firstControl is null && _lastControl is null) {
  149. // first control
  150. _firstControl = control;
  151. _lastControl = control;
  152. control._nextControl = control;
  153. control._prevControl = control;
  154. }
  155. else {
  156. // next control
  157. control._nextControl = _firstControl;
  158. control._prevControl = _lastControl;
  159. _firstControl._prevControl = control;
  160. _lastControl._nextControl = control;
  161. _firstControl = control;
  162. }
  163. // increase the number of controls
  164. _numControls++;
  165. Responder.push(dsp);
  166. control._owner = this;
  167. control._window = _window;
  168. control._base_x = _base_x + this.left;
  169. control._base_y = _base_y + this.top;
  170. _isTabStop |= control.isTabStop();
  171. // Call event
  172. control.onAdd();
  173. if (_inited) {
  174. control.onInit();
  175. }
  176. return;
  177. }
  178. super.push(dsp);
  179. }
  180. override bool isTabStop() {
  181. return _isTabStop;
  182. }
  183. override void move(uint x, uint y) {
  184. // Must report to each control
  185. _reportMove(x, y);
  186. super.move(x,y);
  187. }
  188. void text(string name) {
  189. _name = name.dup;
  190. }
  191. string text() {
  192. return _name.dup;
  193. }
  194. protected:
  195. // head and tail of the control linked list
  196. CuiWidget _firstControl; //head
  197. CuiWidget _lastControl; //tail
  198. // currently focused control
  199. CuiWidget _focusedControl;
  200. uint _numControls;
  201. bool _inited;
  202. bool _isTabStop;
  203. string _name;
  204. void _reportMove(uint x, uint y) {
  205. CuiWidget c = _firstControl;
  206. if (c is null) {
  207. super.move(x,y);
  208. return;
  209. }
  210. do {
  211. c = c._prevControl;
  212. c._base_x = _base_x + x;
  213. c._base_y = _base_y + y;
  214. if (cast(CuiContainer)c) {
  215. CuiContainer container = cast(CuiContainer)c;
  216. container._reportMove(c.left, c.top);
  217. }
  218. } while (c !is _firstControl);
  219. }
  220. package void _tabForward() {
  221. // activate the next control
  222. CuiWidget curFocus = _focusedControl;
  223. if (curFocus is null) { return; }
  224. _focusedControl.onLostFocus();
  225. do {
  226. _focusedControl = _focusedControl._prevControl;
  227. if (_focusedControl is _firstControl && _owner !is null) {
  228. _owner._tabForward();
  229. }
  230. if (_focusedControl.isTabStop()) {
  231. _focusedControl.onGotFocus();
  232. break;
  233. }
  234. } while (_focusedControl !is curFocus);
  235. }
  236. package void _tabBackward() {
  237. // activate the previous control
  238. CuiWidget curFocus = _focusedControl;
  239. if (curFocus is null) { return; }
  240. _focusedControl.onLostFocus();
  241. do {
  242. _focusedControl = _focusedControl._nextControl;
  243. if (_focusedControl is _firstControl && _owner !is null) {
  244. _owner._tabBackward();
  245. }
  246. if (_focusedControl.isTabStop()) {
  247. _focusedControl.onGotFocus();
  248. break;
  249. }
  250. } while (_focusedControl !is curFocus);
  251. }
  252. }