/cui/tabbox.d

http://github.com/wilkie/djehuty · D · 353 lines · 261 code · 73 blank · 19 comment · 39 complexity · e12a3f7ce198e46b7e89a57dbcb55fd2 MD5 · raw file

  1. /*
  2. * tabs.d
  3. *
  4. * This module implements tabs of windows for TUI apps.
  5. *
  6. * Author: Lindsey Bieda
  7. * Originated: October 14th 2009
  8. *
  9. */
  10. module cui.tabbox;
  11. import djehuty;
  12. import data.list;
  13. import cui.container;
  14. import io.console;
  15. // Tabs should loop through CuiContainers that are sized to the size of the tab widget
  16. // Some hints:
  17. // onDraw() { current_container.onDraw(); }
  18. // onKeyDown(Key foo) { current_container.onKeyDown(foo); }
  19. // etc. for all events
  20. // Redraw container when the tab is switched
  21. // Pass resize events down to current container and ALL containers
  22. // (eventually.. like check the size when containers are switched to reduce overhead)
  23. class CuiTabBox : CuiContainer, Iterable!(CuiContainer) {
  24. this(uint x, uint y, uint width, uint height) {
  25. super(x,y,width,height);
  26. _tabList = new List!(CuiContainer);
  27. }
  28. override void onAdd() {
  29. _old_base_y = _base_y;
  30. _base_y++;
  31. }
  32. override void onDraw() {
  33. io.console.Console.hideCaret();
  34. //draw the tabs
  35. io.console.Console.clipSave();
  36. io.console.Console.position(_base_x + this.left, _base_y + this.top - 1);
  37. io.console.Console.forecolor = _forecolor;
  38. io.console.Console.backcolor = _backcolor;
  39. io.console.Console.put(" ");
  40. foreach(i, item; _tabList) {
  41. if(i == _curTab) {
  42. io.console.Console.forecolor = _selectedForecolor;
  43. io.console.Console.backcolor = _selectedBackcolor;
  44. io.console.Console.put(item.text);
  45. io.console.Console.forecolor = _forecolor;
  46. io.console.Console.backcolor = _backcolor;
  47. }
  48. else {
  49. io.console.Console.put(item.text);
  50. }
  51. io.console.Console.put(" | ");
  52. }
  53. if(!_tabList.empty()) {
  54. CuiContainer c = _tabList[_curTab];
  55. io.console.Console.clipSave();
  56. this.widgetClippingContext = c;
  57. c.onDraw();
  58. io.console.Console.clipRestore();
  59. 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);
  60. }
  61. io.console.Console.clipRestore();
  62. }
  63. override void onGotFocus() {
  64. if(!_tabList.empty()) {
  65. _tabList[_curTab].onGotFocus();
  66. }
  67. }
  68. override void onLostFocus() {
  69. if(!_tabList.empty()) {
  70. _tabList[_curTab].onLostFocus();
  71. }
  72. }
  73. override void onResize() {
  74. if(!_tabList.empty()) {
  75. _tabList[_curTab].resize(width, height-1);
  76. }
  77. }
  78. override void onKeyDown(Key key) {
  79. if(!_tabList.empty()) {
  80. if(key.alt == true && key.code >= Key.Zero && key.code <= Key.Nine) {
  81. if (key.code == Key.Zero) {
  82. current(10);
  83. }
  84. else {
  85. current(key.code - Key.One);
  86. }
  87. }
  88. else {
  89. _tabList[_curTab].onKeyDown(key);
  90. }
  91. }
  92. }
  93. override void onKeyChar(dchar keyChar) {
  94. if(!_tabList.empty()) {
  95. _tabList[_curTab].onKeyChar(keyChar);
  96. }
  97. }
  98. override void onPrimaryMouseDown() {
  99. if(!_tabList.empty()) {
  100. _tabList[_curTab].onPrimaryMouseDown();
  101. }
  102. }
  103. override void onPrimaryMouseUp() {
  104. if(!_tabList.empty()) {
  105. _tabList[_curTab].onPrimaryMouseUp();
  106. }
  107. }
  108. override void onSecondaryMouseDown() {
  109. if(!_tabList.empty()) {
  110. _tabList[_curTab].onSecondaryMouseDown();
  111. }
  112. }
  113. override void onSecondaryMouseUp() {
  114. if(!_tabList.empty()) {
  115. _tabList[_curTab].onSecondaryMouseUp();
  116. }
  117. }
  118. override void onTertiaryMouseDown() {
  119. if(!_tabList.empty()) {
  120. _tabList[_curTab].onTertiaryMouseDown();
  121. }
  122. }
  123. override void onTertiaryMouseUp() {
  124. if(!_tabList.empty()) {
  125. _tabList[_curTab].onTertiaryMouseUp();
  126. }
  127. }
  128. override void onMouseWheelY(int amount) {
  129. if(!_tabList.empty()) {
  130. _tabList[_curTab].onMouseWheelY(amount);
  131. }
  132. }
  133. override void onMouseWheelX(int amount) {
  134. if(!_tabList.empty()) {
  135. _tabList[_curTab].onMouseWheelX(amount);
  136. }
  137. }
  138. override void onMouseMove() {
  139. if(!_tabList.empty()) {
  140. _tabList[_curTab].onMouseMove();
  141. }
  142. }
  143. override void push(Dispatcher dsp) {
  144. if (cast(CuiContainer)dsp) {
  145. CuiContainer c = cast(CuiContainer)dsp;
  146. c.resize(width, height-1);
  147. c.move(0,0);
  148. _tabList.add(c);
  149. }
  150. super.push(dsp);
  151. }
  152. void add(CuiContainer c) {
  153. push(c);
  154. }
  155. CuiContainer remove() {
  156. return _tabList.remove();
  157. }
  158. CuiContainer removeAt(size_t idx){
  159. return _tabList.removeAt(idx);
  160. }
  161. CuiContainer peek() {
  162. return _tabList.peek();
  163. }
  164. CuiContainer peekAt(size_t idx) {
  165. return _tabList.peekAt(idx);
  166. }
  167. void set(CuiContainer c) {
  168. _tabList.set(c);
  169. }
  170. void apply(CuiContainer delegate(CuiContainer) func) {
  171. _tabList.apply(func);
  172. }
  173. bool contains(CuiContainer c) {
  174. return _tabList.contains(c);
  175. }
  176. bool empty() {
  177. return _tabList.empty();
  178. }
  179. void clear() {
  180. _tabList.clear();
  181. }
  182. CuiContainer[] array() {
  183. return _tabList.array();
  184. }
  185. List!(CuiContainer) dup() {
  186. return _tabList.dup();
  187. }
  188. List!(CuiContainer) slice(size_t start, size_t end) {
  189. return _tabList.slice(start, end);
  190. }
  191. List!(CuiContainer) reverse() {
  192. return _tabList.reverse();
  193. }
  194. size_t length() {
  195. return _tabList.length();
  196. }
  197. CuiContainer opIndex(size_t i1) {
  198. return _tabList.opIndex(i1);
  199. }
  200. int opApply(int delegate(ref CuiContainer) loopFunc) {
  201. return _tabList.opApply(loopFunc);
  202. }
  203. int opApply(int delegate(ref size_t, ref CuiContainer) loopFunc) {
  204. return _tabList.opApply(loopFunc);
  205. }
  206. int opApplyReverse(int delegate(ref CuiContainer) loopFunc) {
  207. return _tabList.opApplyReverse(loopFunc);
  208. }
  209. int opApplyReverse(int delegate(ref size_t, ref CuiContainer) loopFunc) {
  210. return _tabList.opApplyReverse(loopFunc);
  211. }
  212. void opCatAssign(CuiContainer[] list) {
  213. _tabList.opCatAssign(list);
  214. }
  215. void opCatAssign(Iterable!(CuiContainer) list) {
  216. _tabList.opCatAssign(list);
  217. }
  218. void opCatAssign(CuiContainer item) {
  219. _tabList.opCatAssign(item);
  220. }
  221. Iterable!(CuiContainer) opCat(CuiContainer[] list) {
  222. return _tabList.opCat(list);
  223. }
  224. Iterable!(CuiContainer) opCat(Iterable!(CuiContainer) list) {
  225. return _tabList.opCat(list);
  226. }
  227. Iterable!(CuiContainer) opCat(CuiContainer item) {
  228. return _tabList.opCat(item);
  229. }
  230. void next() {
  231. if(_curTab + 1 < _tabList.length()) {
  232. current(_curTab+1);
  233. }
  234. else {
  235. current(0);
  236. }
  237. }
  238. void prev() {
  239. if(_curTab == 0) {
  240. current(_tabList.length()-1);
  241. }
  242. else {
  243. current(_curTab-1);
  244. }
  245. }
  246. bool isTabStop() {
  247. return true;
  248. }
  249. // properties
  250. size_t current() {
  251. return _curTab;
  252. }
  253. void current(size_t cur) {
  254. if(cur < _tabList.length()) {
  255. if (_curTab == cur) {
  256. return;
  257. }
  258. _tabList[_curTab].onLostFocus();
  259. _curTab = cur;
  260. if((_tabList[_curTab].width != this.width
  261. || _tabList[_curTab].height != (this.height-1))) {
  262. _tabList[_curTab].resize(width, height-1);
  263. }
  264. onDraw();
  265. _tabList[_curTab].onGotFocus();
  266. }
  267. }
  268. protected:
  269. override void _reportMove(uint x, uint y) {
  270. _base_y++;
  271. super._reportMove(x,y);
  272. }
  273. uint _old_base_y;
  274. size_t _curTab = 0;
  275. List!(CuiContainer) _tabList;
  276. Color _forecolor = Color.Gray;
  277. Color _backcolor = Color.Black;
  278. Color _selectedForecolor = Color.Yellow;
  279. Color _selectedBackcolor = Color.Black;
  280. }