diff options
Diffstat (limited to 'src/com/android/gallery3d/ui/ScrollView.java')
-rw-r--r-- | src/com/android/gallery3d/ui/ScrollView.java | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/src/com/android/gallery3d/ui/ScrollView.java b/src/com/android/gallery3d/ui/ScrollView.java new file mode 100644 index 000000000..f7628335c --- /dev/null +++ b/src/com/android/gallery3d/ui/ScrollView.java @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2011 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 com.android.gallery3d.R; +import com.android.gallery3d.common.Utils; + +import android.content.Context; +import android.view.GestureDetector; +import android.view.MotionEvent; +import android.view.View.MeasureSpec; + +// The current implementation can only scroll vertically. +public class ScrollView extends GLView { + + private static final int MIN_SCROLLER_HEIGHT = 20; + + private NinePatchTexture mScroller; + private int mScrollLimit = 0; + private int mScrollerHeight = MIN_SCROLLER_HEIGHT; + private GestureDetector mGestureDetector; + + public ScrollView(Context context) { + mScroller = new NinePatchTexture(context, R.drawable.scrollbar_handle_holo_dark); + mGestureDetector = new GestureDetector(context, new MyGestureListener()); + } + + private GLView getContentView() { + return getComponentCount() == 0 ? null : getComponent(0); + } + + @Override + public void onLayout(boolean sizeChange, int l, int t, int r, int b) { + GLView content = getContentView(); + int width = getWidth(); + int height = getHeight(); + content.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), + MeasureSpec.UNSPECIFIED); + int contentHeight = content.getMeasuredHeight(); + content.layout(0, 0, width, contentHeight); + if (height < contentHeight) { + mScrollLimit = contentHeight - height; + mScrollerHeight = Math.max(MIN_SCROLLER_HEIGHT, + height * height / contentHeight); + } else { + mScrollLimit = 0; + } + mScrollY = Utils.clamp(mScrollY, 0, mScrollLimit); + } + + @Override + public void render(GLCanvas canvas) { + GLView content = getContentView(); + if (content == null) return; + int width = getWidth(); + int height = getHeight(); + + canvas.save(GLCanvas.SAVE_FLAG_CLIP); + canvas.clipRect(0, 0, width, height); + super.render(canvas); + if (mScrollLimit > 0) { + int x = getWidth() - mScroller.getWidth(); + int y = (height - mScrollerHeight) * mScrollY / mScrollLimit; + mScroller.draw(canvas, x, y, mScroller.getWidth(), mScrollerHeight); + } + canvas.restore(); + } + + @Override + public boolean onTouch(MotionEvent event) { + mGestureDetector.onTouchEvent(event); + return true; + } + + private class MyGestureListener + extends GestureDetector.SimpleOnGestureListener { + @Override + public boolean onScroll(MotionEvent e1, + MotionEvent e2, float distanceX, float distanceY) { + mScrollY = Utils.clamp(mScrollY + (int) distanceY, 0, mScrollLimit); + invalidate(); + return true; + } + } +} |