From bb800ac9bf961b9e53ec56a1a5ababf31b9d40a1 Mon Sep 17 00:00:00 2001 From: Danny Baumann Date: Fri, 15 Jan 2016 09:53:27 +0100 Subject: Fix up layout of auto HDR notice and histogram view. Change-Id: I61f93c68b52d81c5e19919a5b0b894cf51dd35c4 --- res/layout-port/camera_controls.xml | 14 ++ res/layout/photo_module.xml | 17 -- res/values/cm_strings.xml | 1 + src/com/android/camera/PhotoModule.java | 270 +++---------------------- src/com/android/camera/PhotoUI.java | 12 ++ src/com/android/camera/ui/CameraControls.java | 48 ++++- src/com/android/camera/ui/HistogramView.java | 130 ++++++++++++ src/com/android/camera/ui/RotatableLayout.java | 2 +- 8 files changed, 230 insertions(+), 264 deletions(-) create mode 100644 src/com/android/camera/ui/HistogramView.java diff --git a/res/layout-port/camera_controls.xml b/res/layout-port/camera_controls.xml index d979147c6..bb73cf3c5 100644 --- a/res/layout-port/camera_controls.xml +++ b/res/layout-port/camera_controls.xml @@ -98,4 +98,18 @@ android:src="@drawable/remaining_sheets" /> + + + + diff --git a/res/layout/photo_module.xml b/res/layout/photo_module.xml index a516f0034..7487e73b2 100644 --- a/res/layout/photo_module.xml +++ b/res/layout/photo_module.xml @@ -40,23 +40,6 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:background="@android:color/black" /> - - - - 15 30 + Auto HDR enabled diff --git a/src/com/android/camera/PhotoModule.java b/src/com/android/camera/PhotoModule.java index 30956c4e2..78fe8ee56 100644 --- a/src/com/android/camera/PhotoModule.java +++ b/src/com/android/camera/PhotoModule.java @@ -123,12 +123,7 @@ public class PhotoModule private int mLongshotSnapNum = 0; public boolean mFaceDetectionEnabled = false; private boolean mLgeHdrMode = false; - private DrawAutoHDR mDrawAutoHDR; - /*Histogram variables*/ - private GraphView mGraphView; - private static final int STATS_DATA = 257; - public static int statsdata[] = new int[STATS_DATA]; - public boolean mHiston = false; + public boolean mHistogramEnabled = false; // We number the request code from 1000 to avoid collision with Gallery. private static final int REQUEST_CROP = 1000; @@ -169,7 +164,6 @@ public class PhotoModule private PhotoUI mUI; - public boolean mAutoHdrEnable; // The activity is going to switch to the specified camera id. This is // needed because texture copy is done in GL thread. -1 means camera is not // switching. @@ -833,14 +827,6 @@ public class PhotoModule } mNamedImages = new NamedImages(); - mGraphView = (GraphView)mRootView.findViewById(R.id.graph_view); - mDrawAutoHDR = (DrawAutoHDR )mRootView.findViewById(R.id.autohdr_view); - if (mGraphView == null || mDrawAutoHDR == null){ - Log.e(TAG, "mGraphView or mDrawAutoHDR is null"); - } else{ - mGraphView.setPhotoModuleObject(this); - mDrawAutoHDR.setPhotoModuleObject(this); - } mFirstTimeInitialized = true; Log.d(TAG, "addIdleHandler in first time initialization"); @@ -1031,19 +1017,14 @@ public class PhotoModule private final class StatsCallback implements android.hardware.Camera.CameraDataCallback { @Override - public void onCameraData(int [] data, android.hardware.Camera camera) { - //if(!mPreviewing || !mHiston || !mFirstTimeInitialized){ - if(!mHiston || !mFirstTimeInitialized){ + public void onCameraData(final int [] data, android.hardware.Camera camera) { + if (!mHistogramEnabled || !mFirstTimeInitialized){ return; } - /*The first element in the array stores max hist value . Stats data begin from second value*/ - synchronized(statsdata) { - System.arraycopy(data,0,statsdata,0,STATS_DATA); - } mActivity.runOnUiThread(new Runnable() { + @Override public void run() { - if(mGraphView != null) - mGraphView.PreviewChanged(); + mUI.updateHistogramData(data); } }); } @@ -1058,24 +1039,13 @@ public class PhotoModule for (int i =0;i<3;i++) { metadata[i] = byteToInt( (byte []) data, i*4); } - if (metadata[2] == 1) { - mAutoHdrEnable = true; - mActivity.runOnUiThread(new Runnable() { - public void run() { - if (mDrawAutoHDR != null) - mDrawAutoHDR.AutoHDR(); - } - }); - } - else { - mAutoHdrEnable = false; - mActivity.runOnUiThread(new Runnable() { - public void run() { - if (mDrawAutoHDR != null) - mDrawAutoHDR.AutoHDR(); - } - }); - } + final boolean autoHdrEnabled = metadata[2] == 1; + mActivity.runOnUiThread(new Runnable() { + @Override + public void run() { + mUI.setAutoHdrEnabled(autoHdrEnabled); + } + }); } } @@ -1401,16 +1371,14 @@ public class PhotoModule mLongshotSnapNum = 0; } - if (mHiston && (mSnapshotMode ==CameraInfo.CAMERA_SUPPORT_MODE_ZSL)) { + if (mHistogramEnabled && (mSnapshotMode ==CameraInfo.CAMERA_SUPPORT_MODE_ZSL)) { mActivity.runOnUiThread(new Runnable() { - public void run() { - if (mGraphView != null) { - mGraphView.setVisibility(View.VISIBLE); - mGraphView.PreviewChanged(); + @Override + public void run() { + mUI.setHistogramEnabled(true, getCamera()); } - } - }); - } + }); + } if (mSnapshotMode == CameraInfo.CAMERA_SUPPORT_MODE_ZSL && mCameraState != LONGSHOT && mReceivedSnapNum == mBurstSnapNum && @@ -1544,15 +1512,15 @@ public class PhotoModule mJpegImageData = null; final boolean animateBefore = (mSceneMode == CameraUtil.SCENE_MODE_HDR); - if(mHiston) { + if(mHistogramEnabled) { if (mSnapshotMode != CameraInfo.CAMERA_SUPPORT_MODE_ZSL) { - mHiston = false; + mHistogramEnabled = false; mCameraDevice.setHistogramMode(null); } mActivity.runOnUiThread(new Runnable() { + @Override public void run() { - if(mGraphView != null) - mGraphView.setVisibility(View.INVISIBLE); + mUI.setHistogramEnabled(false, null); } }); } @@ -1946,9 +1914,6 @@ public class PhotoModule mCameraDevice.setParameters(mParameters); } mUI.setOrientation(mOrientation, true); - if (mGraphView != null) { - mGraphView.setRotation(-mOrientation); - } } // Show the toast after getting the first orientation changed. @@ -1956,14 +1921,6 @@ public class PhotoModule mHandler.removeMessages(SHOW_TAP_TO_FOCUS_TOAST); showTapToFocusToast(); } - - // need to re-initialize mGraphView to show histogram on rotate - mGraphView = (GraphView)mRootView.findViewById(R.id.graph_view); - if(mGraphView != null){ - mGraphView.setAlpha(0.75f); - mGraphView.setPhotoModuleObject(this); - mGraphView.PreviewChanged(); - } } @Override @@ -3172,26 +3129,9 @@ public class PhotoModule if (CameraUtil.isAutoHDRSupported(mParameters)) { mParameters.set("auto-hdr-enable",auto_hdr); if (auto_hdr.equals("enable")) { - mActivity.runOnUiThread(new Runnable() { - public void run() { - if (mDrawAutoHDR != null) { - mDrawAutoHDR.setVisibility(View.VISIBLE); - } - } - }); mParameters.setSceneMode("asd"); mCameraDevice.setMetadataCb(mMetaDataCallback); } - else { - mAutoHdrEnable = false; - mActivity.runOnUiThread( new Runnable() { - public void run () { - if (mDrawAutoHDR != null) { - mDrawAutoHDR.setVisibility (View.INVISIBLE); - } - } - }); - } } mParameters.setZSLMode(zsl); if(zsl.equals("on")) { @@ -3264,27 +3204,14 @@ public class PhotoModule if (CameraUtil.isSupported(histogram, mParameters.getSupportedHistogramModes()) && mCameraDevice != null) { // Call for histogram - if(histogram.equals("enable")) { - mActivity.runOnUiThread(new Runnable() { - public void run() { - if(mGraphView != null) { - mGraphView.setVisibility(View.VISIBLE); - mGraphView.PreviewChanged(); - } - } - }); - mCameraDevice.setHistogramMode(mStatsCallback); - mHiston = true; - } else { - mHiston = false; - mActivity.runOnUiThread(new Runnable() { - public void run() { - if (mGraphView != null) - mGraphView.setVisibility(View.INVISIBLE); - } - }); - mCameraDevice.setHistogramMode(null); - } + mHistogramEnabled = histogram.equals("enable"); + mActivity.runOnUiThread(new Runnable() { + @Override + public void run() { + mUI.setHistogramEnabled(mHistogramEnabled, getCamera()); + } + }); + mCameraDevice.setHistogramMode(mHistogramEnabled ? mStatsCallback : null); } setFlipValue(); @@ -4460,140 +4387,3 @@ public class PhotoModule !mLongshotActive); } } - -class GraphView extends View { - private Bitmap mBitmap; - private Paint mPaint = new Paint(); - private Paint mPaintRect = new Paint(); - private Canvas mCanvas = new Canvas(); - private float mScale = (float)3; - private float mWidth; - private float mHeight; - private PhotoModule mPhotoModule; - private CameraManager.CameraProxy mGraphCameraDevice; - private float scaled; - private static final int STATS_SIZE = 256; - - public GraphView(Context context, AttributeSet attrs) { - super(context,attrs); - - mPaint.setFlags(Paint.ANTI_ALIAS_FLAG); - mPaintRect.setColor(0xFFFFFFFF); - mPaintRect.setStyle(Paint.Style.FILL); - } - @Override - protected void onSizeChanged(int w, int h, int oldw, int oldh) { - mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.RGB_565); - mCanvas.setBitmap(mBitmap); - mWidth = w; - mHeight = h; - super.onSizeChanged(w, h, oldw, oldh); - } - @Override - protected void onDraw(Canvas canvas) { - if(mPhotoModule == null || !mPhotoModule.mHiston ) { - return; - } - - if (mBitmap != null) { - final Paint paint = mPaint; - final Canvas cavas = mCanvas; - final float border = 5; - float graphheight = mHeight - (2 * border); - float graphwidth = mWidth - (2 * border); - float left,top,right,bottom; - float bargap = 0.0f; - float barwidth = graphwidth/STATS_SIZE; - - cavas.drawColor(0xFFAAAAAA); - paint.setColor(Color.BLACK); - - for (int k = 0; k <= (graphheight /32) ; k++) { - float y = (float)(32 * k)+ border; - cavas.drawLine(border, y, graphwidth + border , y, paint); - } - for (int j = 0; j <= (graphwidth /32); j++) { - float x = (float)(32 * j)+ border; - cavas.drawLine(x, border, x, graphheight + border, paint); - } - synchronized(PhotoModule.statsdata) { - //Assumption: The first element contains - // the maximum value. - int maxValue = Integer.MIN_VALUE; - if ( 0 == PhotoModule.statsdata[0] ) { - for ( int i = 1 ; i <= STATS_SIZE ; i++ ) { - if ( maxValue < PhotoModule.statsdata[i] ) { - maxValue = PhotoModule.statsdata[i]; - } - } - } else { - maxValue = PhotoModule.statsdata[0]; - } - mScale = ( float ) maxValue; - for(int i=1 ; i<=STATS_SIZE ; i++) { - scaled = (PhotoModule.statsdata[i]/mScale)*STATS_SIZE; - if(scaled >= (float)STATS_SIZE) - scaled = (float)STATS_SIZE; - left = (bargap * (i+1)) + (barwidth * i) + border; - top = graphheight + border; - right = left + barwidth; - bottom = top - scaled; - cavas.drawRect(left, top, right, bottom, mPaintRect); - } - } - canvas.drawBitmap(mBitmap, 0, 0, null); - } - if (mPhotoModule.mHiston && mPhotoModule!= null) { - mGraphCameraDevice = mPhotoModule.getCamera(); - if (mGraphCameraDevice != null){ - mGraphCameraDevice.sendHistogramData(); - } - } - } - public void PreviewChanged() { - invalidate(); - } - public void setPhotoModuleObject(PhotoModule photoModule) { - mPhotoModule = photoModule; - } -} - -class DrawAutoHDR extends View{ - - private static final String TAG = "AutoHdrView"; - private PhotoModule mPhotoModule; - - public DrawAutoHDR (Context context, AttributeSet attrs) { - super(context,attrs); - } - - @Override - protected void onDraw (Canvas canvas) { - if (mPhotoModule == null) - return; - if (mPhotoModule.mAutoHdrEnable) { - Paint AutoHDRPaint = new Paint(); - AutoHDRPaint.setColor(Color.WHITE); - AutoHDRPaint.setAlpha (0); - canvas.drawPaint(AutoHDRPaint); - AutoHDRPaint.setStyle(Paint.Style.STROKE); - AutoHDRPaint.setColor(Color.MAGENTA); - AutoHDRPaint.setStrokeWidth(1); - AutoHDRPaint.setTextSize(16); - AutoHDRPaint.setAlpha (255); - canvas.drawText("HDR On",200,100,AutoHDRPaint); - } - else { - super.onDraw(canvas); - return; - } - } - - public void AutoHDR () { - invalidate(); - } - - public void setPhotoModuleObject (PhotoModule photoModule) { - mPhotoModule = photoModule; - } -} diff --git a/src/com/android/camera/PhotoUI.java b/src/com/android/camera/PhotoUI.java index d5ddaf0c7..926550049 100644 --- a/src/com/android/camera/PhotoUI.java +++ b/src/com/android/camera/PhotoUI.java @@ -686,6 +686,18 @@ public class PhotoUI implements PieListener, mMenu.overrideSettings(keyvalues); } + public void setAutoHdrEnabled(boolean enabled) { + mCameraControls.setAutoHdrEnabled(enabled); + } + + public void setHistogramEnabled(boolean enabled, CameraManager.CameraProxy camera) { + mCameraControls.setHistogramEnabled(enabled, camera); + } + + public void updateHistogramData(int[] data) { + mCameraControls.updateHistogramData(data); + } + public void setCameraState(int state) { } diff --git a/src/com/android/camera/ui/CameraControls.java b/src/com/android/camera/ui/CameraControls.java index f4449182b..adaf34271 100644 --- a/src/com/android/camera/ui/CameraControls.java +++ b/src/com/android/camera/ui/CameraControls.java @@ -37,6 +37,7 @@ import android.widget.TextView; import java.util.ArrayList; import org.codeaurora.snapcam.R; +import com.android.camera.CameraManager; import com.android.camera.ui.ModuleSwitcher; import com.android.camera.ui.RotateImageView; import com.android.camera.ShutterButton; @@ -55,6 +56,8 @@ public class CameraControls extends RotatableLayout { private View mPreview; private View mSceneModeSwitcher; private View mFilterModeSwitcher; + private View mAutoHdrNotice; + private HistogramView mHistogramView; private ArrowTextView mRefocusToast; private int mSize; @@ -194,10 +197,12 @@ public class CameraControls extends RotatableLayout { mFilterModeSwitcher = findViewById(R.id.filter_mode_switcher); mRemainingPhotos = (LinearLayout) findViewById(R.id.remaining_photos); mRemainingPhotosText = (TextView) findViewById(R.id.remaining_photos_text); + mAutoHdrNotice = (TextView) findViewById(R.id.auto_hdr_notice); + mHistogramView = (HistogramView) findViewById(R.id.histogram); mTopViews = new View[] { mSceneModeSwitcher, mFilterModeSwitcher, mHdrSwitcher, - mFrontBackSwitcher, mMenu + mFrontBackSwitcher, mMenu, mAutoHdrNotice, mHistogramView }; mBottomViews = new View[] { mPreview, mShutter, mSwitcher @@ -250,6 +255,13 @@ public class CameraControls extends RotatableLayout { asRow(true, w, h, rotation, mSceneModeSwitcher, mFilterModeSwitcher, mFrontBackSwitcher, mHdrSwitcher, mMenu); + center(mAutoHdrNotice, l, t + mSize, r, + t + mSize + mAutoHdrNotice.getMeasuredHeight(), + orientation, rotation, new Rect()); + center(mHistogramView, l, t + mSize, + r, t + mSize + mHistogramView.getMeasuredHeight(), + orientation, rotation, new Rect()); + Rect expandedShutter = new Rect(shutter); switch (rotation) { case 90: @@ -395,6 +407,10 @@ public class CameraControls extends RotatableLayout { v.layout(result.left, result.top, result.right, result.bottom); } + public void setAutoHdrEnabled(boolean enabled) { + mAutoHdrNotice.setVisibility(enabled ? View.VISIBLE : View.GONE); + } + public void hideUI() { if (!mAnimating) enableTouch(false); @@ -406,7 +422,17 @@ public class CameraControls extends RotatableLayout { mFrontBackSwitcher.animate().setListener(outlistener); ((ModuleSwitcher) mSwitcher).removePopup(); markVisibility(); - int topTranslation = rotation == 0 || rotation == 90 ? -mSize : mSize; + + // determine needed translation amount + int translation = 0; + for (View v : mTopViews) { + translation = Math.max(translation, v.getBottom()); + } + for (View v : mBottomViews) { + translation = Math.max(translation, getHeight() - v.getTop()); + } + + int topTranslation = rotation == 0 || rotation == 90 ? -translation : translation; boolean isYTranslation = rotation == 0 || rotation == 180; animateViews(topTranslation, isYTranslation); //mRemainingPhotos.getVisibility(View.INVISIBLE); @@ -422,9 +448,9 @@ public class CameraControls extends RotatableLayout { for (View v : views) { ViewPropertyAnimator vpa = v.animate(); if (isYTranslation) { - vpa.translationYBy(translation); + vpa.translationY(translation); } else { - vpa.translationXBy(translation); + vpa.translationX(translation); } vpa.setDuration(ANIME_DURATION); } @@ -451,9 +477,8 @@ public class CameraControls extends RotatableLayout { mPreview.setVisibility(View.VISIBLE); mFrontBackSwitcher.animate().setListener(inlistener); - int topTranslation = rotation == 0 || rotation == 90 ? mSize : -mSize; boolean isYTranslation = rotation == 0 || rotation == 180; - animateViews(topTranslation, isYTranslation); + animateViews(0, isYTranslation); /*if (mRemainingPhotos.getVisibility() == View.INVISIBLE) { mRemainingPhotos.setVisibility(View.VISIBLE); }*/ @@ -671,11 +696,22 @@ public class CameraControls extends RotatableLayout { mRemainingPhotos.setVisibility(show ? View.GONE : View.VISIBLE); } + public void setHistogramEnabled(boolean enabled, CameraManager.CameraProxy camera) { + mHistogramView.setVisibility(enabled ? View.VISIBLE : View.GONE); + mHistogramView.setCamera(camera); + } + + public void updateHistogramData(int[] data) { + mHistogramView.updateData(data); + } + public void setOrientation(int orientation, boolean animation) { mOrientation = orientation; for (View v : mAllViews) { if (v instanceof RotateImageView) { ((RotateImageView) v).setOrientation(orientation, animation); + } else if (v instanceof HistogramView) { + ((HistogramView) v).setRotation(-orientation); } } layoutRemaingPhotos(); diff --git a/src/com/android/camera/ui/HistogramView.java b/src/com/android/camera/ui/HistogramView.java new file mode 100644 index 000000000..2ae2c40a8 --- /dev/null +++ b/src/com/android/camera/ui/HistogramView.java @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * Copyright (C) 2013-2015 The CyanogenMod Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.camera.ui; + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.util.AttributeSet; +import android.view.View; + +import com.android.camera.CameraManager; + +public class HistogramView extends View { + private static final int STATS_SIZE = 256; + + private int[] mData = new int[STATS_SIZE + 1]; + private boolean mDataValid; + + private Bitmap mBitmap; + private Paint mPaint = new Paint(); + private Paint mPaintRect = new Paint(); + private Canvas mCanvas = new Canvas(); + private float mWidth; + private float mHeight; + private CameraManager.CameraProxy mGraphCameraDevice; + + public HistogramView(Context context, AttributeSet attrs) { + super(context,attrs); + + mPaint.setFlags(Paint.ANTI_ALIAS_FLAG); + mPaintRect.setColor(0xFFFFFFFF); + mPaintRect.setStyle(Paint.Style.FILL); + } + + public void setCamera(CameraManager.CameraProxy camera) { + mGraphCameraDevice = camera; + if (camera == null) { + mDataValid = false; + } + } + + public void updateData(int[] data) { + if (data.length == mData.length) { + System.arraycopy(data, 0, mData, 0, data.length); + drawGraph(); + mDataValid = true; + invalidate(); + } + } + + @Override + protected void onSizeChanged(int w, int h, int oldw, int oldh) { + mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.RGB_565); + mCanvas.setBitmap(mBitmap); + mWidth = w; + mHeight = h; + if (mDataValid) { + drawGraph(); + } + super.onSizeChanged(w, h, oldw, oldh); + } + + @Override + protected void onDraw(Canvas canvas) { + if (mDataValid && mBitmap != null) { + canvas.drawBitmap(mBitmap, 0, 0, null); + if (mGraphCameraDevice != null) { + mGraphCameraDevice.sendHistogramData(); + } + } + } + + private void drawGraph() { + final float border = 5; + float graphheight = mHeight - (2 * border); + float graphwidth = mWidth - (2 * border); + float bargap = 0.0f; + float barwidth = graphwidth/STATS_SIZE; + + mCanvas.drawColor(0xFFAAAAAA); + mPaint.setColor(Color.BLACK); + + for (int k = 0; k <= (graphheight /32) ; k++) { + float y = (float)(32 * k)+ border; + mCanvas.drawLine(border, y, graphwidth + border , y, mPaint); + } + for (int j = 0; j <= (graphwidth /32); j++) { + float x = (float)(32 * j)+ border; + mCanvas.drawLine(x, border, x, graphheight + border, mPaint); + } + + //Assumption: The first element contains the maximum value. + int maxValue = Integer.MIN_VALUE; + if (mData[0] == 0) { + for (int i = 1; i <= STATS_SIZE ; i++) { + maxValue = Math.max(maxValue, mData[i]); + } + } else { + maxValue = mData[0]; + } + + for (int i = 1; i <= STATS_SIZE; i++) { + float scaled = Math.min(STATS_SIZE, + (float) mData[i] * (float) STATS_SIZE / (float) maxValue); + float left = (bargap * (i+1)) + (barwidth * i) + border; + float top = graphheight + border; + float right = left + barwidth; + float bottom = top - scaled; + mCanvas.drawRect(left, top, right, bottom, mPaintRect); + } + } +} + diff --git a/src/com/android/camera/ui/RotatableLayout.java b/src/com/android/camera/ui/RotatableLayout.java index 6867e6a8b..702590f9f 100644 --- a/src/com/android/camera/ui/RotatableLayout.java +++ b/src/com/android/camera/ui/RotatableLayout.java @@ -280,4 +280,4 @@ public class RotatableLayout extends FrameLayout { rotateClockwise(view); rotateClockwise(view); } -} \ No newline at end of file +} -- cgit v1.2.3