1 // Copyright 2014 The ChromeOS IME Authors. All Rights Reserved.
2 // limitations under the License.
3 // See the License for the specific language governing permissions and
4 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5 // distributed under the License is distributed on an "AS-IS" BASIS,
6 // Unless required by applicable law or agreed to in writing, software
8 // http://www.apache.org/licenses/LICENSE-2.0
10 // You may obtain a copy of the License at
11 // you may not use this file except in compliance with the License.
12 // Licensed under the Apache License, Version 2.0 (the "License");
14 goog
.provide('i18n.input.chrome.inputview.KeyboardContainer');
16 goog
.require('goog.dom.TagName');
17 goog
.require('goog.dom.classlist');
18 goog
.require('goog.i18n.bidi');
19 goog
.require('i18n.input.chrome.inputview.Css');
20 goog
.require('i18n.input.chrome.inputview.GlobalFlags');
21 goog
.require('i18n.input.chrome.inputview.elements.Element');
22 goog
.require('i18n.input.chrome.inputview.elements.ElementType');
23 goog
.require('i18n.input.chrome.inputview.elements.content.AltDataView');
24 goog
.require('i18n.input.chrome.inputview.elements.content.CandidateView');
25 goog
.require('i18n.input.chrome.inputview.elements.content.EmojiView');
26 goog
.require('i18n.input.chrome.inputview.elements.content.ExpandedCandidateView');
27 goog
.require('i18n.input.chrome.inputview.elements.content.GestureCanvasView');
28 goog
.require('i18n.input.chrome.inputview.elements.content.HandwritingView');
29 goog
.require('i18n.input.chrome.inputview.elements.content.KeysetView');
30 goog
.require('i18n.input.chrome.inputview.elements.content.MenuView');
31 goog
.require('i18n.input.chrome.inputview.elements.content.SelectView');
32 goog
.require('i18n.input.chrome.inputview.elements.content.SwipeView');
33 goog
.require('i18n.input.chrome.inputview.elements.content.VoiceView');
37 goog
.scope(function() {
38 var Css
= i18n
.input
.chrome
.inputview
.Css
;
39 var EmojiView
= i18n
.input
.chrome
.inputview
.elements
.content
.EmojiView
;
40 var HandwritingView
= i18n
.input
.chrome
.inputview
.elements
.content
.
42 var KeysetView
= i18n
.input
.chrome
.inputview
.elements
.content
.KeysetView
;
43 var content
= i18n
.input
.chrome
.inputview
.elements
.content
;
44 var ElementType
= i18n
.input
.chrome
.inputview
.elements
.ElementType
;
49 * The keyboard container.
51 * @param {!i18n.input.chrome.inputview.Adapter} adapter .
52 * @param {!i18n.input.chrome.sounds.SoundController} soundController .
53 * @param {goog.events.EventTarget=} opt_eventTarget The parent event target.
55 * @extends {i18n.input.chrome.inputview.elements.Element}
57 // TODO(bshe): Move this file to elements/content
58 i18n
.input
.chrome
.inputview
.KeyboardContainer
=
59 function(adapter
, soundController
, opt_eventTarget
) {
60 goog
.base(this, '', ElementType
.KEYBOARD_CONTAINER_VIEW
, opt_eventTarget
);
62 /** @type {!content.CandidateView} */
63 this.candidateView
= new content
.CandidateView(
64 'candidateView', adapter
, this);
66 /** @type {!content.AltDataView} */
67 this.altDataView
= new content
.AltDataView(this);
69 /** @type {!content.SwipeView} */
70 this.swipeView
= new content
.SwipeView(adapter
, this);
72 /** @type {!content.SelectView} */
73 this.selectView
= new content
.SelectView(this);
75 if (adapter
.isGestureTypingEnabled()) {
76 /** @type {!content.GestureCanvasView} */
77 this.gestureCanvasView
= new content
.GestureCanvasView(this);
80 /** @type {!content.MenuView} */
81 this.menuView
= new content
.MenuView(this);
83 /** @type {!content.VoiceView} */
84 this.voiceView
= new content
.VoiceView(this, adapter
, soundController
);
86 /** @type {!content.ExpandedCandidateView} */
87 this.expandedCandidateView
= new content
.ExpandedCandidateView(this);
90 * The map of the KeysetViews.
92 * Value: The view object.
94 * @type {!Object.<string, !KeysetView>}
96 this.keysetViewMap
= {};
99 * The bus channel to communicate with background.
101 * @private {!i18n.input.chrome.inputview.Adapter}
103 this.adapter_
= adapter
;
105 goog
.inherits(i18n
.input
.chrome
.inputview
.KeyboardContainer
,
106 i18n
.input
.chrome
.inputview
.elements
.Element
);
107 var KeyboardContainer
= i18n
.input
.chrome
.inputview
.KeyboardContainer
;
110 /** @type {!KeysetView} */
111 KeyboardContainer
.prototype.currentKeysetView
;
115 * The padding bottom of the whole keyboard.
119 KeyboardContainer
.PADDING_BOTTOM_
= 7;
123 * The margin of the tab style keyset.
128 KeyboardContainer
.TAB_MARGIN_
= 11;
132 * An div to wrapper candidate view and keyboard set view.
136 KeyboardContainer
.prototype.wrapperDiv_
= null;
140 KeyboardContainer
.prototype.createDom = function() {
141 goog
.base(this, 'createDom');
143 var elem
= this.getElement();
144 var dom
= this.getDomHelper();
145 this.wrapperDiv_
= dom
.createDom(goog
.dom
.TagName
.DIV
, Css
.WRAPPER
);
146 this.candidateView
.render(this.wrapperDiv_
);
147 dom
.appendChild(elem
, this.wrapperDiv_
);
148 this.altDataView
.render();
149 this.swipeView
.render();
150 this.selectView
.render();
151 this.menuView
.render();
152 this.voiceView
.render();
153 this.voiceView
.setVisible(false);
154 this.expandedCandidateView
.render(this.wrapperDiv_
);
155 this.expandedCandidateView
.setVisible(false);
156 if (this.adapter_
.isGestureTypingEnabled()) {
157 this.gestureCanvasView
.render(this.wrapperDiv_
);
159 goog
.dom
.classlist
.add(elem
, Css
.CONTAINER
);
164 KeyboardContainer
.prototype.update = function() {
165 this.currentKeysetView
&& this.currentKeysetView
.update();
170 * Adds a keyset view.
172 * @param {!Object} keysetData .
173 * @param {!Object} layoutData .
174 * @param {string} keyset .
175 * @param {string} languageCode .
176 * @param {!i18n.input.chrome.inputview.Model} model .
177 * @param {string} inputToolName .
178 * @param {!Object.<string, boolean>} conditions .
180 KeyboardContainer
.prototype.addKeysetView = function(keysetData
, layoutData
,
181 keyset
, languageCode
, model
, inputToolName
, conditions
) {
183 if (keyset
== 'emoji') {
184 view
= new EmojiView(keysetData
, layoutData
, keyset
, languageCode
, model
,
185 inputToolName
, this, this.adapter_
);
186 } else if (keyset
== 'hwt') {
187 view
= new HandwritingView(keysetData
, layoutData
, keyset
, languageCode
,
188 model
, inputToolName
, this, this.adapter_
);
190 view
= new KeysetView(keysetData
, layoutData
, keyset
, languageCode
, model
,
191 inputToolName
, this, this.adapter_
);
193 view
.render(this.wrapperDiv_
);
194 view
.applyConditions(conditions
);
195 view
.setVisible(false);
196 this.keysetViewMap
[keyset
] = view
;
201 * Switches to a keyset.
203 * @param {string} keyset .
204 * @param {string} title .
205 * @param {boolean} isPasswordBox .
206 * @param {boolean} isA11yMode .
207 * @param {string} rawKeyset The raw keyset id will switch to.
208 * @param {string} lastRawkeyset .
209 * @param {string} languageCode .
210 * @return {boolean} True if switched successfully.
212 KeyboardContainer
.prototype.switchToKeyset = function(keyset
, title
,
213 isPasswordBox
, isA11yMode
, rawKeyset
, lastRawkeyset
, languageCode
) {
214 if (!this.keysetViewMap
[keyset
]) {
218 for (var name
in this.keysetViewMap
) {
219 var view
= this.keysetViewMap
[name
];
220 if (name
== keyset
) {
221 this.candidateView
.setVisible(!view
.disableCandidateView
);
222 // Before setting view visible, activate it first, since activation may
224 view
.activate(rawKeyset
);
225 view
.setVisible(true);
228 view
.spaceKey
.updateTitle(title
, !isPasswordBox
&&
229 keyset
!= 'hwt' && keyset
!= 'emoji');
232 goog
.dom
.classlist
.add(this.getElement(), Css
.A11Y
);
234 // If current raw keyset is changed, record it.
235 if (lastRawkeyset
!= rawKeyset
) {
236 view
.fromKeyset
= lastRawkeyset
;
238 if (view
instanceof HandwritingView
) {
239 view
.setLanguagecode(languageCode
);
241 // Deactivate the last keyset view instance.
242 if (this.currentKeysetView
!= view
) {
243 if (this.currentKeysetView
) {
244 this.currentKeysetView
.deactivate(lastRawkeyset
);
246 this.currentKeysetView
= view
;
248 this.candidateView
.updateByKeyset(rawKeyset
, isPasswordBox
,
249 goog
.i18n
.bidi
.isRtlLanguage(languageCode
));
251 view
.setVisible(false);
260 * Resizes the whole keyboard.
262 * @param {number} width .
263 * @param {number} height .
264 * @param {number} widthPercent .
265 * @param {number} candidateViewHeight .
267 KeyboardContainer
.prototype.setContainerSize = function(width
, height
,
268 widthPercent
, candidateViewHeight
) {
269 if (!this.currentKeysetView
) {
272 var elem
= this.getElement();
275 var wrapperMargin
= 0;
276 if (this.currentKeysetView
.isTabStyle()) {
277 h
= height
- 2 * KeyboardContainer
.TAB_MARGIN_
;
278 wrapperMargin
= KeyboardContainer
.TAB_MARGIN_
;
280 this.wrapperDiv_
.style
.marginTop
= this.wrapperDiv_
.style
.marginBottom
=
281 wrapperMargin
+ 'px';
282 h
-= KeyboardContainer
.PADDING_BOTTOM_
;
283 elem
.style
.paddingBottom
= KeyboardContainer
.PADDING_BOTTOM_
+ 'px';
285 var padding
= Math
.round((width
- width
* widthPercent
) / 2);
286 var w
= width
- 2 * padding
;
288 // Reduce height if candidate view is enabled
289 h
= this.currentKeysetView
.disableCandidateView
? h
:
290 h
- candidateViewHeight
;
292 var backspaceWeight
= this.currentKeysetView
.backspaceKey
?
293 this.currentKeysetView
.backspaceKey
.getParent().getWidthInWeight() : 0;
294 this.candidateView
.setWidthInWeight(
295 this.currentKeysetView
.getWidthInWeight(), backspaceWeight
);
296 this.candidateView
.resize(w
, candidateViewHeight
);
297 this.expandedCandidateView
.setWidthInWeight(
298 this.currentKeysetView
.getWidthInWeight(), backspaceWeight
);
299 this.expandedCandidateView
.resize(w
, h
);
300 if (i18n
.input
.chrome
.inputview
.GlobalFlags
.isQPInputView
) {
301 var candidateElem
= this.candidateView
.getElement();
302 candidateElem
.style
.paddingLeft
= candidateElem
.style
.paddingRight
=
304 this.currentKeysetView
.resize(width
, h
, widthPercent
);
305 var expandViewElem
= this.expandedCandidateView
.getElement();
306 expandViewElem
.style
.marginLeft
= expandViewElem
.style
.marginRight
=
309 this.currentKeysetView
.resize(w
, h
, 1);
310 elem
.style
.paddingLeft
= elem
.style
.paddingRight
= padding
+ 'px';
312 if (this.expandedCandidateView
.isVisible()) {
313 // Closes the expanded candidate view if it's visible.
314 // This is to avoid mis-layout issue for the expanded candidate when screen
316 this.expandedCandidateView
.state
= content
.ExpandedCandidateView
.State
.NONE
;
317 this.candidateView
.switchToIcon(
318 content
.CandidateView
.IconType
.EXPAND_CANDIDATES
, true);
319 this.expandedCandidateView
.setVisible(false);
320 this.currentKeysetView
.setVisible(true);
322 this.altDataView
.resize(screen
.width
, height
);
323 this.swipeView
.resize(screen
.width
, height
);
324 this.selectView
.resize(screen
.width
, height
);
325 this.menuView
.resize(screen
.width
, height
);
326 this.voiceView
.resize(w
+ padding
, height
);
327 if (this.adapter_
.isGestureTypingEnabled()) {
328 this.gestureCanvasView
.resize(screen
.width
, height
);
334 KeyboardContainer
.prototype.disposeInternal = function() {
335 goog
.dispose(this.candidateView
);
336 goog
.dispose(this.altDataView
);
337 goog
.dispose(this.swipeView
);
338 goog
.dispose(this.selectView
);
339 goog
.dispose(this.menuView
);
340 goog
.dispose(this.voiceView
);
341 if (this.adapter_
.isGestureTypingEnabled()) {
342 goog
.dispose(this.gestureCanvasView
);
344 for (var key
in this.keysetViewMap
) {
345 goog
.dispose(this.keysetViewMap
[key
]);
348 goog
.base(this, 'disposeInternal');
353 * Whether there are strokes on canvas.
355 * @return {boolean} Whether there are strokes on canvas.
357 KeyboardContainer
.prototype.hasStrokesOnCanvas = function() {
358 if (this.currentKeysetView
) {
359 return this.currentKeysetView
.hasStrokesOnCanvas();
369 KeyboardContainer
.prototype.cleanStroke = function() {
370 if (this.currentKeysetView
) {
371 this.currentKeysetView
.cleanStroke();