PageRenderTime 38ms CodeModel.GetById 17ms app.highlight 18ms RepoModel.GetById 1ms app.codeStats 0ms

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