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