1c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka/* 2c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka * Copyright (C) 2014 The Android Open Source Project 3c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka * 4c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka * Licensed under the Apache License, Version 2.0 (the "License"); 5c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka * you may not use this file except in compliance with the License. 6c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka * You may obtain a copy of the License at 7c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka * 8c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka * http://www.apache.org/licenses/LICENSE-2.0 9c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka * 10c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka * Unless required by applicable law or agreed to in writing, software 11c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka * distributed under the License is distributed on an "AS IS" BASIS, 12c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka * See the License for the specific language governing permissions and 14c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka * limitations under the License. 15c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka */ 16c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka 17c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaokapackage com.android.inputmethod.keyboard.layout.expected; 18c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka 19c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaokaimport com.android.inputmethod.keyboard.Key; 20c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaokaimport com.android.inputmethod.keyboard.internal.KeyboardIconsSet; 21c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaokaimport com.android.inputmethod.keyboard.internal.MoreKeySpec; 22f62b5d633d17b94a7ea46c968e073fdaa3fcbe15Tadashi G. Takaokaimport com.android.inputmethod.latin.common.StringUtils; 23c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka 24c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaokaimport java.util.Locale; 25c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka 26c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka/** 27c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka * This class represents an expected visual outlook of a key. 28c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka * 29c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka * There are two types of expected visual, an integer icon id and a string label. 30c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka */ 3151333ba4c36726a2f7acff859cd8ffb782e8f2b3Tadashi G. Takaokapublic abstract class ExpectedKeyVisual { 3251333ba4c36726a2f7acff859cd8ffb782e8f2b3Tadashi G. Takaoka public static ExpectedKeyVisual newInstance(final String label) { 33c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka return new Label(label); 34c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka } 35c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka 3651333ba4c36726a2f7acff859cd8ffb782e8f2b3Tadashi G. Takaoka public static ExpectedKeyVisual newInstance(final int iconId) { 37c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka return new Icon(iconId); 38c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka } 39c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka 4051333ba4c36726a2f7acff859cd8ffb782e8f2b3Tadashi G. Takaoka public abstract int getIconId(); 4151333ba4c36726a2f7acff859cd8ffb782e8f2b3Tadashi G. Takaoka public abstract String getLabel(); 42c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka abstract ExpectedKeyVisual toUpperCase(final Locale locale); 43c9aa1beb6de6bbea71af8eba94354bff3001e0acTadashi G. Takaoka abstract ExpectedKeyVisual preserveCase(); 4451333ba4c36726a2f7acff859cd8ffb782e8f2b3Tadashi G. Takaoka abstract boolean hasSameKeyVisual(final String text); 4551333ba4c36726a2f7acff859cd8ffb782e8f2b3Tadashi G. Takaoka abstract boolean hasSameKeyVisual(final Key key); 4651333ba4c36726a2f7acff859cd8ffb782e8f2b3Tadashi G. Takaoka abstract boolean hasSameKeyVisual(final MoreKeySpec moreKeySpec); 4751333ba4c36726a2f7acff859cd8ffb782e8f2b3Tadashi G. Takaoka abstract boolean hasSameKeyVisual(final ExpectedKeyOutput output); 4851333ba4c36726a2f7acff859cd8ffb782e8f2b3Tadashi G. Takaoka abstract boolean hasSameKeyVisual(final ExpectedKeyVisual visual); 49c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka 50c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka /** 51c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka * This class represents an integer icon id. 52c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka */ 53c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka private static class Icon extends ExpectedKeyVisual { 54c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka private final int mIconId; 55c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka 56c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka Icon(final int iconId) { 57c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka mIconId = iconId; 58c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka } 59c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka 60c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka @Override 6151333ba4c36726a2f7acff859cd8ffb782e8f2b3Tadashi G. Takaoka public int getIconId() { 6251333ba4c36726a2f7acff859cd8ffb782e8f2b3Tadashi G. Takaoka return mIconId; 6351333ba4c36726a2f7acff859cd8ffb782e8f2b3Tadashi G. Takaoka } 6451333ba4c36726a2f7acff859cd8ffb782e8f2b3Tadashi G. Takaoka 6551333ba4c36726a2f7acff859cd8ffb782e8f2b3Tadashi G. Takaoka @Override 6651333ba4c36726a2f7acff859cd8ffb782e8f2b3Tadashi G. Takaoka public String getLabel() { 6751333ba4c36726a2f7acff859cd8ffb782e8f2b3Tadashi G. Takaoka return null; 6851333ba4c36726a2f7acff859cd8ffb782e8f2b3Tadashi G. Takaoka } 6951333ba4c36726a2f7acff859cd8ffb782e8f2b3Tadashi G. Takaoka 7051333ba4c36726a2f7acff859cd8ffb782e8f2b3Tadashi G. Takaoka @Override 71c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka ExpectedKeyVisual toUpperCase(final Locale locale) { 72c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka return this; 73c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka } 74c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka 75c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka @Override 76c9aa1beb6de6bbea71af8eba94354bff3001e0acTadashi G. Takaoka ExpectedKeyVisual preserveCase() { 77c9aa1beb6de6bbea71af8eba94354bff3001e0acTadashi G. Takaoka return this; 78c9aa1beb6de6bbea71af8eba94354bff3001e0acTadashi G. Takaoka } 79c9aa1beb6de6bbea71af8eba94354bff3001e0acTadashi G. Takaoka 80c9aa1beb6de6bbea71af8eba94354bff3001e0acTadashi G. Takaoka @Override 8151333ba4c36726a2f7acff859cd8ffb782e8f2b3Tadashi G. Takaoka boolean hasSameKeyVisual(final String text) { 82c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka return false; 83c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka } 84c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka 85c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka @Override 8651333ba4c36726a2f7acff859cd8ffb782e8f2b3Tadashi G. Takaoka boolean hasSameKeyVisual(final Key key) { 8751333ba4c36726a2f7acff859cd8ffb782e8f2b3Tadashi G. Takaoka // If the actual key has an icon as its visual, a label has to be null. 8851333ba4c36726a2f7acff859cd8ffb782e8f2b3Tadashi G. Takaoka // See {@link KeyboardView#onDrawKeyTopVisuals(Key,Canvas,Paint,KeyDrawParams). 8951333ba4c36726a2f7acff859cd8ffb782e8f2b3Tadashi G. Takaoka return mIconId == key.getIconId() && key.getLabel() == null; 90c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka } 91c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka 92c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka @Override 9351333ba4c36726a2f7acff859cd8ffb782e8f2b3Tadashi G. Takaoka boolean hasSameKeyVisual(final MoreKeySpec moreKeySpec) { 9451333ba4c36726a2f7acff859cd8ffb782e8f2b3Tadashi G. Takaoka // If the actual more key has an icon as its visual, a label has to be null. 9551333ba4c36726a2f7acff859cd8ffb782e8f2b3Tadashi G. Takaoka // See {@link KeySpecParser#getIconId(String)} and 9651333ba4c36726a2f7acff859cd8ffb782e8f2b3Tadashi G. Takaoka // {@link KeySpecParser#getLabel(String)}. 9751333ba4c36726a2f7acff859cd8ffb782e8f2b3Tadashi G. Takaoka return mIconId == moreKeySpec.mIconId && moreKeySpec.mLabel == null; 98c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka } 99c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka 100c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka @Override 10151333ba4c36726a2f7acff859cd8ffb782e8f2b3Tadashi G. Takaoka boolean hasSameKeyVisual(final ExpectedKeyOutput output) { 102c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka return false; 103c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka } 104c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka 105c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka @Override 10651333ba4c36726a2f7acff859cd8ffb782e8f2b3Tadashi G. Takaoka boolean hasSameKeyVisual(final ExpectedKeyVisual visual) { 107c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka return (visual instanceof Icon) && mIconId == ((Icon)visual).mIconId; 108c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka } 109c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka 110c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka @Override 111c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka public String toString() { 112c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka return KeyboardIconsSet.getIconName(mIconId); 113c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka } 114c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka } 115c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka 116c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka /** 117c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka * This class represents a string label. 118c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka */ 119c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka private static class Label extends ExpectedKeyVisual { 120c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka private final String mLabel; 121c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka 12251333ba4c36726a2f7acff859cd8ffb782e8f2b3Tadashi G. Takaoka Label(final String label) { 12351333ba4c36726a2f7acff859cd8ffb782e8f2b3Tadashi G. Takaoka mLabel = label; 12451333ba4c36726a2f7acff859cd8ffb782e8f2b3Tadashi G. Takaoka } 12551333ba4c36726a2f7acff859cd8ffb782e8f2b3Tadashi G. Takaoka 12651333ba4c36726a2f7acff859cd8ffb782e8f2b3Tadashi G. Takaoka @Override 12751333ba4c36726a2f7acff859cd8ffb782e8f2b3Tadashi G. Takaoka public int getIconId() { 12851333ba4c36726a2f7acff859cd8ffb782e8f2b3Tadashi G. Takaoka return KeyboardIconsSet.ICON_UNDEFINED; 12951333ba4c36726a2f7acff859cd8ffb782e8f2b3Tadashi G. Takaoka } 13051333ba4c36726a2f7acff859cd8ffb782e8f2b3Tadashi G. Takaoka 13151333ba4c36726a2f7acff859cd8ffb782e8f2b3Tadashi G. Takaoka @Override 13251333ba4c36726a2f7acff859cd8ffb782e8f2b3Tadashi G. Takaoka public String getLabel() { 13351333ba4c36726a2f7acff859cd8ffb782e8f2b3Tadashi G. Takaoka return mLabel; 13451333ba4c36726a2f7acff859cd8ffb782e8f2b3Tadashi G. Takaoka } 135c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka 136c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka @Override 137c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka ExpectedKeyVisual toUpperCase(final Locale locale) { 1386c47403e27fd703ece844f4b1b24632721da1772Tadashi G. Takaoka return new Label(StringUtils.toTitleCaseOfKeyLabel(mLabel, locale)); 139c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka } 140c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka 141c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka @Override 142c9aa1beb6de6bbea71af8eba94354bff3001e0acTadashi G. Takaoka ExpectedKeyVisual preserveCase() { 143c9aa1beb6de6bbea71af8eba94354bff3001e0acTadashi G. Takaoka return new CasePreservedLabel(mLabel); 144c9aa1beb6de6bbea71af8eba94354bff3001e0acTadashi G. Takaoka } 145c9aa1beb6de6bbea71af8eba94354bff3001e0acTadashi G. Takaoka 146c9aa1beb6de6bbea71af8eba94354bff3001e0acTadashi G. Takaoka @Override 14751333ba4c36726a2f7acff859cd8ffb782e8f2b3Tadashi G. Takaoka boolean hasSameKeyVisual(final String text) { 148c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka return mLabel.equals(text); 149c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka } 150c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka 151c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka @Override 15251333ba4c36726a2f7acff859cd8ffb782e8f2b3Tadashi G. Takaoka boolean hasSameKeyVisual(final Key key) { 15351333ba4c36726a2f7acff859cd8ffb782e8f2b3Tadashi G. Takaoka // If the actual key has a label as its visual, an icon has to be undefined. 15451333ba4c36726a2f7acff859cd8ffb782e8f2b3Tadashi G. Takaoka // See {@link KeyboardView#onDrawKeyTopVisuals(Key,Canvas,Paint,KeyDrawParams). 15551333ba4c36726a2f7acff859cd8ffb782e8f2b3Tadashi G. Takaoka return mLabel.equals(key.getLabel()) 15651333ba4c36726a2f7acff859cd8ffb782e8f2b3Tadashi G. Takaoka && key.getIconId() == KeyboardIconsSet.ICON_UNDEFINED; 157c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka } 158c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka 159c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka @Override 16051333ba4c36726a2f7acff859cd8ffb782e8f2b3Tadashi G. Takaoka boolean hasSameKeyVisual(final MoreKeySpec moreKeySpec) { 16151333ba4c36726a2f7acff859cd8ffb782e8f2b3Tadashi G. Takaoka // If the actual more key has a label as its visual, an icon has to be undefined. 16251333ba4c36726a2f7acff859cd8ffb782e8f2b3Tadashi G. Takaoka // See {@link KeySpecParser#getIconId(String)} and 16351333ba4c36726a2f7acff859cd8ffb782e8f2b3Tadashi G. Takaoka // {@link KeySpecParser#getLabel(String)}. 16451333ba4c36726a2f7acff859cd8ffb782e8f2b3Tadashi G. Takaoka return mLabel.equals(moreKeySpec.mLabel) 16551333ba4c36726a2f7acff859cd8ffb782e8f2b3Tadashi G. Takaoka && moreKeySpec.mIconId == KeyboardIconsSet.ICON_UNDEFINED; 166c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka } 167c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka 168c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka @Override 16951333ba4c36726a2f7acff859cd8ffb782e8f2b3Tadashi G. Takaoka boolean hasSameKeyVisual(final ExpectedKeyOutput output) { 17051333ba4c36726a2f7acff859cd8ffb782e8f2b3Tadashi G. Takaoka return output.hasSameKeyOutput(mLabel); 171c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka } 172c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka 173c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka @Override 17451333ba4c36726a2f7acff859cd8ffb782e8f2b3Tadashi G. Takaoka boolean hasSameKeyVisual(final ExpectedKeyVisual visual) { 175c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka return (visual instanceof Label) && mLabel.equals(((Label)visual).mLabel); 176c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka } 177c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka 178c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka @Override 179c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka public String toString() { 180c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka return mLabel; 181c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka } 182c9aa1beb6de6bbea71af8eba94354bff3001e0acTadashi G. Takaoka 183c9aa1beb6de6bbea71af8eba94354bff3001e0acTadashi G. Takaoka private static class CasePreservedLabel extends Label { 184c9aa1beb6de6bbea71af8eba94354bff3001e0acTadashi G. Takaoka CasePreservedLabel(final String label) { super(label); } 185c9aa1beb6de6bbea71af8eba94354bff3001e0acTadashi G. Takaoka 186c9aa1beb6de6bbea71af8eba94354bff3001e0acTadashi G. Takaoka @Override 187c9aa1beb6de6bbea71af8eba94354bff3001e0acTadashi G. Takaoka ExpectedKeyVisual toUpperCase(final Locale locale) { return this; } 188c9aa1beb6de6bbea71af8eba94354bff3001e0acTadashi G. Takaoka 189c9aa1beb6de6bbea71af8eba94354bff3001e0acTadashi G. Takaoka @Override 190c9aa1beb6de6bbea71af8eba94354bff3001e0acTadashi G. Takaoka ExpectedKeyVisual preserveCase() { return this; } 191c9aa1beb6de6bbea71af8eba94354bff3001e0acTadashi G. Takaoka } 192c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka } 193c39c912a331c9993438783c6eb03910aa314813dTadashi G. Takaoka} 194