CarouselView.java revision b0f070636c29ad178f4e21306f301fe3d20c183b
15ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller/*
25ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller * Copyright (C) 2010 The Android Open Source Project
35ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller *
45ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller * Licensed under the Apache License, Version 2.0 (the "License");
55ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller * you may not use this file except in compliance with the License.
65ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller * You may obtain a copy of the License at
75ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller *
85ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller *      http://www.apache.org/licenses/LICENSE-2.0
95ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller *
105ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller * Unless required by applicable law or agreed to in writing, software
115ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller * distributed under the License is distributed on an "AS IS" BASIS,
125ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller * See the License for the specific language governing permissions and
145ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller * limitations under the License.
155ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller */
165ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
175ce730797a8a7278dfe19dac8a9460b25675fed0Jim Millerpackage com.android.ex.carousel;
185ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
195ce730797a8a7278dfe19dac8a9460b25675fed0Jim Millerimport com.android.ex.carousel.CarouselRS.CarouselCallback;
205ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
215ce730797a8a7278dfe19dac8a9460b25675fed0Jim Millerimport android.content.Context;
225ce730797a8a7278dfe19dac8a9460b25675fed0Jim Millerimport android.content.res.Resources;
235ce730797a8a7278dfe19dac8a9460b25675fed0Jim Millerimport android.graphics.Bitmap;
245ce730797a8a7278dfe19dac8a9460b25675fed0Jim Millerimport android.graphics.Bitmap.Config;
255ce730797a8a7278dfe19dac8a9460b25675fed0Jim Millerimport android.renderscript.FileA3D;
26b0f070636c29ad178f4e21306f301fe3d20c183bJim Millerimport android.renderscript.Float4;
275ce730797a8a7278dfe19dac8a9460b25675fed0Jim Millerimport android.renderscript.Mesh;
285ce730797a8a7278dfe19dac8a9460b25675fed0Jim Millerimport android.renderscript.RSSurfaceView;
295ce730797a8a7278dfe19dac8a9460b25675fed0Jim Millerimport android.renderscript.RenderScriptGL;
305ce730797a8a7278dfe19dac8a9460b25675fed0Jim Millerimport android.util.AttributeSet;
315ce730797a8a7278dfe19dac8a9460b25675fed0Jim Millerimport android.util.Log;
325ce730797a8a7278dfe19dac8a9460b25675fed0Jim Millerimport android.view.MotionEvent;
335ce730797a8a7278dfe19dac8a9460b25675fed0Jim Millerimport android.view.SurfaceHolder;
345ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
357cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller/**
367cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller * <p>
377cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller * This class represents the basic building block for using a 3D Carousel. The Carousel is
387cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller * basically a scene of cards and slots.  The spacing between cards is dictated by the number
397cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller * of slots and the radius. The number of visible cards dictates how far the Carousel can be moved.
407cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller * If the number of cards exceeds the number of slots, then the Carousel will continue to go
417cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller * around until the last card can be seen.
427cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller */
435ce730797a8a7278dfe19dac8a9460b25675fed0Jim Millerpublic abstract class CarouselView extends RSSurfaceView {
445ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    private static final boolean USE_DEPTH_BUFFER = true;
455ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    private final int DEFAULT_SLOT_COUNT = 10;
46c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma    private final float DEFAULT_RADIUS = 20.0f;
47c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma    private final float DEFAULT_SWAY_SENSITIVITY = 0.0f;
48c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma    private final float DEFAULT_FRICTION_COEFFICIENT = 10.0f;
49c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma    private final float DEFAULT_DRAG_FACTOR = 0.25f;
505ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    private static final String TAG = "CarouselView";
517cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller    private static final boolean DBG = false;
525ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    private CarouselRS mRenderScript;
535ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    private RenderScriptGL mRS;
545ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    private Context mContext;
555ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    private boolean mTracking;
569afba8c61f6aff94c68acbfaae1cc58bd28c13eaJim Miller
577cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller    // These shadow the state of the renderer in case the surface changes so the surface
587cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller    // can be restored to its previous state.
595ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    private Bitmap mDefaultBitmap;
605ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    private Bitmap mLoadingBitmap;
619afba8c61f6aff94c68acbfaae1cc58bd28c13eaJim Miller    private Bitmap mBackgroundBitmap;
627cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller    private Bitmap mDefaultLineBitmap = Bitmap.createBitmap(
637cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller            new int[] {0x80ffffff, 0xffffffff, 0x80ffffff}, 0, 3, 3, 1, Bitmap.Config.ARGB_4444);
645ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    private Mesh mDefaultGeometry;
655ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    private Mesh mLoadingGeometry;
665ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    private int mCardCount = 0;
675ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    private int mVisibleSlots = 0;
685ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    private float mStartAngle;
69c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma    private float mRadius = DEFAULT_RADIUS;
70c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma    private float mCardRotation = 0.0f;
71c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma    private float mSwaySensitivity = DEFAULT_SWAY_SENSITIVITY;
72c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma    private float mFrictionCoefficient = DEFAULT_FRICTION_COEFFICIENT;
73c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma    private float mDragFactor = DEFAULT_DRAG_FACTOR;
745ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    private int mSlotCount = DEFAULT_SLOT_COUNT;
75c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma    private float mEye[] = { 20.6829f, 2.77081f, 16.7314f };
76c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma    private float mAt[] = { 14.7255f, -3.40001f, -1.30184f };
77c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma    private float mUp[] = { 0.0f, 1.0f, 0.0f };
78b0f070636c29ad178f4e21306f301fe3d20c183bJim Miller    private Float4 mBackgroundColor;
795ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
805ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    public static class Info {
819afba8c61f6aff94c68acbfaae1cc58bd28c13eaJim Miller        public Info(int _resId) { resId = _resId; }
825ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        public int resId; // resource for renderscript resource (e.g. R.raw.carousel)
835ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    }
845ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
855ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    public abstract Info getRenderScriptInfo();
865ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
875ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    public CarouselView(Context context) {
885ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        this(context, null);
895ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    }
905ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
915ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    /**
925ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller     * Constructor used when this widget is created from a layout file.
935ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller     */
945ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    public CarouselView(Context context, AttributeSet attrs) {
955ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        super(context, attrs);
965ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        mContext = context;
975ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        boolean useDepthBuffer = true;
985ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        ensureRenderScript();
995ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        // TODO: add parameters to layout
1005ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    }
1015ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
1025ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    private void ensureRenderScript() {
1035ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        mRS = createRenderScript(USE_DEPTH_BUFFER);
1045ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        mRenderScript = new CarouselRS();
1055ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        mRenderScript.init(mRS, getResources(), getRenderScriptInfo().resId);
1065ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    }
1075ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
1085ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    @Override
1095ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
1105ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        super.surfaceChanged(holder, format, w, h);
1115ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        //mRS.contextSetSurface(w, h, holder.getSurface());
1125ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        mRenderScript.init(mRS, getResources(), getRenderScriptInfo().resId);
1135ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        setSlotCount(mSlotCount);
1145ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        createCards(mCardCount);
1155ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        setVisibleSlots(mVisibleSlots);
1165ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        setCallback(mCarouselCallback);
1175ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        setDefaultBitmap(mDefaultBitmap);
1185ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        setLoadingBitmap(mLoadingBitmap);
1195ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        setDefaultGeometry(mDefaultGeometry);
1205ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        setLoadingGeometry(mLoadingGeometry);
121b0f070636c29ad178f4e21306f301fe3d20c183bJim Miller        setBackgroundColor(mBackgroundColor.x, mBackgroundColor.y, mBackgroundColor.z,
122b0f070636c29ad178f4e21306f301fe3d20c183bJim Miller                mBackgroundColor.w);
1239afba8c61f6aff94c68acbfaae1cc58bd28c13eaJim Miller        setBackgroundBitmap(mBackgroundBitmap);
1247cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller        setDetailLineBitmap(mDefaultLineBitmap);
1255ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        setStartAngle(mStartAngle);
126c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma        setRadius(mRadius);
127c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma        setCardRotation(mCardRotation);
128c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma        setSwaySensitivity(mSwaySensitivity);
129c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma        setFrictionCoefficient(mFrictionCoefficient);
130c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma        setDragFactor(mDragFactor);
131c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma        setLookAt(mEye, mAt, mUp);
1325ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    }
1335ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
1345ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    /**
1355ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller     * Loads geometry from a resource id.
1365ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller     *
1375ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller     * @param resId
1385ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller     * @return the loaded mesh or null if it cannot be loaded
1395ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller     */
1405ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    public Mesh loadGeometry(int resId) {
1415ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        Resources res = mContext.getResources();
1425ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        FileA3D model = FileA3D.createFromResource(mRS, res, resId);
1435ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        FileA3D.IndexEntry entry = model.getIndexEntry(0);
1445ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        if(entry == null || entry.getClassID() != FileA3D.ClassID.MESH) {
1455ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller            return null;
1465ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        }
1475ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        return (Mesh) entry.getObject();
1485ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    }
1495ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
1505ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    /**
1515ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller     * Load A3D file from resource.  If resId == 0, will clear geometry for this item.
1525ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller     * @param n
1535ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller     * @param resId
1545ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller     */
1555ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    public void setGeometryForItem(int n, Mesh mesh) {
156c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma        if (mRenderScript != null) {
157c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma            mRenderScript.setGeometry(n, mesh);
158c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma        }
1595ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    }
1605ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
1617cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller    /**
1627cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     * Set the number of slots around the Carousel. Basically equivalent to the poles horses
1637cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     * might attach to on a real Carousel.
1647cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     *
1657cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     * @param n the number of slots
1667cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     */
1675ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    public void setSlotCount(int n) {
1685ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        mSlotCount = n;
1695ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        if (mRenderScript != null) {
1705ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller            mRenderScript.setSlotCount(n);
1715ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        }
1725ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    }
1735ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
1747cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller    /**
1757cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     * Sets the number of visible slots around the Carousel.  This is primarily used as a cheap
1767cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     * form of clipping. The Carousel will never show more than this many cards.
1777cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     * @param n the number of visible slots
1787cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     */
1795ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    public void setVisibleSlots(int n) {
1805ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        mVisibleSlots = n;
1815ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        if (mRenderScript != null) {
1825ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller            mRenderScript.setVisibleSlots(n);
1835ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        }
1845ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    }
1855ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
1867cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller    /**
1877cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     * This dictates how many cards are in the deck.  If the number of cards is greater than the
1887cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     * number of slots, then the Carousel goes around n / slot_count times.
1897cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     *
1907cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     * Can be called again to increase or decrease the number of cards.
1917cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     *
1927cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     * @param n the number of cards to create.
1937cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     */
1945ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    public void createCards(int n) {
1955ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        mCardCount = n;
1965ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        if (mRenderScript != null) {
1975ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller            mRenderScript.createCards(n);
1985ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        }
1995ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    }
2005ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
2017cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller    /**
2027cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     * This sets the texture on card n.  It should only be called in response to
2037cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     * {@link CarouselCallback#onRequestTexture(int)}.  Since there's no guarantee
2047cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     * that a given texture is still on the screen, replacing this texture should be done
2057cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     * by first setting it to null and then waiting for the next
2067cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     * {@link CarouselCallback#onRequestTexture(int)} to swap it with the new one.
2077cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     *
2087cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     * @param n the card given by {@link CarouselCallback#onRequestTexture(int)}
2097cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     * @param bitmap the bitmap image to show
2107cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     */
2115ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    public void setTextureForItem(int n, Bitmap bitmap) {
212c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma        // Also check against mRS, to handle the case where the result is being delivered by a
213c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma        // background thread but the sender no longer exists.
214c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma        if (mRenderScript != null && mRS != null) {
2157cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller            if (DBG) Log.v(TAG, "setTextureForItem(" + n + ")");
2169afba8c61f6aff94c68acbfaae1cc58bd28c13eaJim Miller            mRenderScript.setTexture(n, bitmap);
2177cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller            if (DBG) Log.v(TAG, "done");
2185ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        }
2195ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    }
2205ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
2217cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller    /**
2227cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     * This sets the detail texture that floats above card n. It should only be called in response
2237cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     * to {@link CarouselCallback#onRequestDetailTexture(int)}.  Since there's no guarantee
2247cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     * that a given texture is still on the screen, replacing this texture should be done
2257cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     * by first setting it to null and then waiting for the next
2267cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     * {@link CarouselCallback#onRequestDetailTexture(int)} to swap it with the new one.
2277cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     *
2287cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     * @param n the card to set the help text
2297cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     * @param offx an optional offset to apply to the texture, in pixel coordinates
2307cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     * @param offy an optional offset to apply to the texture, in pixel coordinates
2317cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     * @param bitmap the bitmap to show as the detail
2327cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     */
2337cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller    public void setDetailTextureForItem(int n, float offx, float offy, Bitmap bitmap) {
2347cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller        if (mRenderScript != null) {
2357cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller            if (DBG) Log.v(TAG, "setDetailTextureForItem(" + n + ")");
2367cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller            mRenderScript.setDetailTexture(n, offx, offy, bitmap);
2377cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller            if (DBG) Log.v(TAG, "done");
2387cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller        }
2397cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller    }
2407cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller
2417cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller    /**
2427cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     * Sets the bitmap to show on a card when the card draws the very first time.
2437cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     * Generally, this bitmap will only be seen during the first few frames of startup
2447cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     * or when the number of cards are changed.  It can be ignored in most cases,
2457cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     * as the cards will generally only be in the loading or loaded state.
2467cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     *
2477cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     * @param bitmap
2487cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     */
2495ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    public void setDefaultBitmap(Bitmap bitmap) {
2509afba8c61f6aff94c68acbfaae1cc58bd28c13eaJim Miller        mDefaultBitmap = bitmap;
2515ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        if (mRenderScript != null) {
2525ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller            mRenderScript.setDefaultBitmap(bitmap);
2535ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        }
2545ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    }
2555ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
2567cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller    /**
2577cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     * Sets the bitmap to show on the card while the texture is loading. It is set to this
2587cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     * value just before {@link CarouselCallback#onRequestTexture(int)} is called and changed
2597cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     * when {@link CarouselView#setTextureForItem(int, Bitmap)} is called. It is shared by all
2607cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     * cards.
2617cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     *
2627cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     * @param bitmap
2637cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     */
2645ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    public void setLoadingBitmap(Bitmap bitmap) {
2655ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        mLoadingBitmap = bitmap;
2665ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        if (mRenderScript != null) {
2675ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller            mRenderScript.setLoadingBitmap(bitmap);
2685ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        }
2695ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    }
2705ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
2717cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller    /**
272b0f070636c29ad178f4e21306f301fe3d20c183bJim Miller     * Sets background to specified color.  If a background texture is specified with
273b0f070636c29ad178f4e21306f301fe3d20c183bJim Miller     * {@link CarouselView#setBackgroundBitmap(Bitmap)}, then this call has no effect.
274b0f070636c29ad178f4e21306f301fe3d20c183bJim Miller     *
275b0f070636c29ad178f4e21306f301fe3d20c183bJim Miller     * @param red the amount of red
276b0f070636c29ad178f4e21306f301fe3d20c183bJim Miller     * @param green the amount of green
277b0f070636c29ad178f4e21306f301fe3d20c183bJim Miller     * @param blue the amount of blue
278b0f070636c29ad178f4e21306f301fe3d20c183bJim Miller     * @param alpha the amount of alpha
279b0f070636c29ad178f4e21306f301fe3d20c183bJim Miller     */
280b0f070636c29ad178f4e21306f301fe3d20c183bJim Miller    public void setBackgroundColor(float red, float green, float blue, float alpha) {
281b0f070636c29ad178f4e21306f301fe3d20c183bJim Miller        mBackgroundColor = new Float4(red, green, blue, alpha);
282b0f070636c29ad178f4e21306f301fe3d20c183bJim Miller        if (mRenderScript != null) {
283b0f070636c29ad178f4e21306f301fe3d20c183bJim Miller            mRenderScript.setBackgroundColor(mBackgroundColor);
284b0f070636c29ad178f4e21306f301fe3d20c183bJim Miller        }
285b0f070636c29ad178f4e21306f301fe3d20c183bJim Miller    }
286b0f070636c29ad178f4e21306f301fe3d20c183bJim Miller    /**
287b0f070636c29ad178f4e21306f301fe3d20c183bJim Miller     * Can be used to optionally set the background to a bitmap. When set to something other than
288b0f070636c29ad178f4e21306f301fe3d20c183bJim Miller     * null, this overrides {@link CarouselView#setBackgroundColor(Float4)}.
2897cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     *
2907cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     * @param bitmap
2917cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     */
2929afba8c61f6aff94c68acbfaae1cc58bd28c13eaJim Miller    public void setBackgroundBitmap(Bitmap bitmap) {
2939afba8c61f6aff94c68acbfaae1cc58bd28c13eaJim Miller        mBackgroundBitmap = bitmap;
2949afba8c61f6aff94c68acbfaae1cc58bd28c13eaJim Miller        if (mRenderScript != null) {
2959afba8c61f6aff94c68acbfaae1cc58bd28c13eaJim Miller            mRenderScript.setBackgroundTexture(bitmap);
2969afba8c61f6aff94c68acbfaae1cc58bd28c13eaJim Miller        }
2979afba8c61f6aff94c68acbfaae1cc58bd28c13eaJim Miller    }
2989afba8c61f6aff94c68acbfaae1cc58bd28c13eaJim Miller
2997cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller    /**
3007cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     * This texture is used to draw a line from the card alongside the texture detail. The line
3017cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     * will be as wide as the texture. It can be used to give the line glow effects as well as
3027cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     * allowing other blending effects. It is typically one dimensional, e.g. 3x1.
3037cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     *
3047cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     * @param bitmap
3057cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     */
3067cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller    public void setDetailLineBitmap(Bitmap bitmap) {
3077cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller        mDefaultLineBitmap = bitmap;
3087cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller        if (mRenderScript != null) {
3097cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller            mRenderScript.setDetailLineTexture(bitmap);
3107cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller        }
3117cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller    }
3127cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller
3137cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller    /**
3147cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     * This geometry will be shown when no geometry has been loaded for a given slot. If not set,
3157cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     * a quad will be drawn in its place. It is shared for all cards.
3167cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     *
3177cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     * @param mesh
3187cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     */
3195ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    public void setDefaultGeometry(Mesh mesh) {
3205ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        mDefaultGeometry = mesh;
3215ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        if (mRenderScript != null) {
3225ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller            mRenderScript.setDefaultGeometry(mesh);
3235ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        }
3245ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    }
3255ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
3267cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller    /**
3277cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     * This is an intermediate version of the object to show while geometry is loading. If not set,
3287cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     * a quad will be drawn in its place.  It is shared for all cards.
3297cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     *
3307cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     * @param mesh
3317cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     */
3325ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    public void setLoadingGeometry(Mesh mesh) {
3335ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        mLoadingGeometry = mesh;
3345ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        if (mRenderScript != null) {
3355ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller            mRenderScript.setLoadingGeometry(mesh);
3365ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        }
3375ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    }
3385ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
3397cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller    /**
3407cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     * Sets the callback for receiving events from RenderScript.
3417cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     *
3427cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     * @param callback
3437cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     */
3445ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    public void setCallback(CarouselCallback callback)
3455ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    {
3465ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        mCarouselCallback = callback;
3475ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        if (mRenderScript != null) {
3485ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller            mRenderScript.setCallback(callback);
3495ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        }
3505ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    }
3515ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
3527cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller    /**
3537cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     * Sets the startAngle for the Carousel. The start angle is the first position of the first
3547cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     * slot draw.  Cards will be drawn from this angle in a counter-clockwise manner around the
3557cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     * Carousel.
3567cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     *
3577cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     * @param angle the angle, in radians.
3587cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller     */
3595ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    public void setStartAngle(float angle)
3605ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    {
3615ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        mStartAngle = angle;
3625ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        if (mRenderScript != null) {
3635ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller            mRenderScript.setStartAngle(angle);
3645ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        }
3655ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    }
366c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma
367c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma    public void setRadius(float radius) {
368c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma        mRadius = radius;
369c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma        if (mRenderScript != null) {
370c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma            mRenderScript.setRadius(radius);
371c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma        }
372c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma    }
373c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma
374c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma    public void setCardRotation(float cardRotation) {
375c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma        mCardRotation = cardRotation;
376c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma        if (mRenderScript != null) {
377c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma            mRenderScript.setCardRotation(cardRotation);
378c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma        }
379c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma    }
380c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma
381c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma    public void setSwaySensitivity(float swaySensitivity) {
382c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma        mSwaySensitivity = swaySensitivity;
383c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma        if (mRenderScript != null) {
384c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma            mRenderScript.setSwaySensitivity(swaySensitivity);
385c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma        }
386c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma    }
387c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma
388c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma    public void setFrictionCoefficient(float frictionCoefficient) {
389c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma        mFrictionCoefficient = frictionCoefficient;
390c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma        if (mRenderScript != null) {
391c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma            mRenderScript.setFrictionCoefficient(frictionCoefficient);
392c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma        }
393c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma    }
394c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma
395c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma    public void setDragFactor(float dragFactor) {
396c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma        mDragFactor = dragFactor;
397c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma        if (mRenderScript != null) {
398c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma            mRenderScript.setDragFactor(dragFactor);
399c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma        }
400c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma    }
401c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma
402c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma    public void setLookAt(float[] eye, float[] at, float[] up) {
403c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma        mEye = eye;
404c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma        mAt = at;
405c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma        mUp = up;
406c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma        if (mRenderScript != null) {
407c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma            mRenderScript.setLookAt(eye, at, up);
408c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma        }
409c0bb8af58ae15674178f2db240283719918c6f28Jim Shuma    }
4105ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
411198a060d650bc849ef0f25b597888fac9546803bJack Palevich    public void requestFirstCardPosition() {
412198a060d650bc849ef0f25b597888fac9546803bJack Palevich        if (mRenderScript != null) {
413198a060d650bc849ef0f25b597888fac9546803bJack Palevich            mRenderScript.requestFirstCardPosition();
414198a060d650bc849ef0f25b597888fac9546803bJack Palevich        }
415198a060d650bc849ef0f25b597888fac9546803bJack Palevich    }
416198a060d650bc849ef0f25b597888fac9546803bJack Palevich
4175ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    @Override
4185ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    protected void onDetachedFromWindow() {
4195ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        super.onDetachedFromWindow();
4205ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        if(mRS != null) {
4215ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller            mRS = null;
4225ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller            destroyRenderScript();
4235ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        }
4245ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    }
4255ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
4265ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    @Override
4275ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    protected void onAttachedToWindow() {
4285ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        super.onAttachedToWindow();
4295ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        ensureRenderScript();
4305ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    }
4315ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
4325ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    @Override
4335ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    public boolean onTouchEvent(MotionEvent event) {
4345ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        final int action = event.getAction();
4355ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        final float x = event.getX();
4365ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        final float y = event.getY();
4375ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
4385ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        if (mRenderScript == null) {
4395ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller            return true;
4405ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        }
4415ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
4425ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        switch (action) {
4435ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller            case MotionEvent.ACTION_DOWN:
4445ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller                mTracking = true;
4455ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller                mRenderScript.doStart(x, y);
4465ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller                break;
4475ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
4485ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller            case MotionEvent.ACTION_MOVE:
4495ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller                if (mTracking) {
4505ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller                    mRenderScript.doMotion(x, y);
4515ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller                }
4525ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller                break;
4535ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
4545ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller            case MotionEvent.ACTION_UP:
4555ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller                mRenderScript.doStop(x, y);
4565ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller                mTracking = false;
4575ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller                break;
4585ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        }
4595ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
4605ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        return true;
4615ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    }
4625ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
4635ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    private final CarouselCallback DEBUG_CALLBACK = new CarouselCallback() {
464198a060d650bc849ef0f25b597888fac9546803bJack Palevich        @Override
4655ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        public void onAnimationStarted() {
4667cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller            if (DBG) Log.v(TAG, "onAnimationStarted()");
4675ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        }
4685ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
469198a060d650bc849ef0f25b597888fac9546803bJack Palevich        @Override
4705ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        public void onAnimationFinished() {
4717cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller            if (DBG) Log.v(TAG, "onAnimationFinished()");
4725ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        }
4735ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
474198a060d650bc849ef0f25b597888fac9546803bJack Palevich        @Override
4755ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        public void onCardSelected(int n) {
4767cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller            if (DBG) Log.v(TAG, "onCardSelected(" + n + ")");
4775ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        }
4785ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
479198a060d650bc849ef0f25b597888fac9546803bJack Palevich        @Override
4805ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        public void onRequestGeometry(int n) {
4817cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller            if (DBG) Log.v(TAG, "onRequestGeometry(" + n + ")");
4825ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        }
4835ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
484198a060d650bc849ef0f25b597888fac9546803bJack Palevich        @Override
4855ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        public void onInvalidateGeometry(int n) {
4867cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller            if (DBG) Log.v(TAG, "onInvalidateGeometry(" + n + ")");
4875ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        }
4885ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
489198a060d650bc849ef0f25b597888fac9546803bJack Palevich        @Override
4907cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller        public void onRequestTexture(int n) {
4917cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller            if (DBG) Log.v(TAG, "onRequestTexture(" + n + ")");
4925ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        }
4935ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
494198a060d650bc849ef0f25b597888fac9546803bJack Palevich        @Override
4955ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        public void onInvalidateTexture(int n) {
4967cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller            if (DBG) Log.v(TAG, "onInvalidateTexture(" + n + ")");
4977cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller        }
4987cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller
4997cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller        public void onRequestDetailTexture(int n) {
5007cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller            if (DBG) Log.v(TAG, "onRequestDetailTexture(" + n + ")");
5017cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller        }
5027cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller
5037cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller        public void onInvalidateDetailTexture(int n) {
5047cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller            if (DBG) Log.v(TAG, "onInvalidateDetailTexture(" + n + ")");
5055ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller        }
5065ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
507198a060d650bc849ef0f25b597888fac9546803bJack Palevich        @Override
508198a060d650bc849ef0f25b597888fac9546803bJack Palevich        public void onReportFirstCardPosition(int n) {
509198a060d650bc849ef0f25b597888fac9546803bJack Palevich            Log.v(TAG, "onReportFirstCardPosition(" + n + ")");
510198a060d650bc849ef0f25b597888fac9546803bJack Palevich        }
5115ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    };
5125ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller
5135ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller    private CarouselCallback mCarouselCallback = DEBUG_CALLBACK;
5147cb0068e59dde61ef0e649735199e5ba31c9c6afJim Miller
5155ce730797a8a7278dfe19dac8a9460b25675fed0Jim Miller}
516