11acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb/* 21acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb * Copyright (C) 2011 The Android Open Source Project 31acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb * 41acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb * Licensed under the Apache License, Version 2.0 (the "License"); 51acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb * you may not use this file except in compliance with the License. 61acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb * You may obtain a copy of the License at 71acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb * 81acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb * http://www.apache.org/licenses/LICENSE-2.0 91acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb * 101acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb * Unless required by applicable law or agreed to in writing, software 111acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb * distributed under the License is distributed on an "AS IS" BASIS, 121acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb * See the License for the specific language governing permissions and 141acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb * limitations under the License. 151acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb */ 161acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb 171acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolbpackage com.android.browser.view; 181acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb 191acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolbimport android.database.DataSetObserver; 201acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolbimport android.graphics.Canvas; 211acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolbimport android.view.MotionEvent; 221acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolbimport android.view.View; 231acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolbimport android.widget.Adapter; 241acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb 251acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolbimport java.util.ArrayList; 261acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb 271acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb/** 281acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb * common code for pie views 291acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb */ 301acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolbpublic abstract class BasePieView implements PieMenu.PieView { 311acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb 321acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb protected Adapter mAdapter; 331acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb private DataSetObserver mObserver; 341acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb protected ArrayList<View> mViews; 351acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb 36eb95db48b01b3db935601f25bd1a2358674b76daMichael Kolb protected OnLayoutListener mListener; 37eb95db48b01b3db935601f25bd1a2358674b76daMichael Kolb 381acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb protected int mCurrent; 391acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb protected int mChildWidth; 401acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb protected int mChildHeight; 411acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb protected int mWidth; 421acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb protected int mHeight; 431acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb protected int mLeft; 441acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb protected int mTop; 451acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb 461acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb public BasePieView() { 471acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb } 481acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb 49eb95db48b01b3db935601f25bd1a2358674b76daMichael Kolb public void setLayoutListener(OnLayoutListener l) { 50eb95db48b01b3db935601f25bd1a2358674b76daMichael Kolb mListener = l; 51eb95db48b01b3db935601f25bd1a2358674b76daMichael Kolb } 52eb95db48b01b3db935601f25bd1a2358674b76daMichael Kolb 531acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb public void setAdapter(Adapter adapter) { 541acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb mAdapter = adapter; 551acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb if (adapter == null) { 561acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb if (mAdapter != null) { 571acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb mAdapter.unregisterDataSetObserver(mObserver); 581acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb } 591acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb mViews = null; 601acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb mCurrent = -1; 611acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb } else { 621acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb mObserver = new DataSetObserver() { 631acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb @Override 641acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb public void onChanged() { 651acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb buildViews(); 661acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb } 671acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb 681acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb @Override 691acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb public void onInvalidated() { 701acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb mViews.clear(); 711acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb } 721acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb }; 731acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb mAdapter.registerDataSetObserver(mObserver); 741acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb setCurrent(0); 751acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb } 761acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb } 771acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb 781acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb public void setCurrent(int ix) { 791acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb mCurrent = ix; 801acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb } 811acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb 821acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb public Adapter getAdapter() { 831acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb return mAdapter; 841acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb } 851acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb 861acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb protected void buildViews() { 871acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb if (mAdapter != null) { 881acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb final int n = mAdapter.getCount(); 891acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb if (mViews == null) { 901acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb mViews = new ArrayList<View>(n); 911acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb } else { 921acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb mViews.clear(); 931acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb } 941acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb mChildWidth = 0; 951acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb mChildHeight = 0; 961acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb for (int i = 0; i < n; i++) { 971acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb View view = mAdapter.getView(i, null, null); 981acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb view.measure(View.MeasureSpec.UNSPECIFIED, 991acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb View.MeasureSpec.UNSPECIFIED); 1001acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb mChildWidth = Math.max(mChildWidth, view.getMeasuredWidth()); 1011acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb mChildHeight = Math.max(mChildHeight, view.getMeasuredHeight()); 1021acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb mViews.add(view); 1031acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb } 1041acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb } 1051acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb } 1061acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb 1071acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb /** 1081acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb * this will be called before the first draw call 1091acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb * needs to set top, left, width, height 1101acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb */ 1111acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb @Override 112a4befac241ec69791fd30e11355ed3dc10d7fb37Michael Kolb public void layout(int anchorX, int anchorY, boolean left, float angle, 113a4befac241ec69791fd30e11355ed3dc10d7fb37Michael Kolb int parentHeight) { 114eb95db48b01b3db935601f25bd1a2358674b76daMichael Kolb if (mListener != null) { 115eb95db48b01b3db935601f25bd1a2358674b76daMichael Kolb mListener.onLayout(anchorX, anchorY, left); 116eb95db48b01b3db935601f25bd1a2358674b76daMichael Kolb } 117eb95db48b01b3db935601f25bd1a2358674b76daMichael Kolb } 118eb95db48b01b3db935601f25bd1a2358674b76daMichael Kolb 1191acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb 1201acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb @Override 1211acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb public abstract void draw(Canvas canvas); 1221acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb 1231acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb protected void drawView(View view, Canvas canvas) { 1241acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb final int state = canvas.save(); 1251acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb canvas.translate(view.getLeft(), view.getTop()); 1261acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb view.draw(canvas); 1271acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb canvas.restoreToCount(state); 1281acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb } 1291acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb 1301acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb protected abstract int findChildAt(int y); 1311acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb 1321acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb @Override 1331acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb public boolean onTouchEvent(MotionEvent evt) { 1341acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb int action = evt.getActionMasked(); 1351acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb int evtx = (int) evt.getX(); 1361acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb int evty = (int) evt.getY(); 1371acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb if ((evtx < mLeft) || (evtx >= mLeft + mWidth) 1381acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb || (evty < mTop) || (evty >= mTop + mHeight)) { 1391acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb return false; 1401acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb } 1411acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb switch (action) { 1421acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb case MotionEvent.ACTION_MOVE: 1431acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb View v = mViews.get(mCurrent); 1441acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb setCurrent(Math.max(0, Math.min(mViews.size() -1, 1451acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb findChildAt(evty)))); 1461acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb View v1 = mViews.get(mCurrent); 1471acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb if (v != v1) { 1481acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb v.setPressed(false); 1491acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb v1.setPressed(true); 1501acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb } 1511acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb break; 1521acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb case MotionEvent.ACTION_UP: 1531acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb mViews.get(mCurrent).performClick(); 1541acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb mViews.get(mCurrent).setPressed(false); 1551acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb break; 1561acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb default: 1571acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb break; 1581acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb } 1591acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb return true; 1601acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb } 1611acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb 1621acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb} 163