18872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb/*
28872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * Copyright (C) 2012 The Android Open Source Project
38872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb *
48872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * Licensed under the Apache License, Version 2.0 (the "License");
58872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * you may not use this file except in compliance with the License.
68872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * You may obtain a copy of the License at
78872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb *
88872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb *      http://www.apache.org/licenses/LICENSE-2.0
98872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb *
108872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * Unless required by applicable law or agreed to in writing, software
118872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * distributed under the License is distributed on an "AS IS" BASIS,
128872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * See the License for the specific language governing permissions and
148872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * limitations under the License.
158872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb */
168872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
178872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbpackage com.android.camera.ui;
188872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
198872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.animation.Animator;
208872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.animation.Animator.AnimatorListener;
218872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.animation.AnimatorListenerAdapter;
2248239f4dd39040a9ab2ffc977586035a8784fd78Doris Liuimport android.app.Activity;
238872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.content.Context;
248872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.content.res.Configuration;
258872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.graphics.Canvas;
268872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.graphics.drawable.Drawable;
278872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.util.AttributeSet;
288872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.view.LayoutInflater;
298872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.view.MotionEvent;
308872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.view.View;
318872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.view.View.OnClickListener;
328872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.view.View.OnTouchListener;
338872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.view.ViewGroup;
346a0de79a7066d4ae5cc4677f88989abd15e892ffDoris Liuimport android.widget.FrameLayout.LayoutParams;
358872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.widget.LinearLayout;
368872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
37b50b5cbfbc0a67db6fc43373363b10381c9c61a3Angus Kongimport com.android.camera.util.CameraUtil;
38a9d66bdab247626b31dc182c4d62520b3abffdbdRuben Brunkimport com.android.camera.util.GcamHelper;
398e963a5a6016d246184ed65906f9d103e92b17e2Sascha Haeberlingimport com.android.camera.util.PhotoSphereHelper;
408e963a5a6016d246184ed65906f9d103e92b17e2Sascha Haeberlingimport com.android.camera.util.UsageStatistics;
418e963a5a6016d246184ed65906f9d103e92b17e2Sascha Haeberlingimport com.android.camera2.R;
428872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
43ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kongpublic class ModuleSwitcher extends RotateImageView
448872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        implements OnClickListener, OnTouchListener {
458872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
4657549631449fab8cd4d8dffe730bee4d5c4d8890Sascha Haeberling    @SuppressWarnings("unused")
478872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private static final String TAG = "CAM_Switcher";
488872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private static final int SWITCHER_POPUP_ANIM_DURATION = 200;
498872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
50753bb8aa56fff425fe16b93be368b9b236e4751fDoris Liu    public static final int PHOTO_MODULE_INDEX = 0;
51753bb8aa56fff425fe16b93be368b9b236e4751fDoris Liu    public static final int VIDEO_MODULE_INDEX = 1;
52ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    public static final int WIDE_ANGLE_PANO_MODULE_INDEX = 2;
53ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    public static final int LIGHTCYCLE_MODULE_INDEX = 3;
54a9d66bdab247626b31dc182c4d62520b3abffdbdRuben Brunk    public static final int GCAM_MODULE_INDEX = 4;
55a9d66bdab247626b31dc182c4d62520b3abffdbdRuben Brunk
56753bb8aa56fff425fe16b93be368b9b236e4751fDoris Liu    private static final int[] DRAW_IDS = {
57753bb8aa56fff425fe16b93be368b9b236e4751fDoris Liu            R.drawable.ic_switch_camera,
58753bb8aa56fff425fe16b93be368b9b236e4751fDoris Liu            R.drawable.ic_switch_video,
59ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong            R.drawable.ic_switch_pan,
6077fb852da18c6ee8ba1f1037f385319eb47bdce6Sascha Haeberling            R.drawable.ic_switch_photosphere,
61a9d66bdab247626b31dc182c4d62520b3abffdbdRuben Brunk            R.drawable.ic_switch_gcam,
62753bb8aa56fff425fe16b93be368b9b236e4751fDoris Liu    };
63764b07e6d5143b09c6f1bdd5504a89b81f7a7e74Sascha Haeberling
64ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    public interface ModuleSwitchListener {
65ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong        public void onModuleSelected(int i);
66764b07e6d5143b09c6f1bdd5504a89b81f7a7e74Sascha Haeberling
678872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        public void onShowSwitcherPopup();
688872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
698872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
70ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    private ModuleSwitchListener mListener;
718872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private int mCurrentIndex;
728872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private int[] mModuleIds;
738872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private int[] mDrawIds;
748872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private int mItemSize;
758872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private View mPopup;
768872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private View mParent;
778872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private boolean mShowingPopup;
788872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private boolean mNeedsAnimationSetup;
798872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private Drawable mIndicator;
808872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
818872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private float mTranslationX = 0;
828872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private float mTranslationY = 0;
838872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
848872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private AnimatorListener mHideAnimationListener;
858872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private AnimatorListener mShowAnimationListener;
868872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
87ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    public ModuleSwitcher(Context context) {
888872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        super(context);
898872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        init(context);
908872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
918872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
92ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    public ModuleSwitcher(Context context, AttributeSet attrs) {
938872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        super(context, attrs);
948872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        init(context);
958872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
968872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
978872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private void init(Context context) {
988872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mItemSize = context.getResources().getDimensionPixelSize(R.dimen.switcher_size);
998872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        setOnClickListener(this);
1008872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mIndicator = context.getResources().getDrawable(R.drawable.ic_switcher_menu_indicator);
101753bb8aa56fff425fe16b93be368b9b236e4751fDoris Liu        initializeDrawables(context);
102753bb8aa56fff425fe16b93be368b9b236e4751fDoris Liu    }
103753bb8aa56fff425fe16b93be368b9b236e4751fDoris Liu
104753bb8aa56fff425fe16b93be368b9b236e4751fDoris Liu    public void initializeDrawables(Context context) {
105764b07e6d5143b09c6f1bdd5504a89b81f7a7e74Sascha Haeberling        int numDrawIds = DRAW_IDS.length;
106753bb8aa56fff425fe16b93be368b9b236e4751fDoris Liu
107764b07e6d5143b09c6f1bdd5504a89b81f7a7e74Sascha Haeberling        if (!PhotoSphereHelper.hasLightCycleCapture(context)) {
108764b07e6d5143b09c6f1bdd5504a89b81f7a7e74Sascha Haeberling            --numDrawIds;
109764b07e6d5143b09c6f1bdd5504a89b81f7a7e74Sascha Haeberling        }
110764b07e6d5143b09c6f1bdd5504a89b81f7a7e74Sascha Haeberling
111048bf4d0b46c4c34d8caa801c8ddc8c1ff4e79cfSascha Haeberling        // Always decrement one because of GCam.
112048bf4d0b46c4c34d8caa801c8ddc8c1ff4e79cfSascha Haeberling        --numDrawIds;
113a9d66bdab247626b31dc182c4d62520b3abffdbdRuben Brunk
114764b07e6d5143b09c6f1bdd5504a89b81f7a7e74Sascha Haeberling        int[] drawids = new int[numDrawIds];
115764b07e6d5143b09c6f1bdd5504a89b81f7a7e74Sascha Haeberling        int[] moduleids = new int[numDrawIds];
116753bb8aa56fff425fe16b93be368b9b236e4751fDoris Liu        int ix = 0;
117753bb8aa56fff425fe16b93be368b9b236e4751fDoris Liu        for (int i = 0; i < DRAW_IDS.length; i++) {
1188e963a5a6016d246184ed65906f9d103e92b17e2Sascha Haeberling            if (i == LIGHTCYCLE_MODULE_INDEX && !PhotoSphereHelper.hasLightCycleCapture(context)) {
119147e26ab7075f0acd3978f0cd0541cd1da4b50e1Doris Liu                continue; // not enabled, so don't add to UI
120753bb8aa56fff425fe16b93be368b9b236e4751fDoris Liu            }
121048bf4d0b46c4c34d8caa801c8ddc8c1ff4e79cfSascha Haeberling            if (i == GCAM_MODULE_INDEX) {
122048bf4d0b46c4c34d8caa801c8ddc8c1ff4e79cfSascha Haeberling                continue; // don't add to UI
123a9d66bdab247626b31dc182c4d62520b3abffdbdRuben Brunk            }
124753bb8aa56fff425fe16b93be368b9b236e4751fDoris Liu            moduleids[ix] = i;
125753bb8aa56fff425fe16b93be368b9b236e4751fDoris Liu            drawids[ix++] = DRAW_IDS[i];
126753bb8aa56fff425fe16b93be368b9b236e4751fDoris Liu        }
127753bb8aa56fff425fe16b93be368b9b236e4751fDoris Liu        setIds(moduleids, drawids);
1288872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
1298872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
1308872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public void setIds(int[] moduleids, int[] drawids) {
1318872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mDrawIds = drawids;
1328872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mModuleIds = moduleids;
1338872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
1348872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
1358872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public void setCurrentIndex(int i) {
1368872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mCurrentIndex = i;
137048bf4d0b46c4c34d8caa801c8ddc8c1ff4e79cfSascha Haeberling        if (i == GCAM_MODULE_INDEX) {
138048bf4d0b46c4c34d8caa801c8ddc8c1ff4e79cfSascha Haeberling          setImageResource(R.drawable.ic_switch_camera);
139048bf4d0b46c4c34d8caa801c8ddc8c1ff4e79cfSascha Haeberling        } else {
140048bf4d0b46c4c34d8caa801c8ddc8c1ff4e79cfSascha Haeberling          setImageResource(mDrawIds[i]);
1414601f5d987ad2f57db6b1b65a716f00308e5ae99Ruben Brunk        }
1428872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
1438872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
144ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    public void setSwitchListener(ModuleSwitchListener l) {
1458872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mListener = l;
1468872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
1478872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
1488872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    @Override
1498872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public void onClick(View v) {
1508872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        showSwitcher();
1518872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mListener.onShowSwitcherPopup();
1528872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
1538872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
154ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong    private void onModuleSelected(int ix) {
1558872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        hidePopup();
1568872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        if ((ix != mCurrentIndex) && (mListener != null)) {
15703fc4e9aa172e091134d9dec8f51087cb6581c0dBobby Georgescu            UsageStatistics.onEvent("CameraModeSwitch", null, null);
1580a7dd573732a06879b35cdd07a8c0ee08b62a32eBobby Georgescu            UsageStatistics.setPendingTransitionCause(
1590a7dd573732a06879b35cdd07a8c0ee08b62a32eBobby Georgescu                    UsageStatistics.TRANSITION_MENU_TAP);
1608872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            setCurrentIndex(ix);
161ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong            mListener.onModuleSelected(mModuleIds[ix]);
1628872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
1638872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
1648872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
1658872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    @Override
1668872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    protected void onDraw(Canvas canvas) {
1678872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        super.onDraw(canvas);
1688872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mIndicator.setBounds(getDrawable().getBounds());
1698872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mIndicator.draw(canvas);
1708872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
1718872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
1728872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private void initPopup() {
1738872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mParent = LayoutInflater.from(getContext()).inflate(R.layout.switcher_popup,
1748872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                (ViewGroup) getParent());
1758872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        LinearLayout content = (LinearLayout) mParent.findViewById(R.id.content);
1768872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mPopup = content;
177764b07e6d5143b09c6f1bdd5504a89b81f7a7e74Sascha Haeberling        // Set the gravity of the popup, so that it shows up at the right
178764b07e6d5143b09c6f1bdd5504a89b81f7a7e74Sascha Haeberling        // position
17948239f4dd39040a9ab2ffc977586035a8784fd78Doris Liu        // on screen
18048239f4dd39040a9ab2ffc977586035a8784fd78Doris Liu        LayoutParams lp = ((LayoutParams) mPopup.getLayoutParams());
18148239f4dd39040a9ab2ffc977586035a8784fd78Doris Liu        lp.gravity = ((LayoutParams) mParent.findViewById(R.id.camera_switcher)
18248239f4dd39040a9ab2ffc977586035a8784fd78Doris Liu                .getLayoutParams()).gravity;
18348239f4dd39040a9ab2ffc977586035a8784fd78Doris Liu        mPopup.setLayoutParams(lp);
18448239f4dd39040a9ab2ffc977586035a8784fd78Doris Liu
1858872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mPopup.setVisibility(View.INVISIBLE);
1868872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mNeedsAnimationSetup = true;
1878872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        for (int i = mDrawIds.length - 1; i >= 0; i--) {
1888872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            RotateImageView item = new RotateImageView(getContext());
1898872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            item.setImageResource(mDrawIds[i]);
1908872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            item.setBackgroundResource(R.drawable.bg_pressed);
1918872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            final int index = i;
1928872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            item.setOnClickListener(new OnClickListener() {
1938872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                @Override
1948872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                public void onClick(View v) {
195764b07e6d5143b09c6f1bdd5504a89b81f7a7e74Sascha Haeberling                    if (showsPopup()) {
196ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong                        onModuleSelected(index);
197764b07e6d5143b09c6f1bdd5504a89b81f7a7e74Sascha Haeberling                    }
1988872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                }
1998872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            });
2008872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            switch (mDrawIds[i]) {
2018872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                case R.drawable.ic_switch_camera:
2028872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                    item.setContentDescription(getContext().getResources().getString(
2038872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                            R.string.accessibility_switch_to_camera));
2048872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                    break;
2058872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                case R.drawable.ic_switch_video:
2068872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                    item.setContentDescription(getContext().getResources().getString(
2078872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                            R.string.accessibility_switch_to_video));
2088872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                    break;
209ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong                case R.drawable.ic_switch_pan:
210ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong                    item.setContentDescription(getContext().getResources().getString(
211ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong                            R.string.accessibility_switch_to_panorama));
212ed15d1a140986473bbe7fffd72ec9618c41c5979Angus Kong                    break;
2138872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                case R.drawable.ic_switch_photosphere:
2148872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                    item.setContentDescription(getContext().getResources().getString(
215722c86077d15354ccf0d6e1acf5b6384df5da85fSascha Haeberling                            R.string.accessibility_switch_to_photo_sphere));
2168872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                    break;
217a9d66bdab247626b31dc182c4d62520b3abffdbdRuben Brunk                case R.drawable.ic_switch_gcam:
218a9d66bdab247626b31dc182c4d62520b3abffdbdRuben Brunk                    item.setContentDescription(getContext().getResources().getString(
219a9d66bdab247626b31dc182c4d62520b3abffdbdRuben Brunk                            R.string.accessibility_switch_to_gcam));
220a9d66bdab247626b31dc182c4d62520b3abffdbdRuben Brunk                    break;
2218872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                default:
2228872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                    break;
2238872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            }
2248872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            content.addView(item, new LinearLayout.LayoutParams(mItemSize, mItemSize));
2258872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
226997dfc3211ac036448d18d0c0076fef9623885c0Michael Kolb        mPopup.measure(MeasureSpec.makeMeasureSpec(mParent.getWidth(), MeasureSpec.AT_MOST),
227997dfc3211ac036448d18d0c0076fef9623885c0Michael Kolb                MeasureSpec.makeMeasureSpec(mParent.getHeight(), MeasureSpec.AT_MOST));
2288872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
2298872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
2308872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public boolean showsPopup() {
2318872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        return mShowingPopup;
2328872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
2338872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
2348872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public boolean isInsidePopup(MotionEvent evt) {
235764b07e6d5143b09c6f1bdd5504a89b81f7a7e74Sascha Haeberling        if (!showsPopup()) {
236764b07e6d5143b09c6f1bdd5504a89b81f7a7e74Sascha Haeberling            return false;
237764b07e6d5143b09c6f1bdd5504a89b81f7a7e74Sascha Haeberling        }
238556713fa25b492b6cba9ed8bf4ea6e2f56298fb5Doris Liu        int topLeft[] = new int[2];
239556713fa25b492b6cba9ed8bf4ea6e2f56298fb5Doris Liu        mPopup.getLocationOnScreen(topLeft);
240556713fa25b492b6cba9ed8bf4ea6e2f56298fb5Doris Liu        int left = topLeft[0];
241556713fa25b492b6cba9ed8bf4ea6e2f56298fb5Doris Liu        int top = topLeft[1];
242556713fa25b492b6cba9ed8bf4ea6e2f56298fb5Doris Liu        int bottom = top + mPopup.getHeight();
243556713fa25b492b6cba9ed8bf4ea6e2f56298fb5Doris Liu        int right = left + mPopup.getWidth();
244556713fa25b492b6cba9ed8bf4ea6e2f56298fb5Doris Liu        return evt.getX() >= left && evt.getX() < right
245556713fa25b492b6cba9ed8bf4ea6e2f56298fb5Doris Liu                && evt.getY() >= top && evt.getY() < bottom;
2468872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
2478872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
2488872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private void hidePopup() {
2498872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mShowingPopup = false;
2508872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        setVisibility(View.VISIBLE);
2518872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        if (mPopup != null && !animateHidePopup()) {
2528872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            mPopup.setVisibility(View.INVISIBLE);
2538872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
2548872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mParent.setOnTouchListener(null);
2558872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
2568872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
2576a0de79a7066d4ae5cc4677f88989abd15e892ffDoris Liu    @Override
2586a0de79a7066d4ae5cc4677f88989abd15e892ffDoris Liu    public void onConfigurationChanged(Configuration config) {
2596a0de79a7066d4ae5cc4677f88989abd15e892ffDoris Liu        if (showsPopup()) {
2606a0de79a7066d4ae5cc4677f88989abd15e892ffDoris Liu            ((ViewGroup) mParent).removeView(mPopup);
2616a0de79a7066d4ae5cc4677f88989abd15e892ffDoris Liu            mPopup = null;
2626a0de79a7066d4ae5cc4677f88989abd15e892ffDoris Liu            initPopup();
2636a0de79a7066d4ae5cc4677f88989abd15e892ffDoris Liu            mPopup.setVisibility(View.VISIBLE);
2646a0de79a7066d4ae5cc4677f88989abd15e892ffDoris Liu        }
2656a0de79a7066d4ae5cc4677f88989abd15e892ffDoris Liu    }
2666a0de79a7066d4ae5cc4677f88989abd15e892ffDoris Liu
2678872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private void showSwitcher() {
2688872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mShowingPopup = true;
2698872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        if (mPopup == null) {
2708872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            initPopup();
2718872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
272997dfc3211ac036448d18d0c0076fef9623885c0Michael Kolb        layoutPopup();
2738872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mPopup.setVisibility(View.VISIBLE);
2748872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        if (!animateShowPopup()) {
2758872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            setVisibility(View.INVISIBLE);
2768872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
2778872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mParent.setOnTouchListener(this);
2788872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
2798872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
2808872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    @Override
2818872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public boolean onTouch(View v, MotionEvent event) {
2828872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        closePopup();
2838872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        return true;
2848872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
2858872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
2868872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public void closePopup() {
2878872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        if (showsPopup()) {
2888872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            hidePopup();
2898872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
2908872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
2918872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
2928872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    @Override
2938872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    public void setOrientation(int degree, boolean animate) {
2948872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        super.setOrientation(degree, animate);
2958872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        ViewGroup content = (ViewGroup) mPopup;
296764b07e6d5143b09c6f1bdd5504a89b81f7a7e74Sascha Haeberling        if (content == null) {
297764b07e6d5143b09c6f1bdd5504a89b81f7a7e74Sascha Haeberling            return;
298764b07e6d5143b09c6f1bdd5504a89b81f7a7e74Sascha Haeberling        }
2998872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        for (int i = 0; i < content.getChildCount(); i++) {
3008872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            RotateImageView iv = (RotateImageView) content.getChildAt(i);
3018872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            iv.setOrientation(degree, animate);
3028872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
3038872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
3048872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
305997dfc3211ac036448d18d0c0076fef9623885c0Michael Kolb    private void layoutPopup() {
306b50b5cbfbc0a67db6fc43373363b10381c9c61a3Angus Kong        int orientation = CameraUtil.getDisplayRotation((Activity) getContext());
307997dfc3211ac036448d18d0c0076fef9623885c0Michael Kolb        int w = mPopup.getMeasuredWidth();
308997dfc3211ac036448d18d0c0076fef9623885c0Michael Kolb        int h = mPopup.getMeasuredHeight();
30948239f4dd39040a9ab2ffc977586035a8784fd78Doris Liu        if (orientation == 0) {
310997dfc3211ac036448d18d0c0076fef9623885c0Michael Kolb            mPopup.layout(getRight() - w, getBottom() - h, getRight(), getBottom());
311997dfc3211ac036448d18d0c0076fef9623885c0Michael Kolb            mTranslationX = 0;
312997dfc3211ac036448d18d0c0076fef9623885c0Michael Kolb            mTranslationY = h / 3;
31348239f4dd39040a9ab2ffc977586035a8784fd78Doris Liu        } else if (orientation == 90) {
314997dfc3211ac036448d18d0c0076fef9623885c0Michael Kolb            mTranslationX = w / 3;
315764b07e6d5143b09c6f1bdd5504a89b81f7a7e74Sascha Haeberling            mTranslationY = -h / 3;
316997dfc3211ac036448d18d0c0076fef9623885c0Michael Kolb            mPopup.layout(getRight() - w, getTop(), getRight(), getTop() + h);
31748239f4dd39040a9ab2ffc977586035a8784fd78Doris Liu        } else if (orientation == 180) {
318764b07e6d5143b09c6f1bdd5504a89b81f7a7e74Sascha Haeberling            mTranslationX = -w / 3;
319764b07e6d5143b09c6f1bdd5504a89b81f7a7e74Sascha Haeberling            mTranslationY = -h / 3;
320997dfc3211ac036448d18d0c0076fef9623885c0Michael Kolb            mPopup.layout(getLeft(), getTop(), getLeft() + w, getTop() + h);
32148239f4dd39040a9ab2ffc977586035a8784fd78Doris Liu        } else {
322764b07e6d5143b09c6f1bdd5504a89b81f7a7e74Sascha Haeberling            mTranslationX = -w / 3;
323997dfc3211ac036448d18d0c0076fef9623885c0Michael Kolb            mTranslationY = h - getHeight();
324997dfc3211ac036448d18d0c0076fef9623885c0Michael Kolb            mPopup.layout(getLeft(), getBottom() - h, getLeft() + w, getBottom());
325997dfc3211ac036448d18d0c0076fef9623885c0Michael Kolb        }
326997dfc3211ac036448d18d0c0076fef9623885c0Michael Kolb    }
327997dfc3211ac036448d18d0c0076fef9623885c0Michael Kolb
328997dfc3211ac036448d18d0c0076fef9623885c0Michael Kolb    @Override
329997dfc3211ac036448d18d0c0076fef9623885c0Michael Kolb    public void onLayout(boolean changed, int left, int top, int right, int bottom) {
330997dfc3211ac036448d18d0c0076fef9623885c0Michael Kolb        super.onLayout(changed, left, top, right, bottom);
331997dfc3211ac036448d18d0c0076fef9623885c0Michael Kolb        if (mPopup != null) {
332997dfc3211ac036448d18d0c0076fef9623885c0Michael Kolb            layoutPopup();
3338872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
3348872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
33548239f4dd39040a9ab2ffc977586035a8784fd78Doris Liu
3368872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private void popupAnimationSetup() {
337997dfc3211ac036448d18d0c0076fef9623885c0Michael Kolb        layoutPopup();
3388872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mPopup.setScaleX(0.3f);
3398872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mPopup.setScaleY(0.3f);
3408872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mPopup.setTranslationX(mTranslationX);
3418872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mPopup.setTranslationY(mTranslationY);
3428872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mNeedsAnimationSetup = false;
3438872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
3448872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
3458872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private boolean animateHidePopup() {
3468872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        if (mHideAnimationListener == null) {
3478872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            mHideAnimationListener = new AnimatorListenerAdapter() {
3488872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                @Override
3498872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                public void onAnimationEnd(Animator animation) {
3508872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                    // Verify that we weren't canceled
3515b45e26674bcbb91bdc195bed15a897ba3b96b0eDoris Liu                    if (!showsPopup() && mPopup != null) {
3528872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                        mPopup.setVisibility(View.INVISIBLE);
3536a0de79a7066d4ae5cc4677f88989abd15e892ffDoris Liu                        ((ViewGroup) mParent).removeView(mPopup);
3546a0de79a7066d4ae5cc4677f88989abd15e892ffDoris Liu                        mPopup = null;
3558872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                    }
3568872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                }
3578872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            };
3588872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
3598872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mPopup.animate()
3608872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                .alpha(0f)
3618872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                .scaleX(0.3f).scaleY(0.3f)
3628872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                .translationX(mTranslationX)
3638872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                .translationY(mTranslationY)
3648872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                .setDuration(SWITCHER_POPUP_ANIM_DURATION)
3658872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                .setListener(mHideAnimationListener);
3668872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        animate().alpha(1f).setDuration(SWITCHER_POPUP_ANIM_DURATION)
3678872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                .setListener(null);
3688872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        return true;
3698872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
3708872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb
3718872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    private boolean animateShowPopup() {
3728872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        if (mNeedsAnimationSetup) {
3738872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            popupAnimationSetup();
3748872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
3758872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        if (mShowAnimationListener == null) {
3768872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            mShowAnimationListener = new AnimatorListenerAdapter() {
3778872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                @Override
3788872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                public void onAnimationEnd(Animator animation) {
3798872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                    // Verify that we weren't canceled
3808872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                    if (showsPopup()) {
3818872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                        setVisibility(View.INVISIBLE);
382764b07e6d5143b09c6f1bdd5504a89b81f7a7e74Sascha Haeberling                        // request layout to make sure popup is laid out
383764b07e6d5143b09c6f1bdd5504a89b81f7a7e74Sascha Haeberling                        // correctly on ICS
3841f69b697746b62c76c8a4892c62e20380151be69Doris Liu                        mPopup.requestLayout();
3858872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                    }
3868872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                }
3878872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb            };
3888872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        }
3898872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        mPopup.animate()
3908872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                .alpha(1f)
3918872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                .scaleX(1f).scaleY(1f)
3928872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                .translationX(0)
3938872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                .translationY(0)
3948872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                .setDuration(SWITCHER_POPUP_ANIM_DURATION)
3958872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                .setListener(null);
3968872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        animate().alpha(0f).setDuration(SWITCHER_POPUP_ANIM_DURATION)
3978872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb                .setListener(mShowAnimationListener);
3988872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb        return true;
3998872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb    }
4008872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb}
401