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