OSDN Git Service

fdd3a17e7f8a3a139001a8884b3791f046f2b946
[android-x86/packages-apps-Gallery2.git] / src / com / cooliris / wallpaper / Slideshow.java
1 package com.cooliris.wallpaper;
2
3 //import android.app.Service;
4 import com.cooliris.media.Vector3f;
5
6 import android.content.Context;
7 import android.graphics.Bitmap;
8 import android.graphics.Canvas;
9 import android.graphics.Color;
10 import android.graphics.Paint;
11 import android.graphics.PorterDuffColorFilter;
12 import android.graphics.Rect;
13 import android.graphics.RectF;
14 import android.os.Handler;
15 import android.os.SystemClock;
16 import android.view.SurfaceHolder;
17 import android.view.SurfaceView;
18 import android.graphics.PorterDuff.Mode;
19
20 public class Slideshow extends SurfaceView implements SurfaceHolder.Callback {
21     public Slideshow(Context context) {
22         super(context);
23         SurfaceHolder holder = getHolder();
24         holder.addCallback(this);
25     }
26
27     public static final int SLIDESHOW_DURATION = 5000;
28
29     public interface DataSource {
30         /**
31          * 
32          * @param currentSlideshowCounter
33          * @return
34          */
35         Bitmap getBitmapForIndex(Context context, int currentSlideshowCounter);
36     }
37
38     private final Handler mHandler = new Handler();
39     private final Runnable mDrawFrame = new Runnable() {
40         public void run() {
41             drawFrame();
42         }
43     };
44     private static final Paint sPaint = new Paint();
45     static {
46         sPaint.setFilterBitmap(true);
47         sPaint.setDither(true);
48     }
49     private boolean mVisible = true;
50     private DataSource mSource;
51     private int mCurrentSlideshowCounter;
52     private Bitmap mBitmap;
53     private Rect mRect;
54     private RectF mFrameRect;
55     private static final Vector3f sGrow = new Vector3f();
56     private Bitmap mQueuedBitmap;
57     private Rect mQueuedRect;
58     private RectF mQueuedFrameRect;
59     private static final Vector3f sQueuedGrow = new Vector3f();
60     
61     private long mPrevTime;
62     private long mTimeElapsed;
63
64     public void setDataSource(DataSource source) {
65         mSource = source;
66     }
67
68     public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
69         mHandler.post(mDrawFrame);
70         if (mBitmap != null) {
71             mRect = getRectToFitBitmap(mBitmap.getWidth(), mBitmap.getHeight(), width, height);
72             mFrameRect.right = width;
73             mFrameRect.bottom = height;
74         }
75         if (mQueuedBitmap != null) {
76             mQueuedRect = getRectToFitBitmap(mQueuedBitmap.getWidth(), mQueuedBitmap.getHeight(), width, height);
77             mQueuedFrameRect.right = width;
78             mQueuedFrameRect.bottom = height;
79         }
80     }
81
82     public void surfaceCreated(SurfaceHolder holder) {
83         // We may need to make calls to super once this is a subclass of WallpaperService.
84         mHandler.post(mDrawFrame);
85     }
86
87     public void surfaceDestroyed(SurfaceHolder holder) {
88
89     }
90
91     public void drawFrame() {
92         final SurfaceHolder holder = getHolder();
93         Rect frame = holder.getSurfaceFrame();
94         final Paint paint = sPaint;
95         Canvas c = null;
96         try {
97             c = holder.lockCanvas();
98             if (c != null) {
99                 long now = SystemClock.uptimeMillis();
100                 long delta = now - mPrevTime;
101                 if (delta > 50)
102                     delta = 50;
103                 mTimeElapsed += delta;
104                 mPrevTime = now;
105                 performSetup(frame.width(), frame.height());
106                 // We draw the source bitmap
107                 if (mBitmap != null) {
108                     if (mTimeElapsed > SLIDESHOW_DURATION) {
109                         float alpha = ((float)(mTimeElapsed - SLIDESHOW_DURATION)) / 2000.0f;
110                         paint.setColorFilter(null);
111                         if (alpha < 1.0f) {
112                             //int val = (int)(255 * (1.0f - alpha));
113                             //int srcColor = Color.argb(val, 0, 0, 0);
114                             //PorterDuffColorFilter colorFilter = new PorterDuffColorFilter(srcColor, Mode.SRC_IN);
115                             //paint.setColorFilter(null);
116                         }
117                         c.drawBitmap(mBitmap, mRect, mFrameRect, paint);
118                         if (alpha < 1.0f) {
119                             int val = (int)(255 * alpha);
120                             int srcColor = Color.argb(val, 0, 0, 0);
121                             PorterDuffColorFilter colorFilter = new PorterDuffColorFilter(srcColor, Mode.DST_IN);
122                             paint.setColorFilter(colorFilter);
123                         }
124                         
125                         c.drawBitmap(mQueuedBitmap, mQueuedRect, mQueuedFrameRect, paint);
126                         performUpdate(mQueuedFrameRect, sQueuedGrow, delta);
127                         if (alpha >= 1.0f) {
128                             // We switch the image.
129                             mBitmap.recycle();
130                             mRect = mQueuedRect;
131                             mBitmap = mQueuedBitmap;
132                             mFrameRect =  mQueuedFrameRect;
133                             sGrow.set(sQueuedGrow);
134                             mQueuedBitmap = null;
135                             mQueuedRect = null;
136                             mQueuedFrameRect =  null;
137                             mTimeElapsed = 0;
138                         }
139                     } else {
140                         paint.setColorFilter(null);
141                         c.drawBitmap(mBitmap, mRect, mFrameRect, paint);
142                     }
143                     performUpdate(mFrameRect, sGrow, delta);
144                 }
145
146             }
147         } finally {
148             if (c != null)
149                 holder.unlockCanvasAndPost(c);
150         }
151         mHandler.removeCallbacks(mDrawFrame);
152         if (mVisible) {
153             mHandler.postDelayed(mDrawFrame, 20);
154         }
155     }
156
157     private void performUpdate(RectF rect, Vector3f grow, long delta) {
158         float timeElapsed = ((float)(delta)) / 1000.0f;
159         float amountToGrowX = timeElapsed * (rect.width() / 30.0f);
160         float amountToGrowY = amountToGrowX * (rect.height() / rect.width());
161         rect.top -= amountToGrowY * grow.x;
162         rect.left -= amountToGrowX * grow.y;
163         
164         rect.bottom += amountToGrowY * (1 - grow.x);
165         rect.right += amountToGrowX * (1 - grow.y);
166     }
167
168     private void performSetup(int viewWidth, int viewHeight) {
169         if (mBitmap == null) {
170             mBitmap = getRandomBitmap();
171             if (mBitmap != null) {
172                 mRect = getRectToFitBitmap(mBitmap.getWidth(), mBitmap.getHeight(), viewWidth, viewHeight);
173                 mFrameRect = new RectF();
174                 mFrameRect.right = viewWidth;
175                 mFrameRect.bottom = viewHeight;
176                 sGrow.set((float)Math.random(), (float)Math.random(), 0);
177             }
178         }
179         if (mQueuedBitmap == null) {
180             mQueuedBitmap = getRandomBitmap();
181             if (mQueuedBitmap == null) {
182                 mQueuedBitmap = mBitmap;
183             }
184             if (mQueuedBitmap != null) {
185                 mQueuedRect = getRectToFitBitmap(mQueuedBitmap.getWidth(), mQueuedBitmap.getHeight(), viewWidth, viewHeight);
186                 mQueuedFrameRect = new RectF();
187                 mQueuedFrameRect.right = viewWidth;
188                 mQueuedFrameRect.bottom = viewHeight;
189                 sQueuedGrow.set((float)Math.random(), (float)Math.random(), 0);
190             }
191         }
192     }
193
194     private Rect getRectToFitBitmap(int bitmapWidth, int bitmapHeight, int viewWidth, int viewHeight) {
195         Rect rect = new Rect();
196         float viewAspect = (float)viewHeight / viewWidth;
197         float newWidth = bitmapWidth * viewAspect;
198         if (bitmapHeight < newWidth) {
199             // Vertically constrained.
200             newWidth = bitmapHeight / viewAspect;
201             rect.set((int)(bitmapWidth/2 - newWidth/2), 0, (int)(bitmapWidth/2 + newWidth/2), bitmapHeight);
202         } else {
203             // Horizontally constrained
204             float newHeight = bitmapWidth * viewAspect;
205             rect.set(0, (int)(bitmapHeight/2 - newHeight/2), bitmapWidth, (int)(bitmapHeight/2 + newHeight/2));
206         }
207         return rect;
208     }
209
210     private Bitmap getRandomBitmap() {
211         if (mSource != null) {
212             return mSource.getBitmapForIndex(getContext(), mCurrentSlideshowCounter++);
213         }
214         return null;
215     }
216
217     public void onVisibilityChanged(boolean visible) {
218         mVisible = visible;
219         if (!visible) {
220             mHandler.removeCallbacks(mDrawFrame);
221         }
222         drawFrame();
223     }
224
225 }