diff options
Diffstat (limited to 'java')
-rw-r--r-- | java/res/values/attrs.xml | 1 | ||||
-rw-r--r-- | java/res/values/keypress-vibration-durations.xml | 4 | ||||
-rw-r--r-- | java/res/values/keypress-volumes.xml | 4 | ||||
-rw-r--r-- | java/res/values/strings.xml | 2 | ||||
-rw-r--r-- | java/res/xml/prefs.xml | 2 | ||||
-rw-r--r-- | java/res/xml/rowkeys_hebrew1.xml | 58 | ||||
-rw-r--r-- | java/res/xml/rows_hebrew.xml | 13 | ||||
-rw-r--r-- | java/src/com/android/inputmethod/keyboard/ProximityInfo.java | 127 | ||||
-rw-r--r-- | java/src/com/android/inputmethod/latin/SeekBarDialogPreference.java | 39 | ||||
-rw-r--r-- | java/src/com/android/inputmethod/latin/SettingsFragment.java | 21 |
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=""" /> + <Key + latin:keyLabel="-" + latin:keyHintLabel="2" + latin:additionalMoreKeys="2" + latin:moreKeys="_" /> + </default> + </switch> <!-- U+05E7: "ק" HEBREW LETTER QOF --> <Key - latin:keyLabel="ק" /> + latin:keyLabel="ק" + latin:keyHintLabel="3" + latin:additionalMoreKeys="3" /> <!-- U+05E8: "ר" HEBREW LETTER RESH --> <Key - latin:keyLabel="ר" /> + latin:keyLabel="ר" + latin:keyHintLabel="4" + latin:additionalMoreKeys="4" /> <!-- U+05D0: "א" HEBREW LETTER ALEF --> <Key - latin:keyLabel="א" /> + latin:keyLabel="א" + latin:keyHintLabel="5" + latin:additionalMoreKeys="5" /> <!-- U+05D8: "ט" HEBREW LETTER TET --> <Key - latin:keyLabel="ט" /> + latin:keyLabel="ט" + latin:keyHintLabel="6" + latin:additionalMoreKeys="6" /> <!-- U+05D5: "ו" HEBREW LETTER VAV --> <Key - latin:keyLabel="ו" /> + latin:keyLabel="ו" + latin:keyHintLabel="7" + latin:additionalMoreKeys="7" /> <!-- U+05DF: "ן" HEBREW LETTER FINAL NUN --> <Key - latin:keyLabel="ן" /> + latin:keyLabel="ן" + latin:keyHintLabel="8" + latin:additionalMoreKeys="8" /> <!-- U+05DD: "ם" HEBREW LETTER FINAL MEM --> <Key - latin:keyLabel="ם" /> + latin:keyLabel="ם" + latin:keyHintLabel="9" + latin:additionalMoreKeys="9" /> <!-- U+05E4: "פ" HEBREW LETTER PE --> <Key - latin:keyLabel="פ" /> + latin:keyLabel="פ" + 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)); |