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 17package com.android.camera; 18 19import android.graphics.Bitmap; 20import android.graphics.Matrix; 21import android.graphics.RectF; 22import android.graphics.SurfaceTexture; 23import android.view.GestureDetector; 24import android.view.MotionEvent; 25import android.view.TextureView; 26import android.view.View; 27import android.view.ViewGroup; 28 29import com.android.camera.debug.Log; 30import com.android.camera.ui.CountDownView; 31import com.android.camera.ui.PreviewOverlay; 32import com.android.camera.ui.PreviewOverlay.OnZoomChangedListener; 33import com.android.camera.ui.PreviewStatusListener; 34import com.android.camera.ui.ProgressOverlay; 35import com.android.camera2.R; 36 37/** 38 * Contains the UI for the CaptureModule. 39 */ 40public 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 86 public void onPreviewAreaChanged(RectF previewArea) { 87 // TODO: mFaceView.onPreviewAreaChanged(previewArea); 88 mCountdownView.onPreviewAreaChanged(previewArea); 89 } 90 91 @Override 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 101 public boolean shouldAutoAdjustTransformMatrixOnLayout() { 102 return false; 103 } 104 105 @Override 106 public boolean shouldAutoAdjustBottomBar() { 107 return true; 108 } 109 110 @Override 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 117 public GestureDetector.OnGestureListener getGestureListener() { 118 return mPreviewGestureListener; 119 } 120 121 @Override 122 public View.OnTouchListener getTouchListener() { 123 return null; 124 } 125 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 147 public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { 148 mModule.onSurfaceTextureAvailable(surface, width, height); 149 } 150 151 @Override 152 public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { 153 return mModule.onSurfaceTextureDestroyed(surface); 154 } 155 156 @Override 157 public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) { 158 mModule.onSurfaceTextureSizeChanged(surface, width, height); 159 } 160 161 @Override 162 public void onSurfaceTextureUpdated(SurfaceTexture surface) { 163 mModule.onSurfaceTextureUpdated(surface); 164 } 165 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 */ 173 public int getPreviewAreaWidth() { 174 return mPreviewAreaWidth; 175 } 176 177 /** 178 * Getter for the height of the visible area of the preview. 179 */ 180 public int getPreviewAreaHeight() { 181 return mPreviewAreaHeight; 182 } 183 184 public Matrix getPreviewTransform(Matrix m) { 185 return mPreviewView.getTransform(m); 186 } 187 188 public void showAutoFocusInProgress() { 189 mFocusUI.onFocusStarted(); 190 } 191 192 public void showAutoFocusSuccess() { 193 mFocusUI.onFocusSucceeded(); 194 } 195 196 public void showAutoFocusFailure() { 197 mFocusUI.onFocusFailed(); 198 } 199 200 public void setPassiveFocusSuccess(boolean success) { 201 mFocusUI.setPassiveFocusSuccess(success); 202 } 203 204 public void showDebugMessage(String message) { 205 mFocusUI.showDebugMessage(message); 206 } 207 208 public void setAutoFocusTarget(int x, int y, boolean isPassiveScan, int afSize, int aeSize) { 209 mFocusUI.setFocusPosition(x, y, isPassiveScan, afSize, aeSize); 210 } 211 212 public void clearAutoFocusIndicator() { 213 mFocusUI.clearFocus(); 214 } 215 216 public void clearAutoFocusIndicator(boolean waitUntilProgressIsHidden) { 217 } 218 219 /** 220 * Starts the countdown timer. 221 * 222 * @param sec seconds to countdown 223 */ 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 */ 231 public void setCountdownFinishedListener(CountDownView.OnCountDownStatusListener listener) { 232 mCountdownView.setCountDownStatusListener(listener); 233 } 234 235 /** 236 * Returns whether the countdown is on-going. 237 */ 238 public boolean isCountingDown() { 239 return mCountdownView.isCountingDown(); 240 } 241 242 /** 243 * Cancels the on-going countdown, if any. 244 */ 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 */ 254 public void setPictureTakingProgress(int percent) { 255 mProgressOverlay.setProgress(percent); 256 } 257 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 */ 271 public void initializeZoom(float maxZoom) { 272 mMaxZoom = maxZoom; 273 mPreviewOverlay.setupZoom(mMaxZoom, 0, mZoomChancedListener); 274 } 275} 276