Merge "Move gesture preview trail parameters to resource"
commit
5b8b76baa3
|
@ -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. -->
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue