1b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project/*
2b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
3b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project *
4b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project * you may not use this file except in compliance with the License.
6b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project * You may obtain a copy of the License at
7b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project *
8b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project *
10b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project * See the License for the specific language governing permissions and
14b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project * limitations under the License.
15b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project */
16b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project
17b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Projectpackage com.android.calculator2;
18b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project
19052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikovimport android.content.Context;
20052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikovimport android.util.AttributeSet;
21052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikovimport android.view.GestureDetector;
22b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Projectimport android.view.MotionEvent;
23b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Projectimport android.view.View;
24052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikovimport android.view.animation.Animation;
25052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikovimport android.view.animation.Animation.AnimationListener;
26052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikovimport android.view.animation.TranslateAnimation;
27b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Projectimport android.widget.FrameLayout;
28b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project
29052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikovclass PanelSwitcher extends FrameLayout implements AnimationListener {
30b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project    private static final int MAJOR_MOVE = 60;
31b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project    private static final int ANIM_DURATION = 400;
32b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project
33b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project    private GestureDetector mGestureDetector;
34b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project    private int mCurrentView;
35cf3ca321fa8cc1f5427454c5e2501b7978bb3711Mihai Preda    private View mChildren[] = new View[0];
36b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project
37b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project    private int mWidth;
38b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project    private TranslateAnimation inLeft;
39b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project    private TranslateAnimation outLeft;
40b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project
41b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project    private TranslateAnimation inRight;
42b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project    private TranslateAnimation outRight;
43b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project
445a589624ae4c334987e725c710833cd3588b90feChristian Mehlmauer    private static final int LEFT  = 1;
455a589624ae4c334987e725c710833cd3588b90feChristian Mehlmauer    private static final int RIGHT = 2;
46b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project    private int mPreviousMove;
47b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project
48052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov    public interface Listener {
49052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov        void onChange();
50052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov    }
51052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov
52052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov    private Listener mListener;
53052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov
54b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project    public PanelSwitcher(Context context, AttributeSet attrs) {
55b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project        super(context, attrs);
56b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project        mCurrentView = 0;
57b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project        mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
58052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov                @Override
59b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project                public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
60b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project                                       float velocityY) {
61b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project                    int dx = (int) (e2.getX() - e1.getX());
62b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project
63b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project                    // don't accept the fling if it's too short
64b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project                    // as it may conflict with a button push
65b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project                    if (Math.abs(dx) > MAJOR_MOVE && Math.abs(velocityX) > Math.abs(velocityY)) {
66b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project                        if (velocityX > 0) {
67b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project                            moveRight();
68b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project                        } else {
69b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project                            moveLeft();
70b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project                        }
71b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project                        return true;
72b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project                    } else {
73b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project                        return false;
74b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project                    }
75b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project                }
76b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project            });
77b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project    }
78b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project
79052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov    public void setListener(Listener listener) {
80052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov        this.mListener = listener;
81052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov    }
82052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov
83cf3ca321fa8cc1f5427454c5e2501b7978bb3711Mihai Preda    void setCurrentIndex(int current) {
84052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov        boolean changed = mCurrentView != current;
85cf3ca321fa8cc1f5427454c5e2501b7978bb3711Mihai Preda        mCurrentView = current;
86cf3ca321fa8cc1f5427454c5e2501b7978bb3711Mihai Preda        updateCurrentView();
87052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov        if (changed && mListener != null) {
88052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov            mListener.onChange();
89052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov        }
90cf3ca321fa8cc1f5427454c5e2501b7978bb3711Mihai Preda    }
91cf3ca321fa8cc1f5427454c5e2501b7978bb3711Mihai Preda
92cf3ca321fa8cc1f5427454c5e2501b7978bb3711Mihai Preda    private void updateCurrentView() {
93cf3ca321fa8cc1f5427454c5e2501b7978bb3711Mihai Preda        for (int i = mChildren.length-1; i >= 0 ; --i) {
94cf3ca321fa8cc1f5427454c5e2501b7978bb3711Mihai Preda            mChildren[i].setVisibility(i==mCurrentView ? View.VISIBLE : View.GONE);
95cf3ca321fa8cc1f5427454c5e2501b7978bb3711Mihai Preda        }
96cf3ca321fa8cc1f5427454c5e2501b7978bb3711Mihai Preda    }
97cf3ca321fa8cc1f5427454c5e2501b7978bb3711Mihai Preda
98052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov    @Override
99b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project    public void onSizeChanged(int w, int h, int oldW, int oldH) {
100b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project        mWidth = w;
101b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project        inLeft   = new TranslateAnimation(mWidth, 0, 0, 0);
102052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov        inLeft.setAnimationListener(this);
103052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov        outLeft  = new TranslateAnimation(0, -mWidth, 0, 0);
104b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project        inRight  = new TranslateAnimation(-mWidth, 0, 0, 0);
105052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov        inRight.setAnimationListener(this);
106b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project        outRight = new TranslateAnimation(0, mWidth, 0, 0);
107b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project
108b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project        inLeft.setDuration(ANIM_DURATION);
109b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project        outLeft.setDuration(ANIM_DURATION);
110b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project        inRight.setDuration(ANIM_DURATION);
111b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project        outRight.setDuration(ANIM_DURATION);
112b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project    }
113b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project
114052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov    @Override
115b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project    protected void onFinishInflate() {
116b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project        int count = getChildCount();
117cf3ca321fa8cc1f5427454c5e2501b7978bb3711Mihai Preda        mChildren = new View[count];
118b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project        for (int i = 0; i < count; ++i) {
119cf3ca321fa8cc1f5427454c5e2501b7978bb3711Mihai Preda            mChildren[i] = getChildAt(i);
120b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project        }
121cf3ca321fa8cc1f5427454c5e2501b7978bb3711Mihai Preda        updateCurrentView();
122b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project    }
123b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project
124b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project    @Override
125b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project    public boolean onTouchEvent(MotionEvent event) {
126b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project        mGestureDetector.onTouchEvent(event);
127b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project        return true;
128b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project    }
129b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project
130b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project    @Override
131b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project    public boolean onInterceptTouchEvent(MotionEvent event) {
132b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project        return mGestureDetector.onTouchEvent(event);
133b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project    }
134b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project
135b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project    void moveLeft() {
136b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project        //  <--
137cf3ca321fa8cc1f5427454c5e2501b7978bb3711Mihai Preda        if (mCurrentView < mChildren.length - 1 && mPreviousMove != LEFT) {
138cf3ca321fa8cc1f5427454c5e2501b7978bb3711Mihai Preda            mChildren[mCurrentView+1].setVisibility(View.VISIBLE);
139cf3ca321fa8cc1f5427454c5e2501b7978bb3711Mihai Preda            mChildren[mCurrentView+1].startAnimation(inLeft);
140cf3ca321fa8cc1f5427454c5e2501b7978bb3711Mihai Preda            mChildren[mCurrentView].startAnimation(outLeft);
141cf3ca321fa8cc1f5427454c5e2501b7978bb3711Mihai Preda            mChildren[mCurrentView].setVisibility(View.GONE);
142b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project
143b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project            mCurrentView++;
144b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project            mPreviousMove = LEFT;
145b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project        }
146b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project    }
147b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project
148b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project    void moveRight() {
149b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project        //  -->
150b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project        if (mCurrentView > 0 && mPreviousMove != RIGHT) {
151cf3ca321fa8cc1f5427454c5e2501b7978bb3711Mihai Preda            mChildren[mCurrentView-1].setVisibility(View.VISIBLE);
152cf3ca321fa8cc1f5427454c5e2501b7978bb3711Mihai Preda            mChildren[mCurrentView-1].startAnimation(inRight);
153cf3ca321fa8cc1f5427454c5e2501b7978bb3711Mihai Preda            mChildren[mCurrentView].startAnimation(outRight);
154cf3ca321fa8cc1f5427454c5e2501b7978bb3711Mihai Preda            mChildren[mCurrentView].setVisibility(View.GONE);
155b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project
156b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project            mCurrentView--;
157b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project            mPreviousMove = RIGHT;
158b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project        }
159b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project    }
160b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project
161b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project    int getCurrentIndex() {
162b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project        return mCurrentView;
163b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project    }
164052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov
165052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov    @Override
166052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov    public void onAnimationRepeat(Animation animation) {
167052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov    }
168052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov
169052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov    @Override
170052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov    public void onAnimationStart(Animation animation) {
171052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov    }
172052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov
173052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov    @Override
174052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov    public void onAnimationEnd(Animation animation) {
175052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov        if (mListener != null) {
176052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov            mListener.onChange();
177052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov        }
178052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov    }
179b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project}
180