OSDN Git Service

android-2.1_r1 snapshot
[android-x86/packages-apps-Gallery2.git] / src / com / cooliris / media / GridCameraManager.java
1 package com.cooliris.media;
2
3 public final class GridCameraManager {
4     private final GridCamera mCamera;
5     private static final Pool<Vector3f> sPool;
6     static {
7         final Vector3f[] vectorPool = new Vector3f[128];
8         int length = vectorPool.length;
9         for (int i = 0; i < length; ++i) {
10             vectorPool[i] = new Vector3f();
11         }
12         sPool = new Pool<Vector3f>(vectorPool);
13     }
14
15     public GridCameraManager(final GridCamera camera) {
16         mCamera = camera;
17     }
18
19     public void centerCameraForSlot(LayoutInterface layout, int slotIndex, float baseConvergence, Vector3f deltaAnchorPositionIn,
20             int selectedSlotIndex, float zoomValue, float imageTheta, int state) {
21         final GridCamera camera = mCamera;
22         final Pool<Vector3f> pool = sPool;
23         synchronized (camera) {
24             final boolean zoomin = (selectedSlotIndex != Shared.INVALID);
25             final int theta = (int) imageTheta;
26             final int portrait = (theta / 90) % 2;
27             if (slotIndex == selectedSlotIndex) {
28                 camera.mConvergenceSpeed = baseConvergence * (zoomin ? 2.0f : 2.0f);
29             }
30             final float oneByZoom = 1.0f / zoomValue;
31             if (slotIndex >= 0) {
32                 final Vector3f position = pool.create();
33                 final Vector3f deltaAnchorPosition = pool.create();
34                 try {
35                     deltaAnchorPosition.set(deltaAnchorPositionIn);
36                     GridCameraManager.getSlotPositionForSlotIndex(slotIndex, camera, layout, deltaAnchorPosition, position);
37                     position.x = (zoomValue == 1.0f) ? ((position.x) * camera.mOneByScale) : camera.mLookAtX;
38                     position.y = (zoomValue == 1.0f) ? 0 : camera.mLookAtY;
39                     if (state == GridLayer.STATE_MEDIA_SETS || state == GridLayer.STATE_TIMELINE) {
40                         position.y = -0.1f;
41                     }
42                     float width = camera.mItemWidth;
43                     float height = camera.mItemHeight;
44                     if (portrait != 0) {
45                         float temp = width;
46                         width = height;
47                         height = temp;
48                     }
49                     camera.moveTo(position.x, position.y, zoomin ? camera.getDistanceToFitRect(width * oneByZoom, height
50                             * oneByZoom) : 0);
51                 } finally {
52                     pool.delete(position);
53                     pool.delete(deltaAnchorPosition);
54                 }
55             } else {
56                 camera.moveYTo(0);
57                 camera.moveZTo(0);
58             }
59         }
60     }
61
62     // CR: line too long. Documentation--what are the semantics of the return
63     // value?
64     /**
65      */
66     public boolean constrainCameraForSlot(LayoutInterface layout, int slotIndex, Vector3f deltaAnchorPositionIn,
67             float currentFocusItemWidth, float currentFocusItemHeight) {
68         final GridCamera camera = mCamera;
69         final Pool<Vector3f> pool = sPool;
70         boolean retVal = false;
71         synchronized (camera) {
72             final Vector3f position = pool.create();
73             final Vector3f deltaAnchorPosition = pool.create();
74             final Vector3f topLeft = pool.create();
75             final Vector3f bottomRight = pool.create();
76             final Vector3f imgTopLeft = pool.create();
77             final Vector3f imgBottomRight = pool.create();
78
79             try {
80                 if (slotIndex >= 0) {
81                     deltaAnchorPosition.set(deltaAnchorPositionIn);
82                     GridCameraManager.getSlotPositionForSlotIndex(slotIndex, camera, layout, deltaAnchorPosition, position);
83                     position.x *= camera.mOneByScale;
84                     position.y = 0.0f;
85                     float width = (currentFocusItemWidth / 2);
86                     float height = (currentFocusItemHeight / 2);
87                     imgTopLeft.set(position.x - width, position.y - height, 0);
88                     imgBottomRight.set(position.x + width, position.y + height, 0);
89                     camera.convertToCameraSpace(0, 0, 0, topLeft);
90                     camera.convertToCameraSpace(camera.mWidth, camera.mHeight, 0, bottomRight);
91                     float leftExtent = topLeft.x - imgTopLeft.x;
92                     float rightExtent = bottomRight.x - imgBottomRight.x;
93                     camera.mConvergenceSpeed = 2.0f;
94
95                     if (leftExtent < 0) {
96                         retVal = true;
97                         camera.moveBy(-leftExtent, 0, 0);
98                     }
99                     if (rightExtent > 0) {
100                         retVal = true;
101                         camera.moveBy(-rightExtent, 0, 0);
102                     }
103                     float topExtent = topLeft.y - imgTopLeft.y;
104                     float bottomExtent = bottomRight.y - imgBottomRight.y;
105                     if (topExtent < 0) {
106                         camera.moveBy(0, -topExtent, 0);
107                     }
108                     if (bottomExtent > 0) {
109                         camera.moveBy(0, -bottomExtent, 0);
110                     }
111                 }
112             } finally {
113                 pool.delete(position);
114                 pool.delete(deltaAnchorPosition);
115                 pool.delete(topLeft);
116                 pool.delete(bottomRight);
117                 pool.delete(imgTopLeft);
118                 pool.delete(imgBottomRight);
119             }
120         }
121         return retVal;
122     }
123
124     public void computeVisibleRange(MediaFeed feed, LayoutInterface layout, Vector3f deltaAnchorPositionIn,
125             IndexRange outVisibleRange, IndexRange outBufferedVisibleRange, IndexRange outCompleteRange, int state) {
126         GridCamera camera = mCamera;
127         Pool<Vector3f> pool = sPool;
128         float offset = (camera.mLookAtX * camera.mScale);
129         int itemWidth = camera.mItemWidth;
130         float maxIncrement = camera.mWidth * 0.5f + itemWidth;
131         float left = -maxIncrement + offset;
132         float right = left + 2.0f * maxIncrement;
133         if (state == GridLayer.STATE_MEDIA_SETS || state == GridLayer.STATE_TIMELINE) {
134             right += (itemWidth * 0.5f);
135         }
136         float top = -maxIncrement;
137         float bottom = camera.mHeight + maxIncrement;
138         // the hint to compute the visible display items
139         int numSlots = 0;
140         if (feed != null) {
141             numSlots = feed.getNumSlots();
142         }
143         synchronized (outCompleteRange) {
144             outCompleteRange.set(0, numSlots - 1);
145         }
146
147         Vector3f position = pool.create();
148         Vector3f deltaAnchorPosition = pool.create();
149         try {
150             int firstVisibleSlotIndex = 0;
151             int lastVisibleSlotIndex = numSlots - 1;
152             int leftEdge = firstVisibleSlotIndex;
153             int rightEdge = lastVisibleSlotIndex;
154             int index = (leftEdge + rightEdge) / 2;
155             lastVisibleSlotIndex = firstVisibleSlotIndex;
156             deltaAnchorPosition.set(deltaAnchorPositionIn);
157             while (index != leftEdge) {
158                 GridCameraManager.getSlotPositionForSlotIndex(index, camera, layout, deltaAnchorPosition, position);
159                 if (FloatUtils.boundsContainsPoint(left, right, top, bottom, position.x, position.y)) {
160                     // this index is visible
161                     firstVisibleSlotIndex = index;
162                     lastVisibleSlotIndex = index;
163                     break;
164                 } else {
165                     if (position.x > left) {
166                         rightEdge = index;
167                     } else {
168                         leftEdge = index;
169                     }
170                     index = (leftEdge + rightEdge) / 2;
171                 }
172             }
173             // CR: comments would make me a happy panda.
174             while (firstVisibleSlotIndex >= 0 && firstVisibleSlotIndex < numSlots) {
175                 GridCameraManager.getSlotPositionForSlotIndex(firstVisibleSlotIndex, camera, layout, deltaAnchorPosition, position);
176                 // CR: !fubar instead of fubar == false.
177                 if (FloatUtils.boundsContainsPoint(left, right, top, bottom, position.x, position.y) == false) {
178                     ++firstVisibleSlotIndex;
179                     break;
180                 } else {
181                     --firstVisibleSlotIndex;
182                 }
183             }
184             while (lastVisibleSlotIndex >= 0 && lastVisibleSlotIndex < numSlots) {
185                 GridCameraManager.getSlotPositionForSlotIndex(lastVisibleSlotIndex, camera, layout, deltaAnchorPosition, position);
186                 if (FloatUtils.boundsContainsPoint(left, right, top, bottom, position.x, position.y) == false) {
187                     --lastVisibleSlotIndex;
188                     break;
189                 } else {
190                     ++lastVisibleSlotIndex;
191                 }
192             }
193             if (firstVisibleSlotIndex < 0)
194                 firstVisibleSlotIndex = 0;
195             if (lastVisibleSlotIndex >= numSlots)
196                 lastVisibleSlotIndex = numSlots - 1;
197             synchronized (outVisibleRange) {
198                 outVisibleRange.set(firstVisibleSlotIndex, lastVisibleSlotIndex);
199             }
200             if (feed != null) {
201                 feed.setVisibleRange(firstVisibleSlotIndex, lastVisibleSlotIndex);
202             }
203             final int buffer = 24;
204             firstVisibleSlotIndex = ((firstVisibleSlotIndex - buffer) / buffer) * buffer;
205             lastVisibleSlotIndex += buffer;
206             lastVisibleSlotIndex = (lastVisibleSlotIndex / buffer) * buffer;
207             if (firstVisibleSlotIndex < 0) {
208                 firstVisibleSlotIndex = 0;
209             }
210             if (lastVisibleSlotIndex >= numSlots) {
211                 lastVisibleSlotIndex = numSlots - 1;
212             }
213             synchronized (outBufferedVisibleRange) {
214                 outBufferedVisibleRange.set(firstVisibleSlotIndex, lastVisibleSlotIndex);
215             }
216         } finally {
217             pool.delete(position);
218             pool.delete(deltaAnchorPosition);
219         }
220     }
221
222     public static final void getSlotPositionForSlotIndex(int slotIndex, GridCamera camera, LayoutInterface layout,
223             Vector3f deltaAnchorPosition, Vector3f outVal) {
224         layout.getPositionForSlotIndex(slotIndex, camera.mItemWidth, camera.mItemHeight, outVal);
225         outVal.subtract(deltaAnchorPosition);
226     }
227
228     public static final float getFillScreenZoomValue(GridCamera camera, Pool<Vector3f> pool, float currentFocusItemWidth,
229             float currentFocusItemHeight) {
230         final Vector3f topLeft = pool.create();
231         final Vector3f bottomRight = pool.create();
232         float potentialZoomValue = 1.0f;
233         try {
234             camera.convertToCameraSpace(0, 0, 0, topLeft);
235             camera.convertToCameraSpace(camera.mWidth, camera.mHeight, 0, bottomRight);
236             float xExtent = Math.abs(topLeft.x - bottomRight.x) / currentFocusItemWidth;
237             float yExtent = Math.abs(topLeft.y - bottomRight.y) / currentFocusItemHeight;
238             potentialZoomValue = Math.max(xExtent, yExtent);
239         } finally {
240             pool.delete(topLeft);
241             pool.delete(bottomRight);
242         }
243         return potentialZoomValue;
244     }
245 }