1 package com.cooliris.media;
4 public final class GridCameraManager {
5 private final GridCamera mCamera;
6 private static final Pool<Vector3f> sPool;
8 final Vector3f[] vectorPool = new Vector3f[128];
9 int length = vectorPool.length;
10 for (int i = 0; i < length; ++i) {
11 vectorPool[i] = new Vector3f();
13 sPool = new Pool<Vector3f>(vectorPool);
16 public GridCameraManager(final GridCamera camera) {
20 public void centerCameraForSlot(LayoutInterface layout, int slotIndex, float baseConvergence, Vector3f deltaAnchorPositionIn,
21 int selectedSlotIndex, float zoomValue, float imageTheta, int state) {
22 final GridCamera camera = mCamera;
23 final Pool<Vector3f> pool = sPool;
24 synchronized (camera) {
25 final boolean zoomin = (selectedSlotIndex != Shared.INVALID);
26 final int theta = (int) imageTheta;
27 final int portrait = (theta / 90) % 2;
28 if (slotIndex == selectedSlotIndex) {
29 camera.mConvergenceSpeed = baseConvergence * (zoomin ? 2.0f : 2.0f);
31 final float oneByZoom = 1.0f / zoomValue;
33 final Vector3f position = pool.create();
34 final Vector3f deltaAnchorPosition = pool.create();
36 deltaAnchorPosition.set(deltaAnchorPositionIn);
37 GridCameraManager.getSlotPositionForSlotIndex(slotIndex, camera, layout, deltaAnchorPosition, position);
38 position.x = (zoomValue == 1.0f) ? ((position.x) * camera.mOneByScale) : camera.mLookAtX;
39 position.y = (zoomValue == 1.0f) ? 0 : camera.mLookAtY;
40 if (state == GridLayer.STATE_MEDIA_SETS || state == GridLayer.STATE_TIMELINE) {
43 float width = camera.mItemWidth;
44 float height = camera.mItemHeight;
50 camera.moveTo(position.x, position.y, zoomin ? camera.getDistanceToFitRect(width * oneByZoom, height * oneByZoom) : 0);
52 pool.delete(position);
53 pool.delete(deltaAnchorPosition);
62 // CR: line too long. Documentation--what are the semantics of the return value?
65 public boolean constrainCameraForSlot(LayoutInterface layout, int slotIndex, Vector3f deltaAnchorPositionIn,
66 float currentFocusItemWidth, float currentFocusItemHeight) {
67 final GridCamera camera = mCamera;
68 final Pool<Vector3f> pool = sPool;
69 boolean retVal = false;
70 synchronized (camera) {
71 final Vector3f position = pool.create();
72 final Vector3f deltaAnchorPosition = pool.create();
73 final Vector3f topLeft = pool.create();
74 final Vector3f bottomRight = pool.create();
75 final Vector3f imgTopLeft = pool.create();
76 final Vector3f imgBottomRight = pool.create();
80 deltaAnchorPosition.set(deltaAnchorPositionIn);
81 GridCameraManager.getSlotPositionForSlotIndex(slotIndex, camera, layout, deltaAnchorPosition, position);
82 position.x *= camera.mOneByScale;
84 float width = (currentFocusItemWidth / 2);
85 float height = (currentFocusItemHeight / 2);
86 imgTopLeft.set(position.x - width, position.y - height, 0);
87 imgBottomRight.set(position.x + width, position.y + height, 0);
88 camera.convertToCameraSpace(0, 0, 0, topLeft);
89 camera.convertToCameraSpace(camera.mWidth, camera.mHeight, 0, bottomRight);
90 float leftExtent = topLeft.x - imgTopLeft.x;
91 float rightExtent = bottomRight.x - imgBottomRight.x;
92 camera.mConvergenceSpeed = 2.0f;
96 camera.moveBy(-leftExtent, 0, 0);
98 if (rightExtent > 0) {
100 camera.moveBy(-rightExtent, 0, 0);
102 float topExtent = topLeft.y - imgTopLeft.y;
103 float bottomExtent = bottomRight.y - imgBottomRight.y;
105 camera.moveBy(0, -topExtent, 0);
107 if (bottomExtent > 0) {
108 camera.moveBy(0, -bottomExtent, 0);
112 pool.delete(position);
113 pool.delete(deltaAnchorPosition);
114 pool.delete(topLeft);
115 pool.delete(bottomRight);
116 pool.delete(imgTopLeft);
117 pool.delete(imgBottomRight);
123 public void computeVisibleRange(MediaFeed feed, LayoutInterface layout, Vector3f deltaAnchorPositionIn,
124 IndexRange outVisibleRange, IndexRange outBufferedVisibleRange, IndexRange outCompleteRange, int state) {
125 GridCamera camera = mCamera;
126 Pool<Vector3f> pool = sPool;
127 float offset = (camera.mLookAtX * camera.mScale);
128 int itemWidth = camera.mItemWidth;
129 float maxIncrement = camera.mWidth * 0.5f + itemWidth;
130 float left = -maxIncrement + offset;
131 float right = left + 2.0f * maxIncrement;
132 if (state == GridLayer.STATE_MEDIA_SETS || state == GridLayer.STATE_TIMELINE) {
133 right += (itemWidth * 0.5f);
135 float top = -maxIncrement;
136 float bottom = camera.mHeight + maxIncrement;
137 // the hint to compute the visible display items
140 numSlots = feed.getNumSlots();
142 synchronized (outCompleteRange) {
143 outCompleteRange.set(0, numSlots - 1);
146 Vector3f position = pool.create();
147 Vector3f deltaAnchorPosition = pool.create();
149 int firstVisibleSlotIndex = 0;
150 int lastVisibleSlotIndex = numSlots - 1;
151 int leftEdge = firstVisibleSlotIndex;
152 int rightEdge = lastVisibleSlotIndex;
153 int index = (leftEdge + rightEdge) / 2;
154 lastVisibleSlotIndex = firstVisibleSlotIndex;
155 deltaAnchorPosition.set(deltaAnchorPositionIn);
156 while (index != leftEdge) {
157 GridCameraManager.getSlotPositionForSlotIndex(index, camera, layout, deltaAnchorPosition, position);
158 if (FloatUtils.boundsContainsPoint(left, right, top, bottom, position.x, position.y)) {
159 // this index is visible
160 firstVisibleSlotIndex = index;
161 lastVisibleSlotIndex = index;
164 if (position.x > left) {
169 index = (leftEdge + rightEdge) / 2;
172 // CR: comments would make me a happy panda.
173 while (firstVisibleSlotIndex >= 0 && firstVisibleSlotIndex < numSlots) {
174 GridCameraManager.getSlotPositionForSlotIndex(firstVisibleSlotIndex, camera, layout, deltaAnchorPosition, position);
175 // CR: !fubar instead of fubar == false.
176 if (FloatUtils.boundsContainsPoint(left, right, top, bottom, position.x, position.y) == false) {
177 ++firstVisibleSlotIndex;
180 --firstVisibleSlotIndex;
183 while (lastVisibleSlotIndex >= 0 && lastVisibleSlotIndex < numSlots) {
184 GridCameraManager.getSlotPositionForSlotIndex(lastVisibleSlotIndex, camera, layout, deltaAnchorPosition, position);
185 if (FloatUtils.boundsContainsPoint(left, right, top, bottom, position.x, position.y) == false) {
186 --lastVisibleSlotIndex;
189 ++lastVisibleSlotIndex;
192 if (firstVisibleSlotIndex < 0)
193 firstVisibleSlotIndex = 0;
194 if (lastVisibleSlotIndex >= numSlots)
195 lastVisibleSlotIndex = numSlots - 1;
196 synchronized (outVisibleRange) {
197 outVisibleRange.set(firstVisibleSlotIndex, lastVisibleSlotIndex);
200 feed.setVisibleRange(firstVisibleSlotIndex, lastVisibleSlotIndex);
202 final int buffer = 24;
203 firstVisibleSlotIndex = ((firstVisibleSlotIndex - buffer) / buffer) * buffer;
204 lastVisibleSlotIndex += buffer;
205 lastVisibleSlotIndex = (lastVisibleSlotIndex / buffer) * buffer;
206 if (firstVisibleSlotIndex < 0) {
207 firstVisibleSlotIndex = 0;
209 if (lastVisibleSlotIndex >= numSlots) {
210 lastVisibleSlotIndex = numSlots - 1;
212 synchronized (outBufferedVisibleRange) {
213 outBufferedVisibleRange.set(firstVisibleSlotIndex, lastVisibleSlotIndex);
216 pool.delete(position);
217 pool.delete(deltaAnchorPosition);
221 public static final void getSlotPositionForSlotIndex(int slotIndex, GridCamera camera, LayoutInterface layout,
222 Vector3f deltaAnchorPosition, Vector3f outVal) {
223 layout.getPositionForSlotIndex(slotIndex, camera.mItemWidth, camera.mItemHeight, outVal);
224 outVal.subtract(deltaAnchorPosition);
227 public static final float getFillScreenZoomValue(GridCamera camera, Pool<Vector3f> pool, float currentFocusItemWidth,
228 float currentFocusItemHeight) {
229 final Vector3f topLeft = pool.create();
230 final Vector3f bottomRight = pool.create();
231 float potentialZoomValue = 1.0f;
233 camera.convertToCameraSpace(0, 0, 0, topLeft);
234 camera.convertToCameraSpace(camera.mWidth, camera.mHeight, 0, bottomRight);
235 float xExtent = Math.abs(topLeft.x - bottomRight.x) / currentFocusItemWidth;
236 float yExtent = Math.abs(topLeft.y - bottomRight.y) / currentFocusItemHeight;
237 potentialZoomValue = Math.max(xExtent, yExtent);
239 pool.delete(topLeft);
240 pool.delete(bottomRight);
242 return potentialZoomValue;