diff options
Diffstat (limited to 'src/com/android/gallery3d/ui/GLView.java')
-rw-r--r-- | src/com/android/gallery3d/ui/GLView.java | 465 |
1 files changed, 0 insertions, 465 deletions
diff --git a/src/com/android/gallery3d/ui/GLView.java b/src/com/android/gallery3d/ui/GLView.java deleted file mode 100644 index 83de19fe4..000000000 --- a/src/com/android/gallery3d/ui/GLView.java +++ /dev/null @@ -1,465 +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.SystemClock; -import android.view.MotionEvent; - -import com.android.gallery3d.anim.CanvasAnimation; -import com.android.gallery3d.anim.StateTransitionAnimation; -import com.android.gallery3d.common.Utils; -import com.android.gallery3d.glrenderer.GLCanvas; - -import java.util.ArrayList; - -// GLView is a UI component. It can render to a GLCanvas and accept touch -// events. A GLView may have zero or more child GLView and they form a tree -// structure. The rendering and event handling will pass through the tree -// structure. -// -// A GLView tree should be attached to a GLRoot before event dispatching and -// rendering happens. GLView asks GLRoot to re-render or re-layout the -// GLView hierarchy using requestRender() and requestLayoutContentPane(). -// -// The render() method is called in a separate thread. Before calling -// dispatchTouchEvent() and layout(), GLRoot acquires a lock to avoid the -// rendering thread running at the same time. If there are other entry points -// from main thread (like a Handler) in your GLView, you need to call -// lockRendering() if the rendering thread should not run at the same time. -// -public class GLView { - private static final String TAG = "GLView"; - - public static final int VISIBLE = 0; - public static final int INVISIBLE = 1; - - private static final int FLAG_INVISIBLE = 1; - private static final int FLAG_SET_MEASURED_SIZE = 2; - private static final int FLAG_LAYOUT_REQUESTED = 4; - - public interface OnClickListener { - void onClick(GLView v); - } - - protected final Rect mBounds = new Rect(); - protected final Rect mPaddings = new Rect(); - - private GLRoot mRoot; - protected GLView mParent; - private ArrayList<GLView> mComponents; - private GLView mMotionTarget; - - private CanvasAnimation mAnimation; - - private int mViewFlags = 0; - - protected int mMeasuredWidth = 0; - protected int mMeasuredHeight = 0; - - private int mLastWidthSpec = -1; - private int mLastHeightSpec = -1; - - protected int mScrollY = 0; - protected int mScrollX = 0; - protected int mScrollHeight = 0; - protected int mScrollWidth = 0; - - private float [] mBackgroundColor; - private StateTransitionAnimation mTransition; - - public void startAnimation(CanvasAnimation animation) { - GLRoot root = getGLRoot(); - if (root == null) throw new IllegalStateException(); - mAnimation = animation; - if (mAnimation != null) { - mAnimation.start(); - root.registerLaunchedAnimation(mAnimation); - } - invalidate(); - } - - // Sets the visiblity of this GLView (either GLView.VISIBLE or - // GLView.INVISIBLE). - public void setVisibility(int visibility) { - if (visibility == getVisibility()) return; - if (visibility == VISIBLE) { - mViewFlags &= ~FLAG_INVISIBLE; - } else { - mViewFlags |= FLAG_INVISIBLE; - } - onVisibilityChanged(visibility); - invalidate(); - } - - // Returns GLView.VISIBLE or GLView.INVISIBLE - public int getVisibility() { - return (mViewFlags & FLAG_INVISIBLE) == 0 ? VISIBLE : INVISIBLE; - } - - // This should only be called on the content pane (the topmost GLView). - public void attachToRoot(GLRoot root) { - Utils.assertTrue(mParent == null && mRoot == null); - onAttachToRoot(root); - } - - // This should only be called on the content pane (the topmost GLView). - public void detachFromRoot() { - Utils.assertTrue(mParent == null && mRoot != null); - onDetachFromRoot(); - } - - // Returns the number of children of the GLView. - public int getComponentCount() { - return mComponents == null ? 0 : mComponents.size(); - } - - // Returns the children for the given index. - public GLView getComponent(int index) { - if (mComponents == null) { - throw new ArrayIndexOutOfBoundsException(index); - } - return mComponents.get(index); - } - - // Adds a child to this GLView. - public void addComponent(GLView component) { - // Make sure the component doesn't have a parent currently. - if (component.mParent != null) throw new IllegalStateException(); - - // Build parent-child links - if (mComponents == null) { - mComponents = new ArrayList<GLView>(); - } - mComponents.add(component); - component.mParent = this; - - // If this is added after we have a root, tell the component. - if (mRoot != null) { - component.onAttachToRoot(mRoot); - } - } - - // Removes a child from this GLView. - public boolean removeComponent(GLView component) { - if (mComponents == null) return false; - if (mComponents.remove(component)) { - removeOneComponent(component); - return true; - } - return false; - } - - // Removes all children of this GLView. - public void removeAllComponents() { - for (int i = 0, n = mComponents.size(); i < n; ++i) { - removeOneComponent(mComponents.get(i)); - } - mComponents.clear(); - } - - private void removeOneComponent(GLView component) { - if (mMotionTarget == component) { - long now = SystemClock.uptimeMillis(); - MotionEvent cancelEvent = MotionEvent.obtain( - now, now, MotionEvent.ACTION_CANCEL, 0, 0, 0); - dispatchTouchEvent(cancelEvent); - cancelEvent.recycle(); - } - component.onDetachFromRoot(); - component.mParent = null; - } - - public Rect bounds() { - return mBounds; - } - - public int getWidth() { - return mBounds.right - mBounds.left; - } - - public int getHeight() { - return mBounds.bottom - mBounds.top; - } - - public GLRoot getGLRoot() { - return mRoot; - } - - // Request re-rendering of the view hierarchy. - // This is used for animation or when the contents changed. - public void invalidate() { - GLRoot root = getGLRoot(); - if (root != null) root.requestRender(); - } - - // Request re-layout of the view hierarchy. - public void requestLayout() { - mViewFlags |= FLAG_LAYOUT_REQUESTED; - mLastHeightSpec = -1; - mLastWidthSpec = -1; - if (mParent != null) { - mParent.requestLayout(); - } else { - // Is this a content pane ? - GLRoot root = getGLRoot(); - if (root != null) root.requestLayoutContentPane(); - } - } - - protected void render(GLCanvas canvas) { - boolean transitionActive = false; - if (mTransition != null && mTransition.calculate(AnimationTime.get())) { - invalidate(); - transitionActive = mTransition.isActive(); - } - renderBackground(canvas); - canvas.save(); - if (transitionActive) { - mTransition.applyContentTransform(this, canvas); - } - for (int i = 0, n = getComponentCount(); i < n; ++i) { - renderChild(canvas, getComponent(i)); - } - canvas.restore(); - if (transitionActive) { - mTransition.applyOverlay(this, canvas); - } - } - - public void setIntroAnimation(StateTransitionAnimation intro) { - mTransition = intro; - if (mTransition != null) mTransition.start(); - } - - public float [] getBackgroundColor() { - return mBackgroundColor; - } - - public void setBackgroundColor(float [] color) { - mBackgroundColor = color; - } - - protected void renderBackground(GLCanvas view) { - if (mBackgroundColor != null) { - view.clearBuffer(mBackgroundColor); - } - if (mTransition != null && mTransition.isActive()) { - mTransition.applyBackground(this, view); - return; - } - } - - protected void renderChild(GLCanvas canvas, GLView component) { - if (component.getVisibility() != GLView.VISIBLE - && component.mAnimation == null) return; - - int xoffset = component.mBounds.left - mScrollX; - int yoffset = component.mBounds.top - mScrollY; - - canvas.translate(xoffset, yoffset); - - CanvasAnimation anim = component.mAnimation; - if (anim != null) { - canvas.save(anim.getCanvasSaveFlags()); - if (anim.calculate(AnimationTime.get())) { - invalidate(); - } else { - component.mAnimation = null; - } - anim.apply(canvas); - } - component.render(canvas); - if (anim != null) canvas.restore(); - canvas.translate(-xoffset, -yoffset); - } - - protected boolean onTouch(MotionEvent event) { - return false; - } - - protected boolean dispatchTouchEvent(MotionEvent event, - int x, int y, GLView component, boolean checkBounds) { - Rect rect = component.mBounds; - int left = rect.left; - int top = rect.top; - if (!checkBounds || rect.contains(x, y)) { - event.offsetLocation(-left, -top); - if (component.dispatchTouchEvent(event)) { - event.offsetLocation(left, top); - return true; - } - event.offsetLocation(left, top); - } - return false; - } - - protected boolean dispatchTouchEvent(MotionEvent event) { - int x = (int) event.getX(); - int y = (int) event.getY(); - int action = event.getAction(); - if (mMotionTarget != null) { - if (action == MotionEvent.ACTION_DOWN) { - MotionEvent cancel = MotionEvent.obtain(event); - cancel.setAction(MotionEvent.ACTION_CANCEL); - dispatchTouchEvent(cancel, x, y, mMotionTarget, false); - mMotionTarget = null; - } else { - dispatchTouchEvent(event, x, y, mMotionTarget, false); - if (action == MotionEvent.ACTION_CANCEL - || action == MotionEvent.ACTION_UP) { - mMotionTarget = null; - } - return true; - } - } - if (action == MotionEvent.ACTION_DOWN) { - // in the reverse rendering order - for (int i = getComponentCount() - 1; i >= 0; --i) { - GLView component = getComponent(i); - if (component.getVisibility() != GLView.VISIBLE) continue; - if (dispatchTouchEvent(event, x, y, component, true)) { - mMotionTarget = component; - return true; - } - } - } - return onTouch(event); - } - - public Rect getPaddings() { - return mPaddings; - } - - public void layout(int left, int top, int right, int bottom) { - boolean sizeChanged = setBounds(left, top, right, bottom); - mViewFlags &= ~FLAG_LAYOUT_REQUESTED; - // We call onLayout no matter sizeChanged is true or not because the - // orientation may change without changing the size of the View (for - // example, rotate the device by 180 degrees), and we want to handle - // orientation change in onLayout. - onLayout(sizeChanged, left, top, right, bottom); - } - - private boolean setBounds(int left, int top, int right, int bottom) { - boolean sizeChanged = (right - left) != (mBounds.right - mBounds.left) - || (bottom - top) != (mBounds.bottom - mBounds.top); - mBounds.set(left, top, right, bottom); - return sizeChanged; - } - - public void measure(int widthSpec, int heightSpec) { - if (widthSpec == mLastWidthSpec && heightSpec == mLastHeightSpec - && (mViewFlags & FLAG_LAYOUT_REQUESTED) == 0) { - return; - } - - mLastWidthSpec = widthSpec; - mLastHeightSpec = heightSpec; - - mViewFlags &= ~FLAG_SET_MEASURED_SIZE; - onMeasure(widthSpec, heightSpec); - if ((mViewFlags & FLAG_SET_MEASURED_SIZE) == 0) { - throw new IllegalStateException(getClass().getName() - + " should call setMeasuredSize() in onMeasure()"); - } - } - - protected void onMeasure(int widthSpec, int heightSpec) { - } - - protected void setMeasuredSize(int width, int height) { - mViewFlags |= FLAG_SET_MEASURED_SIZE; - mMeasuredWidth = width; - mMeasuredHeight = height; - } - - public int getMeasuredWidth() { - return mMeasuredWidth; - } - - public int getMeasuredHeight() { - return mMeasuredHeight; - } - - protected void onLayout( - boolean changeSize, int left, int top, int right, int bottom) { - } - - /** - * Gets the bounds of the given descendant that relative to this view. - */ - public boolean getBoundsOf(GLView descendant, Rect out) { - int xoffset = 0; - int yoffset = 0; - GLView view = descendant; - while (view != this) { - if (view == null) return false; - Rect bounds = view.mBounds; - xoffset += bounds.left; - yoffset += bounds.top; - view = view.mParent; - } - out.set(xoffset, yoffset, xoffset + descendant.getWidth(), - yoffset + descendant.getHeight()); - return true; - } - - protected void onVisibilityChanged(int visibility) { - for (int i = 0, n = getComponentCount(); i < n; ++i) { - GLView child = getComponent(i); - if (child.getVisibility() == GLView.VISIBLE) { - child.onVisibilityChanged(visibility); - } - } - } - - protected void onAttachToRoot(GLRoot root) { - mRoot = root; - for (int i = 0, n = getComponentCount(); i < n; ++i) { - getComponent(i).onAttachToRoot(root); - } - } - - protected void onDetachFromRoot() { - for (int i = 0, n = getComponentCount(); i < n; ++i) { - getComponent(i).onDetachFromRoot(); - } - mRoot = null; - } - - public void lockRendering() { - if (mRoot != null) { - mRoot.lockRenderThread(); - } - } - - public void unlockRendering() { - if (mRoot != null) { - mRoot.unlockRenderThread(); - } - } - - // This is for debugging only. - // Dump the view hierarchy into log. - void dumpTree(String prefix) { - Log.d(TAG, prefix + getClass().getSimpleName()); - for (int i = 0, n = getComponentCount(); i < n; ++i) { - getComponent(i).dumpTree(prefix + "...."); - } - } -} |