Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5b8b76ba authored by Tadashi G. Takaoka's avatar Tadashi G. Takaoka Committed by Android (Google) Code Review
Browse files

Merge "Move gesture preview trail parameters to resource"

parents faa94a2d 05124d01
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -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. -->
+8 −0
Original line number Diff line number Diff line
@@ -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.
+4 −0
Original line number Diff line number Diff line
@@ -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>
+5 −1
Original line number Diff line number Diff line
@@ -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();
+60 −32
Original line number Diff line number Diff line
@@ -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 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 params) {
        super(pointerId, params);
    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);