1effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved. 2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file. 45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)(function(exports) { 55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /** 65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * Alignment options for a keyset. 75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * @param {Object=} opt_keyset The keyset to calculate the dimensions for. 85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * Defaults to the current active keyset. 95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) */ 105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var AlignmentOptions = function(opt_keyset) { 115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var keyboard = document.getElementById('keyboard'); 125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var keyset = opt_keyset || keyboard.activeKeyset; 135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) this.calculate(keyset); 145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AlignmentOptions.prototype = { 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /** 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * The width of a regular key in logical pixels. 195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * @type {number} 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) */ 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) keyWidth: 0, 225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /** 245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * The horizontal space between two keys in logical pixels. 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * @type {number} 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) */ 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pitchX: 0, 285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /** 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * The vertical space between two keys in logical pixels. 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * @type {number} 325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) */ 335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pitchY: 0, 345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /** 365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * The width in logical pixels the row should expand within. 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * @type {number} 385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) */ 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) availableWidth: 0, 405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /** 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * The x-coordinate in logical pixels of the left most edge of the keyset. 435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * @type {number} 445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) */ 455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) offsetLeft: 0, 465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /** 485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * The x-coordinate of the right most edge in logical pixels of the keyset. 495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * @type {number} 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) */ 515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) offsetRight: 0, 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /** 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * The height in logical pixels of all keys. 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * @type {number} 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) */ 575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) keyHeight: 0, 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /** 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * The height in logical pixels the keyset should stretch to fit. 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * @type {number} 625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) */ 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) availableHeight: 0, 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /** 665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * The y-coordinate in logical pixels of the top most edge of the keyset. 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * @type {number} 685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) */ 695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) offsetTop: 0, 705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /** 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * The y-coordinate in logical pixels of the bottom most edge of the keyset. 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * @type {number} 745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) */ 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) offsetBottom: 0, 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /** 78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * The ideal width of the keyboard container. 79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * @type {number} 80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) */ 81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) width: 0, 82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) /** 84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * The ideal height of the keyboard container. 85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * @type {number} 86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) */ 87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) height: 0, 88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) /** 905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * Recalculates the alignment options for a specific keyset. 915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * @param {Object} keyset The keyset to align. 925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) */ 935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) calculate: function (keyset) { 945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var rows = keyset.querySelectorAll('kb-row').array(); 955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Pick candidate row. This is the row with the most keys. 965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var row = rows[0]; 975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var candidateLength = rows[0].childElementCount; 985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (var i = 1; i < rows.length; i++) { 995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (rows[i].childElementCount > candidateLength && 1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) rows[i].align == RowAlignment.STRETCH) { 1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) row = rows[i]; 1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) candidateLength = rows[i].childElementCount; 1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var allKeys = row.children; 1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Calculates widths first. 1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Weight of a single interspace. 1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var pitches = keyset.pitch.split(); 1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var pitchWeightX; 1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var pitchWeightY; 1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pitchWeightX = parseFloat(pitches[0]); 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pitchWeightY = pitches.length < 2 ? pitchWeightX : parseFloat(pitch[1]); 1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Sum of all keys in the current row. 1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var keyWeightSumX = 0; 1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (var i = 0; i < allKeys.length; i++) { 1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) keyWeightSumX += allKeys[i].weight; 1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var interspaceWeightSumX = (allKeys.length -1) * pitchWeightX; 1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Total weight of the row in X. 1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var totalWeightX = keyWeightSumX + interspaceWeightSumX + 1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) keyset.weightLeft + keyset.weightRight; 125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) var keyAspectRatio = getKeyAspectRatio(); 1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var totalWeightY = (pitchWeightY * (rows.length - 1)) + 1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) keyset.weightTop + 1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) keyset.weightBottom; 1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (var i = 0; i < rows.length; i++) { 130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) totalWeightY += rows[i].weight / keyAspectRatio; 1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Calculate width and height of the window. 1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var bounds = exports.getKeyboardBounds(); 1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) this.width = bounds.width; 136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) this.height = bounds.height; 1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var pixelPerWeightX = bounds.width/totalWeightX; 1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var pixelPerWeightY = bounds.height/totalWeightY; 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (keyset.align == LayoutAlignment.CENTER) { 1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (totalWeightX/bounds.width < totalWeightY/bounds.height) { 1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pixelPerWeightY = bounds.height/totalWeightY; 1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pixelPerWeightX = pixelPerWeightY; 144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) this.width = Math.floor(pixelPerWeightX * totalWeightX) 1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pixelPerWeightX = bounds.width/totalWeightX; 1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pixelPerWeightY = pixelPerWeightX; 148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) this.height = Math.floor(pixelPerWeightY * totalWeightY); 1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Calculate pitch. 1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) this.pitchX = Math.floor(pitchWeightX * pixelPerWeightX); 1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) this.pitchY = Math.floor(pitchWeightY * pixelPerWeightY); 1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Convert weight to pixels on x axis. 156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) this.keyWidth = Math.floor(DEFAULT_KEY_WEIGHT * pixelPerWeightX); 1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var offsetLeft = Math.floor(keyset.weightLeft * pixelPerWeightX); 1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var offsetRight = Math.floor(keyset.weightRight * pixelPerWeightX); 159a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) this.availableWidth = this.width - offsetLeft - offsetRight; 1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Calculates weight to pixels on the y axis. 162a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) var weightY = Math.floor(DEFAULT_KEY_WEIGHT / keyAspectRatio); 163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) this.keyHeight = Math.floor(weightY * pixelPerWeightY); 1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var offsetTop = Math.floor(keyset.weightTop * pixelPerWeightY); 1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var offsetBottom = Math.floor(keyset.weightBottom * pixelPerWeightY); 166a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) this.availableHeight = this.height - offsetTop - offsetBottom; 1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 168a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) var dX = bounds.width - this.width; 1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) this.offsetLeft = offsetLeft + Math.floor(dX/2); 1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) this.offsetRight = offsetRight + Math.ceil(dX/2) 1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 172a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) var dY = bounds.height - this.height; 1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) this.offsetBottom = offsetBottom + dY; 1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) this.offsetTop = offsetTop; 1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) }, 1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) }; 1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /** 179a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * A simple binary search. 180a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * @param {Array} array The array to search. 181a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * @param {number} start The start index. 182a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * @param {number} end The end index. 183a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * @param {Function<Object>:number} The test function used for searching. 184a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * @private 185a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * @return {number} The index of the search, or -1 if it was not found. 186a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) */ 187a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) function binarySearch_(array, start, end, testFn) { 188a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (start > end) { 189a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // No match found. 190a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return -1; 191a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 192a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) var mid = Math.floor((start+end)/2); 193a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) var result = testFn(mid); 194a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (result == 0) 195a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return mid; 196a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (result < 0) 197a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return binarySearch_(array, start, mid - 1, testFn); 198a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) else 199a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return binarySearch_(array, mid + 1, end, testFn); 200a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 201a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 202a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) /** 2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * Calculate width and height of the window. 2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * @private 2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * @return {Array.<String, number>} The bounds of the keyboard container. 2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) */ 2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) function getKeyboardBounds_() { 2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return { 2090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch "width": screen.width, 2105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu "height": screen.height * DEFAULT_KEYBOARD_ASPECT_RATIO 2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) }; 2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 213a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 214a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) /** 215a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * Calculates the desired key aspect ratio based on screen size. 216a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * @return {number} The aspect ratio to use. 217a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) */ 218a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) function getKeyAspectRatio() { 219a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return (screen.width > screen.height) ? 220a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) KEY_ASPECT_RATIO_LANDSCAPE : KEY_ASPECT_RATIO_PORTRAIT; 221a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 222a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 2235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /** 2245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * Callback function for when the window is resized. 2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) */ 2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var onResize = function() { 2275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var keyboard = $('keyboard'); 2285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) keyboard.stale = true; 2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var keyset = keyboard.activeKeyset; 2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (keyset) 2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) realignAll(); 2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) }; 2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /** 2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * Updates a specific key to the position specified. 2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * @param {Object} key The key to update. 2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * @param {number} width The new width of the key. 2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * @param {number} height The new height of the key. 2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * @param {number} left The left corner of the key. 2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * @param {number} top The top corner of the key. 2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) */ 2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) function updateKey(key, width, height, left, top) { 2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) key.style.position = 'absolute'; 2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) key.style.width = width + 'px'; 2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) key.style.height = (height - KEY_PADDING_TOP - KEY_PADDING_BOTTOM) + 'px'; 2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) key.style.left = left + 'px'; 2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) key.style.top = (top + KEY_PADDING_TOP) + 'px'; 2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /** 2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * Returns the key closest to given x-coordinate 2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * @param {Array.<kb-key>} allKeys Sorted array of all possible key 2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * candidates. 2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * @param {number} x The x-coordinate. 2555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * @param {number} pitch The pitch of the row. 2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * @param {boolean} alignLeft whether to search with respect to the left or 2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * or right edge. 258a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * @return {?kb-key} 2595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) */ 2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) function findClosestKey(allKeys, x, pitch, alignLeft) { 2615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Test function. 2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var testFn = function(i) { 2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var ERROR_THRESH = 1; 2645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var key = allKeys[i]; 2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var left = parseFloat(key.style.left); 2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!alignLeft) 2675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) left += parseFloat(key.style.width); 2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var deltaRight = 0.5*(parseFloat(key.style.width) + pitch) 2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) deltaLeft = 0.5 * pitch; 2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (i > 0) 2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) deltaLeft += 0.5*parseFloat(allKeys[i-1].style.width); 2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var high = Math.ceil(left + deltaRight) + ERROR_THRESH; 2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var low = Math.floor(left - deltaLeft) - ERROR_THRESH; 2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (x <= high && x >= low) 2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return 0; 2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return x >= high? 1 : -1; 2775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 278a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) var index = exports.binarySearch(allKeys, 0, allKeys.length -1, testFn); 279a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return index > 0 ? allKeys[index] : null; 2805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /** 2835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * Redistributes the total width amongst the keys in the range provided. 2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * @param {Array.<kb-key>} allKeys Ordered list of keys to stretch. 2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * @param {AlignmentOptions} params Options for aligning the keyset. 2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * @param {number} xOffset The x-coordinate of the key who's index is start. 2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * @param {number} width The total extraneous width to distribute. 2885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * @param {number} keyHeight The height of each key. 2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * @param {number} yOffset The y-coordinate of the top edge of the row. 2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) */ 2915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) function redistribute(allKeys, params, xOffset, width, keyHeight, yOffset) { 2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var availableWidth = width - (allKeys.length - 1) * params.pitchX; 2935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var stretchWeight = 0; 2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var nStretch = 0; 2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (var i = 0; i < allKeys.length; i++) { 2965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var key = allKeys[i]; 2975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (key.stretch) { 2985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) stretchWeight += key.weight; 2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) nStretch++; 300a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } else if (key.weight == DEFAULT_KEY_WEIGHT) { 3015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) availableWidth -= params.keyWidth; 3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) availableWidth -= 304a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Math.floor(key.weight/DEFAULT_KEY_WEIGHT * params.keyWidth); 3055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (stretchWeight <= 0) 3085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) console.error("Cannot stretch row without a stretchable key"); 3095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Rounding error to distribute. 3105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var pixelsPerWeight = availableWidth / stretchWeight; 3115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (var i = 0; i < allKeys.length; i++) { 3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var key = allKeys[i]; 3135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var keyWidth = params.keyWidth; 314a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (key.weight != DEFAULT_KEY_WEIGHT) { 3155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) keyWidth = 316a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Math.floor(key.weight/DEFAULT_KEY_WEIGHT * params.keyWidth); 3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (key.stretch) { 3195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) nStretch--; 3205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (nStretch > 0) { 3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) keyWidth = Math.floor(key.weight * pixelsPerWeight); 3225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) availableWidth -= keyWidth; 3235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 3245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) keyWidth = availableWidth; 3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) updateKey(key, keyWidth, keyHeight, xOffset, yOffset) 3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) xOffset += keyWidth + params.pitchX; 3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /** 3335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * Aligns a row such that the spacebar is perfectly aligned with the row above 3345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * it. A precondition is that all keys in this row can be stretched as needed. 3355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * @param {!kb-row} row The current row to be aligned. 3365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * @param {!kb-row} prevRow The row above the current row. 3375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * @param {!AlignmentOptions} params Options for aligning the keyset. 3385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * @param {number} keyHeight The height of the keys in this row. 3395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * @param {number} heightOffset The height offset caused by the rows above. 3405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) */ 3415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) function realignSpacebarRow(row, prevRow, params, keyHeight, heightOffset) { 3425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var allKeys = row.children; 3435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var stretchWeightBeforeSpace = 0; 3445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var stretchBefore = 0; 3455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var stretchWeightAfterSpace = 0; 3465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var stretchAfter = 0; 3475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var spaceIndex = -1; 3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (var i=0; i< allKeys.length; i++) { 3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (spaceIndex == -1) { 3515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (allKeys[i].classList.contains('space')) { 3525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) spaceIndex = i; 3535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) continue; 3545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 3555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) stretchWeightBeforeSpace += allKeys[i].weight; 3565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) stretchBefore++; 3575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 3595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) stretchWeightAfterSpace += allKeys[i].weight; 3605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) stretchAfter++; 3615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (spaceIndex == -1) { 3645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) console.error("No spacebar found in this row."); 3655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 3665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var totalWeight = stretchWeightBeforeSpace + 3685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) stretchWeightAfterSpace + 3695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) allKeys[spaceIndex].weight; 3705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var widthForKeys = params.availableWidth - 3715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (params.pitchX * (allKeys.length - 1 )) 3725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Number of pixels to assign per unit weight. 3735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var pixelsPerWeight = widthForKeys/totalWeight; 3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Predicted left edge of the space bar. 3755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var spacePredictedLeft = params.offsetLeft + 3765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (spaceIndex * params.pitchX) + 3775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (stretchWeightBeforeSpace * pixelsPerWeight); 3785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var prevRowKeys = prevRow.children; 3795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Find closest keys to the spacebar in order to align it to them. 3805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var leftKey = 3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) findClosestKey(prevRowKeys, spacePredictedLeft, params.pitchX, true); 3825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var spacePredictedRight = spacePredictedLeft + 3845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) allKeys[spaceIndex].weight * (params.keyWidth/100); 3855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var rightKey = 3875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) findClosestKey(prevRowKeys, spacePredictedRight, params.pitchX, false); 3885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var yOffset = params.offsetTop + heightOffset; 3905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Fix left side. 3915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var leftEdge = parseFloat(leftKey.style.left); 3925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var leftWidth = leftEdge - params.offsetLeft - params.pitchX; 3935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var leftKeys = allKeys.array().slice(0, spaceIndex); 3945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) redistribute(leftKeys, 3955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) params, 3965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) params.offsetLeft, 3975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) leftWidth, 3985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) keyHeight, 3995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) yOffset); 4005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Fix right side. 4015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var rightEdge = parseFloat(rightKey.style.left) + 4025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) parseFloat(rightKey.style.width); 4035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var spacebarWidth = rightEdge - leftEdge; 4045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) updateKey(allKeys[spaceIndex], 4055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) spacebarWidth, 4065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) keyHeight, 4075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) leftEdge, 4085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) yOffset); 4095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var rightWidth = 4105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) params.availableWidth - (rightEdge - params.offsetLeft + params.pitchX); 4115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var rightKeys = allKeys.array().slice(spaceIndex + 1); 4125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) redistribute(rightKeys, 4135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) params, 4145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) rightEdge + params.pitchX,//xOffset. 4155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) rightWidth, 4165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) keyHeight, 4175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) yOffset); 4185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 4195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /** 4215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * Realigns a given row based on the parameters provided. 4225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * @param {!kb-row} row The row to realign. 4235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * @param {!AlignmentOptions} params The parameters used to align the keyset. 4241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * @param {number} keyHeight The height of the keys. 4255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * @param {number} heightOffset The offset caused by rows above it. 4265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) */ 4275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) function realignRow(row, params, keyHeight, heightOffset) { 4285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var all = row.children; 4295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var nStretch = 0; 4305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var stretchWeightSum = 0; 4315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var allSum = 0; 4325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Keeps track of where to distribute pixels caused by round off errors. 4335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var deltaWidth = []; 4345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (var i = 0; i < all.length; i++) { 4355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) deltaWidth.push(0) 4365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var key = all[i]; 437a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (key.weight == DEFAULT_KEY_WEIGHT){ 4385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) allSum += params.keyWidth; 4395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 4405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var width = 441a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Math.floor((params.keyWidth/DEFAULT_KEY_WEIGHT) * key.weight); 4425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) allSum += width; 4435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 4445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!key.stretch) 4455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) continue; 4465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) nStretch++; 4475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) stretchWeightSum += key.weight; 4485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 4495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var nRegular = all.length - nStretch; 4505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Extra space. 4515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var extra = params.availableWidth - 4525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) allSum - 4535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (params.pitchX * (all.length -1)); 4545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var xOffset = params.offsetLeft; 4555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var alignment = row.align; 4575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) switch (alignment) { 4585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case RowAlignment.STRETCH: 4595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var extraPerWeight = extra/stretchWeightSum; 4605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (var i = 0; i < all.length; i++) { 4615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!all[i].stretch) 4625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) continue; 4635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var delta = Math.floor(all[i].weight * extraPerWeight); 4645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) extra -= delta; 4655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) deltaWidth[i] = delta; 4665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // All left-over pixels assigned to right most stretchable key. 4675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) nStretch--; 4685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (nStretch == 0) 4695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) deltaWidth[i] += extra; 4705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 4715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 4725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case RowAlignment.CENTER: 4735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) xOffset += Math.floor(extra/2) 4745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 4755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case RowAlignment.RIGHT: 4765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) xOffset += extra; 4775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 4785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) default: 4795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 4805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) }; 4815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var yOffset = params.offsetTop + heightOffset; 4835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var left = xOffset; 4845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (var i = 0; i < all.length; i++) { 4855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var key = all[i]; 4865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var width = params.keyWidth; 487a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (key.weight != DEFAULT_KEY_WEIGHT) 488a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) width = Math.floor((params.keyWidth/DEFAULT_KEY_WEIGHT) * key.weight) 4895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) width += deltaWidth[i]; 4905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) updateKey(key, width, keyHeight, left, yOffset) 4915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) left += (width + params.pitchX); 4925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 4935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 4945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /** 4965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * Realigns the keysets in all layouts of the keyboard. 4975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) */ 4985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) function realignAll() { 499c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch resizeKeyboardContainer() 5005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var keyboard = $('keyboard'); 5015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var layoutParams = {}; 5025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var idToLayout = function(id) { 5035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var parts = id.split('-'); 5045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) parts.pop(); 5055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return parts.join('-'); 5065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 5075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var keysets = keyboard.querySelectorAll('kb-keyset').array(); 5095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (var i=0; i< keysets.length; i++) { 5105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var keyset = keysets[i]; 5115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var layout = idToLayout(keyset.id); 5125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Caches the layouts size parameters since all keysets in the same layout 5135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // will have the same specs. 5145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!(layout in layoutParams)) 5155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) layoutParams[layout] = new AlignmentOptions(keyset); 5165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) realignKeyset(keyset, layoutParams[layout]); 5175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 518a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) exports.recordKeysets(); 5195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 5205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /** 5225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * Realigns the keysets in the current layout of the keyboard. 5235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) */ 5245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) function realign() { 5255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var keyboard = $('keyboard'); 5265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var params = new AlignmentOptions(); 527c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Check if current window bounds are accurate. 528c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch resizeKeyboardContainer(params) 5295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var layout = keyboard.layout; 5305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var keysets = 5315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) keyboard.querySelectorAll('kb-keyset[id^=' + layout + ']').array(); 5325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (var i = 0; i<keysets.length ; i++) { 5335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) realignKeyset(keysets[i], params); 5345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 5355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) keyboard.stale = false; 536a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) exports.recordKeysets(); 5375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 5385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci /** 5405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * Realigns a given keyset. 5415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * @param {Object} keyset The keyset to realign. 5425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * @param {!AlignmentOptions} params The parameters used to align the keyset. 5435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) */ 5445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) function realignKeyset(keyset, params) { 5455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var rows = keyset.querySelectorAll('kb-row').array(); 5465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) keyset.style.fontSize = (params.availableHeight / 5475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FONT_SIZE_RATIO / rows.length) + 'px'; 5481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci var heightOffset = 0; 5495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (var i = 0; i < rows.length; i++) { 5505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var row = rows[i]; 5515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) var rowHeight = 552a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) Math.floor(params.keyHeight * (row.weight / DEFAULT_KEY_WEIGHT)); 5535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (row.querySelector('.space') && (i > 1)) { 5545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) realignSpacebarRow(row, rows[i-1], params, rowHeight, heightOffset) 5555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 5565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) realignRow(row, params, rowHeight, heightOffset); 5575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 5585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) heightOffset += (rowHeight + params.pitchY); 5595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 5605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 5615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 562c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch /** 563c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch * Resizes the keyboard container if needed. 564c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch * @params {AlignmentOptions=} opt_params Optional parameters to use. Defaults 565c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch * to the parameters of the current active keyset. 566c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch */ 567c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch function resizeKeyboardContainer(opt_params) { 568c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch var params = opt_params ? opt_params : new AlignmentOptions(); 5690529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch if (Math.abs(window.innerHeight - params.height) > RESIZE_THRESHOLD) { 570c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Cannot resize more than 50% of screen height due to crbug.com/338829. 571c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch window.resizeTo(params.width, params.height); 572c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 573c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 574c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 5755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) addEventListener('resize', onResize); 5765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) addEventListener('load', onResize); 5775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) exports.getKeyboardBounds = getKeyboardBounds_; 579a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) exports.binarySearch = binarySearch_; 580e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch exports.realignAll = realignAll; 5815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)})(this); 582c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch/** 5847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch * Recursively replace all kb-key-import elements with imported documents. 5857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch * @param {!Document} content Document to process. 5867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch */ 5877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochfunction importHTML(content) { 5887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch var dom = content.querySelector('template').createInstance(); 5897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch var keyImports = dom.querySelectorAll('kb-key-import'); 5907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (keyImports.length != 0) { 591f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) keyImports.array().forEach(function(element) { 5927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (element.importDoc(content)) { 5937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch var generatedDom = importHTML(element.importDoc(content)); 5947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch element.parentNode.replaceChild(generatedDom, element); 5957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 5967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch }); 5977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 5987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch return dom; 599bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch} 6007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 6017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch/** 602e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch * Flatten the keysets which represents a keyboard layout. 603e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch */ 604e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochfunction flattenKeysets() { 605e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch var keysets = $('keyboard').querySelectorAll('kb-keyset'); 606e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (keysets.length > 0) { 607e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch keysets.array().forEach(function(element) { 608e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch element.flattenKeyset(); 6097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch }); 6107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 611bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch} 6127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 613e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochfunction resolveAudio() { 614a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) var keyboard = $('keyboard'); 615a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) keyboard.addSound(Sound.DEFAULT); 616e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch var nodes = keyboard.querySelectorAll('[sound]').array(); 617a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Get id's of all unique sounds. 618a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) for (var i = 0; i < nodes.length; i++) { 619a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) var id = nodes[i].getAttribute('sound'); 620a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) keyboard.addSound(id); 621a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) } 622a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)} 623a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 6244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Prevents all default actions of touch. Keyboard should use its own gesture 6254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// recognizer. 6264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)addEventListener('touchstart', function(e) { e.preventDefault() }); 6274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)addEventListener('touchend', function(e) { e.preventDefault() }); 6284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)addEventListener('touchmove', function(e) { e.preventDefault() }); 629e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen MurdochaddEventListener('polymer-ready', function(e) { 630e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch flattenKeysets(); 631e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch resolveAudio(); 632e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch}); 633c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen MurdochaddEventListener('stateChange', function(e) { 634c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (e.detail.value == $('keyboard').activeKeysetId) 635c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch realignAll(); 636c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch}) 637