1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.browser.view; 18 19 import android.database.DataSetObserver; 20 import android.graphics.Canvas; 21 import android.view.MotionEvent; 22 import android.view.View; 23 import android.widget.Adapter; 24 25 import java.util.ArrayList; 26 27 /** 28 * common code for pie views 29 */ 30 public abstract class BasePieView implements PieMenu.PieView { 31 32 protected Adapter mAdapter; 33 private DataSetObserver mObserver; 34 protected ArrayList<View> mViews; 35 36 protected OnLayoutListener mListener; 37 38 protected int mCurrent; 39 protected int mChildWidth; 40 protected int mChildHeight; 41 protected int mWidth; 42 protected int mHeight; 43 protected int mLeft; 44 protected int mTop; 45 46 public BasePieView() { 47 } 48 49 public void setLayoutListener(OnLayoutListener l) { 50 mListener = l; 51 } 52 53 public void setAdapter(Adapter adapter) { 54 mAdapter = adapter; 55 if (adapter == null) { 56 if (mAdapter != null) { 57 mAdapter.unregisterDataSetObserver(mObserver); 58 } 59 mViews = null; 60 mCurrent = -1; 61 } else { 62 mObserver = new DataSetObserver() { 63 @Override 64 public void onChanged() { 65 buildViews(); 66 } 67 68 @Override 69 public void onInvalidated() { 70 mViews.clear(); 71 } 72 }; 73 mAdapter.registerDataSetObserver(mObserver); 74 setCurrent(0); 75 } 76 } 77 78 public void setCurrent(int ix) { 79 mCurrent = ix; 80 } 81 82 public Adapter getAdapter() { 83 return mAdapter; 84 } 85 86 protected void buildViews() { 87 if (mAdapter != null) { 88 final int n = mAdapter.getCount(); 89 if (mViews == null) { 90 mViews = new ArrayList<View>(n); 91 } else { 92 mViews.clear(); 93 } 94 mChildWidth = 0; 95 mChildHeight = 0; 96 for (int i = 0; i < n; i++) { 97 View view = mAdapter.getView(i, null, null); 98 view.measure(View.MeasureSpec.UNSPECIFIED, 99 View.MeasureSpec.UNSPECIFIED); 100 mChildWidth = Math.max(mChildWidth, view.getMeasuredWidth()); 101 mChildHeight = Math.max(mChildHeight, view.getMeasuredHeight()); 102 mViews.add(view); 103 } 104 } 105 } 106 107 /** 108 * this will be called before the first draw call 109 * needs to set top, left, width, height 110 */ 111 @Override 112 public void layout(int anchorX, int anchorY, boolean left, float angle) { 113 if (mListener != null) { 114 mListener.onLayout(anchorX, anchorY, left); 115 } 116 } 117 118 119 @Override 120 public abstract void draw(Canvas canvas); 121 122 protected void drawView(View view, Canvas canvas) { 123 final int state = canvas.save(); 124 canvas.translate(view.getLeft(), view.getTop()); 125 view.draw(canvas); 126 canvas.restoreToCount(state); 127 } 128 129 protected abstract int findChildAt(int y); 130 131 @Override 132 public boolean onTouchEvent(MotionEvent evt) { 133 int action = evt.getActionMasked(); 134 int evtx = (int) evt.getX(); 135 int evty = (int) evt.getY(); 136 if ((evtx < mLeft) || (evtx >= mLeft + mWidth) 137 || (evty < mTop) || (evty >= mTop + mHeight)) { 138 return false; 139 } 140 switch (action) { 141 case MotionEvent.ACTION_MOVE: 142 View v = mViews.get(mCurrent); 143 setCurrent(Math.max(0, Math.min(mViews.size() -1, 144 findChildAt(evty)))); 145 View v1 = mViews.get(mCurrent); 146 if (v != v1) { 147 v.setPressed(false); 148 v1.setPressed(true); 149 } 150 break; 151 case MotionEvent.ACTION_UP: 152 mViews.get(mCurrent).performClick(); 153 mViews.get(mCurrent).setPressed(false); 154 break; 155 default: 156 break; 157 } 158 return true; 159 } 160 161 } 162