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
17package com.android.inputmethod.keyboard.layout;
18
19import com.android.inputmethod.keyboard.KeyboardId;
20import com.android.inputmethod.keyboard.layout.customizer.LayoutCustomizer;
21import com.android.inputmethod.keyboard.layout.expected.ExpectedKey;
22import com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder;
23
24/**
25 * The PC QWERTY alphabet keyboard.
26 */
27public final class PcQwerty extends LayoutBase {
28    private static final String LAYOUT_NAME = "pcqwerty";
29
30    public PcQwerty(final LayoutCustomizer customizer) {
31        super(customizer, Symbols.class, SymbolsShifted.class);
32    }
33
34    @Override
35    public String getName() { return LAYOUT_NAME; }
36
37    @Override
38    ExpectedKey[][] getCommonAlphabetLayout(final boolean isPhone) {
39        final LayoutCustomizer customizer = getCustomizer();
40        final ExpectedKeyboardBuilder builder = new ExpectedKeyboardBuilder(ALPHABET_COMMON);
41        customizer.setAccentedLetters(builder);
42        builder.replaceKeyOfLabel(ROW1_1, key("`", moreKey("~")))
43                .replaceKeyOfLabel(ROW2_11, key("[", moreKey("{")))
44                .replaceKeyOfLabel(ROW2_12, key("]", moreKey("}")))
45                .replaceKeyOfLabel(ROW2_13, key("\\", moreKey("|")))
46                .replaceKeyOfLabel(ROW3_10, key(";", moreKey(":")))
47                .replaceKeyOfLabel(ROW3_11, key("'", joinMoreKeys(additionalMoreKey("\""),
48                        customizer.getDoubleQuoteMoreKeys(),
49                        customizer.getSingleQuoteMoreKeys())))
50                .setAdditionalMoreKeysPositionOf("'", 4)
51                .replaceKeyOfLabel(ROW4_8, key(",", moreKey("<")))
52                .replaceKeyOfLabel(ROW4_9, key(".", moreKey(">")))
53                // U+00BF: "¿" INVERTED QUESTION MARK
54                .replaceKeyOfLabel(ROW4_10, key("/", joinMoreKeys("?", "\u00BF")));
55        if (isPhone) {
56            // U+221E: "∞" INFINITY
57            // U+2260: "≠" NOT EQUAL TO
58            // U+2248: "≈" ALMOST EQUAL TO
59            builder.replaceKeyOfLabel(ROW1_13, key("=",
60                    joinMoreKeys("\u221E", "\u2260", "\u2248", "+")));
61        } else {
62            // U+221E: "∞" INFINITY
63            // U+2260: "≠" NOT EQUAL TO
64            // U+2248: "≈" ALMOST EQUAL TO
65            builder.replaceKeyOfLabel(ROW1_13, key("=",
66                    joinMoreKeys("+", "\u221E", "\u2260", "\u2248")));
67        }
68        return builder.build();
69    }
70
71    @Override
72    ExpectedKey[][] getCommonAlphabetShiftLayout(final boolean isPhone, final int elementId) {
73        final ExpectedKeyboardBuilder builder;
74        if (elementId == KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED
75                || elementId == KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCKED) {
76            builder = new ExpectedKeyboardBuilder(getCommonAlphabetLayout(isPhone));
77        } else {
78            builder = new ExpectedKeyboardBuilder(ALPHABET_COMMON);
79            final LayoutCustomizer customizer = getCustomizer();
80            customizer.setAccentedLetters(builder);
81            builder.setKeysOfRow(1,
82                    "~",
83                    // U+00A1: "¡" INVERTED EXCLAMATION MARK
84                    key("!", moreKey("\u00A1")),
85                    "@", "#",
86                    customizer.getCurrencyKey(),
87                    // U+2030: "‰" PER MILLE SIGN
88                    key("%", moreKey("\u2030")),
89                    "^", "&",
90                    // U+2020: "†" DAGGER
91                    // U+2021: "‡" DOUBLE DAGGER
92                    // U+2605: "★" BLACK STAR
93                    key("*", joinMoreKeys("\u2020", "\u2021", "\u2605")),
94                    "(", ")", "_",
95                    // U+00B1: "±" PLUS-MINUS SIGN
96                    // U+00D7: "×" MULTIPLICATION SIGN
97                    // U+00F7: "÷" DIVISION SIGN
98                    // U+221A: "√" SQUARE ROOT
99                    key("+", joinMoreKeys("\u00B1", "\u00D7", "\u00F7", "\u221A")))
100                    .replaceKeyOfLabel(ROW2_11, key("{"))
101                    .replaceKeyOfLabel(ROW2_12, key("}"))
102                    .replaceKeyOfLabel(ROW2_13, key("|"))
103                    .replaceKeyOfLabel(ROW3_10, key(":"))
104                    .replaceKeyOfLabel(ROW3_11, key("\"", joinMoreKeys(
105                            customizer.getDoubleQuoteMoreKeys(),
106                            customizer.getSingleQuoteMoreKeys())))
107                    // U+2039: "‹" SINGLE LEFT-POINTING ANGLE QUOTATION MARK
108                    // U+2264: "≤" LESS-THAN OR EQUAL TO
109                    // U+00AB: "«" LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
110                    .replaceKeyOfLabel(ROW4_8, key("<", joinMoreKeys("\u2039", "\u2264", "\u00AB")))
111                    // U+203A: "›" SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
112                    // U+2265: "≥" GREATER-THAN EQUAL TO
113                    // U+00BB: "»" RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
114                    .replaceKeyOfLabel(ROW4_9, key(">", joinMoreKeys("\u203A", "\u2265", "\u00BB")))
115                    // U+00BF: "¿" INVERTED QUESTION MARK
116                    .replaceKeyOfLabel(ROW4_10, key("?", moreKey("\u00BF")));
117        }
118        builder.toUpperCase(getLocale());
119        return builder.build();
120    }
121
122    // Helper method to create alphabet layout by adding special function keys.
123    @Override
124    ExpectedKeyboardBuilder convertCommonLayoutToKeyboard(final ExpectedKeyboardBuilder builder,
125            final boolean isPhone) {
126        final LayoutCustomizer customizer = getCustomizer();
127        builder.setKeysOfRow(5, (Object[])customizer.getSpaceKeys(isPhone));
128        builder.addKeysOnTheLeftOfRow(5, (Object[])customizer.getKeysLeftToSpacebar(isPhone));
129        builder.addKeysOnTheRightOfRow(5, (Object[])customizer.getKeysRightToSpacebar(isPhone));
130        if (isPhone) {
131            builder.addKeysOnTheRightOfRow(3, DELETE_KEY);
132        } else {
133            builder.addKeysOnTheRightOfRow(1, DELETE_KEY)
134                    .addKeysOnTheLeftOfRow(2, TAB_KEY)
135                    .addKeysOnTheRightOfRow(3, ENTER_KEY);
136        }
137        builder.addKeysOnTheLeftOfRow(4, (Object[])customizer.getLeftShiftKeys(isPhone))
138                .addKeysOnTheRightOfRow(4, (Object[])customizer.getRightShiftKeys(isPhone));
139        return builder;
140    }
141
142    @Override
143    public ExpectedKey[][] getLayout(final boolean isPhone, final int elementId) {
144        if (elementId == KeyboardId.ELEMENT_SYMBOLS
145                || elementId == KeyboardId.ELEMENT_SYMBOLS_SHIFTED) {
146            return null;
147        }
148        return super.getLayout(isPhone, elementId);
149    }
150
151    private static final String ROW1_1 = "ROW1_1";
152    private static final String ROW1_13 = "ROW1_13";
153    private static final String ROW2_11 = "ROW2_11";
154    private static final String ROW2_12 = "ROW2_12";
155    private static final String ROW2_13 = "ROW2_13";
156    private static final String ROW3_10 = "ROW3_10";
157    private static final String ROW3_11 = "ROW3_11";
158    private static final String ROW4_8 = "ROW4_8";
159    private static final String ROW4_9 = "ROW4_9";
160    private static final String ROW4_10 = "ROW4_10";
161
162    private static final ExpectedKey[][] ALPHABET_COMMON = new ExpectedKeyboardBuilder()
163            .setKeysOfRow(1,
164                    ROW1_1,
165                    // U+00A1: "¡" INVERTED EXCLAMATION MARK
166                    // U+00B9: "¹" SUPERSCRIPT ONE
167                    // U+00BD: "½" VULGAR FRACTION ONE HALF
168                    // U+2153: "⅓" VULGAR FRACTION ONE THIRD
169                    // U+00BC: "¼" VULGAR FRACTION ONE QUARTER
170                    // U+215B: "⅛" VULGAR FRACTION ONE EIGHTH
171                    key("1", joinMoreKeys(
172                            "!", "\u00A1", "\u00B9", "\u00BD", "\u2153", "\u00BC", "\u215B")),
173                    // U+00B2: "²" SUPERSCRIPT TWO
174                    // U+2154: "⅔" VULGAR FRACTION TWO THIRDS
175                    key("2", joinMoreKeys("@", "\u00B2", "\u2154")),
176                    // U+00B3: "³" SUPERSCRIPT THREE
177                    // U+00BE: "¾" VULGAR FRACTION THREE QUARTERS
178                    // U+215C: "⅜" VULGAR FRACTION THREE EIGHTHS
179                    key("3", joinMoreKeys("#", "\u00B3", "\u00BE", "\u215C")),
180                    // U+2074: "⁴" SUPERSCRIPT FOUR
181                    key("4", joinMoreKeys("$", "\u2074")),
182                    // U+215D: "⅝" VULGAR FRACTION FIVE EIGHTHS
183                    key("5", joinMoreKeys("%", "\u215D")),
184                    key("6", moreKey("^")),
185                    // U+215E: "⅞" VULGAR FRACTION SEVEN EIGHTHS
186                    key("7", joinMoreKeys("&", "\u215E")),
187                    key("8", moreKey("*")),
188                    key("9", moreKey("(")),
189                    // U+207F: "ⁿ" SUPERSCRIPT LATIN SMALL LETTER N
190                    // U+2205: "∅" EMPTY SET
191                    key("0", joinMoreKeys(")", "\u207F", "\u2205")),
192                    // U+2013: "–" EN DASH
193                    // U+2014: "—" EM DASH
194                    // U+00B7: "·" MIDDLE DOT
195                    key("-", joinMoreKeys("_", "\u2013", "\u2014", "\u00B7")),
196                    ROW1_13)
197            .setKeysOfRow(2, "q", "w", "e", "r", "t", "y", "u", "i", "o", "p",
198                    ROW2_11, ROW2_12, ROW2_13)
199            .setKeysOfRow(3, "a", "s", "d", "f", "g", "h", "j", "k", "l", ROW3_10, ROW3_11)
200            .setKeysOfRow(4, "z", "x", "c", "v", "b", "n", "m", ROW4_8, ROW4_9, ROW4_10)
201            .build();
202}
203