Home | History | Annotate | Download | only in layout
      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 
     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      */
     52     public abstract String getName();
     53 
     54     /**
     55      * The locale of this layout.
     56      * @return the locale of this layout.
     57      */
     58     public final Locale getLocale() { return mCustomizer.getLocale(); }
     59 
     60     /**
     61      * The layout customizer for this layout.
     62      * @return the layout customizer;
     63      */
     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      */
     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      */
    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      */
    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      */
    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