Move gesture preview trail parameters to resource

Bug: 7167303
Change-Id: I22b56588dc5a1c9d5eaec3a39b5f32c9e5a8a5b4
main
Tadashi G. Takaoka 2013-05-07 17:40:47 +09:00
parent 1eb1af75a7
commit 05124d0193
5 changed files with 83 additions and 31 deletions

View File

@ -108,6 +108,14 @@
<attr name="backgroundDimAlpha" format="integer" />
<!-- More keys keyboard will shown at touched point. -->
<attr name="showMoreKeysKeyboardAtTouchedPoint" format="boolean" />
<!-- Minimum distance between gesture preview trail sampling points. -->
<attr name="gesturePreviewTrailMinSamplingDistance" format="dimension" />
<!-- Maximum angular threshold between gesture preview trail interpolation segments in degree. -->
<attr name="gesturePreviewTrailMaxInterpolationAngularThreshold" format="integer" />
<!-- Maximum distance threshold between gesture preview trail interpolation segments. -->
<attr name="gesturePreviewTrailMaxInterpolationDistanceThreshold" format="dimension" />
<!-- Maximum number of gesture preview trail interpolation segments. -->
<attr name="gesturePreviewTrailMaxInterpolationSegments" format="integer" />
<!-- Delay after gesture trail starts fading out in millisecond. -->
<attr name="gesturePreviewTrailFadeoutStartDelay" format="integer" />
<!-- Duration while gesture preview trail is fading out in millisecond. -->

View File

@ -101,6 +101,14 @@
<fraction name="center_suggestion_percentile">36%</fraction>
<!-- Gesture preview trail parameters -->
<!-- Minimum distance between gesture preview trail sampling points. -->
<dimen name="gesture_preview_trail_min_sampling_distance">6.4dp</dimen>
<!-- Maximum angular threshold between gesture preview trails interpolation segments in degree. -->
<integer name="gesture_preview_trail_max_interpolation_angular_threshold">15</integer>
<!-- Maximum distance threshold between gesture preview trails interpolation segments. -->
<dimen name="gesture_preview_trail_max_interpolation_distance_threshold">16.0dp</dimen>
<!-- Maximum number of gesture preview trail interpolation segments. -->
<integer name="gesture_preview_trail_max_interpolation_segments">6</integer>
<dimen name="gesture_preview_trail_start_width">10.0dp</dimen>
<dimen name="gesture_preview_trail_end_width">2.5dp</dimen>
<!-- Percentages of gesture preview taril body and shadow, in proportion to the trail width.

View File

@ -64,6 +64,10 @@
<item name="gestureFloatingPreviewHorizontalPadding">@dimen/gesture_floating_preview_horizontal_padding</item>
<item name="gestureFloatingPreviewVerticalPadding">@dimen/gesture_floating_preview_vertical_padding</item>
<item name="gestureFloatingPreviewRoundRadius">@dimen/gesture_floating_preview_round_radius</item>
<item name="gesturePreviewTrailMinSamplingDistance">@dimen/gesture_preview_trail_min_sampling_distance</item>
<item name="gesturePreviewTrailMaxInterpolationAngularThreshold">@integer/gesture_preview_trail_max_interpolation_angular_threshold</item>
<item name="gesturePreviewTrailMaxInterpolationDistanceThreshold">@dimen/gesture_preview_trail_max_interpolation_distance_threshold</item>
<item name="gesturePreviewTrailMaxInterpolationSegments">@integer/gesture_preview_trail_max_interpolation_segments</item>
<item name="gesturePreviewTrailFadeoutStartDelay">@integer/config_gesture_preview_trail_fadeout_start_delay</item>
<item name="gesturePreviewTrailFadeoutDuration">@integer/config_gesture_preview_trail_fadeout_duration</item>
<item name="gesturePreviewTrailUpdateInterval">@integer/config_gesture_preview_trail_update_interval</item>

View File

@ -25,6 +25,7 @@ import com.android.inputmethod.accessibility.AccessibilityUtils;
import com.android.inputmethod.keyboard.internal.GestureStroke;
import com.android.inputmethod.keyboard.internal.GestureStroke.GestureStrokeParams;
import com.android.inputmethod.keyboard.internal.GestureStrokeWithPreviewPoints;
import com.android.inputmethod.keyboard.internal.GestureStrokeWithPreviewPoints.GestureStrokePreviewParams;
import com.android.inputmethod.keyboard.internal.PointerTrackerQueue;
import com.android.inputmethod.latin.CollectionUtils;
import com.android.inputmethod.latin.Constants;
@ -161,6 +162,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
// Parameters for pointer handling.
private static PointerTrackerParams sParams;
private static GestureStrokeParams sGestureStrokeParams;
private static GestureStrokePreviewParams sGesturePreviewParams;
private static boolean sNeedsPhantomSuddenMoveEventHack;
// Move this threshold to resource.
// TODO: Device specific parameter would be better for device specific hack?
@ -339,12 +341,14 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
sNeedsPhantomSuddenMoveEventHack = needsPhantomSuddenMoveEventHack;
sParams = PointerTrackerParams.DEFAULT;
sGestureStrokeParams = GestureStrokeParams.DEFAULT;
sGesturePreviewParams = GestureStrokePreviewParams.DEFAULT;
sTimeRecorder = new TimeRecorder(sParams, sGestureStrokeParams);
}
public static void setParameters(final TypedArray mainKeyboardViewAttr) {
sParams = new PointerTrackerParams(mainKeyboardViewAttr);
sGestureStrokeParams = new GestureStrokeParams(mainKeyboardViewAttr);
sGesturePreviewParams = new GestureStrokePreviewParams(mainKeyboardViewAttr);
sTimeRecorder = new TimeRecorder(sParams, sGestureStrokeParams);
}
@ -428,7 +432,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
}
mPointerId = id;
mGestureStrokeWithPreviewPoints = new GestureStrokeWithPreviewPoints(
id, sGestureStrokeParams);
id, sGestureStrokeParams, sGesturePreviewParams);
setKeyDetectorInner(handler.getKeyDetector());
mListener = handler.getKeyboardActionListener();
mDrawingProxy = handler.getDrawingProxy();

View File

@ -16,6 +16,9 @@
package com.android.inputmethod.keyboard.internal;
import android.content.res.TypedArray;
import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.ResizableIntArray;
public final class GestureStrokeWithPreviewPoints extends GestureStroke {
@ -25,6 +28,8 @@ public final class GestureStrokeWithPreviewPoints extends GestureStroke {
private final ResizableIntArray mPreviewXCoordinates = new ResizableIntArray(PREVIEW_CAPACITY);
private final ResizableIntArray mPreviewYCoordinates = new ResizableIntArray(PREVIEW_CAPACITY);
private final GestureStrokePreviewParams mPreviewParams;
private int mStrokeId;
private int mLastPreviewSize;
private final HermiteInterpolator mInterpolator = new HermiteInterpolator();
@ -32,23 +37,53 @@ public final class GestureStrokeWithPreviewPoints extends GestureStroke {
private int mLastX;
private int mLastY;
private double mMinPreviewSamplingDistance;
private double mDistanceFromLastSample;
private double mInterpolationDistanceThreshold;
// TODO: Move these constants to resource.
// TODO: Use "dp" instead of ratio to the keyWidth because table has rather large keys.
// The minimum trail distance between sample points for preview in keyWidth unit when using
// interpolation.
private static final float MIN_PREVIEW_SAMPLING_RATIO_TO_KEY_WIDTH = 0.2f;
// The angular threshold to use interpolation in radian. PI/12 is 15 degree.
private static final double INTERPOLATION_ANGULAR_THRESHOLD = Math.PI / 12.0d;
// The distance threshold to use interpolation in keyWidth unit.
private static final float INTERPOLATION_DISTANCE_THRESHOLD_TO_KEY_WIDTH = 0.5f;
private static final int MAX_INTERPOLATION_PARTITIONS = 6;
public static final class GestureStrokePreviewParams {
public final double mMinSamplingDistance; // in pixel
public final double mMaxInterpolationAngularThreshold; // in radian
public final double mMaxInterpolationDistanceThreshold; // in pixel
public final int mMaxInterpolationSegments;
public GestureStrokeWithPreviewPoints(final int pointerId, final GestureStrokeParams params) {
super(pointerId, params);
public static final GestureStrokePreviewParams DEFAULT = new GestureStrokePreviewParams();
private static final int DEFAULT_MAX_INTERPOLATION_ANGULAR_THRESHOLD = 15; // in degree
private GestureStrokePreviewParams() {
mMinSamplingDistance = 0.0d;
mMaxInterpolationAngularThreshold =
degreeToRadian(DEFAULT_MAX_INTERPOLATION_ANGULAR_THRESHOLD);
mMaxInterpolationDistanceThreshold = mMinSamplingDistance;
mMaxInterpolationSegments = 4;
}
private static double degreeToRadian(final int degree) {
return (double)degree / 180.0d * Math.PI;
}
public GestureStrokePreviewParams(final TypedArray mainKeyboardViewAttr) {
mMinSamplingDistance = mainKeyboardViewAttr.getDimension(
R.styleable.MainKeyboardView_gesturePreviewTrailMinSamplingDistance,
(float)DEFAULT.mMinSamplingDistance);
final int interpolationAngularDegree = mainKeyboardViewAttr.getInteger(R.styleable
.MainKeyboardView_gesturePreviewTrailMaxInterpolationAngularThreshold, 0);
mMaxInterpolationAngularThreshold = (interpolationAngularDegree <= 0)
? DEFAULT.mMaxInterpolationAngularThreshold
: degreeToRadian(interpolationAngularDegree);
mMaxInterpolationDistanceThreshold = mainKeyboardViewAttr.getDimension(R.styleable
.MainKeyboardView_gesturePreviewTrailMaxInterpolationDistanceThreshold,
(float)DEFAULT.mMaxInterpolationDistanceThreshold);
mMaxInterpolationSegments = mainKeyboardViewAttr.getInteger(
R.styleable.MainKeyboardView_gesturePreviewTrailMaxInterpolationSegments,
DEFAULT.mMaxInterpolationSegments);
}
}
public GestureStrokeWithPreviewPoints(final int pointerId,
final GestureStrokeParams strokeParams,
final GestureStrokePreviewParams previewParams) {
super(pointerId, strokeParams);
mPreviewParams = previewParams;
}
@Override
@ -66,19 +101,12 @@ public final class GestureStrokeWithPreviewPoints extends GestureStroke {
return mStrokeId;
}
@Override
public void setKeyboardGeometry(final int keyWidth, final int keyboardHeight) {
super.setKeyboardGeometry(keyWidth, keyboardHeight);
mMinPreviewSamplingDistance = keyWidth * MIN_PREVIEW_SAMPLING_RATIO_TO_KEY_WIDTH;
mInterpolationDistanceThreshold = keyWidth * INTERPOLATION_DISTANCE_THRESHOLD_TO_KEY_WIDTH;
}
private boolean needsSampling(final int x, final int y) {
mDistanceFromLastSample += Math.hypot(x - mLastX, y - mLastY);
mLastX = x;
mLastY = y;
final boolean isDownEvent = (mPreviewEventTimes.getLength() == 0);
if (mDistanceFromLastSample >= mMinPreviewSamplingDistance || isDownEvent) {
if (mDistanceFromLastSample >= mPreviewParams.mMinSamplingDistance || isDownEvent) {
mDistanceFromLastSample = 0.0d;
return true;
}
@ -144,19 +172,19 @@ public final class GestureStrokeWithPreviewPoints extends GestureStroke {
final double m1 = Math.atan2(mInterpolator.mSlope1Y, mInterpolator.mSlope1X);
final double m2 = Math.atan2(mInterpolator.mSlope2Y, mInterpolator.mSlope2X);
final double deltaAngle = Math.abs(angularDiff(m2, m1));
final int partitionsByAngle = (int)Math.ceil(
deltaAngle / INTERPOLATION_ANGULAR_THRESHOLD);
final int segmentsByAngle = (int)Math.ceil(
deltaAngle / mPreviewParams.mMaxInterpolationAngularThreshold);
final double deltaDistance = Math.hypot(mInterpolator.mP1X - mInterpolator.mP2X,
mInterpolator.mP1Y - mInterpolator.mP2Y);
final int partitionsByDistance = (int)Math.ceil(deltaDistance
/ mInterpolationDistanceThreshold);
final int partitions = Math.min(MAX_INTERPOLATION_PARTITIONS,
Math.max(partitionsByAngle, partitionsByDistance));
final int segmentsByDistance = (int)Math.ceil(deltaDistance
/ mPreviewParams.mMaxInterpolationDistanceThreshold);
final int segments = Math.min(mPreviewParams.mMaxInterpolationSegments,
Math.max(segmentsByAngle, segmentsByDistance));
final int t1 = eventTimes.get(d1);
final int dt = pt[p2] - pt[p1];
d1++;
for (int i = 1; i < partitions; i++) {
final float t = i / (float)partitions;
for (int i = 1; i < segments; i++) {
final float t = i / (float)segments;
mInterpolator.interpolate(t);
eventTimes.add(d1, (int)(dt * t) + t1);
xCoords.add(d1, (int)mInterpolator.mInterpolatedX);