aboutsummaryrefslogtreecommitdiffstats
path: root/java
diff options
context:
space:
mode:
Diffstat (limited to 'java')
-rw-r--r--java/res/values/attrs.xml1
-rw-r--r--java/res/values/keypress-vibration-durations.xml4
-rw-r--r--java/res/values/keypress-volumes.xml4
-rw-r--r--java/res/values/strings.xml2
-rw-r--r--java/res/xml/prefs.xml2
-rw-r--r--java/res/xml/rowkeys_hebrew1.xml58
-rw-r--r--java/res/xml/rows_hebrew.xml13
-rw-r--r--java/src/com/android/inputmethod/keyboard/ProximityInfo.java127
-rw-r--r--java/src/com/android/inputmethod/latin/SeekBarDialogPreference.java39
-rw-r--r--java/src/com/android/inputmethod/latin/SettingsFragment.java21
10 files changed, 208 insertions, 63 deletions
diff --git a/java/res/values/attrs.xml b/java/res/values/attrs.xml
index 80bf704db..c31831747 100644
--- a/java/res/values/attrs.xml
+++ b/java/res/values/attrs.xml
@@ -439,7 +439,6 @@
</declare-styleable>
<declare-styleable name="SeekBarDialogPreference">
- <attr name="valueFormatText" format="reference" />
<attr name="maxValue" format="integer" />
<attr name="minValue" format="integer" />
<attr name="stepValue" format="integer" />
diff --git a/java/res/values/keypress-vibration-durations.xml b/java/res/values/keypress-vibration-durations.xml
index e8d92256b..e2f2b56e5 100644
--- a/java/res/values/keypress-vibration-durations.xml
+++ b/java/res/values/keypress-vibration-durations.xml
@@ -56,7 +56,7 @@
<item>MODEL=XT907:MANUFACTURER=motorola,30</item>
<!-- Sony Xperia Z -->
<item>MODEL=C6603:MANUFACTURER=Sony,35</item>
- <!-- Default value for unknown device -->
- <item>,20</item>
+ <!-- Default value for unknown device. The negative value means system default. -->
+ <item>,-1</item>
</string-array>
</resources>
diff --git a/java/res/values/keypress-volumes.xml b/java/res/values/keypress-volumes.xml
index a096c341b..d359055c2 100644
--- a/java/res/values/keypress-volumes.xml
+++ b/java/res/values/keypress-volumes.xml
@@ -26,7 +26,7 @@
<item>HARDWARE=grouper,0.3f</item>
<item>HARDWARE=mako,0.3f</item>
<item>HARDWARE=manta,0.2f</item>
- <!-- Default value for unknown device -->
- <item>,0.2f</item>
+ <!-- Default value for unknown device. The negative value means system default. -->
+ <item>,-1.0f</item>
</string-array>
</resources>
diff --git a/java/res/values/strings.xml b/java/res/values/strings.xml
index 85abb08fe..cdc2c3a09 100644
--- a/java/res/values/strings.xml
+++ b/java/res/values/strings.xml
@@ -79,6 +79,8 @@
<!-- Units abbreviation for the duration (milliseconds) [CHAR LIMIT=10] -->
<string name="abbreviation_unit_milliseconds"><xliff:g id="milliseconds">%s</xliff:g>ms</string>
+ <!-- The text that represents the current settings value is the system default [CHAR LIMIT=20] -->
+ <string name="settings_system_default">System default</string>
<!-- Option name for enabling or disabling the use of names of people in Contacts for suggestion and correction [CHAR LIMIT=25] -->
<string name="use_contacts_dict">Suggest Contact names</string>
diff --git a/java/res/xml/prefs.xml b/java/res/xml/prefs.xml
index 51e3420e9..d77adcef9 100644
--- a/java/res/xml/prefs.xml
+++ b/java/res/xml/prefs.xml
@@ -170,14 +170,12 @@
<com.android.inputmethod.latin.SeekBarDialogPreference
android:key="pref_key_longpress_timeout"
android:title="@string/prefs_key_longpress_timeout_settings"
- latin:valueFormatText="@string/abbreviation_unit_milliseconds"
latin:minValue="@integer/config_min_longpress_timeout"
latin:maxValue="@integer/config_max_longpress_timeout"
latin:stepValue="@integer/config_longpress_timeout_step" />
<com.android.inputmethod.latin.SeekBarDialogPreference
android:key="pref_vibration_duration_settings"
android:title="@string/prefs_keypress_vibration_duration_settings"
- latin:valueFormatText="@string/abbreviation_unit_milliseconds"
latin:maxValue="@integer/config_max_vibration_duration" />
<com.android.inputmethod.latin.SeekBarDialogPreference
android:key="pref_keypress_sound_volume"
diff --git a/java/res/xml/rowkeys_hebrew1.xml b/java/res/xml/rowkeys_hebrew1.xml
index 396da785e..81a00e367 100644
--- a/java/res/xml/rowkeys_hebrew1.xml
+++ b/java/res/xml/rowkeys_hebrew1.xml
@@ -21,28 +21,70 @@
<merge
xmlns:latin="http://schemas.android.com/apk/res/com.android.inputmethod.latin"
>
+ <switch>
+ <case
+ latin:mode="email|url"
+ >
+ <Key
+ latin:keyLabel="-"
+ latin:keyHintLabel="1"
+ latin:additionalMoreKeys="1" />
+ <Key
+ latin:keyLabel="_"
+ latin:keyHintLabel="2"
+ latin:additionalMoreKeys="2" />
+ </case>
+ <default>
+ <Key
+ latin:keyLabel="\'"
+ latin:keyHintLabel="1"
+ latin:additionalMoreKeys="1"
+ latin:moreKeys="&quot;" />
+ <Key
+ latin:keyLabel="-"
+ latin:keyHintLabel="2"
+ latin:additionalMoreKeys="2"
+ latin:moreKeys="_" />
+ </default>
+ </switch>
<!-- U+05E7: "ק" HEBREW LETTER QOF -->
<Key
- latin:keyLabel="&#x05E7;" />
+ latin:keyLabel="&#x05E7;"
+ latin:keyHintLabel="3"
+ latin:additionalMoreKeys="3" />
<!-- U+05E8: "ר" HEBREW LETTER RESH -->
<Key
- latin:keyLabel="&#x05E8;" />
+ latin:keyLabel="&#x05E8;"
+ latin:keyHintLabel="4"
+ latin:additionalMoreKeys="4" />
<!-- U+05D0: "א" HEBREW LETTER ALEF -->
<Key
- latin:keyLabel="&#x05D0;" />
+ latin:keyLabel="&#x05D0;"
+ latin:keyHintLabel="5"
+ latin:additionalMoreKeys="5" />
<!-- U+05D8: "ט" HEBREW LETTER TET -->
<Key
- latin:keyLabel="&#x05D8;" />
+ latin:keyLabel="&#x05D8;"
+ latin:keyHintLabel="6"
+ latin:additionalMoreKeys="6" />
<!-- U+05D5: "ו" HEBREW LETTER VAV -->
<Key
- latin:keyLabel="&#x05D5;" />
+ latin:keyLabel="&#x05D5;"
+ latin:keyHintLabel="7"
+ latin:additionalMoreKeys="7" />
<!-- U+05DF: "ן" HEBREW LETTER FINAL NUN -->
<Key
- latin:keyLabel="&#x05DF;" />
+ latin:keyLabel="&#x05DF;"
+ latin:keyHintLabel="8"
+ latin:additionalMoreKeys="8" />
<!-- U+05DD: "ם" HEBREW LETTER FINAL MEM -->
<Key
- latin:keyLabel="&#x05DD;" />
+ latin:keyLabel="&#x05DD;"
+ latin:keyHintLabel="9"
+ latin:additionalMoreKeys="9" />
<!-- U+05E4: "פ" HEBREW LETTER PE -->
<Key
- latin:keyLabel="&#x05E4;" />
+ latin:keyLabel="&#x05E4;"
+ latin:keyHintLabel="0"
+ latin:additionalMoreKeys="0" />
</merge>
diff --git a/java/res/xml/rows_hebrew.xml b/java/res/xml/rows_hebrew.xml
index 2d513df65..f12380a7d 100644
--- a/java/res/xml/rows_hebrew.xml
+++ b/java/res/xml/rows_hebrew.xml
@@ -27,12 +27,7 @@
latin:keyWidth="10%p"
>
<include
- latin:keyboardLayout="@xml/rowkeys_hebrew1"
- latin:keyXPos="5%p" />
- <Key
- latin:keyStyle="deleteKeyStyle"
- latin:keyWidth="fillRight"
- latin:visualInsetsLeft="1%p" />
+ latin:keyboardLayout="@xml/rowkeys_hebrew1" />
</Row>
<Row
latin:keyWidth="10%p"
@@ -44,8 +39,10 @@
latin:keyWidth="10%p"
>
<include
- latin:keyboardLayout="@xml/rowkeys_hebrew3"
- latin:keyXPos="5%p" />
+ latin:keyboardLayout="@xml/rowkeys_hebrew3" />
+ <Key
+ latin:keyStyle="deleteKeyStyle"
+ latin:keyWidth="fillRight" />
</Row>
<include
latin:keyboardLayout="@xml/row_qwerty4" />
diff --git a/java/src/com/android/inputmethod/keyboard/ProximityInfo.java b/java/src/com/android/inputmethod/keyboard/ProximityInfo.java
index 57d3fede4..0e86b051d 100644
--- a/java/src/com/android/inputmethod/keyboard/ProximityInfo.java
+++ b/java/src/com/android/inputmethod/keyboard/ProximityInfo.java
@@ -240,28 +240,121 @@ public class ProximityInfo {
private void computeNearestNeighbors() {
final int defaultWidth = mMostCommonKeyWidth;
- final Key[] keys = mKeys;
- final int thresholdBase = (int) (defaultWidth * SEARCH_DISTANCE);
- final int threshold = thresholdBase * thresholdBase;
+ final int keyCount = mKeys.length;
+ final int gridSize = mGridNeighbors.length;
+ final int threshold = (int) (defaultWidth * SEARCH_DISTANCE);
+ final int thresholdSquared = threshold * threshold;
// Round-up so we don't have any pixels outside the grid
- final Key[] neighborKeys = new Key[keys.length];
- final int gridWidth = mGridWidth * mCellWidth;
- final int gridHeight = mGridHeight * mCellHeight;
- for (int x = 0; x < gridWidth; x += mCellWidth) {
- for (int y = 0; y < gridHeight; y += mCellHeight) {
- final int centerX = x + mCellWidth / 2;
- final int centerY = y + mCellHeight / 2;
- int count = 0;
- for (final Key key : keys) {
- if (key.isSpacer()) continue;
- if (key.squaredDistanceToEdge(centerX, centerY) < threshold) {
- neighborKeys[count++] = key;
+ final int fullGridWidth = mGridWidth * mCellWidth;
+ final int fullGridHeight = mGridHeight * mCellHeight;
+
+ // For large layouts, 'neighborsFlatBuffer' is about 80k of memory: gridSize is usually 512,
+ // keycount is about 40 and a pointer to a Key is 4 bytes. This contains, for each cell,
+ // enough space for as many keys as there are on the keyboard. Hence, every
+ // keycount'th element is the start of a new cell, and each of these virtual subarrays
+ // start empty with keycount spaces available. This fills up gradually in the loop below.
+ // Since in the practice each cell does not have a lot of neighbors, most of this space is
+ // actually just empty padding in this fixed-size buffer.
+ final Key[] neighborsFlatBuffer = new Key[gridSize * keyCount];
+ final int[] neighborCountPerCell = new int[gridSize];
+ final int halfCellWidth = mCellWidth / 2;
+ final int halfCellHeight = mCellHeight / 2;
+ for (final Key key : mKeys) {
+ if (key.isSpacer()) continue;
+
+/* HOW WE PRE-SELECT THE CELLS (iterate over only the relevant cells, instead of all of them)
+
+ We want to compute the distance for keys that are in the cells that are close enough to the
+ key border, as this method is performance-critical. These keys are represented with 'star'
+ background on the diagram below. Let's consider the Y case first.
+
+ We want to select the cells which center falls between the top of the key minus the threshold,
+ and the bottom of the key plus the threshold.
+ topPixelWithinThreshold is key.mY - threshold, and bottomPixelWithinThreshold is
+ key.mY + key.mHeight + threshold.
+
+ Then we need to compute the center of the top row that we need to evaluate, as we'll iterate
+ from there.
+
+(0,0)----> x
+| .-------------------------------------------.
+| | | | | | | | | | | | |
+| |---+---+---+---+---+---+---+---+---+---+---| .- top of top cell (aligned on the grid)
+| | | | | | | | | | | | | |
+| |-----------+---+---+---+---+---+---+---+---|---' v
+| | | | |***|***|*_________________________ topPixelWithinThreshold | yDeltaToGrid
+| |---+---+---+-----^-+-|-+---+---+---+---+---| ^
+| | | | |***|*|*|*|*|***|***| | | | ______________________________________
+v |---+---+--threshold--|-+---+---+---+---+---| |
+ | | | |***|*|*|*|*|***|***| | | | | Starting from key.mY, we substract
+y |---+---+---+---+-v-+-|-+---+---+---+---+---| | thresholdBase and get the top pixel
+ | | | |***|**########------------------- key.mY | within the threshold. We align that on
+ |---+---+---+---+--#+---+-#-+---+---+---+---| | the grid by computing the delta to the
+ | | | |***|**#|***|*#*|***| | | | | grid, and get the top of the top cell.
+ |---+---+---+---+--#+---+-#-+---+---+---+---| |
+ | | | |***|**########*|***| | | | | Adding half the cell height to the top
+ |---+---+---+---+---+-|-+---+---+---+---+---| | of the top cell, we get the middle of
+ | | | |***|***|*|*|***|***| | | | | the top cell (yMiddleOfTopCell).
+ |---+---+---+---+---+-|-+---+---+---+---+---| |
+ | | | |***|***|*|*|***|***| | | | |
+ |---+---+---+---+---+-|________________________ yEnd | Since we only want to add the key to
+ | | | | | | | (bottomPixelWithinThreshold) | the proximity if it's close enough to
+ |---+---+---+---+---+---+---+---+---+---+---| | the center of the cell, we only need
+ | | | | | | | | | | | | | to compute for these cells where
+ '---'---'---'---'---'---'---'---'---'---'---' | topPixelWithinThreshold is above the
+ (positive x,y) | center of the cell. This is the case
+ | when yDeltaToGrid is less than half
+ [Zoomed in diagram] | the height of the cell.
+ +-------+-------+-------+-------+-------+ |
+ | | | | | | | On the zoomed in diagram, on the right
+ | | | | | | | the topPixelWithinThreshold (represented
+ | | | | | | top of | with an = sign) is below and we can skip
+ +-------+-------+-------+--v----+-------+ .. top cell | this cell, while on the left it's above
+ | | = topPixelWT | | yDeltaToGrid | and we need to compute for this cell.
+ |..yStart.|.....|.......|..|....|.......|... y middle | Thus, if yDeltaToGrid is more than half
+ | (left)| | | ^ = | | of top cell | the height of the cell, we start the
+ +-------+-|-----+-------+----|--+-------+ | iteration one cell below the top cell,
+ | | | | | | | | | else we start it on the top cell. This
+ |.......|.|.....|.......|....|..|.....yStart (right) | is stored in yStart.
+
+ Since we only want to go up to bottomPixelWithinThreshold, and we only iterate on the center
+ of the keys, we can stop as soon as the y value exceeds bottomPixelThreshold, so we don't
+ have to align this on the center of the key. Hence, we don't need a separate value for
+ bottomPixelWithinThreshold and call this yEnd right away.
+*/
+ final int topPixelWithinThreshold = key.mY - threshold;
+ final int yDeltaToGrid = topPixelWithinThreshold % mCellHeight;
+ final int yMiddleOfTopCell = topPixelWithinThreshold - yDeltaToGrid + halfCellHeight;
+ final int yStart = Math.max(halfCellHeight,
+ yMiddleOfTopCell + (yDeltaToGrid <= halfCellHeight ? 0 : mCellHeight));
+ final int yEnd = Math.min(fullGridHeight, key.mY + key.mHeight + threshold);
+
+ final int leftPixelWithinThreshold = key.mX - threshold;
+ final int xDeltaToGrid = leftPixelWithinThreshold % mCellWidth;
+ final int xMiddleOfLeftCell = leftPixelWithinThreshold - xDeltaToGrid + halfCellWidth;
+ final int xStart = Math.max(halfCellWidth,
+ xMiddleOfLeftCell + (xDeltaToGrid <= halfCellWidth ? 0 : mCellWidth));
+ final int xEnd = Math.min(fullGridWidth, key.mX + key.mWidth + threshold);
+
+ int baseIndexOfCurrentRow = (yStart / mCellHeight) * mGridWidth + (xStart / mCellWidth);
+ for (int centerY = yStart; centerY <= yEnd; centerY += mCellHeight) {
+ int index = baseIndexOfCurrentRow;
+ for (int centerX = xStart; centerX <= xEnd; centerX += mCellWidth) {
+ if (key.squaredDistanceToEdge(centerX, centerY) < thresholdSquared) {
+ neighborsFlatBuffer[index * keyCount + neighborCountPerCell[index]] = key;
+ ++neighborCountPerCell[index];
}
+ ++index;
}
- mGridNeighbors[(y / mCellHeight) * mGridWidth + (x / mCellWidth)] =
- Arrays.copyOfRange(neighborKeys, 0, count);
+ baseIndexOfCurrentRow += mGridWidth;
}
}
+
+ for (int i = 0; i < gridSize; ++i) {
+ final int base = i * keyCount;
+ mGridNeighbors[i] =
+ Arrays.copyOfRange(neighborsFlatBuffer, base, base + neighborCountPerCell[i]);
+ }
}
public void fillArrayWithNearestKeyCodes(final int x, final int y, final int primaryKeyCode,
diff --git a/java/src/com/android/inputmethod/latin/SeekBarDialogPreference.java b/java/src/com/android/inputmethod/latin/SeekBarDialogPreference.java
index 3ea9fedd7..44065ff33 100644
--- a/java/src/com/android/inputmethod/latin/SeekBarDialogPreference.java
+++ b/java/src/com/android/inputmethod/latin/SeekBarDialogPreference.java
@@ -33,10 +33,10 @@ public final class SeekBarDialogPreference extends DialogPreference
public int readDefaultValue(final String key);
public void writeValue(final int value, final String key);
public void writeDefaultValue(final String key);
+ public String getValueText(final int value);
public void feedbackValue(final int value);
}
- private final int mValueFormatResId;
private final int mMaxValue;
private final int mMinValue;
private final int mStepValue;
@@ -50,7 +50,6 @@ public final class SeekBarDialogPreference extends DialogPreference
super(context, attrs);
final TypedArray a = context.obtainStyledAttributes(
attrs, R.styleable.SeekBarDialogPreference, 0, 0);
- mValueFormatResId = a.getResourceId(R.styleable.SeekBarDialogPreference_valueFormatText, 0);
mMaxValue = a.getInt(R.styleable.SeekBarDialogPreference_maxValue, 0);
mMinValue = a.getInt(R.styleable.SeekBarDialogPreference_minValue, 0);
mStepValue = a.getInt(R.styleable.SeekBarDialogPreference_stepValue, 0);
@@ -60,15 +59,8 @@ public final class SeekBarDialogPreference extends DialogPreference
public void setInterface(final ValueProxy proxy) {
mValueProxy = proxy;
- setSummary(getValueText(clipValue(proxy.readValue(getKey()))));
- }
-
- private String getValueText(final int value) {
- if (mValueFormatResId == 0) {
- return Integer.toString(value);
- } else {
- return getContext().getString(mValueFormatResId, value);
- }
+ final int value = mValueProxy.readValue(getKey());
+ setSummary(mValueProxy.getValueText(value));
}
@Override
@@ -101,16 +93,11 @@ public final class SeekBarDialogPreference extends DialogPreference
return clipValue(getValueFromProgress(progress));
}
- private void setValue(final int value, final boolean fromUser) {
- mValueView.setText(getValueText(value));
- if (!fromUser) {
- mSeekBar.setProgress(getProgressFromValue(value));
- }
- }
-
@Override
protected void onBindDialogView(final View view) {
- setValue(clipValue(mValueProxy.readValue(getKey())), false /* fromUser */);
+ final int value = mValueProxy.readValue(getKey());
+ mValueView.setText(mValueProxy.getValueText(value));
+ mSeekBar.setProgress(getProgressFromValue(clipValue(value)));
}
@Override
@@ -125,13 +112,15 @@ public final class SeekBarDialogPreference extends DialogPreference
super.onClick(dialog, which);
final String key = getKey();
if (which == DialogInterface.BUTTON_NEUTRAL) {
- setValue(clipValue(mValueProxy.readDefaultValue(key)), false /* fromUser */);
+ final int value = mValueProxy.readDefaultValue(key);
+ setSummary(mValueProxy.getValueText(value));
mValueProxy.writeDefaultValue(key);
return;
}
if (which == DialogInterface.BUTTON_POSITIVE) {
- setSummary(mValueView.getText());
- mValueProxy.writeValue(getClippedValueFromProgress(mSeekBar.getProgress()), key);
+ final int value = getClippedValueFromProgress(mSeekBar.getProgress());
+ setSummary(mValueProxy.getValueText(value));
+ mValueProxy.writeValue(value, key);
return;
}
}
@@ -139,7 +128,11 @@ public final class SeekBarDialogPreference extends DialogPreference
@Override
public void onProgressChanged(final SeekBar seekBar, final int progress,
final boolean fromUser) {
- setValue(getClippedValueFromProgress(progress), fromUser);
+ final int value = getClippedValueFromProgress(progress);
+ mValueView.setText(mValueProxy.getValueText(value));
+ if (!fromUser) {
+ mSeekBar.setProgress(getProgressFromValue(value));
+ }
}
@Override
diff --git a/java/src/com/android/inputmethod/latin/SettingsFragment.java b/java/src/com/android/inputmethod/latin/SettingsFragment.java
index 1fad765d7..8017ce161 100644
--- a/java/src/com/android/inputmethod/latin/SettingsFragment.java
+++ b/java/src/com/android/inputmethod/latin/SettingsFragment.java
@@ -364,6 +364,14 @@ public final class SettingsFragment extends InputMethodSettingsFragment
public void feedbackValue(final int value) {
AudioAndHapticFeedbackManager.getInstance().vibrate(value);
}
+
+ @Override
+ public String getValueText(final int value) {
+ if (value < 0) {
+ return res.getString(R.string.settings_system_default);
+ }
+ return res.getString(R.string.abbreviation_unit_milliseconds, value);
+ }
});
}
@@ -396,6 +404,11 @@ public final class SettingsFragment extends InputMethodSettingsFragment
}
@Override
+ public String getValueText(final int value) {
+ return res.getString(R.string.abbreviation_unit_milliseconds, value);
+ }
+
+ @Override
public void feedbackValue(final int value) {}
});
}
@@ -439,6 +452,14 @@ public final class SettingsFragment extends InputMethodSettingsFragment
}
@Override
+ public String getValueText(final int value) {
+ if (value < 0) {
+ return res.getString(R.string.settings_system_default);
+ }
+ return Integer.toString(value);
+ }
+
+ @Override
public void feedbackValue(final int value) {
am.playSoundEffect(
AudioManager.FX_KEYPRESS_STANDARD, getValueFromPercentage(value));