Merge "Move gesture preview trail parameters to resource"
commit
5b8b76baa3
|
@ -108,6 +108,14 @@
|
||||||
<attr name="backgroundDimAlpha" format="integer" />
|
<attr name="backgroundDimAlpha" format="integer" />
|
||||||
<!-- More keys keyboard will shown at touched point. -->
|
<!-- More keys keyboard will shown at touched point. -->
|
||||||
<attr name="showMoreKeysKeyboardAtTouchedPoint" format="boolean" />
|
<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. -->
|
<!-- Delay after gesture trail starts fading out in millisecond. -->
|
||||||
<attr name="gesturePreviewTrailFadeoutStartDelay" format="integer" />
|
<attr name="gesturePreviewTrailFadeoutStartDelay" format="integer" />
|
||||||
<!-- Duration while gesture preview trail is fading out in millisecond. -->
|
<!-- Duration while gesture preview trail is fading out in millisecond. -->
|
||||||
|
|
|
@ -101,6 +101,14 @@
|
||||||
<fraction name="center_suggestion_percentile">36%</fraction>
|
<fraction name="center_suggestion_percentile">36%</fraction>
|
||||||
|
|
||||||
<!-- Gesture preview trail parameters -->
|
<!-- 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_start_width">10.0dp</dimen>
|
||||||
<dimen name="gesture_preview_trail_end_width">2.5dp</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.
|
<!-- 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="gestureFloatingPreviewHorizontalPadding">@dimen/gesture_floating_preview_horizontal_padding</item>
|
||||||
<item name="gestureFloatingPreviewVerticalPadding">@dimen/gesture_floating_preview_vertical_padding</item>
|
<item name="gestureFloatingPreviewVerticalPadding">@dimen/gesture_floating_preview_vertical_padding</item>
|
||||||
<item name="gestureFloatingPreviewRoundRadius">@dimen/gesture_floating_preview_round_radius</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="gesturePreviewTrailFadeoutStartDelay">@integer/config_gesture_preview_trail_fadeout_start_delay</item>
|
||||||
<item name="gesturePreviewTrailFadeoutDuration">@integer/config_gesture_preview_trail_fadeout_duration</item>
|
<item name="gesturePreviewTrailFadeoutDuration">@integer/config_gesture_preview_trail_fadeout_duration</item>
|
||||||
<item name="gesturePreviewTrailUpdateInterval">@integer/config_gesture_preview_trail_update_interval</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;
|
||||||
import com.android.inputmethod.keyboard.internal.GestureStroke.GestureStrokeParams;
|
import com.android.inputmethod.keyboard.internal.GestureStroke.GestureStrokeParams;
|
||||||
import com.android.inputmethod.keyboard.internal.GestureStrokeWithPreviewPoints;
|
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.keyboard.internal.PointerTrackerQueue;
|
||||||
import com.android.inputmethod.latin.CollectionUtils;
|
import com.android.inputmethod.latin.CollectionUtils;
|
||||||
import com.android.inputmethod.latin.Constants;
|
import com.android.inputmethod.latin.Constants;
|
||||||
|
@ -161,6 +162,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
|
||||||
// Parameters for pointer handling.
|
// Parameters for pointer handling.
|
||||||
private static PointerTrackerParams sParams;
|
private static PointerTrackerParams sParams;
|
||||||
private static GestureStrokeParams sGestureStrokeParams;
|
private static GestureStrokeParams sGestureStrokeParams;
|
||||||
|
private static GestureStrokePreviewParams sGesturePreviewParams;
|
||||||
private static boolean sNeedsPhantomSuddenMoveEventHack;
|
private static boolean sNeedsPhantomSuddenMoveEventHack;
|
||||||
// Move this threshold to resource.
|
// Move this threshold to resource.
|
||||||
// TODO: Device specific parameter would be better for device specific hack?
|
// TODO: Device specific parameter would be better for device specific hack?
|
||||||
|
@ -339,12 +341,14 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
|
||||||
sNeedsPhantomSuddenMoveEventHack = needsPhantomSuddenMoveEventHack;
|
sNeedsPhantomSuddenMoveEventHack = needsPhantomSuddenMoveEventHack;
|
||||||
sParams = PointerTrackerParams.DEFAULT;
|
sParams = PointerTrackerParams.DEFAULT;
|
||||||
sGestureStrokeParams = GestureStrokeParams.DEFAULT;
|
sGestureStrokeParams = GestureStrokeParams.DEFAULT;
|
||||||
|
sGesturePreviewParams = GestureStrokePreviewParams.DEFAULT;
|
||||||
sTimeRecorder = new TimeRecorder(sParams, sGestureStrokeParams);
|
sTimeRecorder = new TimeRecorder(sParams, sGestureStrokeParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setParameters(final TypedArray mainKeyboardViewAttr) {
|
public static void setParameters(final TypedArray mainKeyboardViewAttr) {
|
||||||
sParams = new PointerTrackerParams(mainKeyboardViewAttr);
|
sParams = new PointerTrackerParams(mainKeyboardViewAttr);
|
||||||
sGestureStrokeParams = new GestureStrokeParams(mainKeyboardViewAttr);
|
sGestureStrokeParams = new GestureStrokeParams(mainKeyboardViewAttr);
|
||||||
|
sGesturePreviewParams = new GestureStrokePreviewParams(mainKeyboardViewAttr);
|
||||||
sTimeRecorder = new TimeRecorder(sParams, sGestureStrokeParams);
|
sTimeRecorder = new TimeRecorder(sParams, sGestureStrokeParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -428,7 +432,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
|
||||||
}
|
}
|
||||||
mPointerId = id;
|
mPointerId = id;
|
||||||
mGestureStrokeWithPreviewPoints = new GestureStrokeWithPreviewPoints(
|
mGestureStrokeWithPreviewPoints = new GestureStrokeWithPreviewPoints(
|
||||||
id, sGestureStrokeParams);
|
id, sGestureStrokeParams, sGesturePreviewParams);
|
||||||
setKeyDetectorInner(handler.getKeyDetector());
|
setKeyDetectorInner(handler.getKeyDetector());
|
||||||
mListener = handler.getKeyboardActionListener();
|
mListener = handler.getKeyboardActionListener();
|
||||||
mDrawingProxy = handler.getDrawingProxy();
|
mDrawingProxy = handler.getDrawingProxy();
|
||||||
|
|
|
@ -16,6 +16,9 @@
|
||||||
|
|
||||||
package com.android.inputmethod.keyboard.internal;
|
package com.android.inputmethod.keyboard.internal;
|
||||||
|
|
||||||
|
import android.content.res.TypedArray;
|
||||||
|
|
||||||
|
import com.android.inputmethod.latin.R;
|
||||||
import com.android.inputmethod.latin.ResizableIntArray;
|
import com.android.inputmethod.latin.ResizableIntArray;
|
||||||
|
|
||||||
public final class GestureStrokeWithPreviewPoints extends GestureStroke {
|
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 mPreviewXCoordinates = new ResizableIntArray(PREVIEW_CAPACITY);
|
||||||
private final ResizableIntArray mPreviewYCoordinates = new ResizableIntArray(PREVIEW_CAPACITY);
|
private final ResizableIntArray mPreviewYCoordinates = new ResizableIntArray(PREVIEW_CAPACITY);
|
||||||
|
|
||||||
|
private final GestureStrokePreviewParams mPreviewParams;
|
||||||
|
|
||||||
private int mStrokeId;
|
private int mStrokeId;
|
||||||
private int mLastPreviewSize;
|
private int mLastPreviewSize;
|
||||||
private final HermiteInterpolator mInterpolator = new HermiteInterpolator();
|
private final HermiteInterpolator mInterpolator = new HermiteInterpolator();
|
||||||
|
@ -32,23 +37,53 @@ public final class GestureStrokeWithPreviewPoints extends GestureStroke {
|
||||||
|
|
||||||
private int mLastX;
|
private int mLastX;
|
||||||
private int mLastY;
|
private int mLastY;
|
||||||
private double mMinPreviewSamplingDistance;
|
|
||||||
private double mDistanceFromLastSample;
|
private double mDistanceFromLastSample;
|
||||||
private double mInterpolationDistanceThreshold;
|
|
||||||
|
|
||||||
// TODO: Move these constants to resource.
|
public static final class GestureStrokePreviewParams {
|
||||||
// TODO: Use "dp" instead of ratio to the keyWidth because table has rather large keys.
|
public final double mMinSamplingDistance; // in pixel
|
||||||
// The minimum trail distance between sample points for preview in keyWidth unit when using
|
public final double mMaxInterpolationAngularThreshold; // in radian
|
||||||
// interpolation.
|
public final double mMaxInterpolationDistanceThreshold; // in pixel
|
||||||
private static final float MIN_PREVIEW_SAMPLING_RATIO_TO_KEY_WIDTH = 0.2f;
|
public final int mMaxInterpolationSegments;
|
||||||
// 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 GestureStrokeWithPreviewPoints(final int pointerId, final GestureStrokeParams params) {
|
public static final GestureStrokePreviewParams DEFAULT = new GestureStrokePreviewParams();
|
||||||
super(pointerId, params);
|
|
||||||
|
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
|
@Override
|
||||||
|
@ -66,19 +101,12 @@ public final class GestureStrokeWithPreviewPoints extends GestureStroke {
|
||||||
return mStrokeId;
|
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) {
|
private boolean needsSampling(final int x, final int y) {
|
||||||
mDistanceFromLastSample += Math.hypot(x - mLastX, y - mLastY);
|
mDistanceFromLastSample += Math.hypot(x - mLastX, y - mLastY);
|
||||||
mLastX = x;
|
mLastX = x;
|
||||||
mLastY = y;
|
mLastY = y;
|
||||||
final boolean isDownEvent = (mPreviewEventTimes.getLength() == 0);
|
final boolean isDownEvent = (mPreviewEventTimes.getLength() == 0);
|
||||||
if (mDistanceFromLastSample >= mMinPreviewSamplingDistance || isDownEvent) {
|
if (mDistanceFromLastSample >= mPreviewParams.mMinSamplingDistance || isDownEvent) {
|
||||||
mDistanceFromLastSample = 0.0d;
|
mDistanceFromLastSample = 0.0d;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -144,19 +172,19 @@ public final class GestureStrokeWithPreviewPoints extends GestureStroke {
|
||||||
final double m1 = Math.atan2(mInterpolator.mSlope1Y, mInterpolator.mSlope1X);
|
final double m1 = Math.atan2(mInterpolator.mSlope1Y, mInterpolator.mSlope1X);
|
||||||
final double m2 = Math.atan2(mInterpolator.mSlope2Y, mInterpolator.mSlope2X);
|
final double m2 = Math.atan2(mInterpolator.mSlope2Y, mInterpolator.mSlope2X);
|
||||||
final double deltaAngle = Math.abs(angularDiff(m2, m1));
|
final double deltaAngle = Math.abs(angularDiff(m2, m1));
|
||||||
final int partitionsByAngle = (int)Math.ceil(
|
final int segmentsByAngle = (int)Math.ceil(
|
||||||
deltaAngle / INTERPOLATION_ANGULAR_THRESHOLD);
|
deltaAngle / mPreviewParams.mMaxInterpolationAngularThreshold);
|
||||||
final double deltaDistance = Math.hypot(mInterpolator.mP1X - mInterpolator.mP2X,
|
final double deltaDistance = Math.hypot(mInterpolator.mP1X - mInterpolator.mP2X,
|
||||||
mInterpolator.mP1Y - mInterpolator.mP2Y);
|
mInterpolator.mP1Y - mInterpolator.mP2Y);
|
||||||
final int partitionsByDistance = (int)Math.ceil(deltaDistance
|
final int segmentsByDistance = (int)Math.ceil(deltaDistance
|
||||||
/ mInterpolationDistanceThreshold);
|
/ mPreviewParams.mMaxInterpolationDistanceThreshold);
|
||||||
final int partitions = Math.min(MAX_INTERPOLATION_PARTITIONS,
|
final int segments = Math.min(mPreviewParams.mMaxInterpolationSegments,
|
||||||
Math.max(partitionsByAngle, partitionsByDistance));
|
Math.max(segmentsByAngle, segmentsByDistance));
|
||||||
final int t1 = eventTimes.get(d1);
|
final int t1 = eventTimes.get(d1);
|
||||||
final int dt = pt[p2] - pt[p1];
|
final int dt = pt[p2] - pt[p1];
|
||||||
d1++;
|
d1++;
|
||||||
for (int i = 1; i < partitions; i++) {
|
for (int i = 1; i < segments; i++) {
|
||||||
final float t = i / (float)partitions;
|
final float t = i / (float)segments;
|
||||||
mInterpolator.interpolate(t);
|
mInterpolator.interpolate(t);
|
||||||
eventTimes.add(d1, (int)(dt * t) + t1);
|
eventTimes.add(d1, (int)(dt * t) + t1);
|
||||||
xCoords.add(d1, (int)mInterpolator.mInterpolatedX);
|
xCoords.add(d1, (int)mInterpolator.mInterpolatedX);
|
||||||
|
|
Loading…
Reference in New Issue