diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/com/android/camera/Camera.java | 49 | ||||
-rw-r--r-- | src/com/android/camera/CameraSettings.java | 21 | ||||
-rw-r--r-- | src/com/android/camera/IconListPreference.java | 11 | ||||
-rw-r--r-- | src/com/android/camera/MenuHelper.java | 1 | ||||
-rw-r--r-- | src/com/android/camera/Util.java | 49 | ||||
-rw-r--r-- | src/com/android/camera/VideoCamera.java | 247 | ||||
-rw-r--r-- | src/com/android/camera/ui/BasicIndicator.java | 50 | ||||
-rw-r--r-- | src/com/android/camera/ui/CamcorderHeadUpDisplay.java | 14 | ||||
-rw-r--r-- | src/com/android/camera/ui/GpsIndicator.java | 2 | ||||
-rw-r--r-- | src/com/android/camera/ui/HeadUpDisplay.java | 3 |
10 files changed, 320 insertions, 127 deletions
diff --git a/src/com/android/camera/Camera.java b/src/com/android/camera/Camera.java index c62fa22..a863c4b 100644 --- a/src/com/android/camera/Camera.java +++ b/src/com/android/camera/Camera.java @@ -1686,53 +1686,6 @@ public class Camera extends NoSearchActivity implements View.OnClickListener, clearFocusState(); } - private Size getOptimalPreviewSize(List<Size> sizes, double targetRatio) { - final double ASPECT_TOLERANCE = 0.05; - if (sizes == null) return null; - - Size optimalSize = null; - double minDiff = Double.MAX_VALUE; - - // Because of bugs of overlay and layout, we sometimes will try to - // layout the viewfinder in the portrait orientation and thus get the - // wrong size of mSurfaceView. When we change the preview size, the - // new overlay will be created before the old one closed, which causes - // an exception. For now, just get the screen size - - Display display = getWindowManager().getDefaultDisplay(); - int targetHeight = Math.min(display.getHeight(), display.getWidth()); - - if (targetHeight <= 0) { - // We don't know the size of SurefaceView, use screen height - WindowManager windowManager = (WindowManager) - getSystemService(Context.WINDOW_SERVICE); - targetHeight = windowManager.getDefaultDisplay().getHeight(); - } - - // Try to find an size match aspect ratio and size - for (Size size : sizes) { - double ratio = (double) size.width / size.height; - if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue; - if (Math.abs(size.height - targetHeight) < minDiff) { - optimalSize = size; - minDiff = Math.abs(size.height - targetHeight); - } - } - - // Cannot find the one match the aspect ratio, ignore the requirement - if (optimalSize == null) { - Log.v(TAG, "No preview size match the aspect ratio"); - minDiff = Double.MAX_VALUE; - for (Size size : sizes) { - if (Math.abs(size.height - targetHeight) < minDiff) { - optimalSize = size; - minDiff = Math.abs(size.height - targetHeight); - } - } - } - return optimalSize; - } - private static boolean isSupported(String value, List<String> supported) { return supported == null ? false : supported.indexOf(value) >= 0; } @@ -1776,7 +1729,7 @@ public class Camera extends NoSearchActivity implements View.OnClickListener, // Set a preview size that is closest to the viewfinder height and has // the right aspect ratio. List<Size> sizes = mParameters.getSupportedPreviewSizes(); - Size optimalSize = getOptimalPreviewSize( + Size optimalSize = Util.getOptimalPreviewSize(this, sizes, (double) size.width / size.height); if (optimalSize != null) { Size original = mParameters.getPreviewSize(); diff --git a/src/com/android/camera/CameraSettings.java b/src/com/android/camera/CameraSettings.java index 2c6bdf1..cde3d9d 100644 --- a/src/com/android/camera/CameraSettings.java +++ b/src/com/android/camera/CameraSettings.java @@ -39,6 +39,8 @@ public class CameraSettings { public static final String KEY_LOCAL_VERSION = "pref_local_version_key"; public static final String KEY_RECORD_LOCATION = RecordLocationPreference.KEY; public static final String KEY_VIDEO_QUALITY = "pref_video_quality_key"; + public static final String KEY_VIDEO_TIME_LAPSE_QUALITY = "pref_video_time_lapse_quality_key"; + public static final String KEY_VIDEO_TIME_LAPSE_FRAME_INTERVAL = "pref_video_time_lapse_frame_interval_key"; public static final String KEY_PICTURE_SIZE = "pref_camera_picturesize_key"; public static final String KEY_JPEG_QUALITY = "pref_camera_jpegquality_key"; public static final String KEY_FOCUS_MODE = "pref_camera_focusmode_key"; @@ -133,6 +135,7 @@ public class CameraSettings { private void initPreference(PreferenceGroup group) { ListPreference videoQuality = group.findPreference(KEY_VIDEO_QUALITY); + ListPreference videoTimeLapseQuality = group.findPreference(KEY_VIDEO_TIME_LAPSE_QUALITY); ListPreference pictureSize = group.findPreference(KEY_PICTURE_SIZE); ListPreference whiteBalance = group.findPreference(KEY_WHITE_BALANCE); ListPreference colorEffect = group.findPreference(KEY_COLOR_EFFECT); @@ -163,6 +166,9 @@ public class CameraSettings { } // Filter out unsupported settings / options + if (videoTimeLapseQuality != null) { + filterUnsupportedOptions(group, videoTimeLapseQuality, getSupportedTimeLapseProfiles()); + } if (pictureSize != null) { filterUnsupportedOptions(group, pictureSize, sizeListToStringList( mParameters.getSupportedPictureSizes())); @@ -195,6 +201,21 @@ public class CameraSettings { if (cameraId != null) buildCameraId(group, cameraId); } + private static List<String> getSupportedTimeLapseProfiles() { + ArrayList<String> supportedProfiles = new ArrayList<String>(); + if (CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_TIME_LAPSE_480P)) { + supportedProfiles.add(Integer.toString(CamcorderProfile.QUALITY_TIME_LAPSE_480P)); + } + if (CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_TIME_LAPSE_720P)) { + supportedProfiles.add(Integer.toString(CamcorderProfile.QUALITY_TIME_LAPSE_720P)); + } + if (CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_TIME_LAPSE_1080P)) { + supportedProfiles.add(Integer.toString(CamcorderProfile.QUALITY_TIME_LAPSE_1080P)); + } + + return supportedProfiles; + } + private void buildExposureCompensation( PreferenceGroup group, ListPreference exposure) { int max = mParameters.getMaxExposureCompensation(); diff --git a/src/com/android/camera/IconListPreference.java b/src/com/android/camera/IconListPreference.java index fc23f6c..de9cba1 100644 --- a/src/com/android/camera/IconListPreference.java +++ b/src/com/android/camera/IconListPreference.java @@ -77,15 +77,18 @@ public class IconListPreference extends ListPreference { IntArray iconIds = new IntArray(); IntArray largeIconIds = new IntArray(); + // We allow mIconsIds to be null, but not mLargeIconIds. The reason is that if large icons + // are unspecified, the on screen icons will be blank which is a bug. for (int i = 0, len = entryValues.length; i < len; i++) { if (supported.indexOf(entryValues[i].toString()) >= 0) { - iconIds.add(mIconIds[i]); + if (mIconIds != null) { + iconIds.add(mIconIds[i]); + } largeIconIds.add(mLargeIconIds[i]); } } - int size = iconIds.size(); - mIconIds = iconIds.toArray(new int[size]); - mLargeIconIds = iconIds.toArray(new int[size]); + if (mIconIds != null) mIconIds = iconIds.toArray(new int[iconIds.size()]); + mLargeIconIds = largeIconIds.toArray(new int[largeIconIds.size()]); super.filterUnsupported(supported); } } diff --git a/src/com/android/camera/MenuHelper.java b/src/com/android/camera/MenuHelper.java index 17755f9..b5e4a13 100644 --- a/src/com/android/camera/MenuHelper.java +++ b/src/com/android/camera/MenuHelper.java @@ -59,6 +59,7 @@ public class MenuHelper { public static final int POSITION_SWITCH_CAMERA_MODE = 1; public static final int POSITION_GOTO_GALLERY = 2; public static final int POSITION_SWITCH_CAMERA_ID = 3; + public static final int POSITION_SWITCH_TIME_LAPSE_MODE = 4; public static final int NO_STORAGE_ERROR = -1; public static final int CANNOT_STAT_ERROR = -2; diff --git a/src/com/android/camera/Util.java b/src/com/android/camera/Util.java index adf9152..f7c3316 100644 --- a/src/com/android/camera/Util.java +++ b/src/com/android/camera/Util.java @@ -22,7 +22,9 @@ import android.content.DialogInterface; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Matrix; +import android.hardware.Camera.Size; import android.util.Log; +import android.view.Display; import android.view.Surface; import android.view.View; import android.view.animation.Animation; @@ -31,6 +33,7 @@ import android.view.animation.TranslateAnimation; import com.android.camera.gallery.IImage; import com.android.camera.R; +import java.util.List; import java.io.Closeable; /** @@ -301,4 +304,50 @@ public class Util { int result = (info.orientation - degrees + 360) % 360; camera.setDisplayOrientation(result); } + + public static Size getOptimalPreviewSize(Activity currentActivity, + List<Size> sizes, double targetRatio) { + final double ASPECT_TOLERANCE = 0.05; + if (sizes == null) return null; + + Size optimalSize = null; + double minDiff = Double.MAX_VALUE; + + // Because of bugs of overlay and layout, we sometimes will try to + // layout the viewfinder in the portrait orientation and thus get the + // wrong size of mSurfaceView. When we change the preview size, the + // new overlay will be created before the old one closed, which causes + // an exception. For now, just get the screen size + + Display display = currentActivity.getWindowManager().getDefaultDisplay(); + int targetHeight = Math.min(display.getHeight(), display.getWidth()); + + if (targetHeight <= 0) { + // We don't know the size of SurfaceView, use screen height + targetHeight = display.getHeight(); + } + + // Try to find an size match aspect ratio and size + for (Size size : sizes) { + double ratio = (double) size.width / size.height; + if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue; + if (Math.abs(size.height - targetHeight) < minDiff) { + optimalSize = size; + minDiff = Math.abs(size.height - targetHeight); + } + } + + // Cannot find the one match the aspect ratio, ignore the requirement + if (optimalSize == null) { + Log.v(TAG, "No preview size match the aspect ratio"); + minDiff = Double.MAX_VALUE; + for (Size size : sizes) { + if (Math.abs(size.height - targetHeight) < minDiff) { + optimalSize = size; + minDiff = Math.abs(size.height - targetHeight); + } + } + } + return optimalSize; + } } diff --git a/src/com/android/camera/VideoCamera.java b/src/com/android/camera/VideoCamera.java index d617e4c..56f1d3a 100644 --- a/src/com/android/camera/VideoCamera.java +++ b/src/com/android/camera/VideoCamera.java @@ -53,6 +53,7 @@ import android.provider.MediaStore; import android.provider.Settings; import android.provider.MediaStore.Video; import android.util.Log; +import android.view.Display; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.Menu; @@ -130,6 +131,7 @@ public class VideoCamera extends NoSearchActivity private ImageView mVideoFrame; private GLRootView mGLRootView; private CamcorderHeadUpDisplay mHeadUpDisplay; + private MenuItem mSwitchTimeLapseMenuItem; private boolean mIsVideoCaptureIntent; private boolean mQuickCapture; @@ -160,6 +162,13 @@ public class VideoCamera extends NoSearchActivity // The video duration limit. 0 menas no limit. private int mMaxVideoDurationInMs; + // Time Lapse parameters. + private boolean mCaptureTimeLapse = false; + private int mTimeBetweenTimeLapseFrameCaptureMs = 2000; + + private int mDesiredPreviewWidth; + private int mDesiredPreviewHeight; + boolean mPausing = false; boolean mPreviewing = false; // True if preview is started. @@ -402,12 +411,11 @@ public class VideoCamera extends NoSearchActivity CameraSettings settings = new CameraSettings(this, mParameters, CameraHolder.instance().getCameraInfo()); - PreferenceGroup group = - settings.getPreferenceGroup(R.xml.video_preferences); + PreferenceGroup group = settings.getPreferenceGroup(R.xml.video_preferences); if (mIsVideoCaptureIntent) { group = filterPreferenceScreenByIntent(group); } - mHeadUpDisplay.initialize(this, group); + mHeadUpDisplay.initialize(this, group, mCaptureTimeLapse); } private void attachHeadUpDisplay() { @@ -548,7 +556,39 @@ public class VideoCamera extends NoSearchActivity : STORAGE_STATUS_OK; } + private void readTimeLapseVideoPreferences() { + // Read CamcorderProfile quality. + String qualityStr = mPreferences.getString( + CameraSettings.KEY_VIDEO_TIME_LAPSE_QUALITY, + getString(R.string.pref_video_time_lapse_quality_default)); + mProfile = CamcorderProfile.get(Integer.parseInt(qualityStr)); + + // Read interval between frame capture. + String frameIntervalStr = mPreferences.getString( + CameraSettings.KEY_VIDEO_TIME_LAPSE_FRAME_INTERVAL, + getString(R.string.pref_video_time_lapse_frame_interval_default)); + mTimeBetweenTimeLapseFrameCaptureMs = Integer.parseInt(frameIntervalStr); + + mMaxVideoDurationInMs = 0; // No limit + + // Time lapse mode can capture video (using the still camera) at resolutions + // higher than the supported preview sizes. In that case + // mProfile.{videoFrameWidth,videoFrameHeight} will correspond to an unsupported + // preview size. So choose preview size optimally from the supported preview + // sizes. + List<Size> sizes = mParameters.getSupportedPreviewSizes(); + Size optimalSize = Util.getOptimalPreviewSize(this, + sizes, (double) mProfile.videoFrameWidth / mProfile.videoFrameHeight); + mDesiredPreviewWidth = optimalSize.width; + mDesiredPreviewHeight = optimalSize.height; + } + private void readVideoPreferences() { + if (mCaptureTimeLapse) { + readTimeLapseVideoPreferences(); + return; + } + String quality = mPreferences.getString( CameraSettings.KEY_VIDEO_QUALITY, CameraSettings.DEFAULT_VIDEO_QUALITY_VALUE); @@ -576,6 +616,9 @@ public class VideoCamera extends NoSearchActivity mProfile = CamcorderProfile.get(videoQualityHigh ? CamcorderProfile.QUALITY_HIGH : CamcorderProfile.QUALITY_LOW); + + mDesiredPreviewWidth = mProfile.videoFrameWidth; + mDesiredPreviewHeight = mProfile.videoFrameHeight; } private void resizeForPreviewAspectRatio() { @@ -676,17 +719,7 @@ public class VideoCamera extends NoSearchActivity mPreviewing = false; } - @Override - protected void onPause() { - super.onPause(); - mPausing = true; - - changeHeadUpDisplayState(); - - // Hide the preview now. Otherwise, the preview may be rotated during - // onPause and it is annoying to users. - mVideoPreview.setVisibility(View.INVISIBLE); - + private void finishRecorderAndCloseCamera() { // This is similar to what mShutterButton.performClick() does, // but not quite the same. if (mMediaRecorderRecording) { @@ -700,6 +733,20 @@ public class VideoCamera extends NoSearchActivity stopVideoRecording(); } closeCamera(); + } + + @Override + protected void onPause() { + super.onPause(); + mPausing = true; + + changeHeadUpDisplayState(); + + // Hide the preview now. Otherwise, the preview may be rotated during + // onPause and it is annoying to users. + mVideoPreview.setVisibility(View.INVISIBLE); + + finishRecorderAndCloseCamera(); if (mReceiver != null) { unregisterReceiver(mReceiver); @@ -927,10 +974,17 @@ public class VideoCamera extends NoSearchActivity mMediaRecorder = new MediaRecorder(); mMediaRecorder.setCamera(mCameraDevice); - mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); + if (!mCaptureTimeLapse) { + mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); + } mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); mMediaRecorder.setProfile(mProfile); - mMediaRecorder.setMaxDuration(mMaxVideoDurationInMs); + if (mMaxVideoDurationInMs != 0) { + mMediaRecorder.setMaxDuration(mMaxVideoDurationInMs); + } + if (mCaptureTimeLapse) { + mMediaRecorder.setCaptureRate((1000 / (double) mTimeBetweenTimeLapseFrameCaptureMs)); + } // Set output file. if (mStorageStatus != STORAGE_STATUS_OK) { @@ -1058,6 +1112,14 @@ public class VideoCamera extends NoSearchActivity } } + private void setTimeLapseSwitchTitle(boolean enableTimeLapse) { + int labelId = enableTimeLapse + ? R.string.enable_time_lapse_mode + : R.string.disable_time_lapse_mode; + + mSwitchTimeLapseMenuItem.setTitle(labelId); + } + private void addBaseMenuItems(Menu menu) { MenuHelper.addSwitchModeMenuItem(menu, false, new Runnable() { public void run() { @@ -1088,25 +1150,52 @@ public class VideoCamera extends NoSearchActivity } }).setIcon(android.R.drawable.ic_menu_camera); } + + mSwitchTimeLapseMenuItem = menu.add(Menu.NONE, Menu.NONE, + MenuHelper.POSITION_SWITCH_TIME_LAPSE_MODE, + R.string.enable_time_lapse_mode) + .setOnMenuItemClickListener(new OnMenuItemClickListener() { + public boolean onMenuItemClick(MenuItem item) { + switchTimeLapseMode(); + return true; + } + }).setIcon(android.R.drawable.ic_menu_camera); + } + + private void switchTimeLapseMode() { + mCaptureTimeLapse = !mCaptureTimeLapse; + + finishRecorderAndCloseCamera(); + mHandler.removeMessages(INIT_RECORDER); + + // Read the video preferences + readVideoPreferences(); + resetCameraParameters(); + + // Restart preview + try { + startPreview(); + } catch (CameraHardwareException e) { + showCameraErrorAndFinish(); + return; + } + + // Reload the UI. + initializeHeadUpDisplay(); + + if (mSurfaceHolder != null) { + mHandler.sendEmptyMessage(INIT_RECORDER); + } + + // Change menu + setTimeLapseSwitchTitle(!mCaptureTimeLapse); } private void switchCameraId(int cameraId) { mCameraId = cameraId; CameraSettings.writePreferredCameraId(mPreferences, cameraId); - // This is similar to what mShutterButton.performClick() does, - // but not quite the same. - if (mMediaRecorderRecording) { - if (mIsVideoCaptureIntent) { - stopVideoRecording(); - showAlert(); - } else { - stopVideoRecordingAndGetThumbnail(); - } - } else { - stopVideoRecording(); - } - closeCamera(); + finishRecorderAndCloseCamera(); mHandler.removeMessages(INIT_RECORDER); // Reload the preferences. @@ -1376,6 +1465,62 @@ public class VideoCamera extends NoSearchActivity list.close(); } + private static String millisecondToTimeString(long milliSeconds, boolean displayCentiSeconds) { + long seconds = milliSeconds / 1000; // round down to compute seconds + long minutes = seconds / 60; + long hours = minutes / 60; + long remainderMinutes = minutes - (hours * 60); + long remainderSeconds = seconds - (minutes * 60); + + StringBuilder timeStringBuilder = new StringBuilder(); + + // Hours + if (hours > 0) { + if (hours < 10) { + timeStringBuilder.append('0'); + } + timeStringBuilder.append(hours); + + timeStringBuilder.append(':'); + } + + // Minutes + if (remainderMinutes < 10) { + timeStringBuilder.append('0'); + } + timeStringBuilder.append(remainderMinutes); + timeStringBuilder.append(':'); + + // Seconds + if (remainderSeconds < 10) { + timeStringBuilder.append('0'); + } + timeStringBuilder.append(remainderSeconds); + + // Centi seconds + if (displayCentiSeconds) { + timeStringBuilder.append('.'); + long remainderCentiSeconds = (milliSeconds - seconds * 1000) / 10; + if (remainderCentiSeconds < 10) { + timeStringBuilder.append('0'); + } + timeStringBuilder.append(remainderCentiSeconds); + } + + return timeStringBuilder.toString(); + } + + // Calculates the time lapse video length till now and returns it in + // the format hh:mm:ss.dd, where dd are the centi seconds. + private String getTimeLapseVideoLengthString(long deltaMs) { + // For better approximation calculate fractional number of frames captured. + // This will update the video time at a higher resolution. + double numberOfFrames = (double) deltaMs / mTimeBetweenTimeLapseFrameCaptureMs; + long videoTimeMs = + (long) (numberOfFrames / (double) mProfile.videoFrameRate * 1000); + return millisecondToTimeString(videoTimeMs, true); + } + private void updateRecordingTime() { if (!mMediaRecorderRecording) { return; @@ -1388,36 +1533,19 @@ public class VideoCamera extends NoSearchActivity boolean countdownRemainingTime = (mMaxVideoDurationInMs != 0 && delta >= mMaxVideoDurationInMs - 60000); - long next_update_delay = 1000 - (delta % 1000); - long seconds; + long deltaAdjusted = delta; if (countdownRemainingTime) { - delta = Math.max(0, mMaxVideoDurationInMs - delta); - seconds = (delta + 999) / 1000; - } else { - seconds = delta / 1000; // round to nearest + deltaAdjusted = Math.max(0, mMaxVideoDurationInMs - deltaAdjusted) + 999; } + String text = millisecondToTimeString(deltaAdjusted, false); - long minutes = seconds / 60; - long hours = minutes / 60; - long remainderMinutes = minutes - (hours * 60); - long remainderSeconds = seconds - (minutes * 60); - - String secondsString = Long.toString(remainderSeconds); - if (secondsString.length() < 2) { - secondsString = "0" + secondsString; - } - String minutesString = Long.toString(remainderMinutes); - if (minutesString.length() < 2) { - minutesString = "0" + minutesString; - } - String text = minutesString + ":" + secondsString; - if (hours > 0) { - String hoursString = Long.toString(hours); - if (hoursString.length() < 2) { - hoursString = "0" + hoursString; - } - text = hoursString + ":" + text; + if (mCaptureTimeLapse) { + // Since the length of time lapse video is different from the length + // of the actual wall clock time elapsed, we display the video length + // alongside the wall clock time. + text = text + " (" + getTimeLapseVideoLengthString(delta) + ")"; } + mRecordingTimeView.setText(text); if (mRecordingTimeCountsDown != countdownRemainingTime) { @@ -1432,8 +1560,9 @@ public class VideoCamera extends NoSearchActivity mRecordingTimeView.setTextColor(color); } + long nextUpdateDelay = 1000 - (delta % 1000); mHandler.sendEmptyMessageDelayed( - UPDATE_RECORD_TIME, next_update_delay); + UPDATE_RECORD_TIME, nextUpdateDelay); } private static boolean isSupported(String value, List<String> supported) { @@ -1443,7 +1572,7 @@ public class VideoCamera extends NoSearchActivity private void setCameraParameters() { mParameters = mCameraDevice.getParameters(); - mParameters.setPreviewSize(mProfile.videoFrameWidth, mProfile.videoFrameHeight); + mParameters.setPreviewSize(mDesiredPreviewWidth, mDesiredPreviewHeight); mParameters.setPreviewFrameRate(mProfile.videoFrameRate); // Set flash mode. @@ -1516,8 +1645,8 @@ public class VideoCamera extends NoSearchActivity private void resetCameraParameters() { // We need to restart the preview if preview size is changed. Size size = mParameters.getPreviewSize(); - if (size.width != mProfile.videoFrameWidth - || size.height != mProfile.videoFrameHeight) { + if (size.width != mDesiredPreviewWidth + || size.height != mDesiredPreviewHeight) { // It is assumed media recorder is released before // onSharedPreferenceChanged, so we can close the camera here. closeCamera(); diff --git a/src/com/android/camera/ui/BasicIndicator.java b/src/com/android/camera/ui/BasicIndicator.java index 7630a8e..9f076b8 100644 --- a/src/com/android/camera/ui/BasicIndicator.java +++ b/src/com/android/camera/ui/BasicIndicator.java @@ -19,31 +19,47 @@ package com.android.camera.ui; import android.content.Context; import com.android.camera.IconListPreference; +import com.android.camera.ListPreference; import com.android.camera.R; import com.android.camera.Util; import com.android.camera.ui.GLListView.OnItemSelectedListener; class BasicIndicator extends AbstractIndicator { + private static final float FONT_SIZE = 18; + private static final int FONT_COLOR = 0xA8FFFFFF; private static final int COLOR_OPTION_ITEM_HIGHLIGHT = 0xFF181818; private final ResourceTexture mIcon[]; - private final IconListPreference mPreference; + private final ListPreference mPreference; protected int mIndex; private GLListView mPopupContent; private PreferenceAdapter mModel; private String mOverride; + private int mTitleIndex; + private StringTexture mTitle; + private final float mFontSize; + private boolean mIsIconListMode; - public BasicIndicator(Context context, IconListPreference preference) { + public BasicIndicator(Context context, ListPreference preference) { super(context); mPreference = preference; - mIcon = new ResourceTexture[preference.getLargeIconIds().length]; mIndex = preference.findIndexOfValue(preference.getValue()); + if (preference instanceof IconListPreference) { + mIsIconListMode = true; + mIcon = new ResourceTexture[((IconListPreference) preference).getLargeIconIds().length]; + mFontSize = 0; + } else { + mIsIconListMode = false; + mIcon = null; + mFontSize = GLRootView.dpToPixel(context, FONT_SIZE); + mTitleIndex = -1; + } } // Set the override and/or reload the value from preferences. private void updateContent(String override, boolean reloadValue) { if (!reloadValue && Util.equals(mOverride, override)) return; - IconListPreference pref = mPreference; + ListPreference pref = mPreference; mOverride = override; int index = pref.findIndexOfValue( override == null ? pref.getValue() : override); @@ -55,7 +71,7 @@ class BasicIndicator extends AbstractIndicator { @Override public void overrideSettings(String key, String settings) { - IconListPreference pref = mPreference; + ListPreference pref = mPreference; if (!pref.getKey().equals(key)) return; updateContent(settings, false); } @@ -104,13 +120,23 @@ class BasicIndicator extends AbstractIndicator { } @Override - protected ResourceTexture getIcon() { - int index = mIndex; - if (mIcon[index] == null) { - Context context = getGLRootView().getContext(); - mIcon[index] = new ResourceTexture( - context, mPreference.getLargeIconIds()[index]); + protected BitmapTexture getIcon() { + if (mIsIconListMode) { + int index = mIndex; + if (mIcon[index] == null) { + Context context = getGLRootView().getContext(); + mIcon[index] = new ResourceTexture( + context, ((IconListPreference) mPreference).getLargeIconIds()[index]); + } + return mIcon[index]; + } else { + if (mTitleIndex != mIndex) { + mTitleIndex = mIndex; + if (mTitle != null) mTitle.deleteFromGL(); + String value = mPreference.getEntry(); + mTitle = StringTexture.newInstance(value, mFontSize, FONT_COLOR); + } + return mTitle; } - return mIcon[index]; } } diff --git a/src/com/android/camera/ui/CamcorderHeadUpDisplay.java b/src/com/android/camera/ui/CamcorderHeadUpDisplay.java index 8e98100..c69b92b 100644 --- a/src/com/android/camera/ui/CamcorderHeadUpDisplay.java +++ b/src/com/android/camera/ui/CamcorderHeadUpDisplay.java @@ -26,12 +26,19 @@ public class CamcorderHeadUpDisplay extends HeadUpDisplay { private static final String TAG = "CamcorderHeadUpDisplay"; + private boolean mCaptureTimeLapse; private OtherSettingsIndicator mOtherSettings; public CamcorderHeadUpDisplay(Context context) { super(context); } + public void initialize(Context context, PreferenceGroup group, + boolean captureTimeLapse) { + mCaptureTimeLapse = captureTimeLapse; + super.initialize(context, group); + } + @Override protected void initializeIndicatorBar( Context context, PreferenceGroup group) { @@ -57,7 +64,12 @@ public class CamcorderHeadUpDisplay extends HeadUpDisplay { addIndicator(context, group, CameraSettings.KEY_WHITE_BALANCE); addIndicator(context, group, CameraSettings.KEY_VIDEOCAMERA_FLASH_MODE); - addIndicator(context, group, CameraSettings.KEY_VIDEO_QUALITY); + if (mCaptureTimeLapse) { + addIndicator(context, group, CameraSettings.KEY_VIDEO_TIME_LAPSE_FRAME_INTERVAL); + addIndicator(context, group, CameraSettings.KEY_VIDEO_TIME_LAPSE_QUALITY); + } else { + addIndicator(context, group, CameraSettings.KEY_VIDEO_QUALITY); + } addIndicator(context, group, CameraSettings.KEY_CAMERA_ID); } } diff --git a/src/com/android/camera/ui/GpsIndicator.java b/src/com/android/camera/ui/GpsIndicator.java index 78a80b8..c1cb2ef 100644 --- a/src/com/android/camera/ui/GpsIndicator.java +++ b/src/com/android/camera/ui/GpsIndicator.java @@ -33,7 +33,7 @@ class GpsIndicator extends BasicIndicator { } @Override - protected ResourceTexture getIcon() { + protected BitmapTexture getIcon() { if (mIndex == GPS_ON_INDEX && !mHasSignal) { if (mNoSignalIcon == null) { Context context = getGLRootView().getContext(); diff --git a/src/com/android/camera/ui/HeadUpDisplay.java b/src/com/android/camera/ui/HeadUpDisplay.java index 6a7c604..881442b 100644 --- a/src/com/android/camera/ui/HeadUpDisplay.java +++ b/src/com/android/camera/ui/HeadUpDisplay.java @@ -329,8 +329,7 @@ public class HeadUpDisplay extends GLView { protected BasicIndicator addIndicator( Context context, PreferenceGroup group, String key) { - IconListPreference iconPref = - (IconListPreference) group.findPreference(key); + ListPreference iconPref = group.findPreference(key); if (iconPref == null) return null; BasicIndicator indicator = new BasicIndicator(context, iconPref); mIndicatorBar.addComponent(indicator); |