blob: 9e979d99e1ef29e917899d5730548db4b5134d1f [file] [log] [blame]
// 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