summaryrefslogtreecommitdiffstats
path: root/src/com/android/gallery3d/ui/SlotView.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/gallery3d/ui/SlotView.java')
-rw-r--r--src/com/android/gallery3d/ui/SlotView.java788
1 files changed, 0 insertions, 788 deletions
diff --git a/src/com/android/gallery3d/ui/SlotView.java b/src/com/android/gallery3d/ui/SlotView.java
deleted file mode 100644
index bd0ffdc15..000000000
--- a/src/com/android/gallery3d/ui/SlotView.java
+++ /dev/null
@@ -1,788 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.gallery3d.ui;
-
-import android.graphics.Rect;
-import android.os.Handler;
-import android.view.GestureDetector;
-import android.view.MotionEvent;
-import android.view.animation.DecelerateInterpolator;
-
-import com.android.gallery3d.anim.Animation;
-import com.android.gallery3d.app.AbstractGalleryActivity;
-import com.android.gallery3d.common.Utils;
-import com.android.gallery3d.glrenderer.GLCanvas;
-
-public class SlotView extends GLView {
- @SuppressWarnings("unused")
- private static final String TAG = "SlotView";
-
- private static final boolean WIDE = true;
- private static final int INDEX_NONE = -1;
-
- public static final int RENDER_MORE_PASS = 1;
- public static final int RENDER_MORE_FRAME = 2;
-
- public interface Listener {
- public void onDown(int index);
- public void onUp(boolean followedByLongPress);
- public void onSingleTapUp(int index);
- public void onLongTap(int index);
- public void onScrollPositionChanged(int position, int total);
- }
-
- public static class SimpleListener implements Listener {
- @Override public void onDown(int index) {}
- @Override public void onUp(boolean followedByLongPress) {}
- @Override public void onSingleTapUp(int index) {}
- @Override public void onLongTap(int index) {}
- @Override public void onScrollPositionChanged(int position, int total) {}
- }
-
- public static interface SlotRenderer {
- public void prepareDrawing();
- public void onVisibleRangeChanged(int visibleStart, int visibleEnd);
- public void onSlotSizeChanged(int width, int height);
- public int renderSlot(GLCanvas canvas, int index, int pass, int width, int height);
- }
-
- private final GestureDetector mGestureDetector;
- private final ScrollerHelper mScroller;
- private final Paper mPaper = new Paper();
-
- private Listener mListener;
- private UserInteractionListener mUIListener;
-
- private boolean mMoreAnimation = false;
- private SlotAnimation mAnimation = null;
- private final Layout mLayout = new Layout();
- private int mStartIndex = INDEX_NONE;
-
- // whether the down action happened while the view is scrolling.
- private boolean mDownInScrolling;
- private int mOverscrollEffect = OVERSCROLL_3D;
- private final Handler mHandler;
-
- private SlotRenderer mRenderer;
-
- private int[] mRequestRenderSlots = new int[16];
-
- public static final int OVERSCROLL_3D = 0;
- public static final int OVERSCROLL_SYSTEM = 1;
- public static final int OVERSCROLL_NONE = 2;
-
- // to prevent allocating memory
- private final Rect mTempRect = new Rect();
-
- public SlotView(AbstractGalleryActivity activity, Spec spec) {
- mGestureDetector = new GestureDetector(activity, new MyGestureListener());
- mScroller = new ScrollerHelper(activity);
- mHandler = new SynchronizedHandler(activity.getGLRoot());
- setSlotSpec(spec);
- }
-
- public void setSlotRenderer(SlotRenderer slotDrawer) {
- mRenderer = slotDrawer;
- if (mRenderer != null) {
- mRenderer.onSlotSizeChanged(mLayout.mSlotWidth, mLayout.mSlotHeight);
- mRenderer.onVisibleRangeChanged(getVisibleStart(), getVisibleEnd());
- }
- }
-
- public void setCenterIndex(int index) {
- int slotCount = mLayout.mSlotCount;
- if (index < 0 || index >= slotCount) {
- return;
- }
- Rect rect = mLayout.getSlotRect(index, mTempRect);
- int position = WIDE
- ? (rect.left + rect.right - getWidth()) / 2
- : (rect.top + rect.bottom - getHeight()) / 2;
- setScrollPosition(position);
- }
-
- public void makeSlotVisible(int index) {
- Rect rect = mLayout.getSlotRect(index, mTempRect);
- int visibleBegin = WIDE ? mScrollX : mScrollY;
- int visibleLength = WIDE ? getWidth() : getHeight();
- int visibleEnd = visibleBegin + visibleLength;
- int slotBegin = WIDE ? rect.left : rect.top;
- int slotEnd = WIDE ? rect.right : rect.bottom;
-
- int position = visibleBegin;
- if (visibleLength < slotEnd - slotBegin) {
- position = visibleBegin;
- } else if (slotBegin < visibleBegin) {
- position = slotBegin;
- } else if (slotEnd > visibleEnd) {
- position = slotEnd - visibleLength;
- }
-
- setScrollPosition(position);
- }
-
- public void setScrollPosition(int position) {
- position = Utils.clamp(position, 0, mLayout.getScrollLimit());
- mScroller.setPosition(position);
- updateScrollPosition(position, false);
- }
-
- public void setSlotSpec(Spec spec) {
- mLayout.setSlotSpec(spec);
- }
-
- @Override
- public void addComponent(GLView view) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- protected void onLayout(boolean changeSize, int l, int t, int r, int b) {
- if (!changeSize) return;
-
- // Make sure we are still at a resonable scroll position after the size
- // is changed (like orientation change). We choose to keep the center
- // visible slot still visible. This is arbitrary but reasonable.
- int visibleIndex =
- (mLayout.getVisibleStart() + mLayout.getVisibleEnd()) / 2;
- mLayout.setSize(r - l, b - t);
- makeSlotVisible(visibleIndex);
- if (mOverscrollEffect == OVERSCROLL_3D) {
- mPaper.setSize(r - l, b - t);
- }
- }
-
- public void startScatteringAnimation(RelativePosition position) {
- mAnimation = new ScatteringAnimation(position);
- mAnimation.start();
- if (mLayout.mSlotCount != 0) invalidate();
- }
-
- public void startRisingAnimation() {
- mAnimation = new RisingAnimation();
- mAnimation.start();
- if (mLayout.mSlotCount != 0) invalidate();
- }
-
- private void updateScrollPosition(int position, boolean force) {
- if (!force && (WIDE ? position == mScrollX : position == mScrollY)) return;
- if (WIDE) {
- mScrollX = position;
- } else {
- mScrollY = position;
- }
- mLayout.setScrollPosition(position);
- onScrollPositionChanged(position);
- }
-
- protected void onScrollPositionChanged(int newPosition) {
- int limit = mLayout.getScrollLimit();
- mListener.onScrollPositionChanged(newPosition, limit);
- }
-
- public Rect getSlotRect(int slotIndex) {
- return mLayout.getSlotRect(slotIndex, new Rect());
- }
-
- @Override
- protected boolean onTouch(MotionEvent event) {
- if (mUIListener != null) mUIListener.onUserInteraction();
- mGestureDetector.onTouchEvent(event);
- switch (event.getAction()) {
- case MotionEvent.ACTION_DOWN:
- mDownInScrolling = !mScroller.isFinished();
- mScroller.forceFinished();
- break;
- case MotionEvent.ACTION_UP:
- mPaper.onRelease();
- invalidate();
- break;
- }
- return true;
- }
-
- public void setListener(Listener listener) {
- mListener = listener;
- }
-
- public void setUserInteractionListener(UserInteractionListener listener) {
- mUIListener = listener;
- }
-
- public void setOverscrollEffect(int kind) {
- mOverscrollEffect = kind;
- mScroller.setOverfling(kind == OVERSCROLL_SYSTEM);
- }
-
- private static int[] expandIntArray(int array[], int capacity) {
- while (array.length < capacity) {
- array = new int[array.length * 2];
- }
- return array;
- }
-
- @Override
- protected void render(GLCanvas canvas) {
- super.render(canvas);
-
- if (mRenderer == null) return;
- mRenderer.prepareDrawing();
-
- long animTime = AnimationTime.get();
- boolean more = mScroller.advanceAnimation(animTime);
- more |= mLayout.advanceAnimation(animTime);
- int oldX = mScrollX;
- updateScrollPosition(mScroller.getPosition(), false);
-
- boolean paperActive = false;
- if (mOverscrollEffect == OVERSCROLL_3D) {
- // Check if an edge is reached and notify mPaper if so.
- int newX = mScrollX;
- int limit = mLayout.getScrollLimit();
- if (oldX > 0 && newX == 0 || oldX < limit && newX == limit) {
- float v = mScroller.getCurrVelocity();
- if (newX == limit) v = -v;
-
- // I don't know why, but getCurrVelocity() can return NaN.
- if (!Float.isNaN(v)) {
- mPaper.edgeReached(v);
- }
- }
- paperActive = mPaper.advanceAnimation();
- }
-
- more |= paperActive;
-
- if (mAnimation != null) {
- more |= mAnimation.calculate(animTime);
- }
-
- canvas.translate(-mScrollX, -mScrollY);
-
- int requestCount = 0;
- int requestedSlot[] = expandIntArray(mRequestRenderSlots,
- mLayout.mVisibleEnd - mLayout.mVisibleStart);
-
- for (int i = mLayout.mVisibleEnd - 1; i >= mLayout.mVisibleStart; --i) {
- int r = renderItem(canvas, i, 0, paperActive);
- if ((r & RENDER_MORE_FRAME) != 0) more = true;
- if ((r & RENDER_MORE_PASS) != 0) requestedSlot[requestCount++] = i;
- }
-
- for (int pass = 1; requestCount != 0; ++pass) {
- int newCount = 0;
- for (int i = 0; i < requestCount; ++i) {
- int r = renderItem(canvas,
- requestedSlot[i], pass, paperActive);
- if ((r & RENDER_MORE_FRAME) != 0) more = true;
- if ((r & RENDER_MORE_PASS) != 0) requestedSlot[newCount++] = i;
- }
- requestCount = newCount;
- }
-
- canvas.translate(mScrollX, mScrollY);
-
- if (more) invalidate();
-
- final UserInteractionListener listener = mUIListener;
- if (mMoreAnimation && !more && listener != null) {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- listener.onUserInteractionEnd();
- }
- });
- }
- mMoreAnimation = more;
- }
-
- private int renderItem(
- GLCanvas canvas, int index, int pass, boolean paperActive) {
- canvas.save(GLCanvas.SAVE_FLAG_ALPHA | GLCanvas.SAVE_FLAG_MATRIX);
- Rect rect = mLayout.getSlotRect(index, mTempRect);
- if (paperActive) {
- canvas.multiplyMatrix(mPaper.getTransform(rect, mScrollX), 0);
- } else {
- canvas.translate(rect.left, rect.top, 0);
- }
- if (mAnimation != null && mAnimation.isActive()) {
- mAnimation.apply(canvas, index, rect);
- }
- int result = mRenderer.renderSlot(
- canvas, index, pass, rect.right - rect.left, rect.bottom - rect.top);
- canvas.restore();
- return result;
- }
-
- public static abstract class SlotAnimation extends Animation {
- protected float mProgress = 0;
-
- public SlotAnimation() {
- setInterpolator(new DecelerateInterpolator(4));
- setDuration(1500);
- }
-
- @Override
- protected void onCalculate(float progress) {
- mProgress = progress;
- }
-
- abstract public void apply(GLCanvas canvas, int slotIndex, Rect target);
- }
-
- public static class RisingAnimation extends SlotAnimation {
- private static final int RISING_DISTANCE = 128;
-
- @Override
- public void apply(GLCanvas canvas, int slotIndex, Rect target) {
- canvas.translate(0, 0, RISING_DISTANCE * (1 - mProgress));
- }
- }
-
- public static class ScatteringAnimation extends SlotAnimation {
- private int PHOTO_DISTANCE = 1000;
- private RelativePosition mCenter;
-
- public ScatteringAnimation(RelativePosition center) {
- mCenter = center;
- }
-
- @Override
- public void apply(GLCanvas canvas, int slotIndex, Rect target) {
- canvas.translate(
- (mCenter.getX() - target.centerX()) * (1 - mProgress),
- (mCenter.getY() - target.centerY()) * (1 - mProgress),
- slotIndex * PHOTO_DISTANCE * (1 - mProgress));
- canvas.setAlpha(mProgress);
- }
- }
-
- // This Spec class is used to specify the size of each slot in the SlotView.
- // There are two ways to do it:
- //
- // (1) Specify slotWidth and slotHeight: they specify the width and height
- // of each slot. The number of rows and the gap between slots will be
- // determined automatically.
- // (2) Specify rowsLand, rowsPort, and slotGap: they specify the number
- // of rows in landscape/portrait mode and the gap between slots. The
- // width and height of each slot is determined automatically.
- //
- // The initial value of -1 means they are not specified.
- public static class Spec {
- public int slotWidth = -1;
- public int slotHeight = -1;
- public int slotHeightAdditional = 0;
-
- public int rowsLand = -1;
- public int rowsPort = -1;
- public int slotGap = -1;
- }
-
- public class Layout {
-
- private int mVisibleStart;
- private int mVisibleEnd;
-
- private int mSlotCount;
- private int mSlotWidth;
- private int mSlotHeight;
- private int mSlotGap;
-
- private Spec mSpec;
-
- private int mWidth;
- private int mHeight;
-
- private int mUnitCount;
- private int mContentLength;
- private int mScrollPosition;
-
- private IntegerAnimation mVerticalPadding = new IntegerAnimation();
- private IntegerAnimation mHorizontalPadding = new IntegerAnimation();
-
- public void setSlotSpec(Spec spec) {
- mSpec = spec;
- }
-
- public boolean setSlotCount(int slotCount) {
- if (slotCount == mSlotCount) return false;
- if (mSlotCount != 0) {
- mHorizontalPadding.setEnabled(true);
- mVerticalPadding.setEnabled(true);
- }
- mSlotCount = slotCount;
- int hPadding = mHorizontalPadding.getTarget();
- int vPadding = mVerticalPadding.getTarget();
- initLayoutParameters();
- return vPadding != mVerticalPadding.getTarget()
- || hPadding != mHorizontalPadding.getTarget();
- }
-
- public Rect getSlotRect(int index, Rect rect) {
- int col, row;
- if (WIDE) {
- col = index / mUnitCount;
- row = index - col * mUnitCount;
- } else {
- row = index / mUnitCount;
- col = index - row * mUnitCount;
- }
-
- int x = mHorizontalPadding.get() + col * (mSlotWidth + mSlotGap);
- int y = mVerticalPadding.get() + row * (mSlotHeight + mSlotGap);
- rect.set(x, y, x + mSlotWidth, y + mSlotHeight);
- return rect;
- }
-
- public int getSlotWidth() {
- return mSlotWidth;
- }
-
- public int getSlotHeight() {
- return mSlotHeight;
- }
-
- // Calculate
- // (1) mUnitCount: the number of slots we can fit into one column (or row).
- // (2) mContentLength: the width (or height) we need to display all the
- // columns (rows).
- // (3) padding[]: the vertical and horizontal padding we need in order
- // to put the slots towards to the center of the display.
- //
- // The "major" direction is the direction the user can scroll. The other
- // direction is the "minor" direction.
- //
- // The comments inside this method are the description when the major
- // directon is horizontal (X), and the minor directon is vertical (Y).
- private void initLayoutParameters(
- int majorLength, int minorLength, /* The view width and height */
- int majorUnitSize, int minorUnitSize, /* The slot width and height */
- int[] padding) {
- int unitCount = (minorLength + mSlotGap) / (minorUnitSize + mSlotGap);
- if (unitCount == 0) unitCount = 1;
- mUnitCount = unitCount;
-
- // We put extra padding above and below the column.
- int availableUnits = Math.min(mUnitCount, mSlotCount);
- int usedMinorLength = availableUnits * minorUnitSize +
- (availableUnits - 1) * mSlotGap;
- padding[0] = (minorLength - usedMinorLength) / 2;
-
- // Then calculate how many columns we need for all slots.
- int count = ((mSlotCount + mUnitCount - 1) / mUnitCount);
- mContentLength = count * majorUnitSize + (count - 1) * mSlotGap;
-
- // If the content length is less then the screen width, put
- // extra padding in left and right.
- padding[1] = Math.max(0, (majorLength - mContentLength) / 2);
- }
-
- private void initLayoutParameters() {
- // Initialize mSlotWidth and mSlotHeight from mSpec
- if (mSpec.slotWidth != -1) {
- mSlotGap = 0;
- mSlotWidth = mSpec.slotWidth;
- mSlotHeight = mSpec.slotHeight;
- } else {
- int rows = (mWidth > mHeight) ? mSpec.rowsLand : mSpec.rowsPort;
- mSlotGap = mSpec.slotGap;
- mSlotHeight = Math.max(1, (mHeight - (rows - 1) * mSlotGap) / rows);
- mSlotWidth = mSlotHeight - mSpec.slotHeightAdditional;
- }
-
- if (mRenderer != null) {
- mRenderer.onSlotSizeChanged(mSlotWidth, mSlotHeight);
- }
-
- int[] padding = new int[2];
- if (WIDE) {
- initLayoutParameters(mWidth, mHeight, mSlotWidth, mSlotHeight, padding);
- mVerticalPadding.startAnimateTo(padding[0]);
- mHorizontalPadding.startAnimateTo(padding[1]);
- } else {
- initLayoutParameters(mHeight, mWidth, mSlotHeight, mSlotWidth, padding);
- mVerticalPadding.startAnimateTo(padding[1]);
- mHorizontalPadding.startAnimateTo(padding[0]);
- }
- updateVisibleSlotRange();
- }
-
- public void setSize(int width, int height) {
- mWidth = width;
- mHeight = height;
- initLayoutParameters();
- }
-
- private void updateVisibleSlotRange() {
- int position = mScrollPosition;
-
- if (WIDE) {
- int startCol = position / (mSlotWidth + mSlotGap);
- int start = Math.max(0, mUnitCount * startCol);
- int endCol = (position + mWidth + mSlotWidth + mSlotGap - 1) /
- (mSlotWidth + mSlotGap);
- int end = Math.min(mSlotCount, mUnitCount * endCol);
- setVisibleRange(start, end);
- } else {
- int startRow = position / (mSlotHeight + mSlotGap);
- int start = Math.max(0, mUnitCount * startRow);
- int endRow = (position + mHeight + mSlotHeight + mSlotGap - 1) /
- (mSlotHeight + mSlotGap);
- int end = Math.min(mSlotCount, mUnitCount * endRow);
- setVisibleRange(start, end);
- }
- }
-
- public void setScrollPosition(int position) {
- if (mScrollPosition == position) return;
- mScrollPosition = position;
- updateVisibleSlotRange();
- }
-
- private void setVisibleRange(int start, int end) {
- if (start == mVisibleStart && end == mVisibleEnd) return;
- if (start < end) {
- mVisibleStart = start;
- mVisibleEnd = end;
- } else {
- mVisibleStart = mVisibleEnd = 0;
- }
- if (mRenderer != null) {
- mRenderer.onVisibleRangeChanged(mVisibleStart, mVisibleEnd);
- }
- }
-
- public int getVisibleStart() {
- return mVisibleStart;
- }
-
- public int getVisibleEnd() {
- return mVisibleEnd;
- }
-
- public int getSlotIndexByPosition(float x, float y) {
- int absoluteX = Math.round(x) + (WIDE ? mScrollPosition : 0);
- int absoluteY = Math.round(y) + (WIDE ? 0 : mScrollPosition);
-
- absoluteX -= mHorizontalPadding.get();
- absoluteY -= mVerticalPadding.get();
-
- if (absoluteX < 0 || absoluteY < 0) {
- return INDEX_NONE;
- }
-
- int columnIdx = absoluteX / (mSlotWidth + mSlotGap);
- int rowIdx = absoluteY / (mSlotHeight + mSlotGap);
-
- if (!WIDE && columnIdx >= mUnitCount) {
- return INDEX_NONE;
- }
-
- if (WIDE && rowIdx >= mUnitCount) {
- return INDEX_NONE;
- }
-
- if (absoluteX % (mSlotWidth + mSlotGap) >= mSlotWidth) {
- return INDEX_NONE;
- }
-
- if (absoluteY % (mSlotHeight + mSlotGap) >= mSlotHeight) {
- return INDEX_NONE;
- }
-
- int index = WIDE
- ? (columnIdx * mUnitCount + rowIdx)
- : (rowIdx * mUnitCount + columnIdx);
-
- return index >= mSlotCount ? INDEX_NONE : index;
- }
-
- public int getScrollLimit() {
- int limit = WIDE ? mContentLength - mWidth : mContentLength - mHeight;
- return limit <= 0 ? 0 : limit;
- }
-
- public boolean advanceAnimation(long animTime) {
- // use '|' to make sure both sides will be executed
- return mVerticalPadding.calculate(animTime) | mHorizontalPadding.calculate(animTime);
- }
- }
-
- private class MyGestureListener implements GestureDetector.OnGestureListener {
- private boolean isDown;
-
- // We call the listener's onDown() when our onShowPress() is called and
- // call the listener's onUp() when we receive any further event.
- @Override
- public void onShowPress(MotionEvent e) {
- GLRoot root = getGLRoot();
- root.lockRenderThread();
- try {
- if (isDown) return;
- int index = mLayout.getSlotIndexByPosition(e.getX(), e.getY());
- if (index != INDEX_NONE) {
- isDown = true;
- mListener.onDown(index);
- }
- } finally {
- root.unlockRenderThread();
- }
- }
-
- private void cancelDown(boolean byLongPress) {
- if (!isDown) return;
- isDown = false;
- mListener.onUp(byLongPress);
- }
-
- @Override
- public boolean onDown(MotionEvent e) {
- return false;
- }
-
- @Override
- public boolean onFling(MotionEvent e1,
- MotionEvent e2, float velocityX, float velocityY) {
- cancelDown(false);
- int scrollLimit = mLayout.getScrollLimit();
- if (scrollLimit == 0) return false;
- float velocity = WIDE ? velocityX : velocityY;
- mScroller.fling((int) -velocity, 0, scrollLimit);
- if (mUIListener != null) mUIListener.onUserInteractionBegin();
- invalidate();
- return true;
- }
-
- @Override
- public boolean onScroll(MotionEvent e1,
- MotionEvent e2, float distanceX, float distanceY) {
- cancelDown(false);
- float distance = WIDE ? distanceX : distanceY;
- int overDistance = mScroller.startScroll(
- Math.round(distance), 0, mLayout.getScrollLimit());
- if (mOverscrollEffect == OVERSCROLL_3D && overDistance != 0) {
- mPaper.overScroll(overDistance);
- }
- invalidate();
- return true;
- }
-
- @Override
- public boolean onSingleTapUp(MotionEvent e) {
- cancelDown(false);
- if (mDownInScrolling) return true;
- int index = mLayout.getSlotIndexByPosition(e.getX(), e.getY());
- if (index != INDEX_NONE) mListener.onSingleTapUp(index);
- return true;
- }
-
- @Override
- public void onLongPress(MotionEvent e) {
- cancelDown(true);
- if (mDownInScrolling) return;
- lockRendering();
- try {
- int index = mLayout.getSlotIndexByPosition(e.getX(), e.getY());
- if (index != INDEX_NONE) mListener.onLongTap(index);
- } finally {
- unlockRendering();
- }
- }
- }
-
- public void setStartIndex(int index) {
- mStartIndex = index;
- }
-
- // Return true if the layout parameters have been changed
- public boolean setSlotCount(int slotCount) {
- boolean changed = mLayout.setSlotCount(slotCount);
-
- // mStartIndex is applied the first time setSlotCount is called.
- if (mStartIndex != INDEX_NONE) {
- setCenterIndex(mStartIndex);
- mStartIndex = INDEX_NONE;
- }
- // Reset the scroll position to avoid scrolling over the updated limit.
- setScrollPosition(WIDE ? mScrollX : mScrollY);
- return changed;
- }
-
- public int getVisibleStart() {
- return mLayout.getVisibleStart();
- }
-
- public int getVisibleEnd() {
- return mLayout.getVisibleEnd();
- }
-
- public int getScrollX() {
- return mScrollX;
- }
-
- public int getScrollY() {
- return mScrollY;
- }
-
- public Rect getSlotRect(int slotIndex, GLView rootPane) {
- // Get slot rectangle relative to this root pane.
- Rect offset = new Rect();
- rootPane.getBoundsOf(this, offset);
- Rect r = getSlotRect(slotIndex);
- r.offset(offset.left - getScrollX(),
- offset.top - getScrollY());
- return r;
- }
-
- private static class IntegerAnimation extends Animation {
- private int mTarget;
- private int mCurrent = 0;
- private int mFrom = 0;
- private boolean mEnabled = false;
-
- public void setEnabled(boolean enabled) {
- mEnabled = enabled;
- }
-
- public void startAnimateTo(int target) {
- if (!mEnabled) {
- mTarget = mCurrent = target;
- return;
- }
- if (target == mTarget) return;
-
- mFrom = mCurrent;
- mTarget = target;
- setDuration(180);
- start();
- }
-
- public int get() {
- return mCurrent;
- }
-
- public int getTarget() {
- return mTarget;
- }
-
- @Override
- protected void onCalculate(float progress) {
- mCurrent = Math.round(mFrom + progress * (mTarget - mFrom));
- if (progress == 1f) mEnabled = false;
- }
- }
-}