Index: experimental/conways_life/controllers/stamp_editor.js |
diff --git a/experimental/conways_life/controllers/stamp_editor.js b/experimental/conways_life/controllers/stamp_editor.js |
deleted file mode 100644 |
index 2090026892b6197ae01671b3c74440b0470b9bcd..0000000000000000000000000000000000000000 |
--- a/experimental/conways_life/controllers/stamp_editor.js |
+++ /dev/null |
@@ -1,437 +0,0 @@ |
-// Copyright (c) 2011 The Native Client Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-/** |
- * @file |
- * The stamp editor object. This manages a table whose cells represent cells |
- * of the stamp. Clicking on a table cell changes the state of the |
- * corresponding stamp cell. The table can be resized. |
- */ |
- |
- |
-goog.provide('stamp'); |
-goog.provide('stamp.Editor'); |
- |
-goog.require('goog.Disposable'); |
-goog.require('goog.dom'); |
-goog.require('goog.editor.Table'); |
-goog.require('goog.events'); |
-goog.require('goog.style'); |
- |
-/** |
- * Manages the data and interface for the stamp editor. |
- * @param {!Element} noteContainer The element under which DOM nodes for |
- * the stamp editor should be added. |
- * @constructor |
- * @extends {goog.Disposable} |
- */ |
-stamp.Editor = function() { |
- goog.Disposable.call(this); |
-}; |
-goog.inherits(stamp.Editor, goog.events.EventTarget); |
- |
-/** |
- * The table that represents the stamp. |
- * @type {goog.editor.Table} |
- * @private |
- */ |
-stamp.Editor.prototype.stampEditorTable_ = null; |
- |
-/** |
- * The minimum number of rows and columns in the stamp editor table. |
- */ |
-stamp.Editor.prototype.MIN_ROW_COUNT = 3; |
-stamp.Editor.prototype.MIN_COLUMN_COUNT = 3; |
- |
-/** |
- * Attributes added to cells to cache certain parameters like aliveState. |
- * @enum {string} |
- * @private |
- */ |
-stamp.Editor.CellAttributes_ = { |
- IS_ALIVE: 'isalive' // Whether the cell is alive or dead. |
-}; |
- |
-/** |
- * Characters used to encode the stamp as a string. |
- * @enum {string} |
- * @private |
- */ |
-stamp.Editor.StringEncoding_ = { |
- DEAD_CELL: '.', |
- END_OF_ROW: '\n', |
- LIVE_CELL: '*' |
-}; |
- |
-/** |
- * Override of disposeInternal() to dispose of retained objects and unhook all |
- * events. |
- * @override |
- */ |
-stamp.Editor.prototype.disposeInternal = function() { |
- var tableCells = |
- this.stampEditorTable_.element.getElementsByTagName(goog.dom.TagName.TD); |
- for (var i = 0; i < tableCells.length; ++i) { |
- goog.events.removeAll(tableCells[i]); |
- } |
- this.stampEditorTable_ = null; |
- stamp.Editor.superClass_.disposeInternal.call(this); |
-} |
- |
-/** |
- * Fills out the TABLE structure for the stamp editor. The stamp editor |
- * can be resized, and handles clicks in its cells by toggling their state. |
- * The resulting TABLE element will have the minumum number of rows and |
- * columns, and be filled in with a default stamp that creates a glider. |
- * @param {!Element<TABLE>} stampEditorTableElement The TABLE element that gets |
- * filled out with the editable cells. |
- * @private |
- */ |
-stamp.Editor.prototype.makeStampEditorDom = function(stampEditorTableElement) { |
- var domTable = goog.editor.Table.createDomTable( |
- document, |
- this.MIN_COLUMN_COUNT, |
- this.MIN_ROW_COUNT, |
- { 'borderWidth': 1, 'borderColor': 'white' }); |
- var tableStyle = { |
- 'borderCollpase': 'collapse', |
- 'borderSpacing': '0px', |
- 'borderStyle': 'solid' |
- }; |
- |
- goog.style.setStyle(domTable, tableStyle); |
- var tableCells = |
- domTable.getElementsByTagName(goog.dom.TagName.TD); |
- this.initCells_(tableCells); |
- goog.dom.appendChild(stampEditorTableElement, domTable); |
- this.stampEditorTable_ = new goog.editor.Table(domTable); |
-} |
- |
-/** |
- * Initialize a list of cells to the "alive" state: sets the is-alive |
- * attribute and the enclosed image element. Fix up the various attributes |
- * that goog.editor.Table sets on cells. |
- * @param {!Array<Element>} cells The array of cells to initialize. |
- * @private |
- */ |
-stamp.Editor.prototype.initCells_ = function(cells) { |
- var cellStyle = { |
- 'padding': '0px' |
- }; |
- for (var i = 0; i < cells.length; ++i) { |
- var cell = cells[i]; |
- // The goog.editor.Table functions set the cell widths to 60px. |
- cell.style.removeProperty('width'); |
- goog.style.setStyle(cell, cellStyle); |
- this.setCellIsAlive(cell, false); |
- goog.events.listen(cell, goog.events.EventType.CLICK, |
- this.toggleCellState_, false, this); |
- } |
-} |
- |
-/** |
- * Inspect the encoded stamp string and make sure it's valid. Add things like |
- * newline characters when necessary. |stampStringIn| is assumed to have |
- * length > 0. |
- * @param {!string} stampStringIn The input stamp string. Must have length > 0. |
- * @return {!string} The santized version of the input string. |
- * @private |
- */ |
-stamp.Editor.prototype.sanitizeStampString_ = function(stampStringIn) { |
- var stampString = stampStringIn; |
- if (stampString[stampString.length - 1] != |
- stamp.Editor.StringEncoding_.END_OF_ROW) { |
- stampString += stamp.Editor.StringEncoding_.END_OF_ROW; |
- } |
- return stampString; |
-} |
- |
-/** |
- * Compute a stamp size from an encoded stamp string. Stamps are assumed to be |
- * rectangular. The width is the length in characters of the first line in |
- * the stamp string. The height is the number of lines. |
- * @param {!string} stampString The encoded stamp string. Must have length > 0. |
- * @return {!Object} An object containing width and height. |
- * @private |
- */ |
-stamp.Editor.prototype.getSizeFromStampString_ = function(stampString) { |
- var size = {width: 0, height: 0}; |
- var eorPos = stampString.indexOf(stamp.Editor.StringEncoding_.END_OF_ROW); |
- if (eorPos == -1) { |
- // The stamp string is a single row. |
- size.width = stampString.length; |
- size.height = 1; |
- } else { |
- size.width = eorPos; |
- // Count up the number of rows in the encoded string. |
- var rowCount = 0; |
- do { |
- ++rowCount; |
- eorPos = stampString.indexOf(stamp.Editor.StringEncoding_.END_OF_ROW, |
- eorPos + 1); |
- } while (eorPos != -1); |
- size.height = rowCount; |
- } |
- return size; |
-} |
- |
-/** |
- * Return the current stamp expressed as a string. The format loosely follows |
- * the .LIF 1.05 "spec", where rows are delineated by a \n, a live cell is |
- * represented by a '*' and a dead one by a '.'. |
- */ |
-stamp.Editor.prototype.getStampAsString = function() { |
- var stampString = ''; |
- var rowCount = this.rowCount(); |
- for (var rowIndex = 0; rowIndex < rowCount; ++rowIndex) { |
- var row = this.stampEditorTable_.rows[rowIndex]; |
- for (var colIndex = 0; colIndex < row.columns.length; ++colIndex) { |
- var cell = row.columns[colIndex]; |
- if (this.cellIsAlive(cell.element)) { |
- stampString += stamp.Editor.StringEncoding_.LIVE_CELL; |
- } else { |
- stampString += stamp.Editor.StringEncoding_.DEAD_CELL; |
- } |
- } |
- stampString += stamp.Editor.StringEncoding_.END_OF_ROW; |
- } |
- return stampString; |
-} |
- |
-/** |
- * Sets the current stamp baes on the stamp encoding in |stampString|. The |
- * format loosely follows the .LIF 1.05 "spec", where rows are delineated by a |
- * \n, a live cell is represented by a '*' and a dead one by a '.'. |
- * @param {!string} stampString The encoded stamp string. |
- */ |
-stamp.Editor.prototype.setStampFromString = function(stampStringIn) { |
- if (stampStringIn.length == 0) |
- return; // Error? |
- var stampString = this.sanitizeStampString_(stampStringIn); |
- var newSize = this.getSizeFromStampString_(stampString); |
- this.resize(newSize.width, newSize.height); |
- |
- // Set all the cells to "dead". |
- var tableCells = |
- this.stampEditorTable_.element.getElementsByTagName(goog.dom.TagName.TD); |
- this.initCells_(tableCells); |
- |
- // Parse the stamp string and set cell states. |
- var rowIndex = 0; |
- var columnIndex = 0; |
- for (var i = 0; i < stampString.length; ++i) { |
- var cell = this.domCellAt(rowIndex, columnIndex); |
- switch (stampString.charAt(i)) { |
- case stamp.Editor.StringEncoding_.DEAD_CELL: |
- this.setCellIsAlive(cell, false); |
- ++columnIndex; |
- break; |
- case stamp.Editor.StringEncoding_.LIVE_CELL: |
- this.setCellIsAlive(cell, true); |
- ++columnIndex; |
- break; |
- case stamp.Editor.StringEncoding_.END_OF_ROW: |
- ++rowIndex; |
- columnIndex = 0; |
- break; |
- default: |
- // Invalid character, set the cell to "dead". |
- this.setCellIsAlive(cell, false); |
- ++columnIndex; |
- break; |
- } |
- } |
-} |
- |
-/** |
- * Return the first TABLE cell element that contains |target|. Return null |
- * if there is no such enclosing element. |
- * @return {?Element} The DOM element (a TD) that contains |target|. |
- */ |
-stamp.Editor.prototype.enclosingTargetForElement = function(target) { |
- // The cell is the enclosing TD element. |
- var domCell = goog.dom.getAncestor(target, function(node) { |
- return node.tagName && node.tagName.toUpperCase() == goog.dom.TagName.TD; |
- }); |
- return domCell; |
-} |
- |
-/** |
- * Respond to a CLICK event in a table cell by toggling its state. |
- * @param {!goog.events.Event} clickEvent The CLICK event that triggered this |
- * handler. |
- * @private |
- */ |
-stamp.Editor.prototype.toggleCellState_ = function(clickEvent) { |
- var cell = this.enclosingTargetForElement(clickEvent.target); |
- if (!cell) |
- return; |
- // TODO(dspringer): throw an error or assert if no enclosing TD element is |
- // found. |
- this.setCellIsAlive(cell, !this.cellIsAlive(cell)); |
-} |
- |
-/** |
- * Return the DOM element for the cell at location (|row|, |column|) (this is |
- * usually a TD element). |
- * @param {number} rowIndex The row index. This is 0-based. |
- * @param {number} columnIndex The column index. This is 0-based. |
- * @return {?Element} The TD element representing the cell. If no cell exists |
- * then return null. |
- */ |
-stamp.Editor.prototype.domCellAt = function(rowIndex, columnIndex) { |
- if (rowIndex < 0 || rowIndex >= this.stampEditorTable_.rows.length) |
- return null; |
- var row = this.stampEditorTable_.rows[rowIndex]; |
- if (columnIndex < 0 || columnIndex >= row.columns.length) |
- return null; |
- return row.columns[columnIndex].element; |
-} |
- |
-/** |
- * Resize the table of cells to contain |width| columns and |height| rows. A |
- * 0 value for either dimension leaves that dimension unchanged. Both |
- * dimensions are clamped to the minumum and maximum row/column counts. |
- * @param {!number} width The new width, must be >= 0. |
- * @param {!number} height The new height, must be >= 0. |
- */ |
-stamp.Editor.prototype.resize = function(width, height) { |
- if (width < this.MIN_COLUMN_COUNT) { |
- width = this.MIN_COLUMN_COUNT; |
- } |
- if (height < this.MIN_ROW_COUNT) { |
- height = this.MIN_ROW_COUNT; |
- } |
- var currentWidth = this.columnCount(); |
- if (width > 0 && width != currentWidth) { |
- if (currentWidth < width) { |
- for (var col = 0; col < width - currentWidth; ++col) { |
- this.appendColumn(); |
- } |
- } else { |
- for (var col = 0; col < currentWidth - width; ++col) { |
- this.removeLastColumn(); |
- } |
- } |
- } |
- var currentHeight = this.rowCount(); |
- if (height > 0 && height != currentHeight) { |
- if (currentHeight < height) { |
- for (var row = 0; row < height - currentHeight; ++row) { |
- this.appendRow(); |
- } |
- } else { |
- for (var row = 0; row < currentHeight - height; ++row) { |
- this.removeLastRow(); |
- } |
- } |
- } |
-} |
- |
-/** |
- * Add a column at the right-end of the editor table. |
- */ |
-stamp.Editor.prototype.appendColumn = function() { |
- var newCells = this.stampEditorTable_.insertColumn(); |
- this.initCells_(newCells); |
-} |
- |
-/** |
- * Remove the last column of editor table cells. If the number of columns is |
- * already at the minumum, do nothing. |
- */ |
-stamp.Editor.prototype.removeLastColumn = function() { |
- var columnCount = this.columnCount(); |
- if (columnCount <= this.MIN_COLUMN_COUNT) { |
- return; |
- } |
- // Unhook all the listeners that have been attached to the cells in the |
- // last column, then remove the column. |
- for (var i = 0; i < this.stampEditorTable_.rows.length; ++i) { |
- var row = this.stampEditorTable_.rows[i]; |
- var cell = row.columns[columnCount - 1]; |
- goog.events.removeAll(cell); |
- } |
- this.stampEditorTable_.removeColumn(columnCount - 1); |
-} |
- |
-/** |
- * Return the number of columns in the stamp editor table. This assumes that |
- * there are no merged cells in row[0], and that the number of cells in all |
- * rows is the same as the length of row[0]. |
- * @return {int} The number of columns. |
- */ |
-stamp.Editor.prototype.columnCount = function() { |
- if (!this.stampEditorTable_) |
- return 0; |
- if (!this.stampEditorTable_.rows) |
- return 0; |
- if (!this.stampEditorTable_.rows[0].columns) |
- return 0; |
- return this.stampEditorTable_.rows[0].columns.length; |
-} |
- |
-/** |
- * Add a row at the bottom of the editor table. |
- */ |
-stamp.Editor.prototype.appendRow = function() { |
- var newTableRow = this.stampEditorTable_.insertRow(); |
- this.initCells_(goog.editor.Table.getChildCellElements(newTableRow)); |
-} |
- |
-/** |
- * Remove the last row of editor table cells. If the number of rows is already |
- * at the minumum, do nothing. |
- */ |
-stamp.Editor.prototype.removeLastRow = function() { |
- var rowCount = this.rowCount(); |
- if (rowCount <= this.MIN_ROW_COUNT) { |
- return; |
- } |
- // Unhook all the listeners that have been attached to the cells in the |
- // last row, then remove the row. |
- var lastRow = this.stampEditorTable_.rows[rowCount - 1]; |
- for (var i = 0; i < lastRow.columns.length; ++i) { |
- var cell = lastRow.columns[i]; |
- goog.events.removeAll(cell); |
- } |
- this.stampEditorTable_.removeRow(rowCount - 1); |
-} |
- |
-/** |
- * Return the number of rows in the stamp editor table. Assumes that there are |
- * no merged cells in any columns. |
- * @return {int} The number of rows. |
- */ |
-stamp.Editor.prototype.rowCount = function() { |
- if (!this.stampEditorTable_) |
- return 0; |
- if (!this.stampEditorTable_.rows) |
- return 0; |
- return this.stampEditorTable_.rows.length; |
-} |
- |
-/** |
- * Accessor for the is-alive state of a cell. |
- * @param {!Element} domCell The DOM element representing the target cell. |
- * @return {bool} The is-alive state of |cell|. |
- */ |
-stamp.Editor.prototype.cellIsAlive = function(domCell) { |
- isAlive = domCell.getAttribute(stamp.Editor.CellAttributes_.IS_ALIVE); |
- return isAlive != 'false'; |
-} |
- |
-/** |
- * Change the is-alive state of a cell to |isAlive|. The appearance of the cell |
- * is also changed to match the new state. |
- * @param {!Element} domCell The DOM element representing the target cell. |
- * @param {bool} isAlive The new is-alive state of the cell. |
- */ |
-stamp.Editor.prototype.setCellIsAlive = function(domCell, isAlive) { |
- domCell.setAttribute(stamp.Editor.CellAttributes_.IS_ALIVE, isAlive); |
- var cellImg = isAlive ? 'img/live_cell.png' : 'img/dead_cell.png'; |
- domCell.innerHTML = '<img src="' + |
- cellImg + |
- '" alt="Click to change state." />'; |
-} |