• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.inputmethod.keyboard.layout;
18 
19 import com.android.inputmethod.keyboard.KeyboardId;
20 import com.android.inputmethod.keyboard.layout.customizer.LayoutCustomizer;
21 import com.android.inputmethod.keyboard.layout.expected.AbstractLayoutBase;
22 import com.android.inputmethod.keyboard.layout.expected.ExpectedKey;
23 import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder;
24 
25 import java.util.Locale;
26 
27 /**
28  * The base class of keyboard layout.
29  */
30 public abstract class LayoutBase extends AbstractLayoutBase {
31     private final LayoutCustomizer mCustomizer;
32     private final Symbols mSymbols;
33     private final SymbolsShifted mSymbolsShifted;
34 
LayoutBase(final LayoutCustomizer customizer, final Class<? extends Symbols> symbolsClass, final Class<? extends SymbolsShifted> symbolsShiftedClass)35     LayoutBase(final LayoutCustomizer customizer, final Class<? extends Symbols> symbolsClass,
36             final Class<? extends SymbolsShifted> symbolsShiftedClass) {
37         mCustomizer = customizer;
38         try {
39             mSymbols = symbolsClass.getDeclaredConstructor(LayoutCustomizer.class)
40                     .newInstance(customizer);
41             mSymbolsShifted = symbolsShiftedClass.getDeclaredConstructor(LayoutCustomizer.class)
42                     .newInstance(customizer);
43         } catch (final Exception e) {
44             throw new RuntimeException("Unknown Symbols/SymbolsShifted class", e);
45         }
46     }
47 
48     /**
49      * The layout name.
50      * @return the name of this layout.
51      */
getName()52     public abstract String getName();
53 
54     /**
55      * The locale of this layout.
56      * @return the locale of this layout.
57      */
getLocale()58     public final Locale getLocale() { return mCustomizer.getLocale(); }
59 
60     /**
61      * The layout customizer for this layout.
62      * @return the layout customizer;
63      */
getCustomizer()64     public final LayoutCustomizer getCustomizer() { return mCustomizer; }
65 
66     /**
67      * Helper method to create alphabet layout adding special function keys.
68      * @param builder the {@link ExpectedKeyboardBuilder} object that contains common keyboard
69      *     layout
70      * @param isPhone true if requesting phone's layout.
71      * @return the {@link ExpectedKeyboardBuilder} object that is customized and have special keys.
72      */
convertCommonLayoutToKeyboard(final ExpectedKeyboardBuilder builder, final boolean isPhone)73     ExpectedKeyboardBuilder convertCommonLayoutToKeyboard(final ExpectedKeyboardBuilder builder,
74             final boolean isPhone) {
75         final LayoutCustomizer customizer = getCustomizer();
76         final int numberOfRows = customizer.getNumberOfRows();
77         builder.setKeysOfRow(numberOfRows, (Object[])customizer.getSpaceKeys(isPhone));
78         builder.addKeysOnTheLeftOfRow(
79                 numberOfRows, (Object[])customizer.getKeysLeftToSpacebar(isPhone));
80         builder.addKeysOnTheRightOfRow(
81                 numberOfRows, (Object[])customizer.getKeysRightToSpacebar(isPhone));
82         if (isPhone) {
83             builder.addKeysOnTheRightOfRow(numberOfRows - 1, DELETE_KEY)
84                     .addKeysOnTheLeftOfRow(numberOfRows, customizer.getSymbolsKey())
85                     .addKeysOnTheRightOfRow(numberOfRows, customizer.getEnterKey(isPhone));
86         } else {
87             builder.addKeysOnTheRightOfRow(1, DELETE_KEY)
88                     .addKeysOnTheRightOfRow(numberOfRows - 2, customizer.getEnterKey(isPhone))
89                     .addKeysOnTheLeftOfRow(numberOfRows, customizer.getSymbolsKey())
90                     .addKeysOnTheRightOfRow(numberOfRows, customizer.getEmojiKey(isPhone));
91         }
92         builder.addKeysOnTheLeftOfRow(
93                 numberOfRows - 1, (Object[])customizer.getLeftShiftKeys(isPhone));
94         builder.addKeysOnTheRightOfRow(
95                 numberOfRows - 1, (Object[])customizer.getRightShiftKeys(isPhone));
96         return builder;
97     }
98 
99     /**
100      * Get common alphabet layout. This layout doesn't contain any special keys.
101      *
102      * A keyboard layout is an array of rows, and a row consists of an array of
103      * {@link ExpectedKey}s. Each row may have different number of {@link ExpectedKey}s.
104      *
105      * @param isPhone true if requesting phone's layout.
106      * @return the common alphabet keyboard layout.
107      */
getCommonAlphabetLayout(boolean isPhone)108     abstract ExpectedKey[][] getCommonAlphabetLayout(boolean isPhone);
109 
110     /**
111      * Get common alphabet shifted layout. This layout doesn't contain any special keys.
112      *
113      * A keyboard layout is an array of rows, and a row consists of an array of
114      * {@link ExpectedKey}s. Each row may have different number of {@link ExpectedKey}s.
115      *
116      * @param isPhone true if requesting phone's layout.
117      * @param elementId the element id of the requesting shifted mode.
118      * @return the common alphabet shifted keyboard layout.
119      */
getCommonAlphabetShiftLayout(final boolean isPhone, final int elementId)120     ExpectedKey[][] getCommonAlphabetShiftLayout(final boolean isPhone, final int elementId) {
121         final ExpectedKeyboardBuilder builder = new ExpectedKeyboardBuilder(
122                 getCommonAlphabetLayout(isPhone));
123         getCustomizer().setAccentedLetters(builder, elementId);
124         builder.toUpperCase(getLocale());
125         return builder.build();
126     }
127 
128     /**
129      * Get the complete expected keyboard layout.
130      *
131      * A keyboard layout is an array of rows, and a row consists of an array of
132      * {@link ExpectedKey}s. Each row may have different number of {@link ExpectedKey}s.
133      *
134      * @param isPhone true if requesting phone's layout.
135      * @param elementId the element id of the requesting keyboard mode.
136      * @return the keyboard layout of the <code>elementId</code>.
137      */
getLayout(final boolean isPhone, final int elementId)138     public ExpectedKey[][] getLayout(final boolean isPhone, final int elementId) {
139         if (elementId == KeyboardId.ELEMENT_SYMBOLS) {
140             return mSymbols.getLayout(isPhone);
141         }
142         if (elementId == KeyboardId.ELEMENT_SYMBOLS_SHIFTED) {
143             return mSymbolsShifted.getLayout(isPhone);
144         }
145         final ExpectedKeyboardBuilder builder;
146         if (elementId == KeyboardId.ELEMENT_ALPHABET) {
147             builder = new ExpectedKeyboardBuilder(getCommonAlphabetLayout(isPhone));
148             getCustomizer().setAccentedLetters(builder, elementId);
149         } else {
150             final ExpectedKey[][] commonLayout = getCommonAlphabetShiftLayout(isPhone, elementId);
151             if (commonLayout == null) {
152                 return null;
153             }
154             builder = new ExpectedKeyboardBuilder(commonLayout);
155         }
156         convertCommonLayoutToKeyboard(builder, isPhone);
157         if (elementId != KeyboardId.ELEMENT_ALPHABET) {
158             builder.replaceKeysOfAll(SHIFT_KEY, SHIFTED_SHIFT_KEY);
159         }
160         return builder.build();
161     }
162 }
163