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 17package com.android.browser.view; 18 19import android.database.DataSetObserver; 20import android.graphics.Canvas; 21import android.view.MotionEvent; 22import android.view.View; 23import android.widget.Adapter; 24 25import java.util.ArrayList; 26 27/** 28 * common code for pie views 29 */ 30public 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 int parentHeight) { 114 if (mListener != null) { 115 mListener.onLayout(anchorX, anchorY, left); 116 } 117 } 118 119 120 @Override 121 public abstract void draw(Canvas canvas); 122 123 protected void drawView(View view, Canvas canvas) { 124 final int state = canvas.save(); 125 canvas.translate(view.getLeft(), view.getTop()); 126 view.draw(canvas); 127 canvas.restoreToCount(state); 128 } 129 130 protected abstract int findChildAt(int y); 131 132 @Override 133 public boolean onTouchEvent(MotionEvent evt) { 134 int action = evt.getActionMasked(); 135 int evtx = (int) evt.getX(); 136 int evty = (int) evt.getY(); 137 if ((evtx < mLeft) || (evtx >= mLeft + mWidth) 138 || (evty < mTop) || (evty >= mTop + mHeight)) { 139 return false; 140 } 141 switch (action) { 142 case MotionEvent.ACTION_MOVE: 143 View v = mViews.get(mCurrent); 144 setCurrent(Math.max(0, Math.min(mViews.size() -1, 145 findChildAt(evty)))); 146 View v1 = mViews.get(mCurrent); 147 if (v != v1) { 148 v.setPressed(false); 149 v1.setPressed(true); 150 } 151 break; 152 case MotionEvent.ACTION_UP: 153 mViews.get(mCurrent).performClick(); 154 mViews.get(mCurrent).setPressed(false); 155 break; 156 default: 157 break; 158 } 159 return true; 160 } 161 162} 163