16b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang/*
26b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang * Copyright (C) 2012 The Android Open Source Project
36b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang *
46b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang * Licensed under the Apache License, Version 2.0 (the "License");
56b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang * you may not use this file except in compliance with the License.
66b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang * You may obtain a copy of the License at
76b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang *
86b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang *      http://www.apache.org/licenses/LICENSE-2.0
96b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang *
106b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang * Unless required by applicable law or agreed to in writing, software
116b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang * distributed under the License is distributed on an "AS IS" BASIS,
126b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang * See the License for the specific language governing permissions and
146b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang * limitations under the License.
156b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang */
166b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang
176b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Changpackage com.android.gallery3d.ui;
186b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang
196b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Changimport android.content.Context;
206b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Changimport android.view.MotionEvent;
216b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang
226b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Changimport com.android.gallery3d.R;
23517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Changimport com.android.gallery3d.common.Utils;
246b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Changimport com.android.gallery3d.util.GalleryUtils;
256b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang
266b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Changpublic class UndoBarView extends GLView {
277817979db0c52ffeacb951625b1e821eba303285Ahbong Chang    @SuppressWarnings("unused")
286b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    private static final String TAG = "UndoBarView";
296b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang
306b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    private static final int WHITE = 0xFFFFFFFF;
316b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    private static final int GRAY = 0xFFAAAAAA;
326b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang
336b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    private final NinePatchTexture mPanel;
346b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    private final StringTexture mUndoText;
356b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    private final StringTexture mDeletedText;
366b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    private final ResourceTexture mUndoIcon;
376b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    private final int mBarHeight;
386b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    private final int mBarMargin;
396b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    private final int mUndoTextMargin;
406b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    private final int mIconSize;
416b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    private final int mIconMargin;
426b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    private final int mSeparatorTopMargin;
436b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    private final int mSeparatorBottomMargin;
446b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    private final int mSeparatorRightMargin;
456b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    private final int mSeparatorWidth;
466b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    private final int mDeletedTextMargin;
476b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    private final int mClickRegion;
486b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang
496b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    private OnClickListener mOnClickListener;
506b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    private boolean mDownOnButton;
516b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang
526b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    // This is the layout of UndoBarView. The unit is dp.
536b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    //
546b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    //    +-+----+----------------+-+--+----+-+------+--+-+
556b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    // 48 | |    | Deleted        | |  | <- | | UNDO |  | |
566b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    //    +-+----+----------------+-+--+----+-+------+--+-+
576b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    //     4  16                   1 12  32  8        16 4
586b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    public UndoBarView(Context context) {
597817979db0c52ffeacb951625b1e821eba303285Ahbong Chang        mBarHeight = GalleryUtils.dpToPixel(48);
607817979db0c52ffeacb951625b1e821eba303285Ahbong Chang        mBarMargin = GalleryUtils.dpToPixel(4);
617817979db0c52ffeacb951625b1e821eba303285Ahbong Chang        mUndoTextMargin = GalleryUtils.dpToPixel(16);
627817979db0c52ffeacb951625b1e821eba303285Ahbong Chang        mIconMargin = GalleryUtils.dpToPixel(8);
637817979db0c52ffeacb951625b1e821eba303285Ahbong Chang        mIconSize = GalleryUtils.dpToPixel(32);
647817979db0c52ffeacb951625b1e821eba303285Ahbong Chang        mSeparatorRightMargin = GalleryUtils.dpToPixel(12);
657817979db0c52ffeacb951625b1e821eba303285Ahbong Chang        mSeparatorTopMargin = GalleryUtils.dpToPixel(10);
667817979db0c52ffeacb951625b1e821eba303285Ahbong Chang        mSeparatorBottomMargin = GalleryUtils.dpToPixel(10);
677817979db0c52ffeacb951625b1e821eba303285Ahbong Chang        mSeparatorWidth = GalleryUtils.dpToPixel(1);
687817979db0c52ffeacb951625b1e821eba303285Ahbong Chang        mDeletedTextMargin = GalleryUtils.dpToPixel(16);
696b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang
706b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        mPanel = new NinePatchTexture(context, R.drawable.panel_undo_holo);
716b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        mUndoText = StringTexture.newInstance(context.getString(R.string.undo),
726b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang                GalleryUtils.dpToPixel(12), GRAY, 0, true);
736b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        mDeletedText = StringTexture.newInstance(
746b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang                context.getString(R.string.deleted),
756b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang                GalleryUtils.dpToPixel(16), WHITE);
766b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        mUndoIcon = new ResourceTexture(
776b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang                context, R.drawable.ic_menu_revert_holo_dark);
786b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        mClickRegion = mBarMargin + mUndoTextMargin + mUndoText.getWidth()
796b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang                + mIconMargin + mIconSize + mSeparatorRightMargin;
806b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    }
816b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang
826b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    public void setOnClickListener(OnClickListener listener) {
836b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        mOnClickListener = listener;
846b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    }
856b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang
866b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    @Override
876b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    protected void onMeasure(int widthSpec, int heightSpec) {
886b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        setMeasuredSize(0 /* unused */, mBarHeight);
896b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    }
906b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang
916b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    @Override
926b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    protected void render(GLCanvas canvas) {
936b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        super.render(canvas);
94517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang        advanceAnimation();
95517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang
96517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang        canvas.save(GLCanvas.SAVE_FLAG_ALPHA);
97517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang        canvas.multiplyAlpha(mAlpha);
98517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang
996b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        int w = getWidth();
1006b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        int h = getHeight();
1016b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        mPanel.draw(canvas, mBarMargin, 0, w - mBarMargin * 2, mBarHeight);
1026b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang
1036b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        int x = w - mBarMargin;
1046b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        int y;
1056b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang
1066b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        x -= mUndoTextMargin + mUndoText.getWidth();
1076b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        y = (mBarHeight - mUndoText.getHeight()) / 2;
1086b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        mUndoText.draw(canvas, x, y);
1096b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang
1106b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        x -= mIconMargin + mIconSize;
1116b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        y = (mBarHeight - mIconSize) / 2;
1126b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        mUndoIcon.draw(canvas, x, y, mIconSize, mIconSize);
1136b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang
1146b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        x -= mSeparatorRightMargin + mSeparatorWidth;
1156b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        y = mSeparatorTopMargin;
1166b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        canvas.fillRect(x, y, mSeparatorWidth,
1176b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang                mBarHeight - mSeparatorTopMargin - mSeparatorBottomMargin, GRAY);
1186b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang
1196b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        x = mBarMargin + mDeletedTextMargin;
1206b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        y = (mBarHeight - mDeletedText.getHeight()) / 2;
1216b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        mDeletedText.draw(canvas, x, y);
122517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang
123517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang        canvas.restore();
1246b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    }
1256b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang
1266b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    @Override
1276b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    protected boolean onTouch(MotionEvent event) {
1286b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        switch (event.getAction()) {
1296b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang            case MotionEvent.ACTION_DOWN:
1306b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang                mDownOnButton = inUndoButton(event);
1316b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang                break;
1326b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang            case MotionEvent.ACTION_UP:
1336b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang                if (mDownOnButton) {
1346b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang                    if (mOnClickListener != null && inUndoButton(event)) {
1356b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang                        mOnClickListener.onClick(this);
1366b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang                    }
1376b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang                    mDownOnButton = false;
1386b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang                }
1396b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang                break;
1406b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang            case MotionEvent.ACTION_CANCEL:
1416b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang                mDownOnButton = false;
1426b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang                break;
1436b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        }
1446b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        return true;
1456b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    }
1466b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang
1476b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    // Check if the event is on the right of the separator
1486b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    private boolean inUndoButton(MotionEvent event) {
1496b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        float x = event.getX();
1506b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        float y = event.getY();
1516b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        int w = getWidth();
1526b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        int h = getHeight();
1536b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang        return (x >= w - mClickRegion && x < w && y >= 0 && y < h);
1546b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang    }
155517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang
156517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang    ////////////////////////////////////////////////////////////////////////////
157517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang    //  Alpha Animation
158517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang    ////////////////////////////////////////////////////////////////////////////
159517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang
160517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang    private static final long NO_ANIMATION = -1;
161517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang    private static long ANIM_TIME = 200;
162517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang    private long mAnimationStartTime = NO_ANIMATION;
163517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang    private float mFromAlpha, mToAlpha;
164517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang    private float mAlpha;
165517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang
166517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang    private static float getTargetAlpha(int visibility) {
167517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang        return (visibility == VISIBLE) ? 1f : 0f;
168517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang    }
169517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang
1707817979db0c52ffeacb951625b1e821eba303285Ahbong Chang    @Override
171517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang    public void setVisibility(int visibility) {
172517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang        mAlpha = getTargetAlpha(visibility);
173517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang        mAnimationStartTime = NO_ANIMATION;
174517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang        super.setVisibility(visibility);
175517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang        invalidate();
176517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang    }
177517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang
178517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang    public void animateVisibility(int visibility) {
179517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang        float target = getTargetAlpha(visibility);
180517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang        if (mAnimationStartTime == NO_ANIMATION && mAlpha == target) return;
181517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang        if (mAnimationStartTime != NO_ANIMATION && mToAlpha == target) return;
182517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang
183517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang        mFromAlpha = mAlpha;
184517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang        mToAlpha = target;
185517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang        mAnimationStartTime = AnimationTime.startTime();
186517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang
187517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang        super.setVisibility(VISIBLE);
188517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang        invalidate();
189517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang    }
190517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang
191517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang    private void advanceAnimation() {
192517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang        if (mAnimationStartTime == NO_ANIMATION) return;
193517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang
194517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang        float delta = (float) (AnimationTime.get() - mAnimationStartTime) /
195517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang                ANIM_TIME;
196517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang        mAlpha = mFromAlpha + ((mToAlpha > mFromAlpha) ? delta : -delta);
197517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang        mAlpha = Utils.clamp(mAlpha, 0f, 1f);
198517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang
199517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang        if (mAlpha == mToAlpha) {
200517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang            mAnimationStartTime = NO_ANIMATION;
201517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang            if (mAlpha == 0) {
202517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang                super.setVisibility(INVISIBLE);
203517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang            }
204517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang        }
205517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang        invalidate();
206517e1bd25305d4e82d101a8c06be0119dde2eab3Chih-Chung Chang    }
2076b891c6a3739f8c49d42f9db6fc76cb92c7c5f25Chih-Chung Chang}
208