package com.android.camera; import java.lang.reflect.Method; import java.util.ArrayList; import android.animation.Animator; import android.animation.TimeInterpolator; import android.app.Activity; import android.content.Context; import android.content.res.Configuration; import android.graphics.Rect; import android.os.SystemClock; import android.util.AttributeSet; import android.util.Log; import android.view.GestureDetector; import android.view.MotionEvent; import android.view.View; import android.view.animation.DecelerateInterpolator; import android.widget.FrameLayout; import android.widget.RelativeLayout; import android.widget.TextView; import android.view.animation.Animation; import android.view.animation.Animation.AnimationListener; import android.view.animation.TranslateAnimation; import com.android.camera.ui.RotatableLayout; import com.android.camera.util.CameraUtil; import com.android.camera.util.PhotoSphereHelper; import com.android.camera2.R; public class ModuleSwitcherView extends RotatableLayout { private static String TAG = "CAM_ModuleSwitcherView"; private static final float SCROLL_GAT = 100.0f; private float SCROLL_RAT = 100 / 100; private float TEXT_VIEW_WITH = 60.0F; public int FOOT_HIGHT = 130; public static final int PHOTO_MODULE_INDEX = 0; public static final int VIDEO_MODULE_INDEX = 1; public static final int WIDE_ANGLE_PANO_MODULE_INDEX = 2; public static final int LIGHTCYCLE_MODULE_INDEX = 3; public static final int GCAM_MODULE_INDEX = 4; public static boolean isEnableParomara = MemeoryTotal.isGreateMemory(); private static final int[] TEXT_IDS = { R.string.switch_camera_text, R.string.switch_video_text, R.string.switch_panorama_text, R.string.switch_sphere_text, R.string.switch_gcam_text, }; private static int[] FRAMT_MODULE_INDEX = { VIDEO_MODULE_INDEX, PHOTO_MODULE_INDEX, WIDE_ANGLE_PANO_MODULE_INDEX, LIGHTCYCLE_MODULE_INDEX,GCAM_MODULE_INDEX}; public static final int MODULE_NUMBER_MAX = TEXT_IDS.length; private static final int MODULE_NUMBER_SURPORT = (MODULE_NUMBER_MAX-2)- (isEnableParomara?0:1); private float[] mTextLength = new float[MODULE_NUMBER_SURPORT]; private CameraActivity mActivity; private GestureDetector mGestureDetector; private int mOrientation; private int mCameraMoudleIndex; // SPRD: bug 258455 private boolean mVisibility; private boolean mIsLayoutFinish; private int mLastIndex; private int mNextIndex; private float mLastPosation; private boolean mScrolling; private boolean mStopScroll; private boolean mModuleChange; private int mConfiguration = 1; private boolean mIsLeft; private MotionEvent mScrollStart; private MotionEvent mScrollEv1; private String[] mDrawIds; private ArrayList<TextView> mTextViewList; private TextView mDelTextView; private String mLocalLanguage = "en"; private float mSystemTextScale = (float) 1.0; private GestureDetector.SimpleOnGestureListener mSimpleOnGestureListener = new GestureDetector.SimpleOnGestureListener() { @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { if (mStopScroll || mModuleChange) return super.onScroll(e1, e2, distanceX, distanceY); if (!mScrolling) { mScrollStart = MotionEvent.obtain(e2); mScrolling = true; mScrollEv1 = MotionEvent.obtain(e2); } else { if (mConfiguration == 1) { if (Math.abs(e2.getX() - mScrollStart.getX()) >= 100) { scrollEnd(e2.getX() - mScrollStart.getX()); } else if (true) { if (Math.abs(e2.getX() - mScrollEv1.getX()) >= SCROLL_RAT) { scrollIng(e2.getX() - mScrollEv1.getX(), false); mScrollEv1 = MotionEvent.obtain(e2); } } } else if (mConfiguration == 2) { if (Math.abs(e2.getY() - mScrollStart.getY()) >= 100) { scrollEnd(e2.getY() - mScrollStart.getY()); } else if (true) { if (Math.abs(e2.getY() - mScrollEv1.getY()) >= SCROLL_RAT) { scrollIng(e2.getY() - mScrollEv1.getY(), true); mScrollEv1 = MotionEvent.obtain(e2); } } } } return super.onScroll(e1, e2, distanceX, distanceY); } }; public interface ModuleSwitchViewListener { public void onModuleViewSelected(int i); public void onShowSwitcherViewPopup(); } private ModuleSwitchViewListener mListener; public ModuleSwitcherView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); initialize(context); } public ModuleSwitcherView(Context context, AttributeSet attrs) { super(context, attrs); initialize(context); } public ModuleSwitcherView(Context context) { super(context); initialize(context); } private void initialize(Context context) { mActivity = (CameraActivity) context; // SPRD: bug 258455 mVisibility = true; initializeDrawables(context); setSwitchListener(mActivity); mScrolling = false; mStopScroll = false; mScrollStart = null; mScrollEv1 = null; mIsLeft = true; mModuleChange = false; TEXT_VIEW_WITH = getContext().getResources(). getDimensionPixelSize(R.dimen.module_textview_with); FOOT_HIGHT = getContext().getResources(). getDimensionPixelSize(R.dimen.module_margin_bottom); SCROLL_RAT = SCROLL_GAT / TEXT_VIEW_WITH; Configuration c = mActivity.getResources().getConfiguration(); mLocalLanguage = c.locale.getLanguage(); mSystemTextScale = c.fontScale; Log.d(TAG, " mLocalLanguage =" + mLocalLanguage + " mSystemTextScale=" + mSystemTextScale); mGestureDetector = new GestureDetector(mSimpleOnGestureListener); } @Override public boolean onTouchEvent(MotionEvent event) { // SPRD: bug 258455 if(!mVisibility) return false; if (event.getAction() == MotionEvent.ACTION_CANCEL || event.getAction() == MotionEvent.ACTION_UP) { mStopScroll = false; if (mScrolling) { if (mConfiguration == 1) scrollEnd(event.getX() - mScrollStart.getX()); else if ((mConfiguration == 2)) scrollEnd(event.getY() - mScrollStart.getY()); } } mGestureDetector.onTouchEvent(event); return false; } public void setOrientation(int orientation) { Log.d(TAG, "setOrientation orientation = " + orientation); if (!mScrolling) mOrientation = orientation; } public void scrollEnd(float scrollX) { Log.d(TAG, "scrolleEnd Start"); if (mModuleChange) { return; } mScrolling = false; mScrollStart = null; mScrollEv1 = null; mIsLeft = (scrollX <= 0); if (!isEnableSwitch(scrollX <= 0)) { // SPRD: reset position of text view before return scrollEnd scrollBack(mConfiguration == 2); return; } if (mOrientation == 90 || mOrientation == 180) { mIsLeft = !mIsLeft; } if (Math.abs(scrollX) >= SCROLL_GAT) { mModuleChange = true; translateAnimat(scrollX); return; } scrollBack(mConfiguration == 2); } public void scrollIng(float scrollX, boolean lunch) { if (mConfiguration == 1 && lunch) return; if (mConfiguration == 2 && !lunch) return; if (mConfiguration == 1) scrollTextView(scrollX, false); else if (mConfiguration == 2) scrollTextView(scrollX, true); } public void onModuleSelected(int ix) { if (mListener != null) mListener.onModuleViewSelected(ix); } public void initializeDrawables(Context context) { int numDrawIds = TEXT_IDS.length; if (!PhotoSphereHelper.hasLightCycleCapture(context)) { --numDrawIds; } // Always decrement one because of GCam. --numDrawIds; String[] drawids = new String[numDrawIds]; int[] moduleids = new int[numDrawIds]; int ix = 0; for (int i = 0; i < TEXT_IDS.length; i++) { if (i == LIGHTCYCLE_MODULE_INDEX && !PhotoSphereHelper.hasLightCycleCapture(context)) { continue; // not enabled, so don't add to UI } if (i == GCAM_MODULE_INDEX) { continue; // don't add to UI } moduleids[ix] = FRAMT_MODULE_INDEX[i]; drawids[ix++] = mActivity.getString(TEXT_IDS[FRAMT_MODULE_INDEX[i]]); } setIds(moduleids, drawids); } public void setIds(int[] moduleids, String[] drawids) { mDrawIds = drawids; } public void setCurrentIndex(int i) { if (i < 0 || i > MODULE_NUMBER_SURPORT-1) return; mLastIndex = framtModuleIndex(i) - 1; mNextIndex = framtModuleIndex(i) + 1; if (mCameraMoudleIndex != i) mCameraMoudleIndex = i; scrollTextViewBound(mConfiguration == 2); } public void setSwitchListener(ModuleSwitchViewListener l) { mListener = l; } @Override protected void onFinishInflate() { // TODO Auto-generated method stub super.onFinishInflate(); mTextViewList = new ArrayList<TextView>(); mTextViewList.add((TextView) findViewById(R.id.last_switch_textview)); mTextViewList.add((TextView) findViewById(R.id.current_switch_textview)); if(MODULE_NUMBER_SURPORT >= 3) { mTextViewList.add((TextView) findViewById(R.id.next_switch_textview)); } for (int i = 0; i < mTextViewList.size(); i++) { mTextViewList.get(i).setText(mDrawIds[i]); if (mLocalLanguage.endsWith("en") && mSystemTextScale > 1.0) { mTextViewList.get(i).setTextScaleX(1 / mSystemTextScale); } } mDelTextView = (TextView)findViewById(R.id.del_switch_textview); mDelTextView.setText("●"); mDelTextView.setVisibility(VISIBLE); //start by liweiping 20140609 for bug141 for(TextView v : mTextViewList){ v.setOnClickListener(myOncClickListener); } //end by liweiping 20140609 for bug141 } //start by liweiping 20140609 for bug141 OnClickListener myOncClickListener = new OnClickListener() { @Override public void onClick(View v) { TextView tv = (TextView) v; String title = tv.getText().toString(); if(title.equals(getResources().getString(TEXT_IDS[0]))){ onModuleSelected(FRAMT_MODULE_INDEX[1]); }else if(title.equals(getResources().getString(TEXT_IDS[1]))){ onModuleSelected(FRAMT_MODULE_INDEX[0]); }else if(title.equals(getResources().getString(TEXT_IDS[2]))){ onModuleSelected(FRAMT_MODULE_INDEX[2]); } } }; //end by liweiping 20140609 for bug141 private float midX = 0; private float midY = 0; public void onLayoutTextView(boolean changed, int l, int t, int r, int b) { if (mModuleChange) { return; } this.layout(l, t, r, b); // SPRD: bug 258455 clearMove(); int orientation = getResources().getConfiguration().orientation; int rotation = CameraUtil.getDisplayRotation((Activity) getContext()); Log.d(TAG, "onLayoutTextView rotation == " + rotation + " && mConfiguration = " + mConfiguration); r = r - l; b = b - t; l = 0; t = 0; for (int i = 0; i < getChildCount(); i++) { View v = getChildAt(i); v.layout(l, t, r, b); } setOrientation(rotation); Rect shutter = new Rect(); boolean lunch = (r > b) ? true : false; int laignText = (mSystemTextScale == (float)1.3)?3:( (mSystemTextScale == (float)1.15)?2:( (mSystemTextScale == (float)1.0)?1:0)); int laignLanguage = (mLocalLanguage.equals("en"))?( (laignText == 3)?0:((laignText == 2)?3:( (laignText == 1)?6:5))):0; center(mDelTextView, l, t, r, b, orientation, rotation, shutter,FOOT_HIGHT); midX = shutter.left + shutter.width()/2; if(rotation == 270) { midX = midX + shutter.width()/2+ laignText+laignLanguage; } else if(rotation == 90) { midX = midX - shutter.width()/2- laignText-laignLanguage; } midY = shutter.top + shutter.height()/2; for (int i = 0; i < mTextViewList.size(); i++) { center(mTextViewList.get(i), l, t, r, b, orientation, rotation, shutter,FOOT_HIGHT); if (rotation == 90) { mTextLength[i] = midY+(0-i) * TEXT_VIEW_WITH - mTextViewList. get(i).getHeight() / 2; } else if (rotation == 0) { mTextLength[i] = midX+(i) * TEXT_VIEW_WITH - mTextViewList. get(i).getWidth() / 2; } else if (rotation == 270) { mTextLength[i] = midY+(i) * TEXT_VIEW_WITH - mTextViewList. get(i).getHeight() / 2; } else if (rotation == 180) { mTextLength[i] = midX + (0 - i) * TEXT_VIEW_WITH - mTextViewList. get(i).getWidth() / 2; } } updatTextView(rotation); scrollTextViewBound(lunch); } public void updatTextView(int orentation) { switch (orentation) { case 0: for (int i = 0; i < mTextViewList.size(); i++) { mTextViewList.get(i).setX(mTextLength[i]); mTextViewList.get(i).setY(midY+5); } break; case 180: for (int i = 0; i < mTextViewList.size(); i++) { mTextViewList.get(i).setX(mTextLength[i]); mTextViewList.get(i).setY(midY -mTextViewList. get(0).getHeight()-5); } break; case 90: for (int i = 0; i < mTextViewList.size(); i++) { mTextViewList.get(i).setY(mTextLength[i]); mTextViewList.get(i).setX(midX + 5 - (float) ((mTextViewList.get(i).getWidth() - mTextViewList.get(0).getWidth()) / 2)); } break; case 270: for (int i = 0; i < mTextViewList.size(); i++) { mTextViewList.get(i).setY(mTextLength[i]); mTextViewList.get(i).setX(midX-mTextViewList. get(i).getWidth() - 5 + (float)((mTextViewList.get(i).getWidth() - mTextViewList.get(0).getWidth()) / 2)); } break; } } public void scrollTextView(float length, boolean lunch) { length = isEnableScrollText(length,(length<=0)); moveTextView(lunch, length / SCROLL_RAT); } public void scrollBack(boolean lunch) { if(mTextViewList.size() <= 0) return; float length = 0; length = (lunch)?mLastPosation - mTextViewList.get(0).getY(): mLastPosation - mTextViewList.get(0).getX(); moveTextView(lunch, length); } public boolean isEnableSwitch(boolean left) { left = (mOrientation == 90 || mOrientation == 180)?!left:left; if (mLastIndex < 0 && !left) { return false; } if (mNextIndex > MODULE_NUMBER_SURPORT-1 && left) return false; return true; } public float isEnableScrollText(float length, boolean left) { if(length == 0 )return 0; left = (mOrientation == 90 || mOrientation == 180)?!left:left; float bound = (mOrientation == 0 || mOrientation == 180)? mTextViewList.get(0).getX():mTextViewList.get(0).getY(); if (mLastIndex < 0 && !left) { if(mOrientation == 0 || mOrientation == 270 ) { if(mLastPosation <= bound+length) { scrollEnd(0); return 0; } } else if(mOrientation == 90 || mOrientation == 180) { if(mLastPosation >= bound+length) { scrollEnd(0); return 0; } } } if (mNextIndex > MODULE_NUMBER_SURPORT-1 && left) { if(mOrientation == 0 || mOrientation == 270 ) { if(mLastPosation >= bound+length) { scrollEnd(0); return 0; } } else if (mOrientation == 90 || mOrientation == 180) { if(mLastPosation <= bound+length) { scrollEnd(0); return 0; } } } return length; } public void scrollTextViewBound(boolean lunch) { // SPRD: bug 258455 if (mTextLength == null) return; if(mTextViewList.size() <=0) return; float length = mTextLength[FRAMT_MODULE_INDEX[mCameraMoudleIndex]] - (lunch ? mTextViewList.get(0).getY() : mTextViewList.get(0) .getX()-(float)((mTextViewList.get(FRAMT_MODULE_INDEX[mCameraMoudleIndex]).getWidth() - mTextViewList.get(0).getWidth()) / 2)); moveTextView(lunch, -length); mLastPosation = (lunch)?mTextViewList.get(0).getY() : mTextViewList.get(0).getX(); } public void moveTextView(boolean lunch, float length) { Log.d(TAG, "movoTextView lunch == " + lunch + " && length == " + length); if (lunch) { for (int i = 0; i < mTextViewList.size(); i++) mTextViewList.get(i).setY(mTextViewList.get(i) .getY() + length); } else { for (int i = 0; i < mTextViewList.size(); i++) { mTextViewList.get(i).setX(mTextViewList.get(i). getX() + length); } } } public void clearMove() { for (int i = 0; i < mTextViewList.size(); i++) { mTextViewList.get(i).setY(midY); mTextViewList.get(i).setX(midX); } } public boolean isLayoutFinish() { if (mIsLayoutFinish) return true; TextView tmp = (TextView) mActivity .findViewById(R.id.last_switch_textview); if (tmp != null) mIsLayoutFinish = true; if (mIsLayoutFinish) return true; return false; } public void setmConfiguration(int configuration) { mConfiguration = configuration; } // @{ SPRD: bug 258455 begin public void setViewVisibility(int visibal) { mVisibility = !(visibal == INVISIBLE); if (mTextViewList != null && mTextViewList.size() > 0) { for (int i = 0; i < mTextViewList.size(); i++) mTextViewList.get(i).setVisibility(visibal); } if(mDelTextView != null) mDelTextView.setVisibility(visibal); } // SPRD: bug 258455 end @} public void setViewVisibility(int visibal,boolean enable) { if (mTextViewList != null && mTextViewList.size() > 0) { for (int i = 0; i < mTextViewList.size(); i++) mTextViewList.get(i).setVisibility(visibal); } if(mDelTextView != null) mDelTextView.setVisibility(visibal); } private static class MemeoryTotal { private static final long MINX_MEMORY_FOR_PANORAMA = 256 * 1024 * 1024; private static MemeoryTotal mMemeoryTotal; private static boolean isGreateMemory = false; private MemeoryTotal() { long startTime = SystemClock.uptimeMillis(); long iMemorySize = 0; try { Class ownerProcess = Class.forName("android.os.Process"); Method getTotalMemory = ownerProcess.getMethod("getTotalMemory", null); iMemorySize = (Long) getTotalMemory.invoke(null, null); isGreateMemory = iMemorySize > MINX_MEMORY_FOR_PANORAMA; } catch (Exception e) { Log.d(TAG, "invokeStaticGetTotalMemory exception e = " + e); } Log.d(TAG, "take up time : "+(SystemClock.uptimeMillis() - startTime)); } protected static boolean isGreateMemory() { if (mMemeoryTotal == null) { mMemeoryTotal = new MemeoryTotal(); } return isGreateMemory; } } private int framtModuleIndex(int moduleindex) { for(int i=0;i<=MODULE_NUMBER_SURPORT;i++) { if(FRAMT_MODULE_INDEX[i] == moduleindex) return i; } return 0; } private void center(View v, int l, int t, int r, int b, int orientation, int rotation, Rect result,int foot) { FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) v.getLayoutParams(); int tw = lp.leftMargin + v.getMeasuredWidth() + lp.rightMargin; int th = lp.topMargin + v.getMeasuredHeight() + lp.bottomMargin; switch (rotation) { case 0: // phone portrait; controls bottom result.left = (r + l) / 2 - tw / 2 + lp.leftMargin; result.right = (r + l) / 2 + tw / 2 - lp.rightMargin; result.bottom = b - lp.bottomMargin - foot; result.top = b - th + lp.topMargin - foot; break; case 90: // phone landscape: controls right result.right = r - 8 - lp.rightMargin -foot; result.left = r - 8 - tw + lp.leftMargin - foot; result.top = (b + t) / 2 - th / 2 + lp.topMargin; result.bottom = (b + t) / 2 + th / 2 - lp.bottomMargin; break; case 180: // phone upside down: controls top result.left = (r + l) / 2 - tw / 2 + lp.leftMargin; result.right = (r + l) / 2 + tw / 2 - lp.rightMargin; result.top = t + lp.topMargin +foot; result.bottom = t + th - lp.bottomMargin + foot; break; case 270: // reverse landscape: controls left result.left = l + 8 + lp.leftMargin + foot; result.right = l + tw + 8 - lp.rightMargin + foot; result.top = (b + t) / 2 - th / 2 + lp.topMargin; result.bottom = (b + t) / 2 + th / 2 - lp.bottomMargin; break; } v.layout(result.left, result.top, result.right, result.bottom); v.setRotation(360-rotation); } private void translateAnimat(float length) { final boolean sIsLeft = (mOrientation == 90 || mOrientation == 180) ? (length > 0) : (length <= 0); float lengthOf = mTextLength[0] - ((mConfiguration == 2) ? mTextViewList.get( sIsLeft ? mNextIndex : mLastIndex).getY() : mTextViewList.get(sIsLeft ? mNextIndex : mLastIndex) .getX()) - (mTextViewList.get(sIsLeft ? mNextIndex : mLastIndex) .getWidth() - mTextViewList.get(0).getWidth()) / 2; final ArrayList<TranslateAnimation> animatList = new ArrayList<TranslateAnimation>(); for (int i = 0; i < mTextViewList.size(); i++) { animatList.add((mConfiguration == 2) ? (new TranslateAnimation(0, 0, 0, lengthOf)) : (new TranslateAnimation(0, lengthOf, 0, 0))); animatList.get(i).setDuration(200); } if (animatList.size() > 0 && animatList.get(0) != null) { animatList.get(0).setAnimationListener(new AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { setCurrentIndex((sIsLeft) ? FRAMT_MODULE_INDEX[mNextIndex] : FRAMT_MODULE_INDEX[mLastIndex]); onModuleSelected(mCameraMoudleIndex); mStopScroll = true; mModuleChange = false; } @Override public void onAnimationRepeat(Animation animation) { } }); for (int i = 0; i < mTextViewList.size(); i++) { mTextViewList.get(i).startAnimation(animatList.get(i)); } } } }