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