BasePieView.java revision 1acef69ffc079d1bc029ff7eb1f5043f7efd7f36
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
361acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb    protected int mCurrent;
371acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb    protected int mChildWidth;
381acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb    protected int mChildHeight;
391acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb    protected int mWidth;
401acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb    protected int mHeight;
411acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb    protected int mLeft;
421acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb    protected int mTop;
431acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb
441acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb    public BasePieView() {
451acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb    }
461acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb
471acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb    public void setAdapter(Adapter adapter) {
481acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb        mAdapter = adapter;
491acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb        if (adapter == null) {
501acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb            if (mAdapter != null) {
511acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb                mAdapter.unregisterDataSetObserver(mObserver);
521acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb            }
531acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb            mViews = null;
541acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb            mCurrent = -1;
551acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb        } else {
561acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb            mObserver = new DataSetObserver() {
571acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb                @Override
581acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb                public void onChanged() {
591acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb                    buildViews();
601acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb                }
611acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb
621acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb                @Override
631acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb                public void onInvalidated() {
641acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb                    mViews.clear();
651acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb                }
661acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb            };
671acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb            mAdapter.registerDataSetObserver(mObserver);
681acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb            setCurrent(0);
691acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb        }
701acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb    }
711acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb
721acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb    public void setCurrent(int ix) {
731acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb        mCurrent = ix;
741acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb    }
751acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb
761acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb    public Adapter getAdapter() {
771acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb        return mAdapter;
781acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb    }
791acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb
801acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb    protected void buildViews() {
811acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb        if (mAdapter != null) {
821acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb            final int n = mAdapter.getCount();
831acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb            if (mViews == null) {
841acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb                mViews = new ArrayList<View>(n);
851acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb            } else {
861acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb                mViews.clear();
871acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb            }
881acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb            mChildWidth = 0;
891acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb            mChildHeight = 0;
901acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb            for (int i = 0; i < n; i++) {
911acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb                View view = mAdapter.getView(i, null, null);
921acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb                view.measure(View.MeasureSpec.UNSPECIFIED,
931acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb                        View.MeasureSpec.UNSPECIFIED);
941acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb                mChildWidth = Math.max(mChildWidth, view.getMeasuredWidth());
951acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb                mChildHeight = Math.max(mChildHeight, view.getMeasuredHeight());
961acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb                mViews.add(view);
971acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb            }
981acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb        }
991acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb    }
1001acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb
1011acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb    /**
1021acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb     * this will be called before the first draw call
1031acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb     * needs to set top, left, width, height
1041acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb     */
1051acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb    @Override
1061acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb    public abstract void layout(int anchorX, int anchorY, boolean left);
1071acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb
1081acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb    @Override
1091acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb    public abstract void draw(Canvas canvas);
1101acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb
1111acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb    protected void drawView(View view, Canvas canvas) {
1121acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb        final int state = canvas.save();
1131acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb        canvas.translate(view.getLeft(), view.getTop());
1141acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb        view.draw(canvas);
1151acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb        canvas.restoreToCount(state);
1161acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb    }
1171acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb
1181acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb    protected abstract int findChildAt(int y);
1191acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb
1201acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb    @Override
1211acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb    public boolean onTouchEvent(MotionEvent evt) {
1221acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb        int action = evt.getActionMasked();
1231acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb        int evtx = (int) evt.getX();
1241acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb        int evty = (int) evt.getY();
1251acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb        if ((evtx < mLeft) || (evtx >= mLeft + mWidth)
1261acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb                || (evty < mTop) || (evty >= mTop + mHeight)) {
1271acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb            return false;
1281acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb        }
1291acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb        switch (action) {
1301acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb            case MotionEvent.ACTION_MOVE:
1311acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb                View v = mViews.get(mCurrent);
1321acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb                setCurrent(Math.max(0, Math.min(mViews.size() -1,
1331acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb                        findChildAt(evty))));
1341acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb                View v1 = mViews.get(mCurrent);
1351acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb                if (v != v1) {
1361acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb                    v.setPressed(false);
1371acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb                    v1.setPressed(true);
1381acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb                }
1391acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb                break;
1401acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb            case MotionEvent.ACTION_UP:
1411acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb                mViews.get(mCurrent).performClick();
1421acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb                mViews.get(mCurrent).setPressed(false);
1431acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb                break;
1441acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb            default:
1451acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb                break;
1461acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb        }
1471acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb        return true;
1481acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb    }
1491acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb
1501acef69ffc079d1bc029ff7eb1f5043f7efd7f36Michael Kolb}
151