1/*
2 * Copyright (C) 2015 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.calculator2;
18
19import android.content.Context;
20import android.graphics.Color;
21import android.support.v4.view.PagerAdapter;
22import android.support.v4.view.ViewPager;
23import android.util.AttributeSet;
24import android.view.MotionEvent;
25import android.view.View;
26import android.view.ViewGroup;
27
28public class CalculatorPadViewPager extends ViewPager {
29
30    private final PagerAdapter mStaticPagerAdapter = new PagerAdapter() {
31        @Override
32        public int getCount() {
33            return getChildCount();
34        }
35
36        @Override
37        public View instantiateItem(ViewGroup container, int position) {
38            return getChildAt(position);
39        }
40
41        @Override
42        public void destroyItem(ViewGroup container, int position, Object object) {
43            removeViewAt(position);
44        }
45
46        @Override
47        public boolean isViewFromObject(View view, Object object) {
48            return view == object;
49        }
50
51        @Override
52        public float getPageWidth(int position) {
53            return position == 1 ? 7.0f / 9.0f : 1.0f;
54        }
55    };
56
57    private final OnPageChangeListener mOnPageChangeListener = new SimpleOnPageChangeListener() {
58        @Override
59        public void onPageSelected(int position) {
60            for (int i = getChildCount() - 1; i >= 0; --i) {
61                final View child = getChildAt(i);
62                // Prevent clicks and accessibility focus from going through to descendants of
63                // other pages which are covered by the current page.
64                child.setClickable(i == position);
65                child.setImportantForAccessibility(i == position
66                        ? IMPORTANT_FOR_ACCESSIBILITY_AUTO
67                        : IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
68            }
69        }
70    };
71
72    private final PageTransformer mPageTransformer = new PageTransformer() {
73        @Override
74        public void transformPage(View view, float position) {
75            if (position < 0.0f) {
76                // Pin the left page to the left side.
77                view.setTranslationX(getWidth() * -position);
78                view.setAlpha(Math.max(1.0f + position, 0.0f));
79            } else {
80                // Use the default slide transition when moving to the next page.
81                view.setTranslationX(0.0f);
82                view.setAlpha(1.0f);
83            }
84        }
85    };
86
87    public CalculatorPadViewPager(Context context) {
88        this(context, null /* attrs */);
89    }
90
91    public CalculatorPadViewPager(Context context, AttributeSet attrs) {
92        super(context, attrs);
93
94        setAdapter(mStaticPagerAdapter);
95        setBackgroundColor(Color.BLACK);
96        setPageMargin(getResources().getDimensionPixelSize(R.dimen.pad_page_margin));
97        setPageTransformer(false, mPageTransformer);
98        addOnPageChangeListener(mOnPageChangeListener);
99    }
100
101    @Override
102    protected void onFinishInflate() {
103        super.onFinishInflate();
104
105        // Invalidate the adapter's data set since children may have been added during inflation.
106        getAdapter().notifyDataSetChanged();
107
108        // Let page change listener know about our initial position.
109        mOnPageChangeListener.onPageSelected(getCurrentItem());
110    }
111
112    @Override
113    public boolean onInterceptTouchEvent(MotionEvent ev) {
114        boolean shouldIntercept = super.onInterceptTouchEvent(ev);
115
116        // Only allow the current item to receive touch events.
117        if (!shouldIntercept && ev.getActionMasked() == MotionEvent.ACTION_DOWN) {
118            final int x = (int) ev.getX() + getScrollX();
119            final int y = (int) ev.getY() + getScrollY();
120
121            final int childCount = getChildCount();
122            for (int i = childCount - 1; i >= 0; --i) {
123                final int childIndex = getChildDrawingOrder(childCount, i);
124                final View child = getChildAt(childIndex);
125                if (child.getVisibility() == View.VISIBLE
126                        && x >= child.getLeft() && x < child.getRight()
127                        && y >= child.getTop() && y < child.getBottom()) {
128                    shouldIntercept = (childIndex != getCurrentItem());
129                    break;
130                }
131            }
132        }
133
134        return shouldIntercept;
135    }
136}
137