1 /* 2 * Copyright (C) 2014 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; 18 19 import android.graphics.Bitmap; 20 import android.graphics.Matrix; 21 import android.graphics.RectF; 22 import android.graphics.SurfaceTexture; 23 import android.view.GestureDetector; 24 import android.view.MotionEvent; 25 import android.view.TextureView; 26 import android.view.View; 27 import android.view.ViewGroup; 28 29 import com.android.camera.debug.Log; 30 import com.android.camera.ui.CountDownView; 31 import com.android.camera.ui.PreviewOverlay; 32 import com.android.camera.ui.PreviewOverlay.OnZoomChangedListener; 33 import com.android.camera.ui.PreviewStatusListener; 34 import com.android.camera.ui.ProgressOverlay; 35 import com.android.camera2.R; 36 37 /** 38 * Contains the UI for the CaptureModule. 39 */ 40 public class CaptureModuleUI implements 41 PreviewStatusListener { 42 43 private static final Log.Tag TAG = new Log.Tag("CaptureModuleUI"); 44 45 private final CameraActivity mActivity; 46 private final CaptureModule mModule; 47 private final View mRootView; 48 49 private final PreviewOverlay mPreviewOverlay; 50 private final ProgressOverlay mProgressOverlay; 51 private final View.OnLayoutChangeListener mLayoutListener; 52 private final TextureView mPreviewView; 53 54 private final GestureDetector.OnGestureListener mPreviewGestureListener = new GestureDetector.SimpleOnGestureListener() { 55 @Override 56 public boolean onSingleTapUp(MotionEvent ev) { 57 mModule.onSingleTapUp(null, (int) ev.getX(), (int) ev.getY()); 58 return true; 59 } 60 }; 61 private final FocusOverlayManager.FocusUI mFocusUI; 62 private final CountDownView mCountdownView; 63 64 private int mPreviewAreaWidth; 65 private int mPreviewAreaHeight; 66 67 /** Maximum zoom; intialize to 1.0 (disabled) */ 68 private float mMaxZoom = 1f; 69 70 /** Set up listener to receive zoom changes from View and send to module. */ 71 private final OnZoomChangedListener mZoomChancedListener = new OnZoomChangedListener() { 72 @Override 73 public void onZoomValueChanged(float ratio) { 74 mModule.setZoom(ratio); 75 } 76 77 @Override 78 public void onZoomStart() { 79 } 80 81 @Override 82 public void onZoomEnd() { 83 } 84 }; 85 onPreviewAreaChanged(RectF previewArea)86 public void onPreviewAreaChanged(RectF previewArea) { 87 // TODO: mFaceView.onPreviewAreaChanged(previewArea); 88 mCountdownView.onPreviewAreaChanged(previewArea); 89 } 90 91 @Override onPreviewLayoutChanged(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom)92 public void onPreviewLayoutChanged(View v, int left, int top, int right, 93 int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { 94 if (mLayoutListener != null) { 95 mLayoutListener.onLayoutChange(v, left, top, right, bottom, oldLeft, oldTop, oldRight, 96 oldBottom); 97 } 98 } 99 100 @Override shouldAutoAdjustTransformMatrixOnLayout()101 public boolean shouldAutoAdjustTransformMatrixOnLayout() { 102 return false; 103 } 104 105 @Override shouldAutoAdjustBottomBar()106 public boolean shouldAutoAdjustBottomBar() { 107 return true; 108 } 109 110 @Override onPreviewFlipped()111 public void onPreviewFlipped() { 112 // Do nothing because when preview is flipped, TextureView will lay 113 // itself out again, which will then trigger a transform matrix update. 114 } 115 116 @Override getGestureListener()117 public GestureDetector.OnGestureListener getGestureListener() { 118 return mPreviewGestureListener; 119 } 120 121 @Override getTouchListener()122 public View.OnTouchListener getTouchListener() { 123 return null; 124 } 125 CaptureModuleUI(CameraActivity activity, CaptureModule module, View parent, View.OnLayoutChangeListener layoutListener)126 public CaptureModuleUI(CameraActivity activity, CaptureModule module, View parent, 127 View.OnLayoutChangeListener layoutListener) { 128 mActivity = activity; 129 mModule = module; 130 mRootView = parent; 131 mLayoutListener = layoutListener; 132 133 ViewGroup moduleRoot = (ViewGroup) mRootView.findViewById(R.id.module_layout); 134 mActivity.getLayoutInflater().inflate(R.layout.capture_module, 135 moduleRoot, true); 136 137 mPreviewView = (TextureView) mRootView.findViewById(R.id.preview_content); 138 139 mPreviewOverlay = (PreviewOverlay) mRootView.findViewById(R.id.preview_overlay); 140 mProgressOverlay = (ProgressOverlay) mRootView.findViewById(R.id.progress_overlay); 141 142 mFocusUI = (FocusOverlayManager.FocusUI) mRootView.findViewById(R.id.focus_overlay); 143 mCountdownView = (CountDownView) mRootView.findViewById(R.id.count_down_view); 144 } 145 146 @Override onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height)147 public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { 148 mModule.onSurfaceTextureAvailable(surface, width, height); 149 } 150 151 @Override onSurfaceTextureDestroyed(SurfaceTexture surface)152 public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { 153 return mModule.onSurfaceTextureDestroyed(surface); 154 } 155 156 @Override onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height)157 public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) { 158 mModule.onSurfaceTextureSizeChanged(surface, width, height); 159 } 160 161 @Override onSurfaceTextureUpdated(SurfaceTexture surface)162 public void onSurfaceTextureUpdated(SurfaceTexture surface) { 163 mModule.onSurfaceTextureUpdated(surface); 164 } 165 positionProgressOverlay(RectF area)166 public void positionProgressOverlay(RectF area) { 167 mProgressOverlay.setBounds(area); 168 } 169 170 /** 171 * Getter for the width of the visible area of the preview. 172 */ getPreviewAreaWidth()173 public int getPreviewAreaWidth() { 174 return mPreviewAreaWidth; 175 } 176 177 /** 178 * Getter for the height of the visible area of the preview. 179 */ getPreviewAreaHeight()180 public int getPreviewAreaHeight() { 181 return mPreviewAreaHeight; 182 } 183 getPreviewTransform(Matrix m)184 public Matrix getPreviewTransform(Matrix m) { 185 return mPreviewView.getTransform(m); 186 } 187 showAutoFocusInProgress()188 public void showAutoFocusInProgress() { 189 mFocusUI.onFocusStarted(); 190 } 191 showAutoFocusSuccess()192 public void showAutoFocusSuccess() { 193 mFocusUI.onFocusSucceeded(); 194 } 195 showAutoFocusFailure()196 public void showAutoFocusFailure() { 197 mFocusUI.onFocusFailed(); 198 } 199 setPassiveFocusSuccess(boolean success)200 public void setPassiveFocusSuccess(boolean success) { 201 mFocusUI.setPassiveFocusSuccess(success); 202 } 203 showDebugMessage(String message)204 public void showDebugMessage(String message) { 205 mFocusUI.showDebugMessage(message); 206 } 207 setAutoFocusTarget(int x, int y, boolean isPassiveScan, int afSize, int aeSize)208 public void setAutoFocusTarget(int x, int y, boolean isPassiveScan, int afSize, int aeSize) { 209 mFocusUI.setFocusPosition(x, y, isPassiveScan, afSize, aeSize); 210 } 211 clearAutoFocusIndicator()212 public void clearAutoFocusIndicator() { 213 mFocusUI.clearFocus(); 214 } 215 clearAutoFocusIndicator(boolean waitUntilProgressIsHidden)216 public void clearAutoFocusIndicator(boolean waitUntilProgressIsHidden) { 217 } 218 219 /** 220 * Starts the countdown timer. 221 * 222 * @param sec seconds to countdown 223 */ startCountdown(int sec)224 public void startCountdown(int sec) { 225 mCountdownView.startCountDown(sec); 226 } 227 228 /** 229 * Sets a listener that gets notified when the countdown is finished. 230 */ setCountdownFinishedListener(CountDownView.OnCountDownStatusListener listener)231 public void setCountdownFinishedListener(CountDownView.OnCountDownStatusListener listener) { 232 mCountdownView.setCountDownStatusListener(listener); 233 } 234 235 /** 236 * Returns whether the countdown is on-going. 237 */ isCountingDown()238 public boolean isCountingDown() { 239 return mCountdownView.isCountingDown(); 240 } 241 242 /** 243 * Cancels the on-going countdown, if any. 244 */ cancelCountDown()245 public void cancelCountDown() { 246 mCountdownView.cancelCountDown(); 247 } 248 249 /** 250 * Sets the progress of the gcam picture taking. 251 * 252 * @param percent amount of process done in percent 0-100. 253 */ setPictureTakingProgress(int percent)254 public void setPictureTakingProgress(int percent) { 255 mProgressOverlay.setProgress(percent); 256 } 257 getBitMapFromPreview()258 public Bitmap getBitMapFromPreview() { 259 Matrix m = new Matrix(); 260 m = getPreviewTransform(m); 261 Bitmap src = mPreviewView.getBitmap(); 262 return Bitmap.createBitmap(src, 0, 0, src.getWidth(), src.getHeight(), m, true); 263 } 264 265 /** 266 * Enables zoom UI, setting maximum zoom. 267 * Called from Module when camera is available. 268 * 269 * @param maxZoom maximum zoom value. 270 */ initializeZoom(float maxZoom)271 public void initializeZoom(float maxZoom) { 272 mMaxZoom = maxZoom; 273 mPreviewOverlay.setupZoom(mMaxZoom, 0, mZoomChancedListener); 274 } 275 } 276