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.expected;
18 
19 import com.android.inputmethod.keyboard.Key;
20 import com.android.inputmethod.keyboard.internal.KeyboardIconsSet;
21 import com.android.inputmethod.keyboard.internal.MoreKeySpec;
22 import com.android.inputmethod.latin.common.StringUtils;
23 
24 import java.util.Locale;
25 
26 /**
27  * This class represents an expected visual outlook of a key.
28  *
29  * There are two types of expected visual, an integer icon id and a string label.
30  */
31 public abstract class ExpectedKeyVisual {
newInstance(final String label)32     public static ExpectedKeyVisual newInstance(final String label) {
33         return new Label(label);
34     }
35 
newInstance(final int iconId)36     public static ExpectedKeyVisual newInstance(final int iconId) {
37         return new Icon(iconId);
38     }
39 
getIconId()40     public abstract int getIconId();
getLabel()41     public abstract String getLabel();
toUpperCase(final Locale locale)42     abstract ExpectedKeyVisual toUpperCase(final Locale locale);
preserveCase()43     abstract ExpectedKeyVisual preserveCase();
hasSameKeyVisual(final String text)44     abstract boolean hasSameKeyVisual(final String text);
hasSameKeyVisual(final Key key)45     abstract boolean hasSameKeyVisual(final Key key);
hasSameKeyVisual(final MoreKeySpec moreKeySpec)46     abstract boolean hasSameKeyVisual(final MoreKeySpec moreKeySpec);
hasSameKeyVisual(final ExpectedKeyOutput output)47     abstract boolean hasSameKeyVisual(final ExpectedKeyOutput output);
hasSameKeyVisual(final ExpectedKeyVisual visual)48     abstract boolean hasSameKeyVisual(final ExpectedKeyVisual visual);
49 
50     /**
51      * This class represents an integer icon id.
52      */
53     private static class Icon extends ExpectedKeyVisual {
54         private final int mIconId;
55 
Icon(final int iconId)56         Icon(final int iconId) {
57             mIconId = iconId;
58         }
59 
60         @Override
getIconId()61         public int getIconId() {
62             return mIconId;
63         }
64 
65         @Override
getLabel()66         public String getLabel() {
67             return null;
68         }
69 
70         @Override
toUpperCase(final Locale locale)71         ExpectedKeyVisual toUpperCase(final Locale locale) {
72             return this;
73         }
74 
75         @Override
preserveCase()76         ExpectedKeyVisual preserveCase() {
77             return this;
78         }
79 
80         @Override
hasSameKeyVisual(final String text)81         boolean hasSameKeyVisual(final String text) {
82             return false;
83         }
84 
85         @Override
hasSameKeyVisual(final Key key)86         boolean hasSameKeyVisual(final Key key) {
87             // If the actual key has an icon as its visual, a label has to be null.
88             // See {@link KeyboardView#onDrawKeyTopVisuals(Key,Canvas,Paint,KeyDrawParams).
89             return mIconId == key.getIconId() && key.getLabel() == null;
90         }
91 
92         @Override
hasSameKeyVisual(final MoreKeySpec moreKeySpec)93         boolean hasSameKeyVisual(final MoreKeySpec moreKeySpec) {
94             // If the actual more key has an icon as its visual, a label has to be null.
95             // See {@link KeySpecParser#getIconId(String)} and
96             // {@link KeySpecParser#getLabel(String)}.
97             return mIconId == moreKeySpec.mIconId && moreKeySpec.mLabel == null;
98         }
99 
100         @Override
hasSameKeyVisual(final ExpectedKeyOutput output)101         boolean hasSameKeyVisual(final ExpectedKeyOutput output) {
102             return false;
103         }
104 
105         @Override
hasSameKeyVisual(final ExpectedKeyVisual visual)106         boolean hasSameKeyVisual(final ExpectedKeyVisual visual) {
107             return (visual instanceof Icon) && mIconId == ((Icon)visual).mIconId;
108         }
109 
110         @Override
toString()111         public String toString() {
112             return KeyboardIconsSet.getIconName(mIconId);
113         }
114     }
115 
116     /**
117      * This class represents a string label.
118      */
119     private static class Label extends ExpectedKeyVisual {
120         private final String mLabel;
121 
Label(final String label)122         Label(final String label) {
123             mLabel = label;
124         }
125 
126         @Override
getIconId()127         public int getIconId() {
128             return KeyboardIconsSet.ICON_UNDEFINED;
129         }
130 
131         @Override
getLabel()132         public String getLabel() {
133             return mLabel;
134         }
135 
136         @Override
toUpperCase(final Locale locale)137         ExpectedKeyVisual toUpperCase(final Locale locale) {
138             return new Label(StringUtils.toTitleCaseOfKeyLabel(mLabel, locale));
139         }
140 
141         @Override
preserveCase()142         ExpectedKeyVisual preserveCase() {
143             return new CasePreservedLabel(mLabel);
144         }
145 
146         @Override
hasSameKeyVisual(final String text)147         boolean hasSameKeyVisual(final String text) {
148             return mLabel.equals(text);
149         }
150 
151         @Override
hasSameKeyVisual(final Key key)152         boolean hasSameKeyVisual(final Key key) {
153             // If the actual key has a label as its visual, an icon has to be undefined.
154             // See {@link KeyboardView#onDrawKeyTopVisuals(Key,Canvas,Paint,KeyDrawParams).
155             return mLabel.equals(key.getLabel())
156                     && key.getIconId() == KeyboardIconsSet.ICON_UNDEFINED;
157         }
158 
159         @Override
hasSameKeyVisual(final MoreKeySpec moreKeySpec)160         boolean hasSameKeyVisual(final MoreKeySpec moreKeySpec) {
161             // If the actual more key has a label as its visual, an icon has to be undefined.
162             // See {@link KeySpecParser#getIconId(String)} and
163             // {@link KeySpecParser#getLabel(String)}.
164             return mLabel.equals(moreKeySpec.mLabel)
165                     && moreKeySpec.mIconId == KeyboardIconsSet.ICON_UNDEFINED;
166         }
167 
168         @Override
hasSameKeyVisual(final ExpectedKeyOutput output)169         boolean hasSameKeyVisual(final ExpectedKeyOutput output) {
170             return output.hasSameKeyOutput(mLabel);
171         }
172 
173         @Override
hasSameKeyVisual(final ExpectedKeyVisual visual)174         boolean hasSameKeyVisual(final ExpectedKeyVisual visual) {
175             return (visual instanceof Label) && mLabel.equals(((Label)visual).mLabel);
176         }
177 
178         @Override
toString()179         public String toString() {
180             return mLabel;
181         }
182 
183         private static class CasePreservedLabel extends Label {
CasePreservedLabel(final String label)184             CasePreservedLabel(final String label) { super(label); }
185 
186             @Override
toUpperCase(final Locale locale)187             ExpectedKeyVisual toUpperCase(final Locale locale) { return this; }
188 
189             @Override
preserveCase()190             ExpectedKeyVisual preserveCase() { return this; }
191         }
192     }
193 }
194