Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / ui / keyboard / resources / main.js
index d039506..4997486 100644 (file)
@@ -84,7 +84,8 @@
       var row = rows[0];
       var candidateLength = rows[0].childElementCount;
       for (var i = 1; i < rows.length; i++) {
-        if (rows[i].childElementCount > candidateLength) {
+        if (rows[i].childElementCount > candidateLength &&
+            rows[i].align == RowAlignment.STRETCH) {
           row = rows[i];
           candidateLength = rows[i].childElementCount;
         }
 
       // Sum of all keys in the current row.
       var keyWeightSumX = 0;
-      for (var i=0; i< allKeys.length; i++) {
+      for (var i = 0; i < allKeys.length; i++) {
         keyWeightSumX += allKeys[i].weight;
       }
 
       var totalWeightX = keyWeightSumX + interspaceWeightSumX +
           keyset.weightLeft + keyset.weightRight;
 
-      var totalWeightY = (DEFAULT_KEY_WEIGHT_Y * rows.length) +
-                        (pitchWeightY * (rows.length - 1)) +
-                        keyset.weightTop +
-                        keyset.weightBottom;
-
+      var totalWeightY = (pitchWeightY * (rows.length - 1)) +
+                         keyset.weightTop +
+                         keyset.weightBottom;
+      for (var i = 0; i < rows.length; i++) {
+        totalWeightY += rows[i].weight;
+      }
       // Calculate width and height of the window.
       var bounds = exports.getKeyboardBounds();
 
-      var width;
-      var height;
-      var pixelPerWeight;
-      if (totalWeightX/bounds.width < totalWeightY/bounds.height) {
-        height = bounds.height;
-        pixelPerWeight = bounds.height/totalWeightY;
-        width = Math.floor(pixelPerWeight * totalWeightX)
-      }
-      else {
-        width = bounds.width;
-        pixelPerWeight = bounds.width/totalWeightX;
-        height = Math.floor(pixelPerWeight * totalWeightY);
+      var width = bounds.width;
+      var height = bounds.height;
+      var pixelPerWeightX = bounds.width/totalWeightX;
+      var pixelPerWeightY = bounds.height/totalWeightY;
+
+      if (keyset.align == LayoutAlignment.CENTER) {
+        if (totalWeightX/bounds.width < totalWeightY/bounds.height) {
+          pixelPerWeightY = bounds.height/totalWeightY;
+          pixelPerWeightX = pixelPerWeightY;
+          width = Math.floor(pixelPerWeightX * totalWeightX)
+        } else {
+          pixelPerWeightX = bounds.width/totalWeightX;
+          pixelPerWeightY = pixelPerWeightX;
+          height = Math.floor(pixelPerWeightY * totalWeightY);
+        }
       }
       // Calculate pitch.
-      this.pitchX = Math.floor(pitchWeightX * pixelPerWeight);
-      this.pitchY = Math.floor(pitchWeightY * pixelPerWeight);
+      this.pitchX = Math.floor(pitchWeightX * pixelPerWeightX);
+      this.pitchY = Math.floor(pitchWeightY * pixelPerWeightY);
 
       // Convert weight to pixels on x axis.
-      this.keyWidth = Math.floor(DEFAULT_KEY_WEIGHT_X * pixelPerWeight);
-      var offsetLeft = Math.floor(keyset.weightLeft * pixelPerWeight);
-      var offsetRight = Math.floor(keyset.weightRight * pixelPerWeight);
+      this.keyWidth = Math.floor(DEFAULT_KEY_WEIGHT_X * pixelPerWeightX);
+      var offsetLeft = Math.floor(keyset.weightLeft * pixelPerWeightX);
+      var offsetRight = Math.floor(keyset.weightRight * pixelPerWeightX);
       this.availableWidth = width - offsetLeft - offsetRight;
 
       // Calculates weight to pixels on the y axis.
-      this.keyHeight = Math.floor(DEFAULT_KEY_WEIGHT_Y * pixelPerWeight);
-      var offsetTop = Math.floor(keyset.weightTop * pixelPerWeight);
-      var offsetBottom = Math.floor(keyset.weightBottom * pixelPerWeight);
+      this.keyHeight = Math.floor(DEFAULT_KEY_WEIGHT_Y * pixelPerWeightY);
+      var offsetTop = Math.floor(keyset.weightTop * pixelPerWeightY);
+      var offsetBottom = Math.floor(keyset.weightBottom * pixelPerWeightY);
       this.availableHeight = height - offsetTop - offsetBottom;
 
       var dX = bounds.width - width;
   function getKeyboardBounds_() {
     return {
       "width": window.innerWidth,
-      "height": window.innerHeight
+      "height": window.innerHeight,
     };
   }
   /**
    * Callback function for when the window is resized.
    */
   var onResize = function() {
-    var bounds = exports.getKeyboardBounds();
-    var height =  (bounds.width > ASPECT_RATIO * bounds.height) ?
-        bounds.height : Math.floor(bounds.width / ASPECT_RATIO);
     var keyboard = $('keyboard');
-    keyboard.style.fontSize = (height / FONT_SIZE_RATIO / ROW_LENGTH) + 'px';
     keyboard.stale = true;
     var keyset = keyboard.activeKeyset;
     if (keyset)
   function updateKey(key, width, height, left, top) {
     key.style.position = 'absolute';
     key.style.width = width + 'px';
-    key.style.height = (height - KEY_PADDING_TOP) + 'px';
+    key.style.height = (height - KEY_PADDING_TOP - KEY_PADDING_BOTTOM) + 'px';
     key.style.left = left + 'px';
     key.style.top = (top + KEY_PADDING_TOP) + 'px';
   }
   /**
    * Redistributes the total width amongst the keys in the range provided.
    * @param {Array.<kb-key>} allKeys Ordered list of keys to stretch.
-   * @param {number} pitch The space between two keys.
+   * @param {AlignmentOptions} params Options for aligning the keyset.
    * @param {number} xOffset The x-coordinate of the key who's index is start.
    * @param {number} width The total extraneous width to distribute.
    * @param {number} keyHeight The height of each key.
    * @param {number} yOffset The y-coordinate of the top edge of the row.
    */
-  function redistribute(allKeys, pitch, xOffset, width, keyHeight, yOffset) {
-    var weight = 0;
+  function redistribute(allKeys, params, xOffset, width, keyHeight, yOffset) {
+    var availableWidth = width - (allKeys.length - 1) * params.pitchX;
+    var stretchWeight = 0;
+    var nStretch = 0;
     for (var i = 0; i < allKeys.length; i++) {
-      weight += allKeys[i].weight;
+      var key = allKeys[i];
+      if (key.stretch) {
+        stretchWeight += key.weight;
+        nStretch++;
+      } else if (key.weight == DEFAULT_KEY_WEIGHT_X) {
+        availableWidth -= params.keyWidth;
+      } else {
+        availableWidth -=
+            Math.floor(key.weight/DEFAULT_KEY_WEIGHT_X * params.keyWidth);
+      }
     }
-    var availableWidth = width - (allKeys.length - 1) * pitch;
-    var pixelsPerWeight = width / weight;
+    if (stretchWeight <= 0)
+      console.error("Cannot stretch row without a stretchable key");
+    // Rounding error to distribute.
+    var pixelsPerWeight = availableWidth / stretchWeight;
     for (var i = 0; i < allKeys.length; i++) {
-      var keyWidth = Math.floor(allKeys[i].weight * pixelsPerWeight);
-      if (i == allKeys.length -1) {
-        keyWidth =  availableWidth;
+      var key = allKeys[i];
+      var keyWidth = params.keyWidth;
+      if (key.weight != DEFAULT_KEY_WEIGHT_X) {
+        keyWidth =
+            Math.floor(key.weight/DEFAULT_KEY_WEIGHT_X * params.keyWidth);
       }
-      updateKey(allKeys[i], keyWidth, keyHeight, xOffset, yOffset)
-      availableWidth -= keyWidth;
-      xOffset += keyWidth + pitch;
+      if (key.stretch) {
+        nStretch--;
+        if (nStretch > 0) {
+          keyWidth = Math.floor(key.weight * pixelsPerWeight);
+          availableWidth -= keyWidth;
+        } else {
+          keyWidth = availableWidth;
+        }
+      }
+      updateKey(key, keyWidth, keyHeight, xOffset, yOffset)
+      xOffset += keyWidth + params.pitchX;
     }
   }
 
    * it. A precondition is that all keys in this row can be stretched as needed.
    * @param {!kb-row} row The current row to be aligned.
    * @param {!kb-row} prevRow The row above the current row.
-   * @param {!AlignmentOptions} params The parameters used to align the keyset.
+   * @param {!AlignmentOptions} params Options for aligning the keyset.
+   * @param {number} keyHeight The height of the keys in this row.
    * @param {number} heightOffset The height offset caused by the rows above.
    */
-  function realignSpacebarRow(row, prevRow, params, heightOffset) {
+  function realignSpacebarRow(row, prevRow, params, keyHeight, heightOffset) {
     var allKeys = row.children;
     var stretchWeightBeforeSpace = 0;
     var stretchBefore = 0;
     var leftWidth = leftEdge - params.offsetLeft - params.pitchX;
     var leftKeys = allKeys.array().slice(0, spaceIndex);
     redistribute(leftKeys,
-                 params.pitchX,
+                 params,
                  params.offsetLeft,
                  leftWidth,
-                 params.keyHeight,
+                 keyHeight,
                  yOffset);
     // Fix right side.
     var rightEdge = parseFloat(rightKey.style.left) +
     var spacebarWidth = rightEdge - leftEdge;
     updateKey(allKeys[spaceIndex],
               spacebarWidth,
-              params.keyHeight,
+              keyHeight,
               leftEdge,
               yOffset);
     var rightWidth =
         params.availableWidth - (rightEdge - params.offsetLeft + params.pitchX);
     var rightKeys = allKeys.array().slice(spaceIndex + 1);
     redistribute(rightKeys,
-                 params.pitchX,
+                 params,
                  rightEdge + params.pitchX,//xOffset.
                  rightWidth,
-                 params.keyHeight,
+                 keyHeight,
                  yOffset);
   }
 
    * Realigns a given row based on the parameters provided.
    * @param {!kb-row} row The row to realign.
    * @param {!AlignmentOptions} params The parameters used to align the keyset.
+   * @param {number} The height of the keys.
    * @param {number} heightOffset The offset caused by rows above it.
    */
-  function realignRow(row, params, heightOffset) {
+  function realignRow(row, params, keyHeight, heightOffset) {
     var all = row.children;
-    var stretch = [];
+    var nStretch = 0;
     var stretchWeightSum = 0;
     var allSum = 0;
-
+    // Keeps track of where to distribute pixels caused by round off errors.
+    var deltaWidth = [];
     for (var i = 0; i < all.length; i++) {
+      deltaWidth.push(0)
       var key = all[i];
       if (key.weight == DEFAULT_KEY_WEIGHT_X){
         allSum += params.keyWidth;
-        continue;
-      }
-      stretch.push(key)
-      var width =
+      } else {
+        var width =
           Math.floor((params.keyWidth/DEFAULT_KEY_WEIGHT_X) * key.weight);
-      allSum += width;
+        allSum += width;
+      }
+      if (!key.stretch)
+        continue;
+      nStretch++;
       stretchWeightSum += key.weight;
     }
-    var nStretch = stretch.length;
     var nRegular = all.length - nStretch;
     // Extra space.
     var extra = params.availableWidth -
                 allSum -
                 (params.pitchX * (all.length -1));
     var xOffset = params.offsetLeft;
+
     var alignment = row.align;
     switch (alignment) {
       case RowAlignment.STRETCH:
         var extraPerWeight = extra/stretchWeightSum;
-        for (var i = 0; i < stretch.length; i++) {
-          var bonus = Math.floor(stretch[i].weight * extraPerWeight);
-          extra -= bonus;
-          // All left-over pixels assigned to right most key.
-          if (i == (stretch.length - 1))
-            stretch[i].setAttribute('bonus', bonus + extra);
-          else
-            stretch[i].setAttribute('bonus', bonus);
+        for (var i = 0; i < all.length; i++) {
+          if (!all[i].stretch)
+            continue;
+          var delta = Math.floor(all[i].weight * extraPerWeight);
+          extra -= delta;
+          deltaWidth[i] = delta;
+          // All left-over pixels assigned to right most stretchable key.
+          nStretch--;
+          if (nStretch == 0)
+            deltaWidth[i] += extra;
         }
         break;
       case RowAlignment.CENTER:
         xOffset += Math.floor(extra/2)
         break;
-      case RowAlignment.JUSTIFY:
+      case RowAlignment.RIGHT:
         xOffset += extra;
         break;
       default:
     for (var i = 0; i < all.length; i++) {
       var key = all[i];
       var width = params.keyWidth;
-      if (key.weight != DEFAULT_KEY_WEIGHT_X) {
+      if (key.weight != DEFAULT_KEY_WEIGHT_X)
         width = Math.floor((params.keyWidth/DEFAULT_KEY_WEIGHT_X) * key.weight)
-        var bonus = key.getAttribute('bonus')
-        if (bonus)
-          width += parseInt(bonus)
-      }
-      updateKey(key, width, params.keyHeight, left, yOffset)
+      width += deltaWidth[i];
+      updateKey(key, width, keyHeight, left, yOffset)
       left += (width + params.pitchX);
     }
   }
    */
   function realignKeyset(keyset, params) {
     var rows = keyset.querySelectorAll('kb-row').array();
+    keyset.style.fontSize = (params.availableHeight /
+      FONT_SIZE_RATIO / rows.length) + 'px';
+
     var heightOffset  = 0;
     for (var i = 0; i < rows.length; i++) {
       var row = rows[i];
+      var rowHeight =
+          Math.floor(params.keyHeight * (row.weight/DEFAULT_KEY_WEIGHT_Y))
       if (row.querySelector('.space') && (i > 1)) {
-        realignSpacebarRow(row, rows[i-1], params, heightOffset)
+        realignSpacebarRow(row, rows[i-1], params, rowHeight, heightOffset)
       } else {
-        realignRow(row, params, heightOffset);
+        realignRow(row, params, rowHeight, heightOffset);
       }
-      heightOffset += (params.keyHeight + params.pitchY);
+      heightOffset += (rowHeight + params.pitchY);
     }
   }
   window.addEventListener('realign', requestRealign);