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

Commit 70832a3d authored by Jim Miller's avatar Jim Miller
Browse files

Some tuning for MultiWaveView animations and assets:

- allow individual chevrons to be specified for (top, bottom, left, right).
- move ring to pressed position (currently w/o animation)
- add top/bottom chevron handling and refactor code accordingly.
- constrain drag handle to the ring

Change-Id: I859b2d03d8f0397c68b87a8ee15df20d55c9552c
parent fcc79771
Loading
Loading
Loading
Loading
+10 −8
Original line number Diff line number Diff line
@@ -259,6 +259,7 @@ package android {
    field public static final int borderlessButtonStyle = 16843563; // 0x101032b
    field public static final int bottom = 16843184; // 0x10101b0
    field public static final int bottomBright = 16842957; // 0x10100cd
    field public static final int bottomChevronDrawable = 16843661; // 0x101038d
    field public static final int bottomDark = 16842953; // 0x10100c9
    field public static final int bottomLeftRadius = 16843179; // 0x10101ab
    field public static final int bottomMedium = 16842958; // 0x10100ce
@@ -425,7 +426,7 @@ package android {
    field public static final int fastScrollTextColor = 16843609; // 0x1010359
    field public static final int fastScrollThumbDrawable = 16843574; // 0x1010336
    field public static final int fastScrollTrackDrawable = 16843577; // 0x1010339
    field public static final int feedbackCount = 16843665; // 0x1010391
    field public static final int feedbackCount = 16843667; // 0x1010393
    field public static final int fillAfter = 16843197; // 0x10101bd
    field public static final int fillBefore = 16843196; // 0x10101bc
    field public static final int fillEnabled = 16843343; // 0x101024f
@@ -488,12 +489,12 @@ package android {
    field public static final int headerDividersEnabled = 16843310; // 0x101022e
    field public static final int height = 16843093; // 0x1010155
    field public static final int hint = 16843088; // 0x1010150
    field public static final int hitRadius = 16843662; // 0x101038e
    field public static final int hitRadius = 16843664; // 0x1010390
    field public static final int homeAsUpIndicator = 16843531; // 0x101030b
    field public static final int homeLayout = 16843549; // 0x101031d
    field public static final int horizontalDivider = 16843053; // 0x101012d
    field public static final int horizontalGap = 16843327; // 0x101023f
    field public static final int horizontalOffset = 16843667; // 0x1010393
    field public static final int horizontalOffset = 16843669; // 0x1010395
    field public static final int horizontalScrollViewStyle = 16843603; // 0x1010353
    field public static final int horizontalSpacing = 16843028; // 0x1010114
    field public static final int host = 16842792; // 0x1010028
@@ -686,7 +687,7 @@ package android {
    field public static final int orderingFromXml = 16843239; // 0x10101e7
    field public static final int orientation = 16842948; // 0x10100c4
    field public static final int outAnimation = 16843128; // 0x1010178
    field public static final int outerRadius = 16843661; // 0x101038d
    field public static final int outerRadius = 16843663; // 0x101038f
    field public static final int overScrollFooter = 16843459; // 0x10102c3
    field public static final int overScrollHeader = 16843458; // 0x10102c2
    field public static final int overScrollMode = 16843457; // 0x10102c1
@@ -851,7 +852,7 @@ package android {
    field public static final int smallIcon = 16843422; // 0x101029e
    field public static final int smallScreens = 16843396; // 0x1010284
    field public static final int smoothScrollbar = 16843313; // 0x1010231
    field public static final int snapMargin = 16843664; // 0x1010390
    field public static final int snapMargin = 16843666; // 0x1010392
    field public static final int soundEffectsEnabled = 16843285; // 0x1010215
    field public static final int spacing = 16843027; // 0x1010113
    field public static final int spinnerDropDownItemStyle = 16842887; // 0x1010087
@@ -1006,6 +1007,7 @@ package android {
    field public static final int toYScale = 16843205; // 0x10101c5
    field public static final int top = 16843182; // 0x10101ae
    field public static final int topBright = 16842955; // 0x10100cb
    field public static final int topChevronDrawable = 16843660; // 0x101038c
    field public static final int topDark = 16842951; // 0x10100c7
    field public static final int topLeftRadius = 16843177; // 0x10101a9
    field public static final int topOffset = 16843352; // 0x1010258
@@ -1035,10 +1037,10 @@ package android {
    field public static final int verticalCorrection = 16843322; // 0x101023a
    field public static final int verticalDivider = 16843054; // 0x101012e
    field public static final int verticalGap = 16843328; // 0x1010240
    field public static final int verticalOffset = 16843666; // 0x1010392
    field public static final int verticalOffset = 16843668; // 0x1010394
    field public static final int verticalScrollbarPosition = 16843572; // 0x1010334
    field public static final int verticalSpacing = 16843029; // 0x1010115
    field public static final int vibrationDuration = 16843663; // 0x101038f
    field public static final int vibrationDuration = 16843665; // 0x1010391
    field public static final int visibility = 16842972; // 0x10100dc
    field public static final int visible = 16843156; // 0x1010194
    field public static final int vmSafeMode = 16843448; // 0x10102b8
@@ -1055,7 +1057,7 @@ package android {
    field public static final int wallpaperIntraOpenExitAnimation = 16843416; // 0x1010298
    field public static final int wallpaperOpenEnterAnimation = 16843411; // 0x1010293
    field public static final int wallpaperOpenExitAnimation = 16843412; // 0x1010294
    field public static final int waveDrawable = 16843660; // 0x101038c
    field public static final int waveDrawable = 16843662; // 0x101038e
    field public static final int webTextViewStyle = 16843449; // 0x10102b9
    field public static final int webViewStyle = 16842885; // 0x1010085
    field public static final int weekDayTextAppearance = 16843592; // 0x1010348
+66 −47
Original line number Diff line number Diff line
@@ -134,18 +134,26 @@ public class MultiWaveView extends View implements AnimatorUpdateListener {
        mTapRadius = mHandleDrawable.getWidth()/2;
        mOuterRing = new TargetDrawable(res, a.getDrawable(R.styleable.MultiWaveView_waveDrawable));

        // Read animation drawables
        // Read chevron animation drawables
        Drawable leftChevron = a.getDrawable(R.styleable.MultiWaveView_leftChevronDrawable);
        if (leftChevron != null) {
        for (int i = 0; i < mFeedbackCount; i++) {
                mChevronDrawables.add(new TargetDrawable(res, leftChevron));
            }
            mChevronDrawables.add(
                    leftChevron != null ? new TargetDrawable(res, leftChevron) : null);
        }
        Drawable rightChevron = a.getDrawable(R.styleable.MultiWaveView_rightChevronDrawable);
        if (rightChevron != null) {
        for (int i = 0; i < mFeedbackCount; i++) {
                mChevronDrawables.add(new TargetDrawable(res, rightChevron));
            mChevronDrawables.add(
                    rightChevron != null ? new TargetDrawable(res, rightChevron) : null);
        }
        Drawable topChevron = a.getDrawable(R.styleable.MultiWaveView_topChevronDrawable);
        for (int i = 0; i < mFeedbackCount; i++) {
            mChevronDrawables.add(
                    topChevron != null ? new TargetDrawable(res, topChevron) : null);
        }
        Drawable bottomChevron = a.getDrawable(R.styleable.MultiWaveView_bottomChevronDrawable);
        for (int i = 0; i < mFeedbackCount; i++) {
            mChevronDrawables.add(
                    bottomChevron != null ? new TargetDrawable(res, bottomChevron) : null);
        }

        // Read array of target drawables
@@ -190,7 +198,6 @@ public class MultiWaveView extends View implements AnimatorUpdateListener {
    private void switchToState(int state, float x, float y) {
        switch (state) {
            case STATE_IDLE:
                stopChevronAnimation();
                deactivateTargets();
                mHandleDrawable.setState(TargetDrawable.STATE_INACTIVE);
                break;
@@ -221,33 +228,32 @@ public class MultiWaveView extends View implements AnimatorUpdateListener {
     * followed by right chevrons.
     */
    private void startChevronAnimation() {
        final int icons = mChevronDrawables.size();
        for (Tweener tween : mChevronAnimations) {
            tween.animator.cancel();
        }
        for (int i = 0; i < icons; i++) {
            TargetDrawable icon = mChevronDrawables.get(i);
            icon.setY(mWaveCenterY);
            icon.setAlpha(1.0f);
        final float r = mHandleDrawable.getWidth() / 2;
        final float from[][] = {
                {mWaveCenterX - r, mWaveCenterY},  // left
                {mWaveCenterX + r, mWaveCenterY},  // right
                {mWaveCenterX, mWaveCenterY - r},  // top
                {mWaveCenterX, mWaveCenterY + r} }; // bottom
        final float to[][] = {
                {mWaveCenterX - mOuterRadius, mWaveCenterY},  // left
                {mWaveCenterX + mOuterRadius, mWaveCenterY},  // right
                {mWaveCenterX, mWaveCenterY - mOuterRadius},  // top
                {mWaveCenterX, mWaveCenterY + mOuterRadius} }; // bottom

        mChevronAnimations.clear();
            int delay = (int) (Math.abs(0.5f + i - icons / 2) * CHEVRON_INCREMENTAL_DELAY);
            if (i < icons/2) {
                // Left chevrons
                icon.setX(mWaveCenterX - mHandleDrawable.getWidth() / 2);
                mChevronAnimations.add(Tweener.to(icon, CHEVRON_ANIMATION_DURATION,
                        "ease", mChevronAnimationInterpolator,
                        "delay", delay,
                        "x", mWaveCenterX - mOuterRadius,
                        "alpha", 0.0f,
                        "onUpdate", this));
            } else {
                // Right chevrons
                icon.setX(mWaveCenterX + mHandleDrawable.getWidth() / 2);
        for (int direction = 0; direction < 4; direction++) {
            for (int count = 0; count < mFeedbackCount; count++) {
                int delay = count * CHEVRON_INCREMENTAL_DELAY;
                final TargetDrawable icon = mChevronDrawables.get(direction*mFeedbackCount + count);
                if (icon == null) {
                    continue;
                }
                mChevronAnimations.add(Tweener.to(icon, CHEVRON_ANIMATION_DURATION,
                        "ease", mChevronAnimationInterpolator,
                        "delay", delay,
                        "x", mWaveCenterX + mOuterRadius,
                        "alpha", 0.0f,
                        "x", new float[] { from[direction][0], to[direction][0] },
                        "y", new float[] { from[direction][1], to[direction][1] },
                        "alpha", new float[] {1.0f, 0.0f},
                        "onUpdate", this));
            }
        }
@@ -330,8 +336,6 @@ public class MultiWaveView extends View implements AnimatorUpdateListener {
        if (targetHit) {
            mTargetDrawables.get(activeTarget).setState(TargetDrawable.STATE_ACTIVE);
        }

        stopChevronAnimation();
    }

    private void hideTargets(boolean animate) {
@@ -392,11 +396,12 @@ public class MultiWaveView extends View implements AnimatorUpdateListener {
        Resources res = getContext().getResources();
        TypedArray array = res.obtainTypedArray(resourceId);
        int count = array.length();
        mTargetDrawables = new ArrayList<TargetDrawable>(count);
        ArrayList<TargetDrawable> targetDrawables = new ArrayList<TargetDrawable>(count);
        for (int i = 0; i < count; i++) {
            Drawable drawable = array.getDrawable(i);
            mTargetDrawables.add(new TargetDrawable(res, drawable));
            targetDrawables.add(new TargetDrawable(res, drawable));
        }
        mTargetDrawables = targetDrawables;
    }

    /**
@@ -472,12 +477,19 @@ public class MultiWaveView extends View implements AnimatorUpdateListener {
        return handled ? true : super.onTouchEvent(event);
    }

    private void moveHandleTo(float x, float y, boolean animate) {
        // TODO: animate the handle based on the current state/position
        mHandleDrawable.setX(x);
        mHandleDrawable.setY(y);
    }

    private void handleDown(float x, float y) {
        final float dx = x - mWaveCenterX;
        final float dy = y - mWaveCenterY;
        if (dist2(dx,dy) <= square(mTapRadius)) {
            if (DEBUG) Log.v(TAG, "** Handle HIT");
            switchToState(STATE_FIRST_TOUCH, x, y);
            moveHandleTo(x, y, false);
            mDragging = true;
        } else {
            mDragging = false;
@@ -528,11 +540,14 @@ public class MultiWaveView extends View implements AnimatorUpdateListener {
                    best = dist2;
                }
            }
            x = limitX;
            y = limitY;
        }
        if (activeTarget != -1) {
            switchToState(STATE_SNAP, x,y);
            mHandleDrawable.setX(singleTarget ? limitX : mTargetDrawables.get(activeTarget).getX());
            mHandleDrawable.setY(singleTarget ? limitY : mTargetDrawables.get(activeTarget).getY());
            float newX = singleTarget ? limitX : mTargetDrawables.get(activeTarget).getX();
            float newY = singleTarget ? limitY : mTargetDrawables.get(activeTarget).getY();
            moveHandleTo(newX, newY, false);
            TargetDrawable currentTarget = mTargetDrawables.get(activeTarget);
            if (currentTarget.hasState(TargetDrawable.STATE_FOCUSED)) {
                currentTarget.setState(TargetDrawable.STATE_FOCUSED);
@@ -540,8 +555,7 @@ public class MultiWaveView extends View implements AnimatorUpdateListener {
            }
        } else {
            switchToState(STATE_TRACKING, x, y);
            mHandleDrawable.setX(x);
            mHandleDrawable.setY(y);
            moveHandleTo(x, y, false);
            mHandleDrawable.setAlpha(1.0f);
        }
        // Draw handle outside parent's bounds
@@ -577,8 +591,7 @@ public class MultiWaveView extends View implements AnimatorUpdateListener {

        mWaveCenterX = mHorizontalOffset + Math.max(width, mOuterRing.getWidth() ) / 2;
        mWaveCenterY = mVerticalOffset + Math.max(height, mOuterRing.getHeight()) / 2;
        mHandleDrawable.setX(mWaveCenterX);
        mHandleDrawable.setY(mWaveCenterY);
        moveHandleTo(mWaveCenterX, mWaveCenterY, false);
        mOuterRing.setX(mWaveCenterX);
        mOuterRing.setY(Math.max(mWaveCenterY, mWaveCenterY));
        mOuterRing.setAlpha(0.0f);
@@ -609,19 +622,25 @@ public class MultiWaveView extends View implements AnimatorUpdateListener {

    private void hideChevrons() {
        for (TargetDrawable chevron : mChevronDrawables) {
            if (chevron != null) {
                chevron.setAlpha(0.0f);
            }
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        mOuterRing.draw(canvas);
        for (TargetDrawable target : mTargetDrawables) {
            if (target != null) {
                target.draw(canvas);
            }
        }
        for (TargetDrawable target : mChevronDrawables) {
            if (target != null) {
                target.draw(canvas);
            }
        }
        mHandleDrawable.draw(canvas);
    }

+4 −3
Original line number Diff line number Diff line
@@ -63,14 +63,15 @@ class Tweener {
                delay = ((Number) value).longValue();
            } else if ("syncWith".equals(key)) {
                // TODO
            } else if (value instanceof Number[]) {
                // TODO: support Tween.from()
            } else if (value instanceof float[]) {
                props.add(PropertyValuesHolder.ofFloat(key,
                        ((float[])value)[0], ((float[])value)[1]));
            } else if (value instanceof Number) {
                float floatValue = ((Number)value).floatValue();
                props.add(PropertyValuesHolder.ofFloat(key, floatValue));
            } else {
                throw new IllegalArgumentException(
                        "Bad argument for key \"" + key + "with value" + value);
                        "Bad argument for key \"" + key + "\" with value " + value.getClass());
            }
        }

+688 B
Loading image diff...
+698 B
Loading image diff...
Loading