Loot-Quest

Dungeon crawler game made in js
Log | Files | Refs | README | LICENSE

Console.js (6547B)


      1 /*
      2 A DOS-like output console for JavaScript.
      3 http://www.codeproject.com/script/Articles/MemberArticles.aspx?amid=3290305
      4 
      5 Example usage:
      6 var console = new Console('myConsoleDivId', 20, 40);
      7 console.println('A console window with 20 rows and 40 characters.');
      8 console.setCursorPosition(6,6);
      9 console.print('Printing in row 6, column 6');
     10 
     11 To get user-input, include the URL of PromptWindow.htm in the constructor:
     12 var console = new Console('myConsoleDivId', 20, 40);
     13 var yourName = console.input('What is your name? ');
     14 console.println('Hello, ' + yourName);
     15 
     16 */
     17 
     18 
     19 
     20 function Console(elementId, rows, columns, promptWindowUrl) {
     21 	/// <summary>Creates a new Console in the HTML element with given ID, with the specified rows and columns, and optionally the URL to the PromptWindow if the input() function is used.</summary>
     22 
     23 	// Get a reference to the HTML element which will hold the console.
     24 	this.element = document.getElementById(elementId);
     25 	if (!this.element) {
     26 		alert('No element with the ID ' + elementId + ' was found.');
     27 		return;
     28 	}
     29 	// remove any child nodes of the element
     30 	while (this.element.hasChildNodes()) {
     31 		this.element.removeChild(this.element.childNodes[0]);
     32 	}
     33 	// make sure it acts like a 'pre'
     34 	this.element.style.whiteSpace = 'pre';
     35 
     36 	this.rows = Math.floor(rows);
     37 	this.columns = Math.floor(columns);
     38 	this.cursorPosition = {
     39 		row: 0,
     40 		column: 0
     41 	};
     42 	this.charGrid = new Array(this.rows);
     43 	this.promptWindowUrl = promptWindowUrl;
     44 
     45 
     46 	// add the TextNode objects
     47 	for (var i = 0; i < rows; i++) {
     48 		var textNode = document.createTextNode('');
     49 		this.charGrid[i] = textNode;
     50 		this.element.appendChild(textNode);
     51 		if (i < rows - 1) {
     52 			// add a line break between each TextNode
     53 			this.element.appendChild(document.createElement('br'));
     54 		}
     55 	}
     56 
     57 	// clear the console screen
     58 	this.cls();
     59 
     60 }
     61 
     62 Console.prototype.cls = function () {
     63 	/// <summary>Clears all the characters from the console and sets the cursor to 0,0.</summary>
     64 
     65 	// go through each row
     66 	for (var row = 0; row < this.rows; row++) {
     67 
     68 		// get the text node, make a string with 'col' spaces, and set this row as the string
     69 		var textNode = this.charGrid[row];
     70 		var s = '';
     71 		for (var col = 0; col < this.columns; col++) {
     72 			s += ' ';
     73 		}
     74 		textNode.data = s;
     75 	}
     76 	// move cursor to 0,0
     77 	this.setCursorPos(0, 0);
     78 };
     79 
     80 Console.prototype.printAt = function (row, column, str, cycle) {
     81 	/// <summary>Private function - not intended to be used by outside programs. Prints a string at the given row and column, and optionally wraps the text if needed.</summary>
     82 	if (row >= this.rows || row < 0 || column < 0 || !str) {
     83 		// nothing to print
     84 		return;
     85 	}
     86 
     87 	// get the text in the target row
     88 	var oldRow = this.charGrid[row].data;
     89 
     90 	// tentatively put the new text for the row in newRow. This is probably too long or too short
     91 	var newRow = oldRow.substring(0, column) + str;
     92 
     93 	if (newRow.length < this.columns) {
     94 		// the text was too short, so get the remaining characters from the old string.
     95 		// E.g.: oldRow = "0123456789", printing "hi" over '4' so newRow = "0123hi", then appending "6789" to get "0123hi6789"
     96 		newRow += oldRow.substring(column + str.length);
     97 		// move the cursor to the character after the new string, e.g. just after "hi".
     98 		this.setCursorPos(row, column + str.length);
     99 	} else {
    100 		// need to wrap to the next row.
    101 		this.setCursorPos(row + 1, 0);
    102 		if (cycle && this.cursorPosition.row >= this.rows) {
    103 			// moved passed the bottom of the console.  Need to delete the first line, and move each line up by one.
    104 			for (var rowIndex = 0; rowIndex < this.rows - 1; rowIndex++) {
    105 				this.charGrid[rowIndex].data = this.charGrid[rowIndex + 1].data;
    106 			}
    107 			// After moving up, there needs to be a new row at the bottom. Set to empty string.
    108 			var emptyRow = '';
    109 			for (var col = 0; col < this.columns; col++) {
    110 				emptyRow += ' ';
    111 			}
    112 			this.charGrid[this.rows - 1].data = emptyRow;
    113 			// Cycled the lines up, so the current row should cycle by one as well
    114 			this.cursorPosition.row--;
    115 			row--;
    116 		}
    117 	}
    118 
    119 	// truncate the text if it is too long
    120 	if (newRow.length > this.columns) {
    121 		newRow = newRow.substring(0, this.columns);
    122 	}
    123 	// set the text to the current row.
    124 	this.charGrid[row].data = newRow;
    125 };
    126 
    127 Console.prototype.print = function (str) {
    128 	/// <summary>Prints the given string at the current cursor position, wrapping text where necessary.</summary>
    129 
    130 	// get new location of cursor after text added
    131 	var newColumnPos = this.cursorPosition.column + str.length;
    132 
    133 	if (newColumnPos > this.columns) {
    134 		// text is too long to fit on one line.  Add as much as possible, then recursively call print with the remainder of the string
    135 
    136 		var charsLeftOnCurLine = this.columns - this.cursorPosition.column;
    137 		var s = str.substring(0, charsLeftOnCurLine);
    138 
    139 		// print the first part
    140 		this.print(s);
    141 
    142 		// print rest of string
    143 		this.print(str.substring(charsLeftOnCurLine));
    144 
    145 	} else {
    146 		// print the string at the current cursor position
    147 		this.printAt(this.cursorPosition.row, this.cursorPosition.column, str, true);
    148 	}
    149 
    150 };
    151 
    152 Console.prototype.println = function (str) {
    153 	/// <summary>Prints the given string at the current cursor position, wrapping text where necessary, and appends a line break.</summary>
    154 	if (!str) {
    155 		str = '';
    156 	}
    157 
    158 	// Actually, we don't add line-breaks. We simply pad out the line with spaces to that the cursor will be forced to the next line.
    159 	var extraSpaces = this.columns - ((this.cursorPosition.column + str.length) % this.columns);
    160 	var s2 = str;
    161 	for (var i = 0; i < extraSpaces; i++) {
    162 		s2 += ' ';
    163 	}
    164 	this.print(s2);
    165 };
    166 
    167 Console.prototype.setCursorPos = function (row, column) {
    168 	/// <summary>Sets the cursor position to the given row and column.</summary>
    169 	this.cursorPosition.row = row;
    170 	this.cursorPosition.column = column;
    171 };
    172 
    173 Console.prototype.input = function (message) {
    174 	/// <summary>Gets textual input from the user, and prints the message and the user's input to the screen.</summary>
    175 	if (message) {
    176 		this.print(message);
    177 	}
    178 
    179 	var result;
    180 	if (window.showModalDialog) {
    181 		// IE7 blocks calls to window.prompt (insanity!), so we need to use their showModalDialog
    182 		if (!this.promptWindowUrl) {
    183 			alert('JS Console Error\nConsole.promptWindowUrl not set. Set this to the URL of PromptWindow.htm\nPrompts disabled in Internet Explorer.');
    184 			return '';
    185 		}
    186 		result = window.showModalDialog(this.promptWindowUrl, message, "dialogWidth:300px;dialogHeight:200px");
    187 	} else {
    188 		result = prompt(message);
    189 	}
    190 
    191 	if (result) {
    192 		this.println(result);
    193 		return result;
    194 	} else {
    195 		return '';
    196 	}
    197 };