1238e9898cd3d2eae22d73728b028da67915807faTadashi G. Takaoka/*
2238e9898cd3d2eae22d73728b028da67915807faTadashi G. Takaoka * Copyright (C) 2014 The Android Open Source Project
3238e9898cd3d2eae22d73728b028da67915807faTadashi G. Takaoka *
4238e9898cd3d2eae22d73728b028da67915807faTadashi G. Takaoka * Licensed under the Apache License, Version 2.0 (the "License");
5238e9898cd3d2eae22d73728b028da67915807faTadashi G. Takaoka * you may not use this file except in compliance with the License.
6238e9898cd3d2eae22d73728b028da67915807faTadashi G. Takaoka * You may obtain a copy of the License at
7238e9898cd3d2eae22d73728b028da67915807faTadashi G. Takaoka *
8238e9898cd3d2eae22d73728b028da67915807faTadashi G. Takaoka *      http://www.apache.org/licenses/LICENSE-2.0
9238e9898cd3d2eae22d73728b028da67915807faTadashi G. Takaoka *
10238e9898cd3d2eae22d73728b028da67915807faTadashi G. Takaoka * Unless required by applicable law or agreed to in writing, software
11238e9898cd3d2eae22d73728b028da67915807faTadashi G. Takaoka * distributed under the License is distributed on an "AS IS" BASIS,
12238e9898cd3d2eae22d73728b028da67915807faTadashi G. Takaoka * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13238e9898cd3d2eae22d73728b028da67915807faTadashi G. Takaoka * See the License for the specific language governing permissions and
14238e9898cd3d2eae22d73728b028da67915807faTadashi G. Takaoka * limitations under the License.
15238e9898cd3d2eae22d73728b028da67915807faTadashi G. Takaoka */
16238e9898cd3d2eae22d73728b028da67915807faTadashi G. Takaoka
17238e9898cd3d2eae22d73728b028da67915807faTadashi G. Takaokapackage com.android.inputmethod.keyboard.layout;
18238e9898cd3d2eae22d73728b028da67915807faTadashi G. Takaoka
196959a0f214fc18e314f54213877956d95a1631e8Tadashi G. Takaokaimport com.android.inputmethod.keyboard.layout.customizer.LayoutCustomizer;
2015a6b66ddaee302fc539311201b2b9f76778fd78Tadashi G. Takaokaimport com.android.inputmethod.keyboard.layout.expected.AbstractLayoutBase;
21238e9898cd3d2eae22d73728b028da67915807faTadashi G. Takaokaimport com.android.inputmethod.keyboard.layout.expected.ExpectedKey;
22238e9898cd3d2eae22d73728b028da67915807faTadashi G. Takaokaimport com.android.inputmethod.keyboard.layout.expected.ExpectedKeyboardBuilder;
23238e9898cd3d2eae22d73728b028da67915807faTadashi G. Takaoka
24238e9898cd3d2eae22d73728b028da67915807faTadashi G. Takaoka/**
25238e9898cd3d2eae22d73728b028da67915807faTadashi G. Takaoka * The symbols keyboard layout.
26238e9898cd3d2eae22d73728b028da67915807faTadashi G. Takaoka */
2715a6b66ddaee302fc539311201b2b9f76778fd78Tadashi G. Takaokapublic class Symbols extends AbstractLayoutBase {
2815a6b66ddaee302fc539311201b2b9f76778fd78Tadashi G. Takaoka    private final LayoutCustomizer mCustomizer;
2915a6b66ddaee302fc539311201b2b9f76778fd78Tadashi G. Takaoka
3015a6b66ddaee302fc539311201b2b9f76778fd78Tadashi G. Takaoka    public Symbols(final LayoutCustomizer customizer) {
3115a6b66ddaee302fc539311201b2b9f76778fd78Tadashi G. Takaoka        mCustomizer = customizer;
32238e9898cd3d2eae22d73728b028da67915807faTadashi G. Takaoka    }
33238e9898cd3d2eae22d73728b028da67915807faTadashi G. Takaoka
3415a6b66ddaee302fc539311201b2b9f76778fd78Tadashi G. Takaoka    public ExpectedKey[][] getLayout(final boolean isPhone) {
35746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka        final ExpectedKeyboardBuilder builder = new ExpectedKeyboardBuilder(SYMBOLS_COMMON);
36746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka        final LayoutCustomizer customizer = mCustomizer;
37746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka        builder.replaceKeyOfLabel(CURRENCY, customizer.getCurrencyKey());
38746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka        builder.replaceKeyOfLabel(DOUBLE_QUOTE, key("\"", joinMoreKeys(
39746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka                customizer.getDoubleQuoteMoreKeys(), customizer.getDoubleAngleQuoteKeys())));
40746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka        builder.replaceKeyOfLabel(SINGLE_QUOTE, key("'", joinMoreKeys(
41746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka                customizer.getSingleQuoteMoreKeys(), customizer.getSingleAngleQuoteKeys())));
42746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka        if (isPhone) {
43746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka            builder.addKeysOnTheLeftOfRow(3, customizer.getSymbolsShiftKey(isPhone))
446959a0f214fc18e314f54213877956d95a1631e8Tadashi G. Takaoka                    .addKeysOnTheRightOfRow(3, DELETE_KEY)
45746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka                    .addKeysOnTheLeftOfRow(4, customizer.getAlphabetKey())
46c9aa1beb6de6bbea71af8eba94354bff3001e0acTadashi G. Takaoka                    .addKeysOnTheRightOfRow(4, customizer.getEnterKey(isPhone));
47746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka        } else {
48746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka            // Tablet symbols keyboard has extra two keys at the left edge of the 3rd row.
496d44cb512239a11572ec18b850d609bacc3267beTadashi G. Takaoka            builder.addKeysOnTheLeftOfRow(3, (Object[])joinKeys("\\", "="));
506959a0f214fc18e314f54213877956d95a1631e8Tadashi G. Takaoka            builder.addKeysOnTheRightOfRow(1, DELETE_KEY)
51c9aa1beb6de6bbea71af8eba94354bff3001e0acTadashi G. Takaoka                    .addKeysOnTheRightOfRow(2, customizer.getEnterKey(isPhone))
52746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka                    .addKeysOnTheLeftOfRow(3, customizer.getSymbolsShiftKey(isPhone))
53746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka                    .addKeysOnTheRightOfRow(3, customizer.getSymbolsShiftKey(isPhone))
54746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka                    .addKeysOnTheLeftOfRow(4, customizer.getAlphabetKey())
55c9aa1beb6de6bbea71af8eba94354bff3001e0acTadashi G. Takaoka                    .addKeysOnTheRightOfRow(4, customizer.getEmojiKey(isPhone));
56746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka        }
570722e6b3df9904d07d74091122e422395810dfb3Tadashi G. Takaoka        return builder.build();
58f247b171ce98fd35f1f8de7e3d7f8f35099cf6feTadashi G. Takaoka    }
59f247b171ce98fd35f1f8de7e3d7f8f35099cf6feTadashi G. Takaoka
60f247b171ce98fd35f1f8de7e3d7f8f35099cf6feTadashi G. Takaoka    // Variations of the "currency" key on the 2nd row.
6115a6b66ddaee302fc539311201b2b9f76778fd78Tadashi G. Takaoka    public static final String CURRENCY = "CURRENCY";
62f247b171ce98fd35f1f8de7e3d7f8f35099cf6feTadashi G. Takaoka    // U+00A2: "¢" CENT SIGN
63f247b171ce98fd35f1f8de7e3d7f8f35099cf6feTadashi G. Takaoka    // U+00A3: "£" POUND SIGN
64f247b171ce98fd35f1f8de7e3d7f8f35099cf6feTadashi G. Takaoka    // U+00A5: "¥" YEN SIGN
65f247b171ce98fd35f1f8de7e3d7f8f35099cf6feTadashi G. Takaoka    // U+20AC: "€" EURO SIGN
66f247b171ce98fd35f1f8de7e3d7f8f35099cf6feTadashi G. Takaoka    // U+20B1: "₱" PESO SIGN
67f247b171ce98fd35f1f8de7e3d7f8f35099cf6feTadashi G. Takaoka    public static final ExpectedKey DOLLAR_SIGN = key("$");
68f247b171ce98fd35f1f8de7e3d7f8f35099cf6feTadashi G. Takaoka    public static final ExpectedKey CENT_SIGN = key("\u00A2");
69f247b171ce98fd35f1f8de7e3d7f8f35099cf6feTadashi G. Takaoka    public static final ExpectedKey POUND_SIGN = key("\u00A3");
70f247b171ce98fd35f1f8de7e3d7f8f35099cf6feTadashi G. Takaoka    public static final ExpectedKey YEN_SIGN = key("\u00A5");
71f247b171ce98fd35f1f8de7e3d7f8f35099cf6feTadashi G. Takaoka    public static final ExpectedKey EURO_SIGN = key("\u20AC");
72f247b171ce98fd35f1f8de7e3d7f8f35099cf6feTadashi G. Takaoka    public static final ExpectedKey PESO_SIGN = key("\u20B1");
73f247b171ce98fd35f1f8de7e3d7f8f35099cf6feTadashi G. Takaoka    public static final ExpectedKey CURRENCY_DOLLAR = key("$",
74f247b171ce98fd35f1f8de7e3d7f8f35099cf6feTadashi G. Takaoka            CENT_SIGN, POUND_SIGN, EURO_SIGN, YEN_SIGN, PESO_SIGN);
75f247b171ce98fd35f1f8de7e3d7f8f35099cf6feTadashi G. Takaoka    public static final ExpectedKey CURRENCY_EURO = key("\u20AC",
76f247b171ce98fd35f1f8de7e3d7f8f35099cf6feTadashi G. Takaoka            CENT_SIGN, POUND_SIGN, DOLLAR_SIGN, YEN_SIGN, PESO_SIGN);
77bef6a4e20965a8e664ee92b3c75405a6754afb4eTadashi G. Takaoka    public static final ExpectedKey[] CURRENCY_GENERIC_MORE_KEYS = joinMoreKeys(
78bef6a4e20965a8e664ee92b3c75405a6754afb4eTadashi G. Takaoka            Symbols.DOLLAR_SIGN, Symbols.CENT_SIGN, Symbols.EURO_SIGN, Symbols.POUND_SIGN,
79bef6a4e20965a8e664ee92b3c75405a6754afb4eTadashi G. Takaoka            Symbols.YEN_SIGN, Symbols.PESO_SIGN);
80f247b171ce98fd35f1f8de7e3d7f8f35099cf6feTadashi G. Takaoka
81f247b171ce98fd35f1f8de7e3d7f8f35099cf6feTadashi G. Takaoka    // Variations of the "double quote" key's "more keys" on the 3rd row.
8215a6b66ddaee302fc539311201b2b9f76778fd78Tadashi G. Takaoka    public static final String DOUBLE_QUOTE = "DOUBLE_QUOTE";
83f247b171ce98fd35f1f8de7e3d7f8f35099cf6feTadashi G. Takaoka    // U+201C: "“" LEFT DOUBLE QUOTATION MARK
84f247b171ce98fd35f1f8de7e3d7f8f35099cf6feTadashi G. Takaoka    // U+201D: "”" RIGHT DOUBLE QUOTATION MARK
85f247b171ce98fd35f1f8de7e3d7f8f35099cf6feTadashi G. Takaoka    // U+201E: "„" DOUBLE LOW-9 QUOTATION MARK
8615a6b66ddaee302fc539311201b2b9f76778fd78Tadashi G. Takaoka    private static final ExpectedKey DQUOTE_LEFT = key("\u201C");
8715a6b66ddaee302fc539311201b2b9f76778fd78Tadashi G. Takaoka    private static final ExpectedKey DQUOTE_RIGHT = key("\u201D");
8815a6b66ddaee302fc539311201b2b9f76778fd78Tadashi G. Takaoka    private static final ExpectedKey DQUOTE_LOW9 = key("\u201E");
89f247b171ce98fd35f1f8de7e3d7f8f35099cf6feTadashi G. Takaoka    public static ExpectedKey[] DOUBLE_QUOTES_9LR = { DQUOTE_LOW9, DQUOTE_LEFT, DQUOTE_RIGHT };
90f247b171ce98fd35f1f8de7e3d7f8f35099cf6feTadashi G. Takaoka    public static ExpectedKey[] DOUBLE_QUOTES_R9L = { DQUOTE_RIGHT, DQUOTE_LOW9, DQUOTE_LEFT };
91f247b171ce98fd35f1f8de7e3d7f8f35099cf6feTadashi G. Takaoka    public static ExpectedKey[] DOUBLE_QUOTES_L9R = { DQUOTE_LEFT, DQUOTE_LOW9, DQUOTE_RIGHT };
92f247b171ce98fd35f1f8de7e3d7f8f35099cf6feTadashi G. Takaoka    public static ExpectedKey[] DOUBLE_QUOTES_LR9 = { DQUOTE_LEFT, DQUOTE_RIGHT, DQUOTE_LOW9 };
93f247b171ce98fd35f1f8de7e3d7f8f35099cf6feTadashi G. Takaoka    // U+00AB: "«" LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
94f247b171ce98fd35f1f8de7e3d7f8f35099cf6feTadashi G. Takaoka    // U+00BB: "»" RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
95f247b171ce98fd35f1f8de7e3d7f8f35099cf6feTadashi G. Takaoka    private static final ExpectedKey DAQUOTE_LEFT = key("\u00AB");
96f247b171ce98fd35f1f8de7e3d7f8f35099cf6feTadashi G. Takaoka    private static final ExpectedKey DAQUOTE_RIGHT = key("\u00BB");
97f247b171ce98fd35f1f8de7e3d7f8f35099cf6feTadashi G. Takaoka    public static ExpectedKey[] DOUBLE_ANGLE_QUOTES_LR = { DAQUOTE_LEFT, DAQUOTE_RIGHT };
98f247b171ce98fd35f1f8de7e3d7f8f35099cf6feTadashi G. Takaoka    public static ExpectedKey[] DOUBLE_ANGLE_QUOTES_RL = { DAQUOTE_RIGHT, DAQUOTE_LEFT };
99f247b171ce98fd35f1f8de7e3d7f8f35099cf6feTadashi G. Takaoka
100f247b171ce98fd35f1f8de7e3d7f8f35099cf6feTadashi G. Takaoka    // Variations of the "single quote" key's "more keys" on the 3rd row.
10115a6b66ddaee302fc539311201b2b9f76778fd78Tadashi G. Takaoka    public static final String SINGLE_QUOTE = "SINGLE_QUOTE";
102f247b171ce98fd35f1f8de7e3d7f8f35099cf6feTadashi G. Takaoka    // U+2018: "‘" LEFT SINGLE QUOTATION MARK
103f247b171ce98fd35f1f8de7e3d7f8f35099cf6feTadashi G. Takaoka    // U+2019: "’" RIGHT SINGLE QUOTATION MARK
104f247b171ce98fd35f1f8de7e3d7f8f35099cf6feTadashi G. Takaoka    // U+201A: "‚" SINGLE LOW-9 QUOTATION MARK
10515a6b66ddaee302fc539311201b2b9f76778fd78Tadashi G. Takaoka    private static final ExpectedKey SQUOTE_LEFT = key("\u2018");
10615a6b66ddaee302fc539311201b2b9f76778fd78Tadashi G. Takaoka    private static final ExpectedKey SQUOTE_RIGHT = key("\u2019");
10715a6b66ddaee302fc539311201b2b9f76778fd78Tadashi G. Takaoka    private static final ExpectedKey SQUOTE_LOW9 = key("\u201A");
108f247b171ce98fd35f1f8de7e3d7f8f35099cf6feTadashi G. Takaoka    public static ExpectedKey[] SINGLE_QUOTES_9LR = { SQUOTE_LOW9, SQUOTE_LEFT, SQUOTE_RIGHT };
109f247b171ce98fd35f1f8de7e3d7f8f35099cf6feTadashi G. Takaoka    public static ExpectedKey[] SINGLE_QUOTES_R9L = { SQUOTE_RIGHT, SQUOTE_LOW9, SQUOTE_LEFT };
110f247b171ce98fd35f1f8de7e3d7f8f35099cf6feTadashi G. Takaoka    public static ExpectedKey[] SINGLE_QUOTES_L9R = { SQUOTE_LEFT, SQUOTE_LOW9, SQUOTE_RIGHT };
111f247b171ce98fd35f1f8de7e3d7f8f35099cf6feTadashi G. Takaoka    public static ExpectedKey[] SINGLE_QUOTES_LR9 = { SQUOTE_LEFT, SQUOTE_RIGHT, SQUOTE_LOW9 };
112f247b171ce98fd35f1f8de7e3d7f8f35099cf6feTadashi G. Takaoka    // U+2039: "‹" SINGLE LEFT-POINTING ANGLE QUOTATION MARK
113f247b171ce98fd35f1f8de7e3d7f8f35099cf6feTadashi G. Takaoka    // U+203A: "›" SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
114f247b171ce98fd35f1f8de7e3d7f8f35099cf6feTadashi G. Takaoka    private static final ExpectedKey SAQUOTE_LEFT = key("\u2039");
115f247b171ce98fd35f1f8de7e3d7f8f35099cf6feTadashi G. Takaoka    private static final ExpectedKey SAQUOTE_RIGHT = key("\u203A");
116f247b171ce98fd35f1f8de7e3d7f8f35099cf6feTadashi G. Takaoka    public static ExpectedKey[] SINGLE_ANGLE_QUOTES_LR = { SAQUOTE_LEFT, SAQUOTE_RIGHT };
117f247b171ce98fd35f1f8de7e3d7f8f35099cf6feTadashi G. Takaoka    public static ExpectedKey[] SINGLE_ANGLE_QUOTES_RL = { SAQUOTE_RIGHT, SAQUOTE_LEFT };
118f247b171ce98fd35f1f8de7e3d7f8f35099cf6feTadashi G. Takaoka
119238e9898cd3d2eae22d73728b028da67915807faTadashi G. Takaoka    // Common symbols keyboard layout.
120cd15cfdaaba7f361f4744bd3ff51ce6cdae1e608Tadashi G. Takaoka    private static final ExpectedKey[][] SYMBOLS_COMMON = new ExpectedKeyboardBuilder()
121746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka            .setKeysOfRow(1,
122746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka                    // U+00B9: "¹" SUPERSCRIPT ONE
123746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka                    // U+00BD: "½" VULGAR FRACTION ONE HALF
124746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka                    // U+2153: "⅓" VULGAR FRACTION ONE THIRD
125746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka                    // U+00BC: "¼" VULGAR FRACTION ONE QUARTER
126746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka                    // U+215B: "⅛" VULGAR FRACTION ONE EIGHTH
127746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka                    key("1", joinMoreKeys("\u00B9", "\u00BD", "\u2153", "\u00BC", "\u215B")),
128746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka                    // U+00B2: "²" SUPERSCRIPT TWO
129746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka                    // U+2154: "⅔" VULGAR FRACTION TWO THIRDS
130746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka                    key("2", joinMoreKeys("\u00B2", "\u2154")),
131746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka                    // U+00B3: "³" SUPERSCRIPT THREE
132746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka                    // U+00BE: "¾" VULGAR FRACTION THREE QUARTERS
133746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka                    // U+215C: "⅜" VULGAR FRACTION THREE EIGHTHS
134746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka                    key("3", joinMoreKeys("\u00B3", "\u00BE", "\u215C")),
135746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka                    // U+2074: "⁴" SUPERSCRIPT FOUR
136746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka                    key("4", moreKey("\u2074")),
137746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka                    // U+215D: "⅝" VULGAR FRACTION FIVE EIGHTHS
138746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka                    key("5", moreKey("\u215D")),
1396d44cb512239a11572ec18b850d609bacc3267beTadashi G. Takaoka                    "6",
140746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka                    // U+215E: "⅞" VULGAR FRACTION SEVEN EIGHTHS
141746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka                    key("7", moreKey("\u215E")),
1426d44cb512239a11572ec18b850d609bacc3267beTadashi G. Takaoka                    "8", "9",
143746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka                    // U+207F: "ⁿ" SUPERSCRIPT LATIN SMALL LETTER N
144746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka                    // U+2205: "∅" EMPTY SET
145746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka                    key("0", joinMoreKeys("\u207F", "\u2205")))
146746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka            .setKeysOfRow(2,
147746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka                    key("@"), key("#"), key(CURRENCY),
148746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka                    // U+2030: "‰" PER MILLE SIGN
149746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka                    key("%", moreKey("\u2030")),
1506d44cb512239a11572ec18b850d609bacc3267beTadashi G. Takaoka                    "&",
151746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka                    // U+2013: "–" EN DASH
152746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka                    // U+2014: "—" EM DASH
153746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka                    // U+00B7: "·" MIDDLE DOT
154746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka                    key("-", joinMoreKeys("_", "\u2013", "\u2014", "\u00B7")),
155746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka                    // U+00B1: "±" PLUS-MINUS SIGN
156746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka                    key("+", moreKey("\u00B1")),
157746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka                    key("(", joinMoreKeys("<", "{", "[")),
158746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka                    key(")", joinMoreKeys(">", "}", "]")))
159746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka            .setKeysOfRow(3,
160746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka                    // U+2020: "†" DAGGER
161746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka                    // U+2021: "‡" DOUBLE DAGGER
162746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka                    // U+2605: "★" BLACK STAR
163746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka                    key("*", joinMoreKeys("\u2020", "\u2021", "\u2605")),
164746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka                    key(DOUBLE_QUOTE), key(SINGLE_QUOTE), key(":"), key(";"),
165746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka                    // U+00A1: "¡" INVERTED EXCLAMATION MARK
166746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka                    key("!", moreKey("\u00A1")),
167746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka                    // U+00BF: "¿" INVERTED QUESTION MARK
168746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka                    key("?", moreKey("\u00BF")))
169746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka            .setKeysOfRow(4,
1706959a0f214fc18e314f54213877956d95a1631e8Tadashi G. Takaoka                    key(","), key("_"), SPACE_KEY, key("/"),
171746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka                    // U+2026: "…" HORIZONTAL ELLIPSIS
172746f94c671607521f66fd3c989072b5ec7c390c4Tadashi G. Takaoka                    key(".", moreKey("\u2026")))
173238e9898cd3d2eae22d73728b028da67915807faTadashi G. Takaoka            .build();
174238e9898cd3d2eae22d73728b028da67915807faTadashi G. Takaoka
17515a6b66ddaee302fc539311201b2b9f76778fd78Tadashi G. Takaoka    public static class RtlSymbols extends Symbols {
17615a6b66ddaee302fc539311201b2b9f76778fd78Tadashi G. Takaoka        public RtlSymbols(final LayoutCustomizer customizer) {
17715a6b66ddaee302fc539311201b2b9f76778fd78Tadashi G. Takaoka            super(customizer);
17815a6b66ddaee302fc539311201b2b9f76778fd78Tadashi G. Takaoka        }
17915a6b66ddaee302fc539311201b2b9f76778fd78Tadashi G. Takaoka
18015a6b66ddaee302fc539311201b2b9f76778fd78Tadashi G. Takaoka        // U+00AB: "«" LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
18115a6b66ddaee302fc539311201b2b9f76778fd78Tadashi G. Takaoka        // U+00BB: "»" RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
18215a6b66ddaee302fc539311201b2b9f76778fd78Tadashi G. Takaoka        private static final ExpectedKey DAQUOTE_LEFT_RTL = key("\u00AB", "\u00BB");
18315a6b66ddaee302fc539311201b2b9f76778fd78Tadashi G. Takaoka        private static final ExpectedKey DAQUOTE_RIGHT_RTL = key("\u00BB", "\u00AB");
18415a6b66ddaee302fc539311201b2b9f76778fd78Tadashi G. Takaoka        public static ExpectedKey[] DOUBLE_ANGLE_QUOTES_LR_RTL = {
18515a6b66ddaee302fc539311201b2b9f76778fd78Tadashi G. Takaoka                DAQUOTE_LEFT_RTL, DAQUOTE_RIGHT_RTL
18615a6b66ddaee302fc539311201b2b9f76778fd78Tadashi G. Takaoka        };
18715a6b66ddaee302fc539311201b2b9f76778fd78Tadashi G. Takaoka        // U+2039: "‹" SINGLE LEFT-POINTING ANGLE QUOTATION MARK
18815a6b66ddaee302fc539311201b2b9f76778fd78Tadashi G. Takaoka        // U+203A: "›" SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
18915a6b66ddaee302fc539311201b2b9f76778fd78Tadashi G. Takaoka        private static final ExpectedKey SAQUOTE_LEFT_RTL = key("\u2039", "\u203A");
19015a6b66ddaee302fc539311201b2b9f76778fd78Tadashi G. Takaoka        private static final ExpectedKey SAQUOTE_RIGHT_RTL = key("\u203A", "\u2039");
19115a6b66ddaee302fc539311201b2b9f76778fd78Tadashi G. Takaoka        public static ExpectedKey[] SINGLE_ANGLE_QUOTES_LR_RTL = {
19215a6b66ddaee302fc539311201b2b9f76778fd78Tadashi G. Takaoka                SAQUOTE_LEFT_RTL, SAQUOTE_RIGHT_RTL
19315a6b66ddaee302fc539311201b2b9f76778fd78Tadashi G. Takaoka        };
19415a6b66ddaee302fc539311201b2b9f76778fd78Tadashi G. Takaoka
19515a6b66ddaee302fc539311201b2b9f76778fd78Tadashi G. Takaoka        @Override
19615a6b66ddaee302fc539311201b2b9f76778fd78Tadashi G. Takaoka        public ExpectedKey[][] getLayout(final boolean isPhone) {
19715a6b66ddaee302fc539311201b2b9f76778fd78Tadashi G. Takaoka            return new ExpectedKeyboardBuilder(super.getLayout(isPhone))
19815a6b66ddaee302fc539311201b2b9f76778fd78Tadashi G. Takaoka                    .replaceKeyOfLabel("(", key("(", ")",
19915a6b66ddaee302fc539311201b2b9f76778fd78Tadashi G. Takaoka                            moreKey("<", ">"), moreKey("{", "}"), moreKey("[", "]")))
20015a6b66ddaee302fc539311201b2b9f76778fd78Tadashi G. Takaoka                    .replaceKeyOfLabel(")", key(")", "(",
20115a6b66ddaee302fc539311201b2b9f76778fd78Tadashi G. Takaoka                            moreKey(">", "<"), moreKey("}", "{"), moreKey("]", "[")))
20215a6b66ddaee302fc539311201b2b9f76778fd78Tadashi G. Takaoka                    .build();
20315a6b66ddaee302fc539311201b2b9f76778fd78Tadashi G. Takaoka        }
20415a6b66ddaee302fc539311201b2b9f76778fd78Tadashi G. Takaoka    }
205238e9898cd3d2eae22d73728b028da67915807faTadashi G. Takaoka}
206