diff options
Diffstat (limited to 'src/com/android/camera/ui/CameraSwitcher.java')
-rw-r--r-- | src/com/android/camera/ui/CameraSwitcher.java | 293 |
1 files changed, 293 insertions, 0 deletions
diff --git a/src/com/android/camera/ui/CameraSwitcher.java b/src/com/android/camera/ui/CameraSwitcher.java new file mode 100644 index 000000000..7b9fb6499 --- /dev/null +++ b/src/com/android/camera/ui/CameraSwitcher.java @@ -0,0 +1,293 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.camera.ui; + +import android.animation.Animator; +import android.animation.Animator.AnimatorListener; +import android.animation.AnimatorListenerAdapter; +import android.content.Context; +import android.content.res.Configuration; +import android.graphics.Canvas; +import android.graphics.drawable.Drawable; +import android.util.AttributeSet; +import android.view.LayoutInflater; +import android.view.MotionEvent; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.View.OnTouchListener; +import android.view.ViewGroup; +import android.widget.LinearLayout; + +import com.android.camera.R; +import com.android.gallery3d.common.ApiHelper; + +public class CameraSwitcher extends RotateImageView + implements OnClickListener, OnTouchListener { + + private static final String TAG = "CAM_Switcher"; + private static final int SWITCHER_POPUP_ANIM_DURATION = 200; + + public interface CameraSwitchListener { + public void onCameraSelected(int i); + public void onShowSwitcherPopup(); + } + + private CameraSwitchListener mListener; + private int mCurrentIndex; + private int[] mModuleIds; + private int[] mDrawIds; + private int mItemSize; + private View mPopup; + private View mParent; + private boolean mShowingPopup; + private boolean mNeedsAnimationSetup; + private Drawable mIndicator; + + private float mTranslationX = 0; + private float mTranslationY = 0; + + private AnimatorListener mHideAnimationListener; + private AnimatorListener mShowAnimationListener; + + public CameraSwitcher(Context context) { + super(context); + init(context); + } + + public CameraSwitcher(Context context, AttributeSet attrs) { + super(context, attrs); + init(context); + } + + private void init(Context context) { + mItemSize = context.getResources().getDimensionPixelSize(R.dimen.switcher_size); + setOnClickListener(this); + mIndicator = context.getResources().getDrawable(R.drawable.ic_switcher_menu_indicator); + } + + public void setIds(int[] moduleids, int[] drawids) { + mDrawIds = drawids; + mModuleIds = moduleids; + } + + public void setCurrentIndex(int i) { + mCurrentIndex = i; + setImageResource(mDrawIds[i]); + } + + public void setSwitchListener(CameraSwitchListener l) { + mListener = l; + } + + @Override + public void onClick(View v) { + showSwitcher(); + mListener.onShowSwitcherPopup(); + } + + private void onCameraSelected(int ix) { + hidePopup(); + if ((ix != mCurrentIndex) && (mListener != null)) { + setCurrentIndex(ix); + mListener.onCameraSelected(mModuleIds[ix]); + } + } + + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + mIndicator.setBounds(getDrawable().getBounds()); + mIndicator.draw(canvas); + } + + private void initPopup() { + mParent = LayoutInflater.from(getContext()).inflate(R.layout.switcher_popup, + (ViewGroup) getParent()); + LinearLayout content = (LinearLayout) mParent.findViewById(R.id.content); + mPopup = content; + mPopup.setVisibility(View.INVISIBLE); + mNeedsAnimationSetup = true; + for (int i = mDrawIds.length - 1; i >= 0; i--) { + RotateImageView item = new RotateImageView(getContext()); + item.setImageResource(mDrawIds[i]); + item.setBackgroundResource(R.drawable.bg_pressed); + final int index = i; + item.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + onCameraSelected(index); + } + }); + switch (mDrawIds[i]) { + case R.drawable.ic_switch_camera: + item.setContentDescription(getContext().getResources().getString( + R.string.accessibility_switch_to_camera)); + break; + case R.drawable.ic_switch_video: + item.setContentDescription(getContext().getResources().getString( + R.string.accessibility_switch_to_video)); + break; + case R.drawable.ic_switch_pan: + item.setContentDescription(getContext().getResources().getString( + R.string.accessibility_switch_to_panorama)); + break; + case R.drawable.ic_switch_photosphere: + item.setContentDescription(getContext().getResources().getString( + R.string.accessibility_switch_to_new_panorama)); + break; + default: + break; + } + content.addView(item, new LinearLayout.LayoutParams(mItemSize, mItemSize)); + } + } + + public boolean showsPopup() { + return mShowingPopup; + } + + public boolean isInsidePopup(MotionEvent evt) { + if (!showsPopup()) return false; + return evt.getX() >= mPopup.getLeft() + && evt.getX() < mPopup.getRight() + && evt.getY() >= mPopup.getTop() + && evt.getY() < mPopup.getBottom(); + } + + private void hidePopup() { + mShowingPopup = false; + setVisibility(View.VISIBLE); + if (mPopup != null && !animateHidePopup()) { + mPopup.setVisibility(View.INVISIBLE); + } + mParent.setOnTouchListener(null); + } + + private void showSwitcher() { + mShowingPopup = true; + if (mPopup == null) { + initPopup(); + } + mPopup.setVisibility(View.VISIBLE); + if (!animateShowPopup()) { + setVisibility(View.INVISIBLE); + } + mParent.setOnTouchListener(this); + } + + @Override + public boolean onTouch(View v, MotionEvent event) { + closePopup(); + return true; + } + + public void closePopup() { + if (showsPopup()) { + hidePopup(); + } + } + + @Override + public void setOrientation(int degree, boolean animate) { + super.setOrientation(degree, animate); + ViewGroup content = (ViewGroup) mPopup; + if (content == null) return; + for (int i = 0; i < content.getChildCount(); i++) { + RotateImageView iv = (RotateImageView) content.getChildAt(i); + iv.setOrientation(degree, animate); + } + } + + private void updateInitialTranslations() { + if (getResources().getConfiguration().orientation + == Configuration.ORIENTATION_PORTRAIT) { + mTranslationX = -getWidth() / 2; + mTranslationY = getHeight(); + } else { + mTranslationX = getWidth(); + mTranslationY = getHeight() / 2; + } + } + private void popupAnimationSetup() { + if (!ApiHelper.HAS_VIEW_PROPERTY_ANIMATOR) { + return; + } + updateInitialTranslations(); + mPopup.setScaleX(0.3f); + mPopup.setScaleY(0.3f); + mPopup.setTranslationX(mTranslationX); + mPopup.setTranslationY(mTranslationY); + mNeedsAnimationSetup = false; + } + + private boolean animateHidePopup() { + if (!ApiHelper.HAS_VIEW_PROPERTY_ANIMATOR) { + return false; + } + if (mHideAnimationListener == null) { + mHideAnimationListener = new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + // Verify that we weren't canceled + if (!showsPopup()) { + mPopup.setVisibility(View.INVISIBLE); + } + } + }; + } + mPopup.animate() + .alpha(0f) + .scaleX(0.3f).scaleY(0.3f) + .translationX(mTranslationX) + .translationY(mTranslationY) + .setDuration(SWITCHER_POPUP_ANIM_DURATION) + .setListener(mHideAnimationListener); + animate().alpha(1f).setDuration(SWITCHER_POPUP_ANIM_DURATION) + .setListener(null); + return true; + } + + private boolean animateShowPopup() { + if (!ApiHelper.HAS_VIEW_PROPERTY_ANIMATOR) { + return false; + } + if (mNeedsAnimationSetup) { + popupAnimationSetup(); + } + if (mShowAnimationListener == null) { + mShowAnimationListener = new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + // Verify that we weren't canceled + if (showsPopup()) { + setVisibility(View.INVISIBLE); + } + } + }; + } + mPopup.animate() + .alpha(1f) + .scaleX(1f).scaleY(1f) + .translationX(0) + .translationY(0) + .setDuration(SWITCHER_POPUP_ANIM_DURATION) + .setListener(null); + animate().alpha(0f).setDuration(SWITCHER_POPUP_ANIM_DURATION) + .setListener(mShowAnimationListener); + return true; + } +} |