14e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi/*
24e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi * Copyright (C) 2014 The Android Open Source Project
34e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi *
44e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi * Licensed under the Apache License, Version 2.0 (the "License");
54e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi * you may not use this file except in compliance with the License.
64e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi * You may obtain a copy of the License at
74e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi *
84e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi *      http://www.apache.org/licenses/LICENSE-2.0
94e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi *
104e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi * Unless required by applicable law or agreed to in writing, software
114e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi * distributed under the License is distributed on an "AS IS" BASIS,
124e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi * See the License for the specific language governing permissions and
144e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi * limitations under the License
154e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi */
164e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi
174e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggipackage com.android.systemui;
184e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi
194e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggiimport android.animation.Animator;
204e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggiimport android.animation.AnimatorListenerAdapter;
214e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggiimport android.animation.ValueAnimator;
224e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggiimport android.graphics.ColorMatrix;
234e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggiimport android.graphics.ColorMatrixColorFilter;
244e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggiimport android.graphics.Paint;
254e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggiimport android.view.View;
264e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggiimport android.view.animation.AnimationUtils;
274e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggiimport android.view.animation.Interpolator;
284e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi
294e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi/**
304e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi * Helper to invert the colors of views and fade between the states.
314e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi */
324e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggipublic class ViewInvertHelper {
334e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi
344e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi    private final Paint mDarkPaint = new Paint();
354e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi    private final Interpolator mLinearOutSlowInInterpolator;
364e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi    private final View mTarget;
374e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi    private final ColorMatrix mMatrix = new ColorMatrix();
384e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi    private final ColorMatrix mGrayscaleMatrix = new ColorMatrix();
394e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi    private final long mFadeDuration;
404e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi
414e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi    public ViewInvertHelper(View target, long fadeDuration) {
424e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi        mTarget = target;
434e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi        mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator(mTarget.getContext(),
444e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi                android.R.interpolator.linear_out_slow_in);
454e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi        mFadeDuration = fadeDuration;
464e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi    }
474e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi
484e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi    public void fade(final boolean invert, long delay) {
494e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi        float startIntensity = invert ? 0f : 1f;
504e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi        float endIntensity = invert ? 1f : 0f;
514e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi        ValueAnimator animator = ValueAnimator.ofFloat(startIntensity, endIntensity);
524e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
534e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi            @Override
544e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi            public void onAnimationUpdate(ValueAnimator animation) {
554e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi                updateInvertPaint((Float) animation.getAnimatedValue());
564e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi                mTarget.setLayerType(View.LAYER_TYPE_HARDWARE, mDarkPaint);
574e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi            }
584e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi        });
594e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi        animator.addListener(new AnimatorListenerAdapter() {
604e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi            @Override
614e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi            public void onAnimationEnd(Animator animation) {
624e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi                if (!invert) {
634e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi                    mTarget.setLayerType(View.LAYER_TYPE_NONE, null);
644e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi                }
654e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi            }
664e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi        });
674e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi        animator.setDuration(mFadeDuration);
684e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi        animator.setInterpolator(mLinearOutSlowInInterpolator);
694e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi        animator.setStartDelay(delay);
704e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi        animator.start();
714e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi    }
724e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi
734e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi    public void update(boolean invert) {
744e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi        if (invert) {
754e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi            updateInvertPaint(1f);
764e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi            mTarget.setLayerType(View.LAYER_TYPE_HARDWARE, mDarkPaint);
774e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi        } else {
784e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi            mTarget.setLayerType(View.LAYER_TYPE_NONE, null);
794e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi        }
804e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi    }
814e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi
824e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi    public View getTarget() {
834e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi        return mTarget;
844e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi    }
854e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi
864e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi    private void updateInvertPaint(float intensity) {
874e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi        float components = 1 - 2 * intensity;
884e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi        final float[] invert = {
894e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi                components, 0f,         0f,         0f, 255f * intensity,
904e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi                0f,         components, 0f,         0f, 255f * intensity,
914e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi                0f,         0f,         components, 0f, 255f * intensity,
924e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi                0f,         0f,         0f,         1f, 0f
934e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi        };
944e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi        mMatrix.set(invert);
954e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi        mGrayscaleMatrix.setSaturation(1 - intensity);
964e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi        mMatrix.preConcat(mGrayscaleMatrix);
974e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi        mDarkPaint.setColorFilter(new ColorMatrixColorFilter(mMatrix));
984e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi    }
994e857f4ef0357e05806819d0488a73a12208fe8fJorim Jaggi}