1 /* 2 * Copyright (C) 2013 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 17 package com.android.camera.ui; 18 19 import android.app.Activity; 20 import android.content.Context; 21 import android.content.Intent; 22 import android.provider.MediaStore; 23 import android.util.AttributeSet; 24 import android.view.MotionEvent; 25 import android.view.View; 26 import android.view.ViewConfiguration; 27 import android.widget.FrameLayout; 28 29 import com.android.camera.app.CameraAppUI; 30 import com.android.camera.debug.Log; 31 import com.android.camera.util.CameraUtil; 32 import com.android.camera.widget.FilmstripLayout; 33 import com.android.camera2.R; 34 35 public class MainActivityLayout extends FrameLayout { 36 37 private final Log.Tag TAG = new Log.Tag("MainActivityLayout"); 38 // Only check for intercepting touch events within first 500ms 39 private static final int SWIPE_TIME_OUT = 500; 40 41 private ModeListView mModeList; 42 private FilmstripLayout mFilmstripLayout; 43 private boolean mCheckToIntercept; 44 private MotionEvent mDown; 45 private final int mSlop; 46 private boolean mRequestToInterceptTouchEvents = false; 47 private View mTouchReceiver = null; 48 private final boolean mIsCaptureIntent; 49 private CameraAppUI.NonDecorWindowSizeChangedListener mNonDecorWindowSizeChangedListener = null; 50 51 // TODO: This can be removed once we come up with a new design for b/13751653. 52 @Deprecated 53 private boolean mSwipeEnabled = true; 54 MainActivityLayout(Context context, AttributeSet attrs)55 public MainActivityLayout(Context context, AttributeSet attrs) { 56 super(context, attrs); 57 mSlop = ViewConfiguration.get(context).getScaledTouchSlop(); 58 59 Activity activity = (Activity) context; 60 Intent intent = activity.getIntent(); 61 String action = intent.getAction(); 62 mIsCaptureIntent = (MediaStore.ACTION_IMAGE_CAPTURE.equals(action) 63 || MediaStore.ACTION_IMAGE_CAPTURE_SECURE.equals(action) 64 || MediaStore.ACTION_VIDEO_CAPTURE.equals(action)); 65 } 66 67 /** 68 * Enables or disables the swipe for modules not supporting the new swipe 69 * logic yet. 70 */ 71 @Deprecated setSwipeEnabled(boolean enabled)72 public void setSwipeEnabled(boolean enabled) { 73 mSwipeEnabled = enabled; 74 } 75 76 @Override onInterceptTouchEvent(MotionEvent ev)77 public boolean onInterceptTouchEvent(MotionEvent ev) { 78 if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) { 79 mCheckToIntercept = true; 80 mDown = MotionEvent.obtain(ev); 81 mTouchReceiver = null; 82 mRequestToInterceptTouchEvents = false; 83 return false; 84 } else if (mRequestToInterceptTouchEvents) { 85 mRequestToInterceptTouchEvents = false; 86 onTouchEvent(mDown); 87 return true; 88 } else if (ev.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN) { 89 // Do not intercept touch once child is in zoom mode 90 mCheckToIntercept = false; 91 return false; 92 } else { 93 // TODO: This can be removed once we come up with a new design for b/13751653. 94 if (!mCheckToIntercept) { 95 return false; 96 } 97 if (ev.getEventTime() - ev.getDownTime() > SWIPE_TIME_OUT) { 98 return false; 99 } 100 if (mIsCaptureIntent || !mSwipeEnabled) { 101 return false; 102 } 103 int deltaX = (int) (ev.getX() - mDown.getX()); 104 int deltaY = (int) (ev.getY() - mDown.getY()); 105 if (ev.getActionMasked() == MotionEvent.ACTION_MOVE 106 && Math.abs(deltaX) > mSlop) { 107 // Intercept right swipe 108 if (deltaX >= Math.abs(deltaY) * 2) { 109 mTouchReceiver = mModeList; 110 onTouchEvent(mDown); 111 return true; 112 } 113 // Intercept left swipe 114 else if (deltaX < -Math.abs(deltaY) * 2) { 115 mTouchReceiver = mFilmstripLayout; 116 onTouchEvent(mDown); 117 return true; 118 } 119 } 120 } 121 return false; 122 } 123 124 @Override onTouchEvent(MotionEvent ev)125 public boolean onTouchEvent(MotionEvent ev) { 126 if (mTouchReceiver != null) { 127 mTouchReceiver.setVisibility(VISIBLE); 128 return mTouchReceiver.dispatchTouchEvent(ev); 129 } 130 return false; 131 } 132 133 @Override onFinishInflate()134 public void onFinishInflate() { 135 mModeList = (ModeListView) findViewById(R.id.mode_list_layout); 136 mFilmstripLayout = (FilmstripLayout) findViewById(R.id.filmstrip_layout); 137 } 138 redirectTouchEventsTo(View touchReceiver)139 public void redirectTouchEventsTo(View touchReceiver) { 140 if (touchReceiver == null) { 141 Log.e(TAG, "Cannot redirect touch to a null receiver."); 142 return; 143 } 144 mTouchReceiver = touchReceiver; 145 mRequestToInterceptTouchEvents = true; 146 } 147 148 @Override onMeasure(int widthMeasureSpec, int heightMeasureSpec)149 public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 150 if (mNonDecorWindowSizeChangedListener != null) { 151 mNonDecorWindowSizeChangedListener.onNonDecorWindowSizeChanged( 152 MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.getSize(heightMeasureSpec), 153 CameraUtil.getDisplayRotation()); 154 } 155 super.onMeasure(widthMeasureSpec, heightMeasureSpec); 156 } 157 158 /** 159 * Sets a listener that gets notified when the layout size is changed. This 160 * size is the size of main activity layout. It is also the size of the window 161 * excluding the system decor such as status bar and nav bar. 162 */ setNonDecorWindowSizeChangedListener( CameraAppUI.NonDecorWindowSizeChangedListener listener)163 public void setNonDecorWindowSizeChangedListener( 164 CameraAppUI.NonDecorWindowSizeChangedListener listener) { 165 mNonDecorWindowSizeChangedListener = listener; 166 if (mNonDecorWindowSizeChangedListener != null) { 167 mNonDecorWindowSizeChangedListener.onNonDecorWindowSizeChanged( 168 getMeasuredWidth(), getMeasuredHeight(), 169 CameraUtil.getDisplayRotation()); 170 } 171 } 172 }