1 package com.cooliris.media;
3 public final class GridCameraManager {
4 private final GridCamera mCamera;
5 private static final Pool<Vector3f> sPool;
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();
12 sPool = new Pool<Vector3f>(vectorPool);
15 public GridCameraManager(final GridCamera camera) {
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);
30 final float oneByZoom = 1.0f / zoomValue;
32 final Vector3f position = pool.create();
33 final Vector3f deltaAnchorPosition = pool.create();
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) {
42 float width = camera.mItemWidth;
43 float height = camera.mItemHeight;
49 camera.moveTo(position.x, position.y, zoomin ? camera.getDistanceToFitRect(width * oneByZoom, height
52 pool.delete(position);
53 pool.delete(deltaAnchorPosition);
62 // CR: line too long. Documentation--what are the semantics of the return
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();
81 deltaAnchorPosition.set(deltaAnchorPositionIn);
82 GridCameraManager.getSlotPositionForSlotIndex(slotIndex, camera, layout, deltaAnchorPosition, position);
83 position.x *= camera.mOneByScale;
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;
97 camera.moveBy(-leftExtent, 0, 0);
99 if (rightExtent > 0) {
101 camera.moveBy(-rightExtent, 0, 0);
103 float topExtent = topLeft.y - imgTopLeft.y;
104 float bottomExtent = bottomRight.y - imgBottomRight.y;
106 camera.moveBy(0, -topExtent, 0);
108 if (bottomExtent > 0) {
109 camera.moveBy(0, -bottomExtent, 0);
113 pool.delete(position);
114 pool.delete(deltaAnchorPosition);
115 pool.delete(topLeft);
116 pool.delete(bottomRight);
117 pool.delete(imgTopLeft);
118 pool.delete(imgBottomRight);
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);
136 float top = -maxIncrement;
137 float bottom = camera.mHeight + maxIncrement;
138 // the hint to compute the visible display items
141 numSlots = feed.getNumSlots();
143 synchronized (outCompleteRange) {
144 outCompleteRange.set(0, numSlots - 1);
147 Vector3f position = pool.create();
148 Vector3f deltaAnchorPosition = pool.create();
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;
165 if (position.x > left) {
170 index = (leftEdge + rightEdge) / 2;
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;
181 --firstVisibleSlotIndex;
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;
190 ++lastVisibleSlotIndex;
193 if (firstVisibleSlotIndex < 0)
194 firstVisibleSlotIndex = 0;
195 if (lastVisibleSlotIndex >= numSlots)
196 lastVisibleSlotIndex = numSlots - 1;
197 synchronized (outVisibleRange) {
198 outVisibleRange.set(firstVisibleSlotIndex, lastVisibleSlotIndex);
201 feed.setVisibleRange(firstVisibleSlotIndex, lastVisibleSlotIndex);
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;
210 if (lastVisibleSlotIndex >= numSlots) {
211 lastVisibleSlotIndex = numSlots - 1;
213 synchronized (outBufferedVisibleRange) {
214 outBufferedVisibleRange.set(firstVisibleSlotIndex, lastVisibleSlotIndex);
217 pool.delete(position);
218 pool.delete(deltaAnchorPosition);
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);
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;
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);
240 pool.delete(topLeft);
241 pool.delete(bottomRight);
243 return potentialZoomValue;