• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2012 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.gallery3d.ui;
18 
19 import android.content.Context;
20 import android.view.MotionEvent;
21 
22 import com.android.gallery3d.R;
23 import com.android.gallery3d.common.Utils;
24 import com.android.gallery3d.util.GalleryUtils;
25 
26 public class UndoBarView extends GLView {
27     private static final String TAG = "UndoBarView";
28 
29     private static final int WHITE = 0xFFFFFFFF;
30     private static final int GRAY = 0xFFAAAAAA;
31 
32     private final NinePatchTexture mPanel;
33     private final StringTexture mUndoText;
34     private final StringTexture mDeletedText;
35     private final ResourceTexture mUndoIcon;
36     private final int mBarHeight;
37     private final int mBarMargin;
38     private final int mUndoTextMargin;
39     private final int mIconSize;
40     private final int mIconMargin;
41     private final int mSeparatorTopMargin;
42     private final int mSeparatorBottomMargin;
43     private final int mSeparatorRightMargin;
44     private final int mSeparatorWidth;
45     private final int mDeletedTextMargin;
46     private final int mClickRegion;
47 
48     private OnClickListener mOnClickListener;
49     private boolean mDownOnButton;
50 
51     // This is the layout of UndoBarView. The unit is dp.
52     //
53     //    +-+----+----------------+-+--+----+-+------+--+-+
54     // 48 | |    | Deleted        | |  | <- | | UNDO |  | |
55     //    +-+----+----------------+-+--+----+-+------+--+-+
56     //     4  16                   1 12  32  8        16 4
UndoBarView(Context context)57     public UndoBarView(Context context) {
58         mBarHeight = (int) GalleryUtils.dpToPixel(48);
59         mBarMargin = (int) GalleryUtils.dpToPixel(4);
60         mUndoTextMargin = (int) GalleryUtils.dpToPixel(16);
61         mIconMargin = (int) GalleryUtils.dpToPixel(8);
62         mIconSize = (int) GalleryUtils.dpToPixel(32);
63         mSeparatorRightMargin = (int) GalleryUtils.dpToPixel(12);
64         mSeparatorTopMargin = (int) GalleryUtils.dpToPixel(10);
65         mSeparatorBottomMargin = (int) GalleryUtils.dpToPixel(10);
66         mSeparatorWidth = (int) GalleryUtils.dpToPixel(1);
67         mDeletedTextMargin = (int) GalleryUtils.dpToPixel(16);
68 
69         mPanel = new NinePatchTexture(context, R.drawable.panel_undo_holo);
70         mUndoText = StringTexture.newInstance(context.getString(R.string.undo),
71                 GalleryUtils.dpToPixel(12), GRAY, 0, true);
72         mDeletedText = StringTexture.newInstance(
73                 context.getString(R.string.deleted),
74                 GalleryUtils.dpToPixel(16), WHITE);
75         mUndoIcon = new ResourceTexture(
76                 context, R.drawable.ic_menu_revert_holo_dark);
77         mClickRegion = mBarMargin + mUndoTextMargin + mUndoText.getWidth()
78                 + mIconMargin + mIconSize + mSeparatorRightMargin;
79     }
80 
setOnClickListener(OnClickListener listener)81     public void setOnClickListener(OnClickListener listener) {
82         mOnClickListener = listener;
83     }
84 
85     @Override
onMeasure(int widthSpec, int heightSpec)86     protected void onMeasure(int widthSpec, int heightSpec) {
87         setMeasuredSize(0 /* unused */, mBarHeight);
88     }
89 
90     @Override
render(GLCanvas canvas)91     protected void render(GLCanvas canvas) {
92         super.render(canvas);
93         advanceAnimation();
94 
95         canvas.save(GLCanvas.SAVE_FLAG_ALPHA);
96         canvas.multiplyAlpha(mAlpha);
97 
98         int w = getWidth();
99         int h = getHeight();
100         mPanel.draw(canvas, mBarMargin, 0, w - mBarMargin * 2, mBarHeight);
101 
102         int x = w - mBarMargin;
103         int y;
104 
105         x -= mUndoTextMargin + mUndoText.getWidth();
106         y = (mBarHeight - mUndoText.getHeight()) / 2;
107         mUndoText.draw(canvas, x, y);
108 
109         x -= mIconMargin + mIconSize;
110         y = (mBarHeight - mIconSize) / 2;
111         mUndoIcon.draw(canvas, x, y, mIconSize, mIconSize);
112 
113         x -= mSeparatorRightMargin + mSeparatorWidth;
114         y = mSeparatorTopMargin;
115         canvas.fillRect(x, y, mSeparatorWidth,
116                 mBarHeight - mSeparatorTopMargin - mSeparatorBottomMargin, GRAY);
117 
118         x = mBarMargin + mDeletedTextMargin;
119         y = (mBarHeight - mDeletedText.getHeight()) / 2;
120         mDeletedText.draw(canvas, x, y);
121 
122         canvas.restore();
123     }
124 
125     @Override
onTouch(MotionEvent event)126     protected boolean onTouch(MotionEvent event) {
127         switch (event.getAction()) {
128             case MotionEvent.ACTION_DOWN:
129                 mDownOnButton = inUndoButton(event);
130                 break;
131             case MotionEvent.ACTION_UP:
132                 if (mDownOnButton) {
133                     if (mOnClickListener != null && inUndoButton(event)) {
134                         mOnClickListener.onClick(this);
135                     }
136                     mDownOnButton = false;
137                 }
138                 break;
139             case MotionEvent.ACTION_CANCEL:
140                 mDownOnButton = false;
141                 break;
142         }
143         return true;
144     }
145 
146     // Check if the event is on the right of the separator
inUndoButton(MotionEvent event)147     private boolean inUndoButton(MotionEvent event) {
148         float x = event.getX();
149         float y = event.getY();
150         int w = getWidth();
151         int h = getHeight();
152         return (x >= w - mClickRegion && x < w && y >= 0 && y < h);
153     }
154 
155     ////////////////////////////////////////////////////////////////////////////
156     //  Alpha Animation
157     ////////////////////////////////////////////////////////////////////////////
158 
159     private static final long NO_ANIMATION = -1;
160     private static long ANIM_TIME = 200;
161     private long mAnimationStartTime = NO_ANIMATION;
162     private float mFromAlpha, mToAlpha;
163     private float mAlpha;
164 
getTargetAlpha(int visibility)165     private static float getTargetAlpha(int visibility) {
166         return (visibility == VISIBLE) ? 1f : 0f;
167     }
168 
setVisibility(int visibility)169     public void setVisibility(int visibility) {
170         mAlpha = getTargetAlpha(visibility);
171         mAnimationStartTime = NO_ANIMATION;
172         super.setVisibility(visibility);
173         invalidate();
174     }
175 
animateVisibility(int visibility)176     public void animateVisibility(int visibility) {
177         float target = getTargetAlpha(visibility);
178         if (mAnimationStartTime == NO_ANIMATION && mAlpha == target) return;
179         if (mAnimationStartTime != NO_ANIMATION && mToAlpha == target) return;
180 
181         mFromAlpha = mAlpha;
182         mToAlpha = target;
183         mAnimationStartTime = AnimationTime.startTime();
184 
185         super.setVisibility(VISIBLE);
186         invalidate();
187     }
188 
advanceAnimation()189     private void advanceAnimation() {
190         if (mAnimationStartTime == NO_ANIMATION) return;
191 
192         float delta = (float) (AnimationTime.get() - mAnimationStartTime) /
193                 ANIM_TIME;
194         mAlpha = mFromAlpha + ((mToAlpha > mFromAlpha) ? delta : -delta);
195         mAlpha = Utils.clamp(mAlpha, 0f, 1f);
196 
197         if (mAlpha == mToAlpha) {
198             mAnimationStartTime = NO_ANIMATION;
199             if (mAlpha == 0) {
200                 super.setVisibility(INVISIBLE);
201             }
202         }
203         invalidate();
204     }
205 }
206