PageRenderTime 52ms CodeModel.GetById 2ms app.highlight 46ms RepoModel.GetById 1ms app.codeStats 1ms

/cui/filebox.d

http://github.com/wilkie/djehuty
D | 387 lines | 288 code | 77 blank | 22 comment | 58 complexity | dd3b75280b577c062c3b442e852dd6e4 MD5 | raw file
  1/*
  2 * filebox.d
  3 *
  4 * This module implements a CuiWidget that lists a directory.
  5 *
  6 * Author: Dave Wilkinson
  7 * Originated: August 20th 2009
  8 *
  9 */
 10
 11module cui.filebox;
 12
 13import cui.listbox;
 14import cui.widget;
 15
 16import io.directory;
 17import io.console;
 18
 19import djehuty;
 20
 21import data.list;
 22
 23class CuiFileBox : CuiWidget, Iterable!(string) {
 24	this(uint x, uint y, uint width, uint height) {
 25		super(x,y,width,height);
 26		_path = new Directory();
 27		_list = new List!(string);
 28		string[] list = _path.list.sort;
 29		if (!_path.isRoot) {
 30			list = [".."] ~ list;
 31		}
 32		foreach(item; list) {
 33			_list.add(item);
 34		}
 35	}
 36
 37	override void onDraw() {
 38		uint i;
 39
 40		for (i = _firstVisible; (i < this.height + _firstVisible) && (i < _list.length); i++) {
 41			drawLine(i);
 42		}
 43		
 44		Console.forecolor = _forecolor;
 45		Console.backcolor = _backcolor;
 46
 47		for (; i < this.height + _firstVisible; i++) {
 48			Console.position(0, i-_firstVisible);
 49			Console.putSpaces(this.width);
 50		}
 51	}
 52
 53	override void onKeyDown(Key key) {
 54		if (key.code == Key.Up) {
 55			if (_pos == 0) {
 56				return;
 57			}
 58
 59			if (_pos == _firstVisible) {
 60				_firstVisible--;
 61				_pos--;
 62				onDraw();
 63
 64				return;
 65			}
 66
 67			if (_pos > 0) {
 68				_pos--;
 69				drawLine(_pos+1);
 70				drawLine(_pos);
 71			}
 72		}
 73		else if (key.code == Key.Down) {
 74			if (_pos == _list.length - 1) {
 75				return;
 76			}
 77
 78			if (_pos == (_firstVisible + this.height - 1)) {
 79				_firstVisible++;
 80				_pos++;
 81				onDraw();
 82
 83				return;
 84			}
 85
 86			if (_list.length > 0 && _pos < _list.length - 1) {
 87				_pos++;
 88				drawLine(_pos-1);
 89				drawLine(_pos);
 90			}
 91		}
 92		else if (key.code == Key.Return) {
 93			// Traverse Directory
 94			if (_list[_pos] == "..") {
 95				_path = _path.parent;
 96				string[] list = _path.list.sort;
 97				if (!_path.isRoot) {
 98					list = [".."] ~ list;
 99				}
100				_list.clear();
101				// XXX: Make this work for List!()
102				foreach(item; list) {
103					_list.add(item);
104				}
105				_pos = 0;
106				_firstVisible = 0;
107				onDraw();
108				onDirectorySelect(_path.path);
109			}
110			else if (_path.isDir(_list[_pos])) {
111				_path = _path.traverse(_list[_pos]);
112				string[] list = _path.list.sort;
113				if (!_path.isRoot) {
114					list = [".."] ~ list;
115				}
116				_pos = 0;
117				_firstVisible = 0;
118				_list.clear();
119				foreach(item; list) {
120					_list.add(item);
121				}
122				onDraw();
123				onDirectorySelect(_path.path);
124			}
125			else {
126				onFileSelect(_path.path ~ "/" ~ _list[_pos]);
127			}
128		}
129		else if (key.code == Key.PageUp) {
130			if (_pos == 0) {
131				return;
132			}
133			
134			if (_pos != _firstVisible) {
135				_pos = _firstVisible;
136			}
137			else {
138				if (_firstVisible > this.height - 1) {
139					_firstVisible -= this.height - 1;
140				}
141				else {
142					_firstVisible = 0;
143				}
144	
145				if (_pos > this.height - 1) {
146					_pos -= this.height - 1;
147				}
148				else {
149					_pos = 0;
150				}
151			}
152
153			onDraw();
154		}
155		else if (key.code == Key.PageDown) {
156			if (_pos == _list.length - 1) {
157				return;
158			}
159			
160			if (_pos != _firstVisible + this.height - 1) {
161				_pos = _firstVisible + this.height - 1;
162			}
163			else {
164				_firstVisible += this.height - 1;
165				_pos += this.height - 1;
166
167				if (_firstVisible > _list.length - this.height) {
168					_firstVisible = _list.length - this.height;
169				}
170			}
171
172			if ( _pos >= _list.length) {
173				_pos = _list.length - 1;
174			}
175
176			onDraw();
177		}
178	}
179
180	override void onLostFocus() {
181		if (_list.length > 0) {
182			drawLine(_pos);
183		}
184	}
185
186	override void onGotFocus() {
187		Console.hideCaret();
188
189		if (_list.length > 0) {
190			drawLine(_pos);
191		}
192	}
193
194	// Events
195
196	// Description: This event will be fired upon selection of a file within the widget.
197	// file: The complete path to the file.
198	void onFileSelect(string file) {
199	}
200
201	// Description: This event will be fired upon selection of a directory within the widget.
202	// dir: The complete path to the directory.
203	void onDirectorySelect(string dir) {
204	}
205
206	// Methods
207
208	override bool isTabStop() {
209		return true;
210	}
211	
212	void add(string c) {
213		return;
214	}
215	
216	string remove() {
217		return _list.peek();
218	}
219	
220	string removeAt(size_t idx){
221		return _list.peekAt(idx);
222	}
223	
224	string peek() {
225		return _list.peek();
226	}
227	
228	string peekAt(size_t idx) {
229		return _list.peekAt(idx);
230	}
231	
232	void set(string c) {
233		return;
234	}
235	
236	void apply(string delegate(string) func) {
237		return;
238	}
239	
240	bool contains(string c) {
241		return _list.contains(c);
242	}
243	
244	bool empty() {
245		return _list.empty();
246	}
247	
248	void clear() {
249		return;
250	}
251	
252	string[] array() {
253		return _list.array();
254	}
255	
256	List!(string) dup() {
257		return _list.dup();
258	}
259	
260	List!(string) slice(size_t start, size_t end) {
261		return _list.slice(start, end);
262	}
263	
264	List!(string) reverse() {
265		return _list.reverse();
266	}
267	
268	size_t length() {
269		return _list.length();
270	}
271	
272	string opIndex(size_t i1) {
273		return _list.opIndex(i1);
274	}
275	
276	int opApply(int delegate(ref string) loopFunc) {
277		return _list.opApply(loopFunc);
278	}
279	
280	int opApply(int delegate(ref size_t, ref string) loopFunc) {
281		return _list.opApply(loopFunc);
282	}
283
284	int opApplyReverse(int delegate(ref string) loopFunc) {
285		return _list.opApplyReverse(loopFunc);
286	}
287
288	int opApplyReverse(int delegate(ref size_t, ref string) loopFunc) {
289		return _list.opApplyReverse(loopFunc);
290	}
291
292	void opCatAssign(string[] list) {
293		_list.opCatAssign(list);
294	}
295
296	void opCatAssign(Iterable!(string) list) {
297		_list.opCatAssign(list);
298	}
299
300	void opCatAssign(string item) {
301		_list.opCatAssign(item);
302	}
303
304	Iterable!(string) opCat(string[] list) {
305		return _list.opCat(list);
306	}
307
308	Iterable!(string) opCat(Iterable!(string) list) {
309		return _list.opCat(list);
310	}
311
312	Iterable!(string) opCat(string item) {
313		return _list.opCat(item);
314	}
315
316	// Propeties
317
318	// Description: This property is for setting the backcolor for normal items.
319	Color backcolor() {
320		return _backcolor;
321	}
322
323	void backcolor(Color value) {
324		_backcolor = value;
325	}
326
327	// Description: This property is for setting the forecolor for normal items.
328	Color forecolor() {
329		return _forecolor;
330	}
331
332	void forecolor(Color value) {
333		_forecolor = value;
334	}
335
336	// Description: This property is for setting the forecolor for selected items.
337	Color selectedForecolor() {
338		return _selectedForecolor;
339	}
340
341	void selectedForecolor(Color value) {
342		_selectedForecolor = value;
343	}
344
345	// Description: This property is for setting the backcolor for selected items.
346	Color selectedBackcolor() {
347		return _selectedBackcolor;
348	}
349
350	void selectedBackcolor(Color value) {
351		_selectedBackcolor = value;
352	}
353
354protected:
355
356	void drawLine(uint pos) {
357		Console.position(0, pos - _firstVisible);
358
359		if(pos == _pos) {
360			Console.backcolor = _selectedBackcolor;
361			Console.forecolor = _selectedForecolor;
362		}
363		else {
364			Console.backcolor = _backcolor;
365			Console.forecolor = _forecolor;
366		}
367
368		Console.put(_list[pos]);
369
370		if(_list[pos].length < this.width) {
371			Console.putSpaces(this.width - _list[pos].length);
372		}
373	}
374
375	uint _pos = 0;
376	uint _firstVisible = 0;
377
378	Directory _path;
379	List!(string) _list;
380
381	Color _forecolor = Color.White;
382	Color _backcolor = Color.Black;
383
384	Color _selectedForecolor = Color.Yellow;
385	Color _selectedBackcolor = Color.Black;
386
387}