1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
package com.anysoftkeyboard.keyboards;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.util.SparseIntArray;
import android.util.TypedValue;
import com.anysoftkeyboard.utils.Log;
import com.menny.android.anysoftkeyboard.AnyApplication;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import javax.annotation.Nonnull;
public class KeyboardSupport {
private static final String TAG = "KeyboardSupport";
public static int[] parseCSV(String value) {
int count = 0;
int lastIndex = 0;
if (value.length() > 0) {
count++;
while ((lastIndex = value.indexOf(",", lastIndex + 1)) > 0) {
count++;
}
}
int[] values = new int[count];
count = 0;
StringTokenizer st = new StringTokenizer(value, ",");
while (st.hasMoreTokens()) {
String nextToken = st.nextToken();
try {
// Issue 395
// default behavior
if (nextToken.length() != 1) {
values[count++] = Integer.parseInt(nextToken);
} else {
// length == 1, assume a char!
values[count++] = (int) nextToken.charAt(0);
}
} catch (NumberFormatException nfe) {
Log.e(TAG, "Error parsing keycodes " + value);
}
}
return values;
}
public static void updateDrawableBounds(Drawable icon) {
if (icon == null) return;
icon.setBounds(0, 0, icon.getIntrinsicWidth(), icon.getIntrinsicHeight());
}
public static int[] getKeyCodesFromTypedArray(TypedArray typedArray, int index) {
TypedValue codesValue = new TypedValue();
typedArray.getValue(index, codesValue);
if (codesValue.type == TypedValue.TYPE_INT_DEC || codesValue.type == TypedValue.TYPE_INT_HEX) {
return new int[]{ codesValue.data };
} else if (codesValue.type == TypedValue.TYPE_STRING) {
return parseCSV(codesValue.string.toString());
} else {
return null;
}
}
/**
* Creates a mapping between the local styleable and the remote.
* @param localStyleableArray the local styleable to map against
* @param localContext local APK's Context
* @param remoteContext remote package's Context
* @param attributeIdMap a mapping between the remote-id -> local-id
* @return Always returns the remote version of localStyleableArray
*/
public static int[] createBackwardCompatibleStyleable(@Nonnull int[] localStyleableArray, @Nonnull Context localContext, @Nonnull Context remoteContext, @Nonnull SparseIntArray attributeIdMap) {
final String remotePackageName = remoteContext.getPackageName();
if (localContext.getPackageName().equals(remotePackageName)) {
Log.d(TAG, "This is a local context ("+remotePackageName+"), optimization will be done.");
//optimization
for(int attrId : localStyleableArray) {
attributeIdMap.put(attrId, attrId);
}
return localStyleableArray;
}
final Resources localRes = localContext.getResources();
final Resources remoteRes = remoteContext.getResources();
List<Integer> styleableIdList = new ArrayList<Integer>(localStyleableArray.length);
for(int attrId : localStyleableArray) {
final boolean isAndroidAttribute = localRes.getResourcePackageName(attrId).equals("android");
final int remoteAttrId;
if (isAndroidAttribute) {
//android attribute IDs are the same always. So, I can optimize.
remoteAttrId = attrId;
} else {
final String attributeName = localRes.getResourceEntryName(attrId);
remoteAttrId = remoteRes.getIdentifier(attributeName, "attr", remotePackageName);
Log.d(TAG, "attr "+attributeName+", local id "+attrId+", remote id "+remoteAttrId);
}
if (remoteAttrId != 0) {
attributeIdMap.put(remoteAttrId, attrId);
styleableIdList.add(remoteAttrId);
}
}
final int[] remoteMappedStyleable = new int[styleableIdList.size()];
for(int i=0; i<remoteMappedStyleable.length; i++) {
remoteMappedStyleable[i] = styleableIdList.get(i);
}
return remoteMappedStyleable;
}
public static int getKeyHeightFromHeightCode(KeyboardDimens keyboardDimens, int heightCode, int orientation) {
int height;
switch (heightCode) {
case 0:
height = 0;
break;
case -2:
height = keyboardDimens.getSmallKeyHeight();
break;
case -3:
height = keyboardDimens.getLargeKeyHeight();
break;
default:// -1
height = keyboardDimens.getNormalKeyHeight();
break;
}
if (orientation == Configuration.ORIENTATION_LANDSCAPE)
height = (int) (height * AnyApplication.getConfig()
.getKeysHeightFactorInLandscape());
else
height = (int) (height * AnyApplication.getConfig().getKeysHeightFactorInPortrait());
return height;
}
}
|