chromium/third_party/google_input_tools/src/chrome/os/inputview/keyboardcontainer.js

// Copyright 2014 The ChromeOS IME Authors. All Rights Reserved.
// limitations under the License.
// See the License for the specific language governing permissions and
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// distributed under the License is distributed on an "AS-IS" BASIS,
// Unless required by applicable law or agreed to in writing, software
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// You may obtain a copy of the License at
// you may not use this file except in compliance with the License.
// Licensed under the Apache License, Version 2.0 (the "License");
//
goog.provide('i18n.input.chrome.inputview.KeyboardContainer');

goog.require('goog.dom.TagName');
goog.require('goog.dom.classlist');
goog.require('goog.i18n.bidi');
goog.require('i18n.input.chrome.ElementType');
goog.require('i18n.input.chrome.WindowUtil');
goog.require('i18n.input.chrome.inputview.Css');
goog.require('i18n.input.chrome.inputview.GesturePreviewWindow');
goog.require('i18n.input.chrome.inputview.elements.Element');
goog.require('i18n.input.chrome.inputview.elements.content.AltDataView');
goog.require('i18n.input.chrome.inputview.elements.content.CandidateView');
goog.require('i18n.input.chrome.inputview.elements.content.EmojiView');
goog.require('i18n.input.chrome.inputview.elements.content.ExpandedCandidateView');
goog.require('i18n.input.chrome.inputview.elements.content.FloatingView');
goog.require('i18n.input.chrome.inputview.elements.content.GestureCanvasView');
goog.require('i18n.input.chrome.inputview.elements.content.HandwritingView');
goog.require('i18n.input.chrome.inputview.elements.content.KeysetView');
goog.require('i18n.input.chrome.inputview.elements.content.MenuView');
goog.require('i18n.input.chrome.inputview.elements.content.SelectView');
goog.require('i18n.input.chrome.inputview.elements.content.SwipeView');
goog.require('i18n.input.chrome.inputview.elements.content.VoiceView');



goog.scope(function() {
var Css = i18n.input.chrome.inputview.Css;
var EmojiView = i18n.input.chrome.inputview.elements.content.EmojiView;
var GesturePreviewWindow = i18n.input.chrome.inputview.GesturePreviewWindow;
var HandwritingView = i18n.input.chrome.inputview.elements.content.
    HandwritingView;
var KeysetView = i18n.input.chrome.inputview.elements.content.KeysetView;
var content = i18n.input.chrome.inputview.elements.content;
var ElementType = i18n.input.chrome.ElementType;
var WindowUtil = i18n.input.chrome.WindowUtil;



/**
 * The keyboard container.
 *
 * @param {!i18n.input.chrome.inputview.Adapter} adapter .
 * @param {!i18n.input.chrome.sounds.SoundController} soundController .
 * @param {goog.events.EventTarget=} opt_eventTarget The parent event target.
 * @constructor
 * @extends {i18n.input.chrome.inputview.elements.Element}
 */
// TODO(bshe): Move this file to elements/content
i18n.input.chrome.inputview.KeyboardContainer =
    function(adapter, soundController, opt_eventTarget) {
  goog.base(this, '', ElementType.KEYBOARD_CONTAINER_VIEW, opt_eventTarget);

  /** @type {!content.CandidateView} */
  this.candidateView = new content.CandidateView(
      'candidateView', adapter, this);

  /** @type {!content.AltDataView} */
  this.altDataView = new content.AltDataView(this);

  // Create a new window and construct a GesturePreviewWindow with it
  // once it's ready.
  WindowUtil.createWindow(
      function(newWindow) {
        /** @type {!GesturePreviewWindow} */
        this.gesturePreviewWindow = new GesturePreviewWindow(newWindow);
      }.bind(this));

  /** @type {!content.SwipeView} */
  this.swipeView = new content.SwipeView(adapter, this.candidateView, this);

  /** @type {!content.SelectView} */
  this.selectView = new content.SelectView(this);

  /** @type {!content.MenuView} */
  this.menuView = new content.MenuView(this);

  /** @type {!content.VoiceView} */
  this.voiceView = new content.VoiceView(this, adapter, soundController);

  /** @type {!content.ExpandedCandidateView} */
  this.expandedCandidateView = new content.ExpandedCandidateView(this);

  /**
   * The map of the KeysetViews.
   * Key: keyboard code.
   * Value: The view object.
   *
   * @type {!Object.<string, !KeysetView>}
   */
  this.keysetViewMap = {};

  /**
   * The bus channel to communicate with background.
   *
   * @private {!i18n.input.chrome.inputview.Adapter}
   */
  this.adapter_ = adapter;
};
goog.inherits(i18n.input.chrome.inputview.KeyboardContainer,
    i18n.input.chrome.inputview.elements.Element);
var KeyboardContainer = i18n.input.chrome.inputview.KeyboardContainer;


/** @type {!KeysetView} */
KeyboardContainer.prototype.currentKeysetView;


/**
 * The padding bottom of the whole keyboard.
 *
 * @private {number}
 */
KeyboardContainer.PADDING_BOTTOM_ = 7;


/**
 * The margin of the tab style keyset.
 *
 * @type {number}
 * @private
 */
KeyboardContainer.TAB_MARGIN_ = 11;


/**
 * An div to wrapper candidate view and keyboard set view.
 *
 * @private {Element}
 */
KeyboardContainer.prototype.wrapperDiv_ = null;


/**
 * The gesture canvas view.
 *
 * @type {content.GestureCanvasView}
 */
KeyboardContainer.prototype.gestureCanvasView = null;


/**
 * The gesture canvas view.
 *
 * @type {content.FloatingView}
 */
KeyboardContainer.prototype.floatingView = null;


/** @override */
KeyboardContainer.prototype.createDom = function() {
  goog.base(this, 'createDom');

  var elem = this.getElement();
  var dom = this.getDomHelper();
  this.wrapperDiv_ = dom.createDom(goog.dom.TagName.DIV, Css.WRAPPER);
  this.candidateView.render(this.wrapperDiv_);
  dom.appendChild(elem, this.wrapperDiv_);
  this.altDataView.render();
  this.swipeView.render();
  this.selectView.render();
  this.menuView.render();
  this.voiceView.render();
  this.voiceView.setVisible(false);
  this.expandedCandidateView.render(this.wrapperDiv_);
  this.expandedCandidateView.setVisible(false);
  if (this.adapter_.isFloatingVirtualKeyboardEnabled()) {
    inputview.setMode('FLOATING');
    this.floatingView = new content.FloatingView(this);
    this.floatingView.render();
    this.candidateView.setFloatingVKButtonsVisible(true);
  }
  this.gestureCanvasView = new content.GestureCanvasView(this);
  this.gestureCanvasView.render(this.wrapperDiv_);
  goog.dom.classlist.add(elem, Css.CONTAINER);
};


/** @override */
KeyboardContainer.prototype.update = function() {
  this.currentKeysetView && this.currentKeysetView.update();
};


/**
 * Adds a keyset view.
 *
 * @param {!Object} keysetData .
 * @param {!Object} layoutData .
 * @param {string} keyset .
 * @param {string} languageCode .
 * @param {!i18n.input.chrome.inputview.Model} model .
 * @param {string} inputToolName .
 * @param {!Object.<string, boolean>} conditions .
 */
KeyboardContainer.prototype.addKeysetView = function(keysetData, layoutData,
    keyset, languageCode, model, inputToolName, conditions) {
  var view;
  if (keyset == 'emoji') {
    view = new EmojiView(keysetData, layoutData, keyset, languageCode, model,
        inputToolName, this, this.adapter_);
  } else if (keyset == 'hwt') {
    view = new HandwritingView(keysetData, layoutData, keyset, languageCode,
        model, inputToolName, this, this.adapter_);
  } else {
    view = new KeysetView(keysetData, layoutData, keyset, languageCode, model,
        inputToolName, this, this.adapter_);
  }
  view.render(this.wrapperDiv_);
  view.applyConditions(conditions);
  view.setVisible(false);
  this.keysetViewMap[keyset] = view;
};


/**
 * Switches to a keyset.
 *
 * @param {string} keyset .
 * @param {string} title .
 * @param {boolean} isPasswordBox .
 * @param {boolean} isA11yMode .
 * @param {string} rawKeyset The raw keyset id will switch to.
 * @param {string} lastRawkeyset .
 * @param {string} languageCode .
 * @return {boolean} True if switched successfully.
 */
KeyboardContainer.prototype.switchToKeyset = function(keyset, title,
    isPasswordBox, isA11yMode, rawKeyset, lastRawkeyset, languageCode) {
  if (!this.keysetViewMap[keyset]) {
    return false;
  }

  for (var name in this.keysetViewMap) {
    var view = this.keysetViewMap[name];
    if (name == keyset) {
      this.candidateView.setVisible(!view.disableCandidateView);
      // Before setting view visible, activate it first, since activation may
      // change view keys.
      view.activate(rawKeyset);
      view.setVisible(true);
      view.update();
      if (view.spaceKey) {
        view.spaceKey.updateTitle(title, !isPasswordBox &&
            keyset != 'hwt' && keyset != 'emoji');
      }
      if (isA11yMode) {
        goog.dom.classlist.add(this.getElement(), Css.A11Y);
      }
      // If current raw keyset is changed, record it.
      if (lastRawkeyset != rawKeyset) {
        view.fromKeyset = lastRawkeyset;
      }
      if (view instanceof HandwritingView) {
        view.setLanguagecode(languageCode);
      }
      // Deactivate the last keyset view instance.
      if (this.currentKeysetView != view) {
        if (this.currentKeysetView) {
          this.currentKeysetView.deactivate(lastRawkeyset);
        }
        this.currentKeysetView = view;
      }
      this.candidateView.updateByKeyset(rawKeyset, isPasswordBox,
          goog.i18n.bidi.isRtlLanguage(languageCode));
    } else {
      view.setVisible(false);
    }
  }
  var isCompact = keyset.indexOf('compact') >= 0;
  this.selectView.setKeysetSupported(isCompact);
  this.swipeView.setKeysetSupported(isCompact);
  return true;
};


/**
 * Resizes the whole keyboard.
 *
 * @param {number} width .
 * @param {number} height .
 * @param {number} widthPercent .
 * @param {number} candidateViewHeight .
 */
KeyboardContainer.prototype.setContainerSize = function(width, height,
    widthPercent, candidateViewHeight) {
  if (!this.currentKeysetView) {
    return;
  }
  var elem = this.getElement();

  var h = height;
  var wrapperMargin = 0;
  this.wrapperDiv_.style.marginTop = this.wrapperDiv_.style.marginBottom =
      wrapperMargin + 'px';
  h -= KeyboardContainer.PADDING_BOTTOM_;
  elem.style.paddingBottom = KeyboardContainer.PADDING_BOTTOM_ + 'px';

  var padding = Math.round((width - width * widthPercent) / 2);
  var w = width - 2 * padding;

  // Reduce height if candidate view is enabled
  h = this.currentKeysetView.disableCandidateView ? h :
      h - candidateViewHeight;

  var backspaceWeight = this.currentKeysetView.backspaceKey ?
      this.currentKeysetView.backspaceKey.getParent().getWidthInWeight() : 0;
  this.candidateView.setWidthInWeight(
      this.currentKeysetView.getWidthInWeight(), backspaceWeight);
  this.candidateView.resize(w, candidateViewHeight);
  this.expandedCandidateView.setWidthInWeight(
      this.currentKeysetView.getWidthInWeight(), backspaceWeight);
  this.expandedCandidateView.resize(w, h);
  var candidateElem = this.candidateView.getElement();
  candidateElem.style.paddingLeft = candidateElem.style.paddingRight =
      padding + 'px';
  this.currentKeysetView.resize(width, h, widthPercent);
  var expandViewElem = this.expandedCandidateView.getElement();
  expandViewElem.style.marginLeft = expandViewElem.style.marginRight =
      padding + 'px';
  if (this.expandedCandidateView.isVisible()) {
    // Closes the expanded candidate view if it's visible.
    // This is to avoid mis-layout issue for the expanded candidate when screen
    // is rotated.
    this.expandedCandidateView.state = content.ExpandedCandidateView.State.NONE;
    this.candidateView.switchToIcon(
        content.CandidateView.IconType.EXPAND_CANDIDATES, true);
    this.expandedCandidateView.setVisible(false);
    this.currentKeysetView.setVisible(true);
  }
  this.altDataView.resize(width, height);
  this.swipeView.resize(width, height);
  this.selectView.resize(width, height);
  this.menuView.resize(width, height);
  this.voiceView.resize(w + padding, height);
  if (this.floatingView) {
    this.floatingView.resize(width, height);
  }
  this.gestureCanvasView.resize(width, height);
};


/** @override */
KeyboardContainer.prototype.disposeInternal = function() {
  goog.dispose(this.candidateView);
  goog.dispose(this.altDataView);
  goog.dispose(this.gesturePreviewWindow);
  goog.dispose(this.swipeView);
  goog.dispose(this.selectView);
  goog.dispose(this.menuView);
  goog.dispose(this.voiceView);
  if (this.floatingView) {
    goog.dispose(this.floatingView);
  }
  goog.dispose(this.gestureCanvasView);
  for (var key in this.keysetViewMap) {
    goog.dispose(this.keysetViewMap[key]);
  }

  goog.base(this, 'disposeInternal');
};


/**
 * Whether there are strokes on canvas.
 *
 * @return {boolean} Whether there are strokes on canvas.
 */
KeyboardContainer.prototype.hasStrokesOnCanvas = function() {
  if (this.currentKeysetView) {
    return this.currentKeysetView.hasStrokesOnCanvas();
  } else {
    return false;
  }
};


/**
 * Cleans the stokes.
 */
KeyboardContainer.prototype.cleanStroke = function() {
  if (this.currentKeysetView) {
    this.currentKeysetView.cleanStroke();
  }
};

});  // goog.scope