OSDN Git Service

376a739253d100768608cb2b38dccbdffe8988b2
[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 = 2000;
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                             mRect = mQueuedRect;
130                             mBitmap = mQueuedBitmap;
131                             mFrameRect =  mQueuedFrameRect;
132                             sGrow.set(sQueuedGrow);
133                             mQueuedBitmap = null;
134                             mQueuedRect = null;
135                             mQueuedFrameRect =  null;
136                             mTimeElapsed = 0;
137                         }
138                     } else {
139                         paint.setColorFilter(null);
140                         c.drawBitmap(mBitmap, mRect, mFrameRect, paint);
141                     }
142                     performUpdate(mFrameRect, sGrow, delta);
143                 }
144
145             }
146         } finally {
147             if (c != null)
148                 holder.unlockCanvasAndPost(c);
149         }
150         mHandler.removeCallbacks(mDrawFrame);
151         if (mVisible) {
152             mHandler.postDelayed(mDrawFrame, 20);
153         }
154     }
155
156     private void performUpdate(RectF rect, Vector3f grow, long delta) {
157         float timeElapsed = ((float)(delta)) / 1000.0f;
158         float amountToGrowX = timeElapsed * (rect.width() / 15.0f);
159         float amountToGrowY = amountToGrowX * (rect.height() / rect.width());
160         rect.top -= amountToGrowY * grow.x;
161         rect.left -= amountToGrowX * grow.y;
162         
163         rect.bottom += amountToGrowY * (1 - grow.x);
164         rect.right += amountToGrowX * (1 - grow.y);
165     }
166
167     private void performSetup(int viewWidth, int viewHeight) {
168         if (mBitmap == null) {
169             mBitmap = getRandomBitmap();
170             if (mBitmap != null) {
171                 mRect = getRectToFitBitmap(mBitmap.getWidth(), mBitmap.getHeight(), viewWidth, viewHeight);
172                 mFrameRect = new RectF();
173                 mFrameRect.right = viewWidth;
174                 mFrameRect.bottom = viewHeight;
175                 sGrow.set((float)Math.random(), (float)Math.random(), 0);
176             }
177         }
178         if (mQueuedBitmap == null) {
179             mQueuedBitmap = getRandomBitmap();
180             if (mQueuedBitmap == null) {
181                 mQueuedBitmap = mBitmap;
182             }
183             if (mQueuedBitmap != null) {
184                 mQueuedRect = getRectToFitBitmap(mQueuedBitmap.getWidth(), mQueuedBitmap.getHeight(), viewWidth, viewHeight);
185                 mQueuedFrameRect = new RectF();
186                 mQueuedFrameRect.right = viewWidth;
187                 mQueuedFrameRect.bottom = viewHeight;
188                 sQueuedGrow.set((float)Math.random(), (float)Math.random(), 0);
189             }
190         }
191     }
192
193     private Rect getRectToFitBitmap(int bitmapWidth, int bitmapHeight, int viewWidth, int viewHeight) {
194         Rect rect = new Rect();
195         float viewAspect = (float)viewHeight / viewWidth;
196         float newWidth = bitmapWidth * viewAspect;
197         if (bitmapHeight < newWidth) {
198             // Vertically constrained.
199             newWidth = bitmapHeight / viewAspect;
200             rect.set((int)(bitmapWidth/2 - newWidth/2), 0, (int)(bitmapWidth/2 + newWidth/2), bitmapHeight);
201         } else {
202             // Horizontally constrained
203             float newHeight = bitmapWidth * viewAspect;
204             rect.set(0, (int)(bitmapHeight/2 - newHeight/2), bitmapWidth, (int)(bitmapHeight/2 + newHeight/2));
205         }
206         return rect;
207     }
208
209     private Bitmap getRandomBitmap() {
210         if (mSource != null) {
211             return mSource.getBitmapForIndex(getContext(), mCurrentSlideshowCounter++);
212         }
213         return null;
214     }
215
216     public void onVisibilityChanged(boolean visible) {
217         mVisible = visible;
218         if (!visible) {
219             mHandler.removeCallbacks(mDrawFrame);
220         }
221         drawFrame();
222     }
223
224 }