1c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki/*
2c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * Copyright (C) 2016 The Android Open Source Project
3c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki *
4c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * Licensed under the Apache License, Version 2.0 (the "License");
5c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * you may not use this file except in compliance with the License.
6c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * You may obtain a copy of the License at
7c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki *
8c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki *      http://www.apache.org/licenses/LICENSE-2.0
9c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki *
10c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * Unless required by applicable law or agreed to in writing, software
11c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * distributed under the License is distributed on an "AS IS" BASIS,
12c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * See the License for the specific language governing permissions and
14c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki * limitations under the License.
15c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki */
16c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki
17c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Arakipackage android.support.transition;
18c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki
1950ce74b0963de66b294761c045428562d946b65aYuichi Arakiimport android.graphics.Matrix;
204e5a72756eb66c31baf1a3054c66520f1c3f5b8cYuichi Arakiimport android.support.annotation.NonNull;
218f886fe8c7e23fe6ccb8734167c960c2ed3429c3Alan Viveretteimport android.support.annotation.RequiresApi;
224e5a72756eb66c31baf1a3054c66520f1c3f5b8cYuichi Arakiimport android.view.View;
2350ce74b0963de66b294761c045428562d946b65aYuichi Arakiimport android.view.ViewParent;
248f886fe8c7e23fe6ccb8734167c960c2ed3429c3Alan Viverette
258f886fe8c7e23fe6ccb8734167c960c2ed3429c3Alan Viverette@RequiresApi(14)
264e5a72756eb66c31baf1a3054c66520f1c3f5b8cYuichi Arakiclass ViewUtilsApi14 implements ViewUtilsImpl {
27c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki
2850ce74b0963de66b294761c045428562d946b65aYuichi Araki    private float[] mMatrixValues;
2950ce74b0963de66b294761c045428562d946b65aYuichi Araki
304e5a72756eb66c31baf1a3054c66520f1c3f5b8cYuichi Araki    @Override
314e5a72756eb66c31baf1a3054c66520f1c3f5b8cYuichi Araki    public ViewOverlayImpl getOverlay(@NonNull View view) {
324e5a72756eb66c31baf1a3054c66520f1c3f5b8cYuichi Araki        return ViewOverlayApi14.createFrom(view);
33c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki    }
34c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki
35733b5aaadf1b1f5dc3038876dbfbabb79f649b03Yuichi Araki    @Override
364e5a72756eb66c31baf1a3054c66520f1c3f5b8cYuichi Araki    public WindowIdImpl getWindowId(@NonNull View view) {
374e5a72756eb66c31baf1a3054c66520f1c3f5b8cYuichi Araki        return new WindowIdApi14(view.getWindowToken());
38733b5aaadf1b1f5dc3038876dbfbabb79f649b03Yuichi Araki    }
39733b5aaadf1b1f5dc3038876dbfbabb79f649b03Yuichi Araki
40a6f2ebe33d03c42114b0082720cf9c42f7dad5a3Yuichi Araki    @Override
41a6f2ebe33d03c42114b0082720cf9c42f7dad5a3Yuichi Araki    public void setTransitionAlpha(@NonNull View view, float alpha) {
42db860514bf4c9aa50169d2c9964d83aec53dabecYuichi Araki        Float savedAlpha = (Float) view.getTag(R.id.save_non_transition_alpha);
43db860514bf4c9aa50169d2c9964d83aec53dabecYuichi Araki        if (savedAlpha != null) {
44db860514bf4c9aa50169d2c9964d83aec53dabecYuichi Araki            view.setAlpha(savedAlpha * alpha);
45db860514bf4c9aa50169d2c9964d83aec53dabecYuichi Araki        } else {
46db860514bf4c9aa50169d2c9964d83aec53dabecYuichi Araki            view.setAlpha(alpha);
47db860514bf4c9aa50169d2c9964d83aec53dabecYuichi Araki        }
48a6f2ebe33d03c42114b0082720cf9c42f7dad5a3Yuichi Araki    }
49a6f2ebe33d03c42114b0082720cf9c42f7dad5a3Yuichi Araki
50a6f2ebe33d03c42114b0082720cf9c42f7dad5a3Yuichi Araki    @Override
51a6f2ebe33d03c42114b0082720cf9c42f7dad5a3Yuichi Araki    public float getTransitionAlpha(@NonNull View view) {
52db860514bf4c9aa50169d2c9964d83aec53dabecYuichi Araki        Float savedAlpha = (Float) view.getTag(R.id.save_non_transition_alpha);
53db860514bf4c9aa50169d2c9964d83aec53dabecYuichi Araki        if (savedAlpha != null) {
54db860514bf4c9aa50169d2c9964d83aec53dabecYuichi Araki            return view.getAlpha() / savedAlpha;
55db860514bf4c9aa50169d2c9964d83aec53dabecYuichi Araki        } else {
56db860514bf4c9aa50169d2c9964d83aec53dabecYuichi Araki            return view.getAlpha();
57db860514bf4c9aa50169d2c9964d83aec53dabecYuichi Araki        }
58db860514bf4c9aa50169d2c9964d83aec53dabecYuichi Araki    }
59db860514bf4c9aa50169d2c9964d83aec53dabecYuichi Araki
60db860514bf4c9aa50169d2c9964d83aec53dabecYuichi Araki    @Override
61db860514bf4c9aa50169d2c9964d83aec53dabecYuichi Araki    public void saveNonTransitionAlpha(@NonNull View view) {
62db860514bf4c9aa50169d2c9964d83aec53dabecYuichi Araki        if (view.getTag(R.id.save_non_transition_alpha) == null) {
63db860514bf4c9aa50169d2c9964d83aec53dabecYuichi Araki            view.setTag(R.id.save_non_transition_alpha, view.getAlpha());
64db860514bf4c9aa50169d2c9964d83aec53dabecYuichi Araki        }
65db860514bf4c9aa50169d2c9964d83aec53dabecYuichi Araki    }
66db860514bf4c9aa50169d2c9964d83aec53dabecYuichi Araki
67db860514bf4c9aa50169d2c9964d83aec53dabecYuichi Araki    @Override
68db860514bf4c9aa50169d2c9964d83aec53dabecYuichi Araki    public void clearNonTransitionAlpha(@NonNull View view) {
69db860514bf4c9aa50169d2c9964d83aec53dabecYuichi Araki        // We don't clear the saved value when the view is hidden; that's the situation we are
70db860514bf4c9aa50169d2c9964d83aec53dabecYuichi Araki        // saving this value for.
71db860514bf4c9aa50169d2c9964d83aec53dabecYuichi Araki        if (view.getVisibility() == View.VISIBLE) {
72db860514bf4c9aa50169d2c9964d83aec53dabecYuichi Araki            view.setTag(R.id.save_non_transition_alpha, null);
73db860514bf4c9aa50169d2c9964d83aec53dabecYuichi Araki        }
74a6f2ebe33d03c42114b0082720cf9c42f7dad5a3Yuichi Araki    }
75a6f2ebe33d03c42114b0082720cf9c42f7dad5a3Yuichi Araki
7650ce74b0963de66b294761c045428562d946b65aYuichi Araki    @Override
7750ce74b0963de66b294761c045428562d946b65aYuichi Araki    public void transformMatrixToGlobal(@NonNull View view, @NonNull Matrix matrix) {
7850ce74b0963de66b294761c045428562d946b65aYuichi Araki        final ViewParent parent = view.getParent();
7950ce74b0963de66b294761c045428562d946b65aYuichi Araki        if (parent instanceof View) {
8050ce74b0963de66b294761c045428562d946b65aYuichi Araki            final View vp = (View) parent;
8150ce74b0963de66b294761c045428562d946b65aYuichi Araki            transformMatrixToGlobal(vp, matrix);
8250ce74b0963de66b294761c045428562d946b65aYuichi Araki            matrix.preTranslate(-vp.getScrollX(), -vp.getScrollY());
8350ce74b0963de66b294761c045428562d946b65aYuichi Araki        }
8450ce74b0963de66b294761c045428562d946b65aYuichi Araki        matrix.preTranslate(view.getLeft(), view.getTop());
8550ce74b0963de66b294761c045428562d946b65aYuichi Araki        final Matrix vm = view.getMatrix();
8650ce74b0963de66b294761c045428562d946b65aYuichi Araki        if (!vm.isIdentity()) {
8750ce74b0963de66b294761c045428562d946b65aYuichi Araki            matrix.preConcat(vm);
8850ce74b0963de66b294761c045428562d946b65aYuichi Araki        }
8950ce74b0963de66b294761c045428562d946b65aYuichi Araki    }
9050ce74b0963de66b294761c045428562d946b65aYuichi Araki
9150ce74b0963de66b294761c045428562d946b65aYuichi Araki    @Override
9250ce74b0963de66b294761c045428562d946b65aYuichi Araki    public void transformMatrixToLocal(@NonNull View view, @NonNull Matrix matrix) {
9350ce74b0963de66b294761c045428562d946b65aYuichi Araki        final ViewParent parent = view.getParent();
9450ce74b0963de66b294761c045428562d946b65aYuichi Araki        if (parent instanceof View) {
9550ce74b0963de66b294761c045428562d946b65aYuichi Araki            final View vp = (View) parent;
9650ce74b0963de66b294761c045428562d946b65aYuichi Araki            transformMatrixToLocal(vp, matrix);
9750ce74b0963de66b294761c045428562d946b65aYuichi Araki            matrix.postTranslate(vp.getScrollX(), vp.getScrollY());
9850ce74b0963de66b294761c045428562d946b65aYuichi Araki        }
9950ce74b0963de66b294761c045428562d946b65aYuichi Araki        matrix.postTranslate(view.getLeft(), view.getTop());
10050ce74b0963de66b294761c045428562d946b65aYuichi Araki        final Matrix vm = view.getMatrix();
10150ce74b0963de66b294761c045428562d946b65aYuichi Araki        if (!vm.isIdentity()) {
10250ce74b0963de66b294761c045428562d946b65aYuichi Araki            final Matrix inverted = new Matrix();
10350ce74b0963de66b294761c045428562d946b65aYuichi Araki            if (vm.invert(inverted)) {
10450ce74b0963de66b294761c045428562d946b65aYuichi Araki                matrix.postConcat(inverted);
10550ce74b0963de66b294761c045428562d946b65aYuichi Araki            }
10650ce74b0963de66b294761c045428562d946b65aYuichi Araki        }
10750ce74b0963de66b294761c045428562d946b65aYuichi Araki    }
10850ce74b0963de66b294761c045428562d946b65aYuichi Araki
10950ce74b0963de66b294761c045428562d946b65aYuichi Araki    @Override
11050ce74b0963de66b294761c045428562d946b65aYuichi Araki    public void setAnimationMatrix(@NonNull View view, Matrix matrix) {
11150ce74b0963de66b294761c045428562d946b65aYuichi Araki        if (matrix == null || matrix.isIdentity()) {
11250ce74b0963de66b294761c045428562d946b65aYuichi Araki            view.setPivotX(view.getWidth() / 2);
11350ce74b0963de66b294761c045428562d946b65aYuichi Araki            view.setPivotY(view.getHeight() / 2);
11450ce74b0963de66b294761c045428562d946b65aYuichi Araki            view.setTranslationX(0);
11550ce74b0963de66b294761c045428562d946b65aYuichi Araki            view.setTranslationY(0);
11650ce74b0963de66b294761c045428562d946b65aYuichi Araki            view.setScaleX(1);
11750ce74b0963de66b294761c045428562d946b65aYuichi Araki            view.setScaleY(1);
11850ce74b0963de66b294761c045428562d946b65aYuichi Araki            view.setRotation(0);
11950ce74b0963de66b294761c045428562d946b65aYuichi Araki        } else {
12050ce74b0963de66b294761c045428562d946b65aYuichi Araki            float[] values = mMatrixValues;
12150ce74b0963de66b294761c045428562d946b65aYuichi Araki            if (values == null) {
12250ce74b0963de66b294761c045428562d946b65aYuichi Araki                mMatrixValues = values = new float[9];
12350ce74b0963de66b294761c045428562d946b65aYuichi Araki            }
12450ce74b0963de66b294761c045428562d946b65aYuichi Araki            matrix.getValues(values);
12550ce74b0963de66b294761c045428562d946b65aYuichi Araki            final float sin = values[Matrix.MSKEW_Y];
12650ce74b0963de66b294761c045428562d946b65aYuichi Araki            final float cos = (float) Math.sqrt(1 - sin * sin)
12750ce74b0963de66b294761c045428562d946b65aYuichi Araki                    * (values[Matrix.MSCALE_X] < 0 ? -1 : 1);
12850ce74b0963de66b294761c045428562d946b65aYuichi Araki            final float rotation = (float) Math.toDegrees(Math.atan2(sin, cos));
12950ce74b0963de66b294761c045428562d946b65aYuichi Araki            final float scaleX = values[Matrix.MSCALE_X] / cos;
13050ce74b0963de66b294761c045428562d946b65aYuichi Araki            final float scaleY = values[Matrix.MSCALE_Y] / cos;
13150ce74b0963de66b294761c045428562d946b65aYuichi Araki            final float dx = values[Matrix.MTRANS_X];
13250ce74b0963de66b294761c045428562d946b65aYuichi Araki            final float dy = values[Matrix.MTRANS_Y];
13350ce74b0963de66b294761c045428562d946b65aYuichi Araki            view.setPivotX(0);
13450ce74b0963de66b294761c045428562d946b65aYuichi Araki            view.setPivotY(0);
13550ce74b0963de66b294761c045428562d946b65aYuichi Araki            view.setTranslationX(dx);
13650ce74b0963de66b294761c045428562d946b65aYuichi Araki            view.setTranslationY(dy);
13750ce74b0963de66b294761c045428562d946b65aYuichi Araki            view.setRotation(rotation);
13850ce74b0963de66b294761c045428562d946b65aYuichi Araki            view.setScaleX(scaleX);
13950ce74b0963de66b294761c045428562d946b65aYuichi Araki            view.setScaleY(scaleY);
14050ce74b0963de66b294761c045428562d946b65aYuichi Araki        }
14150ce74b0963de66b294761c045428562d946b65aYuichi Araki    }
14250ce74b0963de66b294761c045428562d946b65aYuichi Araki
1437bd2fbcdcfeb9014c16fd78446c34a4eef489626Yuichi Araki    @Override
1447bd2fbcdcfeb9014c16fd78446c34a4eef489626Yuichi Araki    public void setLeftTopRightBottom(View v, int left, int top, int right, int bottom) {
1457bd2fbcdcfeb9014c16fd78446c34a4eef489626Yuichi Araki        v.setLeft(left);
1467bd2fbcdcfeb9014c16fd78446c34a4eef489626Yuichi Araki        v.setTop(top);
1477bd2fbcdcfeb9014c16fd78446c34a4eef489626Yuichi Araki        v.setRight(right);
1487bd2fbcdcfeb9014c16fd78446c34a4eef489626Yuichi Araki        v.setBottom(bottom);
1497bd2fbcdcfeb9014c16fd78446c34a4eef489626Yuichi Araki    }
1507bd2fbcdcfeb9014c16fd78446c34a4eef489626Yuichi Araki
151c876cd8f9334e2423de00836009f3fd7a9566938Yuichi Araki}
152