diff options
author | Byunghun Jeon <bjeon@codeaurora.org> | 2014-06-16 17:42:26 -0700 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2014-11-17 17:49:35 -0800 |
commit | 41d18fed018678492323150c661f2b9f6c8931a8 (patch) | |
tree | 5154564878f6b61b1edc68ee8241cf0166ca210e /src/com/android | |
parent | 0231aab003276d2142fe745e50d6eb44e3f11c9c (diff) | |
download | android_packages_apps_Snap-41d18fed018678492323150c661f2b9f6c8931a8.tar.gz android_packages_apps_Snap-41d18fed018678492323150c661f2b9f6c8931a8.tar.bz2 android_packages_apps_Snap-41d18fed018678492323150c661f2b9f6c8931a8.zip |
SnapdragonCamera: Modify SnapdragonCamera UI
Modified SnapdragonCamera setting menus with new icons
Change-Id: I726296dfb100ac81ad6f1cd84420ae27c0ae1201
Diffstat (limited to 'src/com/android')
22 files changed, 3536 insertions, 137 deletions
diff --git a/src/com/android/camera/CameraActivity.java b/src/com/android/camera/CameraActivity.java index c40dacc0a..8091353ff 100644 --- a/src/com/android/camera/CameraActivity.java +++ b/src/com/android/camera/CameraActivity.java @@ -16,6 +16,8 @@ package com.android.camera; +import android.view.Display; +import android.graphics.Point; import android.animation.Animator; import android.annotation.TargetApi; import android.app.ActionBar; @@ -143,6 +145,10 @@ public class CameraActivity extends Activity private static final int SUPPORT_SHOW_ON_MAP = 1 << 9; private static final int SUPPORT_ALL = 0xffffffff; + // Pie Setting Menu enabled + private static boolean PIE_MENU_ENABLED = false; + private boolean mDeveloperMenuEnabled = false; + /** This data adapter is used by FilmStripView. */ private LocalDataAdapter mDataAdapter; /** This data adapter represents the real local camera data. */ @@ -193,6 +199,8 @@ public class CameraActivity extends Activity private Intent mVideoShareIntent; private Intent mImageShareIntent; + public static int SETTING_LIST_WIDTH_1 = 250; + public static int SETTING_LIST_WIDTH_2 = 250; private class MyOrientationEventListener extends OrientationEventListener { @@ -303,6 +311,18 @@ public class CameraActivity extends Activity return sFirstStartAfterScreenOn; } + public static boolean isPieMenuEnabled() { + return PIE_MENU_ENABLED; + } + + public boolean isDeveloperMenuEnabled() { + return mDeveloperMenuEnabled; + } + + public void enableDeveloperMenu() { + mDeveloperMenuEnabled = true; + } + public static void resetFirstStartAfterScreenOn() { sFirstStartAfterScreenOn = false; } @@ -1182,6 +1202,21 @@ public class CameraActivity extends Activity getContentResolver().registerContentObserver( MediaStore.Video.Media.EXTERNAL_CONTENT_URI, true, mLocalVideosObserver); + + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); + mDeveloperMenuEnabled = prefs.getBoolean(CameraSettings.KEY_DEVELOPER_MENU, false); + + Display display = getWindowManager().getDefaultDisplay(); + Point size = new Point(); + display.getSize(size); + int width = size.x; + int height = size.y; + + int lower = Math.min(width, height); + + int offset = lower * 10 / 100; + SETTING_LIST_WIDTH_1 = lower / 2 + offset; + SETTING_LIST_WIDTH_2 = lower / 2 - offset; } private void setRotationAnimation() { @@ -1201,7 +1236,12 @@ public class CameraActivity extends Activity @Override public boolean dispatchTouchEvent(MotionEvent ev) { - boolean result = super.dispatchTouchEvent(ev); + boolean result = false; + if (mFilmStripView.checkSendToModeView(ev)) { + result = mFilmStripView.sendToModeView(ev); + } + if (result == false) + result = super.dispatchTouchEvent(ev); if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) { // Real deletion is postponed until the next user interaction after // the gesture that triggers deletion. Until real deletion is performed, @@ -1354,6 +1394,10 @@ public class CameraActivity extends Activity } } + public void setPreviewGestures(PreviewGestures previewGestures) { + mFilmStripView.setPreviewGestures(previewGestures); + } + public boolean isAutoRotateScreen() { return mAutoRotateScreen; } diff --git a/src/com/android/camera/CameraSettings.java b/src/com/android/camera/CameraSettings.java index 356869b9b..315cf62b9 100644 --- a/src/com/android/camera/CameraSettings.java +++ b/src/com/android/camera/CameraSettings.java @@ -106,6 +106,7 @@ public class CameraSettings { public static final String KEY_ADVANCED_FEATURES = "pref_camera_advanced_features_key"; public static final String KEY_HDR_MODE = "pref_camera_hdr_mode_key"; public static final String KEY_HDR_NEED_1X = "pref_camera_hdr_need_1x_key"; + public static final String KEY_DEVELOPER_MENU = "pref_developer_menu_key"; public static final String KEY_VIDEO_SNAPSHOT_SIZE = "pref_camera_videosnapsize_key"; public static final String KEY_VIDEO_HIGH_FRAME_RATE = "pref_camera_hfr_key"; @@ -826,7 +827,6 @@ public class CameraSettings { exposure.setEntries(entries); exposure.setLabels(labels); exposure.setEntryValues(entryValues); - exposure.setLargeIconIds(icons); } private void buildCameraId( diff --git a/src/com/android/camera/CountDownTimerPreference.java b/src/com/android/camera/CountDownTimerPreference.java index c256f0783..3d5f3a4c7 100644 --- a/src/com/android/camera/CountDownTimerPreference.java +++ b/src/com/android/camera/CountDownTimerPreference.java @@ -21,7 +21,7 @@ import android.util.AttributeSet; import org.codeaurora.snapcam.R; -public class CountDownTimerPreference extends ListPreference { +public class CountDownTimerPreference extends IconListPreference { private static final int[] DURATIONS = { 0, 1, 2, 3, 4, 5, 10, 15, 20, 30, 60 }; diff --git a/src/com/android/camera/CustomPhotoMenu.java b/src/com/android/camera/CustomPhotoMenu.java new file mode 100644 index 000000000..93afac250 --- /dev/null +++ b/src/com/android/camera/CustomPhotoMenu.java @@ -0,0 +1,1006 @@ +/* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * Not a Contribution. + * + * Copyright (C) 2012 The Android Open Source 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; + +import java.util.Locale; + +import android.animation.Animator; +import android.animation.Animator.AnimatorListener; +import android.content.Context; +import android.content.SharedPreferences; +import android.content.res.Resources; +import android.hardware.Camera.Parameters; +import android.graphics.Rect; +import android.preference.PreferenceManager; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.MotionEvent; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.ViewPropertyAnimator; +import android.widget.ListView; +import android.widget.Toast; +import android.widget.TextView; +import android.widget.GridView; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.FrameLayout; +import android.widget.FrameLayout.LayoutParams; + +import com.android.camera.CameraPreference.OnPreferenceChangedListener; +import com.android.camera.ui.CameraControls; +import com.android.camera.ui.CountdownTimerPopup; +import com.android.camera.ui.ListSubMenu; +import com.android.camera.ui.PieItem; +import com.android.camera.ui.ListMenu; +import com.android.camera.ui.RotateImageView; +import org.codeaurora.snapcam.R; +import android.widget.HorizontalScrollView; +import android.view.ViewGroup; +import android.view.WindowManager; +import android.view.Display; +import com.android.camera.util.CameraUtil; + +public class CustomPhotoMenu extends MenuController + implements ListMenu.Listener, + CountdownTimerPopup.Listener, + ListSubMenu.Listener { + private static String TAG = "CustomPhotoMenu"; + + private final String mSettingOff; + + private String[] mOtherKeys1; + private String[] mOtherKeys2; + private ListMenu mListMenu; + private View mPreviewMenu; + private static final int POPUP_NONE = 0; + private static final int POPUP_FIRST_LEVEL = 1; + private static final int POPUP_SECOND_LEVEL = 2; + private static final int POPUP_IN_ANIMATION = 3; + private static final int PREVIEW_MENU_NONE = 0; + private static final int PREVIEW_MENU_IN_ANIMATION = 1; + private static final int PREVIEW_MENU_ON = 2; + private static final int MODE_SCENE = 0; + private static final int MODE_FILTER = 1; + private static final int DEVELOPER_MENU_TOUCH_COUNT = 10; + private int mSceneStatus; + private View mFlashSwitcher; + private View mHdrSwitcher; + private View mFrontBackSwitcher; + private View mSceneModeSwitcher; + private View mFilterModeSwitcher; + private PhotoUI mUI; + private int mPopupStatus; + private int mPreviewMenuStatus; + private ListSubMenu mListSubMenu; + private CameraActivity mActivity; + private boolean mHdrOn = false; + private int privateCounter = 0; + private static final int ANIMATION_DURATION = 300; + private static final int CLICK_THRESHOLD = 200; + private int previewMenuSize; + + public CustomPhotoMenu(CameraActivity activity, PhotoUI ui) { + super(activity); + mUI = ui; + mSettingOff = activity.getString(R.string.setting_off_value); + mActivity = activity; + mFrontBackSwitcher = ui.getRootView().findViewById(R.id.front_back_switcher); + mFlashSwitcher = ui.getRootView().findViewById(R.id.flash_switcher); + mHdrSwitcher = ui.getRootView().findViewById(R.id.hdr_switcher); + mSceneModeSwitcher = ui.getRootView().findViewById(R.id.scene_mode_switcher); + mFilterModeSwitcher = ui.getRootView().findViewById(R.id.filter_mode_switcher); + } + + public void initialize(PreferenceGroup group) { + super.initialize(group); + mListSubMenu = null; + mListMenu = null; + mPopupStatus = POPUP_NONE; + mPreviewMenuStatus = POPUP_NONE; + final Resources res = mActivity.getResources(); + Locale locale = res.getConfiguration().locale; + // The order is from left to right in the menu. + + initSceneModeButton(mSceneModeSwitcher); + initFilterModeButton(mFilterModeSwitcher); + mHdrSwitcher.setVisibility(View.INVISIBLE); + mFlashSwitcher.setVisibility(View.INVISIBLE); + + mFrontBackSwitcher.setVisibility(View.INVISIBLE); + // HDR. + if (group.findPreference(CameraSettings.KEY_CAMERA_HDR) != null) { + mHdrSwitcher.setVisibility(View.VISIBLE); + initSwitchItem(CameraSettings.KEY_CAMERA_HDR, mHdrSwitcher); + } else { + mHdrSwitcher.setVisibility(View.INVISIBLE); + } + + mOtherKeys1 = new String[] { + CameraSettings.KEY_SCENE_MODE, + CameraSettings.KEY_RECORD_LOCATION, + CameraSettings.KEY_PICTURE_SIZE, + CameraSettings.KEY_JPEG_QUALITY, + CameraSettings.KEY_TIMER, + CameraSettings.KEY_CAMERA_SAVEPATH, + CameraSettings.KEY_LONGSHOT, + CameraSettings.KEY_COLOR_EFFECT, + CameraSettings.KEY_FACE_DETECTION, + CameraSettings.KEY_ISO, + CameraSettings.KEY_EXPOSURE, + CameraSettings.KEY_WHITE_BALANCE, + CameraSettings.KEY_FLASH_MODE, + CameraSettings.KEY_FOCUS_MODE, + CameraSettings.KEY_REDEYE_REDUCTION + }; + + mOtherKeys2 = new String[] { + CameraSettings.KEY_SCENE_MODE, + CameraSettings.KEY_RECORD_LOCATION, + CameraSettings.KEY_PICTURE_SIZE, + CameraSettings.KEY_JPEG_QUALITY, + CameraSettings.KEY_TIMER, + CameraSettings.KEY_CAMERA_SAVEPATH, + CameraSettings.KEY_LONGSHOT, + CameraSettings.KEY_COLOR_EFFECT, + CameraSettings.KEY_FACE_DETECTION, + CameraSettings.KEY_ISO, + CameraSettings.KEY_EXPOSURE, + CameraSettings.KEY_WHITE_BALANCE, + CameraSettings.KEY_FLASH_MODE, + CameraSettings.KEY_FOCUS_MODE, + CameraSettings.KEY_REDEYE_REDUCTION, + CameraSettings.KEY_HISTOGRAM, + CameraSettings.KEY_ZSL, + CameraSettings.KEY_TIMER_SOUND_EFFECTS, + CameraSettings.KEY_FACE_RECOGNITION, + CameraSettings.KEY_TOUCH_AF_AEC, + CameraSettings.KEY_SELECTABLE_ZONE_AF, + CameraSettings.KEY_PICTURE_FORMAT, + CameraSettings.KEY_SATURATION, + CameraSettings.KEY_CONTRAST, + CameraSettings.KEY_SHARPNESS, + CameraSettings.KEY_AUTOEXPOSURE, + CameraSettings.KEY_ANTIBANDING, + CameraSettings.KEY_DENOISE, + CameraSettings.KEY_ADVANCED_FEATURES, + CameraSettings.KEY_AE_BRACKET_HDR + }; + + initSwitchItem(CameraSettings.KEY_CAMERA_ID, mFrontBackSwitcher); + initSwitchItem(CameraSettings.KEY_FLASH_MODE, mFlashSwitcher); + } + + @Override + // Hit when an item in a popup gets selected + public void onListPrefChanged(ListPreference pref) { + animateFadeOut(mListSubMenu, 2); + onSettingChanged(pref); + ((ListMenu) mListMenu).resetHighlight(); + } + + public boolean handleBackKey() { + if (mPreviewMenuStatus == PREVIEW_MENU_ON) { + animateSlideOut(mPreviewMenu); + return true; + } + if (mPopupStatus == POPUP_NONE) + return false; + if (mPopupStatus == POPUP_FIRST_LEVEL) { + animateSlideOut(mListMenu, 1); + } else if (mPopupStatus == POPUP_SECOND_LEVEL) { + animateFadeOut(mListSubMenu, 2); + ((ListMenu) mListMenu).resetHighlight(); + } + return true; + } + + public void closeSceneMode() { + mUI.removeSceneModeMenu(); + } + + public void tryToCloseSubList() { + if (mListMenu != null) + ((ListMenu) mListMenu).resetHighlight(); + + if (mPopupStatus == POPUP_SECOND_LEVEL) { + mUI.dismissLevel2(); + mPopupStatus = POPUP_FIRST_LEVEL; + } + } + + private void animateFadeOut(final ListView v, final int level) { + if (v == null || mPopupStatus == POPUP_IN_ANIMATION) + return; + mPopupStatus = POPUP_IN_ANIMATION; + + ViewPropertyAnimator vp = v.animate(); + vp.alpha(0f).setDuration(ANIMATION_DURATION); + vp.setListener(new AnimatorListener() { + @Override + public void onAnimationStart(Animator animation) { + } + + @Override + public void onAnimationRepeat(Animator animation) { + + } + + @Override + public void onAnimationEnd(Animator animation) { + if (level == 1) { + mUI.dismissLevel1(); + initializePopup(); + mPopupStatus = POPUP_NONE; + mUI.cleanupListview(); + } + else if (level == 2) { + mUI.dismissLevel2(); + mPopupStatus = POPUP_FIRST_LEVEL; + } + } + + @Override + public void onAnimationCancel(Animator animation) { + if (level == 1) { + mUI.dismissLevel1(); + initializePopup(); + mPopupStatus = POPUP_NONE; + mUI.cleanupListview(); + } + else if (level == 2) { + mUI.dismissLevel2(); + mPopupStatus = POPUP_FIRST_LEVEL; + } + + } + }); + vp.start(); + } + + private void animateSlideOut(final ListView v, final int level) { + if (v == null || mPopupStatus == POPUP_IN_ANIMATION) + return; + mPopupStatus = POPUP_IN_ANIMATION; + + ViewPropertyAnimator vp = v.animate(); + vp.translationX(v.getX() - v.getWidth()).setDuration(ANIMATION_DURATION); + vp.setListener(new AnimatorListener() { + @Override + public void onAnimationStart(Animator animation) { + } + + @Override + public void onAnimationRepeat(Animator animation) { + + } + + @Override + public void onAnimationEnd(Animator animation) { + if (level == 1) { + mUI.dismissLevel1(); + initializePopup(); + mPopupStatus = POPUP_NONE; + mUI.cleanupListview(); + } + else if (level == 2) { + mUI.dismissLevel2(); + mPopupStatus = POPUP_FIRST_LEVEL; + } + } + + @Override + public void onAnimationCancel(Animator animation) { + if (level == 1) { + mUI.dismissLevel1(); + initializePopup(); + mPopupStatus = POPUP_NONE; + mUI.cleanupListview(); + } + else if (level == 2) { + mUI.dismissLevel2(); + mPopupStatus = POPUP_FIRST_LEVEL; + } + + } + }); + vp.start(); + } + + public void animateFadeIn(final ListView v) { + ViewPropertyAnimator vp = v.animate(); + vp.alpha(0.85f).setDuration(ANIMATION_DURATION); + vp.start(); + } + + public void animateSlideIn(final View v, int delta, boolean settingMenu) { + int rotation = CameraUtil.getDisplayRotation(mActivity); + boolean mIsDefaultToPortrait = CameraUtil.isDefaultToPortrait(mActivity); + if (!mIsDefaultToPortrait) { + rotation = (rotation + 90) % 360; + } + boolean portrait = (rotation == 0) || (rotation == 180); + if (settingMenu) + portrait = true; + ViewPropertyAnimator vp = v.animate(); + if (portrait) { + float dest = v.getX(); + v.setX(dest - delta); + vp.translationX(dest).setDuration(ANIMATION_DURATION); + } + else { + float dest = v.getY(); + v.setY(dest + delta); + vp.translationY(dest).setDuration(ANIMATION_DURATION); + } + vp.start(); + } + + public void animateSlideOutPreviewMenu() { + if (mPreviewMenu == null) + return; + animateSlideOut(mPreviewMenu); + } + + private void animateSlideOut(final View v) { + if (v == null || mPreviewMenuStatus == PREVIEW_MENU_IN_ANIMATION) + return; + mPreviewMenuStatus = PREVIEW_MENU_IN_ANIMATION; + int rotation = CameraUtil.getDisplayRotation(mActivity); + boolean mIsDefaultToPortrait = CameraUtil.isDefaultToPortrait(mActivity); + if (!mIsDefaultToPortrait) { + rotation = (rotation + 90) % 360; + } + boolean portrait = (rotation == 0) || (rotation == 180); + ViewPropertyAnimator vp = v.animate(); + if (portrait) { + vp.translationX(v.getX() - v.getWidth()).setDuration(ANIMATION_DURATION); + + } else { + vp.translationY(v.getY() + v.getHeight()).setDuration(ANIMATION_DURATION); + + } + vp.setListener(new AnimatorListener() { + @Override + public void onAnimationStart(Animator animation) { + } + + @Override + public void onAnimationRepeat(Animator animation) { + + } + + @Override + public void onAnimationEnd(Animator animation) { + closeSceneMode(); + mPreviewMenuStatus = PREVIEW_MENU_NONE; + } + + @Override + public void onAnimationCancel(Animator animation) { + closeSceneMode(); + mPreviewMenuStatus = PREVIEW_MENU_NONE; + + } + }); + vp.start(); + } + + private void buttonSetEnabled(View v, boolean enable) { + v.setEnabled(enable); + if (v instanceof ViewGroup) { + View v2 = ((ViewGroup) v).getChildAt(0); + if (v2 != null) + v2.setEnabled(enable); + + } + + } + + public boolean isOverMenu(MotionEvent ev) { + if (mPopupStatus == POPUP_NONE || mPopupStatus == POPUP_IN_ANIMATION) + return false; + if (mUI.getMenuLayout() == null) + return false; + Rect rec = new Rect(); + mUI.getMenuLayout().getChildAt(0).getHitRect(rec); + return rec.contains((int) ev.getX(), (int) ev.getY()); + } + + public boolean isOverPreviewMenu(MotionEvent ev) { + if (mPreviewMenuStatus != PREVIEW_MENU_ON) + return false; + if (mUI.getPreviewMenuLayout() == null) + return false; + Rect rec = new Rect(); + mUI.getPreviewMenuLayout().getChildAt(0).getHitRect(rec); + rec.top += (int) mUI.getPreviewMenuLayout().getY(); + rec.bottom += (int) mUI.getPreviewMenuLayout().getY(); + return rec.contains((int) ev.getX(), (int) ev.getY()); + } + + public boolean isMenuBeingShown() { + return mPopupStatus != POPUP_NONE; + } + + public boolean isMenuBeingAnimated() { + return mPopupStatus == POPUP_IN_ANIMATION; + } + + public boolean isPreviewMenuBeingShown() { + return mPreviewMenuStatus == PREVIEW_MENU_ON; + } + + public boolean isPreviewMenuBeingAnimated() { + return mPreviewMenuStatus == PREVIEW_MENU_IN_ANIMATION; + } + + public boolean sendTouchToPreviewMenu(MotionEvent ev) { + return mUI.sendTouchToPreviewMenu(ev); + } + + public boolean sendTouchToMenu(MotionEvent ev) { + return mUI.sendTouchToMenu(ev); + } + + @Override + public void overrideSettings(final String... keyvalues) { + for (int i = 0; i < keyvalues.length; i += 2) { + if (keyvalues[i].equals(CameraSettings.KEY_FLASH_MODE)) { + buttonSetEnabled(mFlashSwitcher, keyvalues[i + 1] == null); + } + if (keyvalues[i].equals(CameraSettings.KEY_SCENE_MODE)) { + buttonSetEnabled(mSceneModeSwitcher, keyvalues[i + 1] == null); + } + } + super.overrideSettings(keyvalues); + if ((mListMenu == null)) + initializePopup(); + mListMenu.overrideSettings(keyvalues); + } + + protected void initializePopup() { + LayoutInflater inflater = (LayoutInflater) mActivity.getSystemService( + Context.LAYOUT_INFLATER_SERVICE); + ListMenu popup1 = (ListMenu) inflater.inflate( + R.layout.list_menu, null, false); + + popup1.setSettingChangedListener(this); + + String[] keys = mOtherKeys1; + if (mActivity.isDeveloperMenuEnabled()) + keys = mOtherKeys2; + popup1.initialize(mPreferenceGroup, keys); + if (mActivity.isSecureCamera()) { + // Prevent location preference from getting changed in secure camera + // mode + popup1.setPreferenceEnabled(CameraSettings.KEY_RECORD_LOCATION, false); + } + mListMenu = popup1; + + ListPreference pref = mPreferenceGroup.findPreference( + CameraSettings.KEY_SCENE_MODE); + String sceneMode = (pref != null) ? pref.getValue() : null; + pref = mPreferenceGroup.findPreference(CameraSettings.KEY_FACE_DETECTION); + String faceDetection = (pref != null) ? pref.getValue() : null; + pref = mPreferenceGroup.findPreference(CameraSettings.KEY_ZSL); + String zsl = (pref != null) ? pref.getValue() : null; + if ((sceneMode != null) && !Parameters.SCENE_MODE_AUTO.equals(sceneMode)) { + popup1.setPreferenceEnabled(CameraSettings.KEY_FOCUS_MODE, false); + popup1.setPreferenceEnabled(CameraSettings.KEY_AUTOEXPOSURE, false); + popup1.setPreferenceEnabled(CameraSettings.KEY_TOUCH_AF_AEC, false); + popup1.setPreferenceEnabled(CameraSettings.KEY_SATURATION, false); + popup1.setPreferenceEnabled(CameraSettings.KEY_CONTRAST, false); + popup1.setPreferenceEnabled(CameraSettings.KEY_SHARPNESS, false); + popup1.setPreferenceEnabled(CameraSettings.KEY_COLOR_EFFECT, false); + popup1.setPreferenceEnabled(CameraSettings.KEY_FLASH_MODE, false); + popup1.setPreferenceEnabled(CameraSettings.KEY_WHITE_BALANCE, false); + popup1.setPreferenceEnabled(CameraSettings.KEY_EXPOSURE, false); + } + if ((zsl != null) && Parameters.ZSL_ON.equals(zsl)) { + popup1.setPreferenceEnabled(CameraSettings.KEY_FOCUS_MODE, false); + } + if ((faceDetection != null) && !Parameters.FACE_DETECTION_ON.equals(faceDetection)) { + popup1.setPreferenceEnabled(CameraSettings.KEY_FACE_RECOGNITION, false); + } + + pref = mPreferenceGroup.findPreference(CameraSettings.KEY_ADVANCED_FEATURES); + String advancedFeatures = (pref != null) ? pref.getValue() : null; + + String ubiFocusOn = mActivity.getString(R.string. + pref_camera_advanced_feature_value_ubifocus_on); + String chromaFlashOn = mActivity.getString(R.string. + pref_camera_advanced_feature_value_chromaflash_on); + String optiZoomOn = mActivity.getString(R.string. + pref_camera_advanced_feature_value_optizoom_on); + + if ((zsl != null) && Parameters.ZSL_OFF.equals(zsl)) { + popup1.overrideSettings(CameraSettings.KEY_ADVANCED_FEATURES, + mActivity.getString(R.string.pref_camera_advanced_feature_default)); + + popup1.setPreferenceEnabled(CameraSettings.KEY_ADVANCED_FEATURES, false); + if (mHdrSwitcher.getVisibility() == View.VISIBLE) { + buttonSetEnabled(mHdrSwitcher, true); + } + } else { + if ((advancedFeatures != null) && (advancedFeatures.equals(ubiFocusOn) || + advancedFeatures.equals(chromaFlashOn) || + advancedFeatures.equals(optiZoomOn))) { + popup1.setPreferenceEnabled(CameraSettings.KEY_FOCUS_MODE, false); + popup1.setPreferenceEnabled(CameraSettings.KEY_FLASH_MODE, false); + popup1.setPreferenceEnabled(CameraSettings.KEY_AE_BRACKET_HDR, false); + popup1.setPreferenceEnabled(CameraSettings.KEY_REDEYE_REDUCTION, false); + popup1.setPreferenceEnabled(CameraSettings.KEY_EXPOSURE, false); + popup1.setPreferenceEnabled(CameraSettings.KEY_COLOR_EFFECT, false); + popup1.setPreferenceEnabled(CameraSettings.KEY_TOUCH_AF_AEC, false); + popup1.setPreferenceEnabled(CameraSettings.KEY_SCENE_MODE, false); + + setPreference(CameraSettings.KEY_CAMERA_HDR, mSettingOff); + if (mHdrSwitcher.getVisibility() == View.VISIBLE) { + buttonSetEnabled(mHdrSwitcher, false); + } + } else { + if (mHdrSwitcher.getVisibility() == View.VISIBLE) { + buttonSetEnabled(mHdrSwitcher, true); + } + } + } + + pref = mPreferenceGroup.findPreference(CameraSettings.KEY_SCENE_MODE); + if (pref != null) { + if (notSame(pref, CameraSettings.KEY_SCENE_MODE, Parameters.SCENE_MODE_AUTO)) { + buttonSetEnabled(mFilterModeSwitcher, false); + } else { + buttonSetEnabled(mFilterModeSwitcher, true); + } + } + + if (mListener != null) { + mListener.onSharedPreferenceChanged(); + } + } + + public void initSwitchItem(final String prefKey, View switcher) { + final IconListPreference pref = + (IconListPreference) mPreferenceGroup.findPreference(prefKey); + if (pref == null) + return; + + int[] iconIds = pref.getLargeIconIds(); + int resid = -1; + int index = pref.findIndexOfValue(pref.getValue()); + if (!pref.getUseSingleIcon() && iconIds != null) { + // Each entry has a corresponding icon. + resid = iconIds[index]; + } else { + // The preference only has a single icon to represent it. + resid = pref.getSingleIcon(); + } + ImageView iv = (ImageView) ((FrameLayout) switcher).getChildAt(0); + iv.setImageResource(resid); + switcher.setVisibility(View.VISIBLE); + mPreferences.add(pref); + mPreferenceMap.put(pref, switcher); + switcher.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + IconListPreference pref = (IconListPreference) mPreferenceGroup + .findPreference(prefKey); + if (pref == null) + return; + int index = pref.findIndexOfValue(pref.getValue()); + CharSequence[] values = pref.getEntryValues(); + index = (index + 1) % values.length; + pref.setValueIndex(index); + ImageView iv = (ImageView) ((FrameLayout) v).getChildAt(0); + iv.setImageResource(((IconListPreference) pref).getLargeIconIds()[index]); + if (prefKey.equals(CameraSettings.KEY_CAMERA_ID)) + mListener.onCameraPickerClicked(index); + reloadPreference(pref); + onSettingChanged(pref); + } + }); + } + + public void initSceneModeButton(View button) { + button.setVisibility(View.INVISIBLE); + final IconListPreference pref = (IconListPreference) mPreferenceGroup + .findPreference(CameraSettings.KEY_SCENE_MODE); + if (pref == null) + return; + + int[] iconIds = pref.getLargeIconIds(); + int resid = -1; + // The preference only has a single icon to represent it. + resid = pref.getSingleIcon(); + ImageView iv = (ImageView) ((FrameLayout) button).getChildAt(0); + iv.setImageResource(resid); + button.setVisibility(View.VISIBLE); + button.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + addSceneMode(); + View view = mUI.getPreviewMenuLayout().getChildAt(0); + animateSlideIn(view, previewMenuSize, false); + } + }); + } + + public void addModeBack() { + if (mSceneStatus == MODE_SCENE) { + addSceneMode(); + } + if (mSceneStatus == MODE_FILTER) { + addFilterMode(); + } + } + + public void addSceneMode() { + final IconListPreference pref = (IconListPreference) mPreferenceGroup + .findPreference(CameraSettings.KEY_SCENE_MODE); + if (pref == null) + return; + + int rotation = CameraUtil.getDisplayRotation(mActivity); + boolean mIsDefaultToPortrait = CameraUtil.isDefaultToPortrait(mActivity); + if (!mIsDefaultToPortrait) { + rotation = (rotation + 90) % 360; + } + WindowManager wm = (WindowManager) mActivity.getSystemService(Context.WINDOW_SERVICE); + Display display = wm.getDefaultDisplay(); + + CharSequence[] entries = pref.getEntries(); + + int[] thumbnails = pref.getThumbnailIds(); + + int gridRes = 0; + boolean portrait = (rotation == 0) || (rotation == 180); + int size = Math.min(display.getWidth(), display.getHeight()) * 30 / 100; + if (portrait) { + gridRes = R.layout.vertical_grid; + size = Math.min(display.getWidth(), display.getHeight()) * 30 / 100; + } else { + gridRes = R.layout.horiz_grid; + } + previewMenuSize = size; + mUI.hideUI(); + mPreviewMenuStatus = PREVIEW_MENU_ON; + mSceneStatus = MODE_SCENE; + + LayoutInflater inflater = (LayoutInflater) mActivity.getSystemService( + Context.LAYOUT_INFLATER_SERVICE); + FrameLayout basic = (FrameLayout) inflater.inflate( + gridRes, null, false); + + mUI.dismissSceneModeMenu(); + LinearLayout previewMenuLayout = new LinearLayout(mActivity); + mUI.setPreviewMenuLayout(previewMenuLayout); + ViewGroup.LayoutParams params = null; + if (portrait) { + params = new ViewGroup.LayoutParams(size, LayoutParams.MATCH_PARENT); + previewMenuLayout.setLayoutParams(params); + ((ViewGroup) mUI.getRootView()).addView(previewMenuLayout); + } else { + params = new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT, size); + + previewMenuLayout.setLayoutParams(params); + ((ViewGroup) mUI.getRootView()).addView(previewMenuLayout); + previewMenuLayout.setY(display.getHeight() - size); + } + basic.setLayoutParams(new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, + LayoutParams.MATCH_PARENT)); + LinearLayout layout = (LinearLayout) basic.findViewById(R.id.layout); + + final View[] views = new View[entries.length]; + int init = pref.getCurrentIndex(); + for (int i = 0; i < entries.length; i++) { + LinearLayout layout2 = (LinearLayout) inflater.inflate( + R.layout.scene_mode_view, null, false); + + ImageView imageView = (ImageView) layout2.findViewById(R.id.image); + TextView label = (TextView) layout2.findViewById(R.id.label); + final int j = i; + + layout2.setOnTouchListener(new View.OnTouchListener() { + private long startTime; + + @Override + public boolean onTouch(View v, MotionEvent event) { + if (event.getAction() == MotionEvent.ACTION_DOWN) { + startTime = System.currentTimeMillis(); + + } else if (event.getAction() == MotionEvent.ACTION_UP) { + if (System.currentTimeMillis() - startTime < CLICK_THRESHOLD) { + pref.setValueIndex(j); + onSettingChanged(pref); + for (View v1 : views) { + v1.setBackgroundResource(R.drawable.scene_mode_view_border); + } + View border = v.findViewById(R.id.border); + border.setBackgroundResource(R.drawable.scene_mode_view_border_selected); + } + + } + return true; + } + }); + + View border = layout2.findViewById(R.id.border); + views[j] = border; + if (i == init) + border.setBackgroundResource(R.drawable.scene_mode_view_border_selected); + imageView.setImageResource(thumbnails[i]); + label.setText(entries[i]); + layout.addView(layout2); + } + previewMenuLayout.addView(basic); + mPreviewMenu = basic; + } + + public void initFilterModeButton(View button) { + button.setVisibility(View.INVISIBLE); + final IconListPreference pref = (IconListPreference) mPreferenceGroup + .findPreference(CameraSettings.KEY_COLOR_EFFECT); + if (pref == null) + return; + + int[] iconIds = pref.getLargeIconIds(); + int resid = -1; + // The preference only has a single icon to represent it. + resid = pref.getSingleIcon(); + ImageView iv = (ImageView) ((FrameLayout) button).getChildAt(0); + iv.setImageResource(resid); + button.setVisibility(View.VISIBLE); + button.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + addFilterMode(); + View view = mUI.getPreviewMenuLayout().getChildAt(0); + animateSlideIn(view, previewMenuSize, false); + } + }); + } + + public void addFilterMode() { + final IconListPreference pref = (IconListPreference) mPreferenceGroup + .findPreference(CameraSettings.KEY_COLOR_EFFECT); + if (pref == null) + return; + + int rotation = CameraUtil.getDisplayRotation(mActivity); + boolean mIsDefaultToPortrait = CameraUtil.isDefaultToPortrait(mActivity); + if (!mIsDefaultToPortrait) { + rotation = (rotation + 90) % 360; + } + WindowManager wm = (WindowManager) mActivity.getSystemService(Context.WINDOW_SERVICE); + Display display = wm.getDefaultDisplay(); + CharSequence[] entries = pref.getEntries(); + int gridRes = 0; + boolean portrait = (rotation == 0) || (rotation == 180); + int size = Math.min(display.getWidth(), display.getHeight()) * 35 / 100; + if (portrait) { + gridRes = R.layout.vertical_grid; + size = Math.min(display.getWidth(), display.getHeight()) * 30 / 100; + } else { + gridRes = R.layout.horiz_grid; + } + previewMenuSize = size; + mUI.hideUI(); + mPreviewMenuStatus = PREVIEW_MENU_ON; + mSceneStatus = MODE_FILTER; + + int[] thumbnails = pref.getThumbnailIds(); + + LayoutInflater inflater = (LayoutInflater) mActivity.getSystemService( + Context.LAYOUT_INFLATER_SERVICE); + FrameLayout basic = (FrameLayout) inflater.inflate( + gridRes, null, false); + + mUI.dismissSceneModeMenu(); + LinearLayout previewMenuLayout = new LinearLayout(mActivity); + mUI.setPreviewMenuLayout(previewMenuLayout); + ViewGroup.LayoutParams params = null; + if (portrait) { + params = new ViewGroup.LayoutParams(size, LayoutParams.MATCH_PARENT); + previewMenuLayout.setLayoutParams(params); + ((ViewGroup) mUI.getRootView()).addView(previewMenuLayout); + } else { + params = new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT, size); + previewMenuLayout.setLayoutParams(params); + ((ViewGroup) mUI.getRootView()).addView(previewMenuLayout); + previewMenuLayout.setY(display.getHeight() - size); + } + basic.setLayoutParams(new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, + LayoutParams.MATCH_PARENT)); + LinearLayout layout = (LinearLayout) basic.findViewById(R.id.layout); + final View[] views = new View[entries.length]; + int init = pref.getCurrentIndex(); + for (int i = 0; i < entries.length; i++) { + LinearLayout layout2 = (LinearLayout) inflater.inflate( + R.layout.filter_mode_view, null, false); + ImageView imageView = (ImageView) layout2.findViewById(R.id.image); + final int j = i; + + layout2.setOnTouchListener(new View.OnTouchListener() { + private long startTime; + + @Override + public boolean onTouch(View v, MotionEvent event) { + if (event.getAction() == MotionEvent.ACTION_DOWN) { + startTime = System.currentTimeMillis(); + } else if (event.getAction() == MotionEvent.ACTION_UP) { + if (System.currentTimeMillis() - startTime < CLICK_THRESHOLD) { + pref.setValueIndex(j); + onSettingChanged(pref); + for (View v1 : views) { + v1.setBackground(null); + } + ImageView image = (ImageView) v.findViewById(R.id.image); + image.setBackgroundColor(0xff33b5e5); + } + } + return true; + } + }); + + views[j] = imageView; + if (i == init) + imageView.setBackgroundColor(0xff33b5e5); + TextView label = (TextView) layout2.findViewById(R.id.label); + imageView.setImageResource(thumbnails[i]); + label.setText(entries[i]); + layout.addView(layout2); + } + previewMenuLayout.addView(basic); + mPreviewMenu = basic; + } + + public void openFirstLevel() { + if (isMenuBeingShown() || CameraControls.isAnimating()) + return; + if (mListMenu == null || mPopupStatus != POPUP_FIRST_LEVEL) { + initializePopup(); + mPopupStatus = POPUP_FIRST_LEVEL; + } + mUI.showPopup(mListMenu, 1, true); + + } + + public void popupDismissed(boolean dismissAll) { + if (!dismissAll && mPopupStatus == POPUP_SECOND_LEVEL) { + initializePopup(); + mPopupStatus = POPUP_FIRST_LEVEL; + mUI.showPopup(mListMenu, 1, false); + if (mListMenu != null) + mListMenu = null; + + } else { + initializePopup(); + } + + } + + @Override + // Hit when an item in the first-level popup gets selected, then bring up + // the second-level popup + public void onPreferenceClicked(ListPreference pref) { + onPreferenceClicked(pref, 0); + } + + public void onPreferenceClicked(ListPreference pref, int y) { + if (!mActivity.isDeveloperMenuEnabled()) { + if (pref.getKey().equals(CameraSettings.KEY_REDEYE_REDUCTION)) { + privateCounter++; + if (privateCounter >= DEVELOPER_MENU_TOUCH_COUNT) { + mActivity.enableDeveloperMenu(); + SharedPreferences prefs = PreferenceManager + .getDefaultSharedPreferences(mActivity); + prefs.edit().putBoolean(CameraSettings.KEY_DEVELOPER_MENU, true).apply(); + Toast toast = Toast.makeText(mActivity, + "Camera developer option is enabled now", Toast.LENGTH_SHORT); + toast.show(); + } + } else { + privateCounter = 0; + } + } + + LayoutInflater inflater = (LayoutInflater) mActivity.getSystemService( + Context.LAYOUT_INFLATER_SERVICE); + ListSubMenu basic = (ListSubMenu) inflater.inflate( + R.layout.list_sub_menu, null, false); + basic.initialize(pref, y); + basic.setSettingChangedListener(this); + basic.setAlpha(0f); + mListSubMenu = basic; + mUI.removeLevel2(); + if (mPopupStatus == POPUP_SECOND_LEVEL) { + mUI.showPopup(mListSubMenu, 2, false); + } else { + mUI.showPopup(mListSubMenu, 2, true); + } + mPopupStatus = POPUP_SECOND_LEVEL; + } + + public void onListMenuTouched() { + mUI.removeLevel2(); + } + + public void closeAllView() { + if (mUI != null) + mUI.removeLevel2(); + + if (mListMenu != null) { + animateSlideOut(mListMenu, 1); + } + animateSlideOutPreviewMenu(); + } + + public void closeView() { + if (mUI != null) + mUI.removeLevel2(); + + if (mListMenu != null && mPopupStatus != POPUP_NONE) + animateSlideOut(mListMenu, 1); + } + + // Return true if the preference has the specified key but not the value. + private static boolean notSame(ListPreference pref, String key, String value) { + return (key.equals(pref.getKey()) && !value.equals(pref.getValue())); + } + + private void setPreference(String key, String value) { + ListPreference pref = mPreferenceGroup.findPreference(key); + if (pref != null && !value.equals(pref.getValue())) { + pref.setValue(value); + reloadPreferences(); + } + } + + @Override + public void onSettingChanged(ListPreference pref) { + // Reset the scene mode if HDR is set to on. Reset HDR if scene mode is + // set to non-auto. + if (notSame(pref, CameraSettings.KEY_CAMERA_HDR, mSettingOff)) { + setPreference(CameraSettings.KEY_SCENE_MODE, Parameters.SCENE_MODE_AUTO); + setPreference(CameraSettings.KEY_ZSL, mSettingOff); + Toast.makeText(mActivity, R.string.hdr_enable_message, + Toast.LENGTH_LONG).show(); + mHdrOn = true; + } else if (notSame(pref, CameraSettings.KEY_SCENE_MODE, Parameters.SCENE_MODE_AUTO)) { + setPreference(CameraSettings.KEY_CAMERA_HDR, mSettingOff); + if (mHdrOn) { + Toast.makeText(mActivity, R.string.scene_enable_message, + Toast.LENGTH_LONG).show(); + } + mHdrOn = false; + } + if (notSame(pref, CameraSettings.KEY_ZSL, mSettingOff)) { + setPreference(CameraSettings.KEY_CAMERA_HDR, mSettingOff); + } + if (notSame(pref, CameraSettings.KEY_SCENE_MODE, Parameters.SCENE_MODE_AUTO)) { + buttonSetEnabled(mFilterModeSwitcher, false); + } else { + buttonSetEnabled(mFilterModeSwitcher, true); + } + super.onSettingChanged(pref); + } + +} diff --git a/src/com/android/camera/CustomVideoMenu.java b/src/com/android/camera/CustomVideoMenu.java new file mode 100644 index 000000000..0bf0095f6 --- /dev/null +++ b/src/com/android/camera/CustomVideoMenu.java @@ -0,0 +1,683 @@ +/* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * Not a Contribution. + * + * Copyright (C) 2012 The Android Open Source 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; + +import android.animation.Animator; +import android.animation.Animator.AnimatorListener; +import android.content.Context; +import android.content.SharedPreferences; +import android.graphics.Rect; +import android.preference.PreferenceManager; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.MotionEvent; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.ViewPropertyAnimator; +import android.widget.ListView; +import android.widget.TextView; +import android.widget.GridView; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.FrameLayout; +import android.widget.FrameLayout.LayoutParams; + +import com.android.camera.ui.CameraControls; +import com.android.camera.ui.ListSubMenu; +import com.android.camera.ui.ListMenu; +import com.android.camera.ui.TimeIntervalPopup; +import com.android.camera.ui.RotateImageView; +import org.codeaurora.snapcam.R; +import android.widget.HorizontalScrollView; +import android.view.ViewGroup; +import android.view.WindowManager; +import android.view.Display; +import com.android.camera.util.CameraUtil; + +public class CustomVideoMenu extends MenuController + implements ListMenu.Listener, + ListSubMenu.Listener, + TimeIntervalPopup.Listener { + + private static String TAG = "CustomVideoMenu"; + + private VideoUI mUI; + private String[] mOtherKeys1; + private String[] mOtherKeys2; + + private ListMenu mListMenu; + private ListSubMenu mListSubMenu; + private View mPreviewMenu; + private static final int POPUP_NONE = 0; + private static final int POPUP_FIRST_LEVEL = 1; + private static final int POPUP_SECOND_LEVEL = 2; + private static final int POPUP_IN_ANIMATION = 3; + private static final int PREVIEW_MENU_NONE = 0; + private static final int PREVIEW_MENU_IN_ANIMATION = 1; + private static final int PREVIEW_MENU_ON = 2; + private static final int MODE_FILTER = 1; + private int mSceneStatus; + private View mFrontBackSwitcher; + private View mFilterModeSwitcher; + private int mPopupStatus; + private int mPreviewMenuStatus; + private CameraActivity mActivity; + private static final int ANIMATION_DURATION = 300; + private static final int CLICK_THRESHOLD = 200; + private int previewMenuSize; + + public CustomVideoMenu(CameraActivity activity, VideoUI ui) { + super(activity); + mUI = ui; + mActivity = activity; + mFrontBackSwitcher = ui.getRootView().findViewById(R.id.front_back_switcher); + mFilterModeSwitcher = ui.getRootView().findViewById(R.id.filter_mode_switcher); + } + + public void initialize(PreferenceGroup group) { + super.initialize(group); + mListMenu = null; + mListSubMenu = null; + mPopupStatus = POPUP_NONE; + mPreviewMenuStatus = POPUP_NONE; + initFilterModeButton(mFilterModeSwitcher); + // settings popup + mOtherKeys1 = new String[] { + CameraSettings.KEY_VIDEO_QUALITY, + CameraSettings.KEY_VIDEO_DURATION, + CameraSettings.KEY_RECORD_LOCATION, + CameraSettings.KEY_CAMERA_SAVEPATH, + CameraSettings.KEY_COLOR_EFFECT, + CameraSettings.KEY_WHITE_BALANCE, + CameraSettings.KEY_VIDEO_HIGH_FRAME_RATE, + CameraSettings.KEY_VIDEOCAMERA_FLASH_MODE + }; + mOtherKeys2 = new String[] { + CameraSettings.KEY_VIDEO_QUALITY, + CameraSettings.KEY_VIDEO_DURATION, + CameraSettings.KEY_RECORD_LOCATION, + CameraSettings.KEY_CAMERA_SAVEPATH, + CameraSettings.KEY_COLOR_EFFECT, + CameraSettings.KEY_WHITE_BALANCE, + CameraSettings.KEY_VIDEO_HIGH_FRAME_RATE, + CameraSettings.KEY_VIDEOCAMERA_FLASH_MODE, + CameraSettings.KEY_DIS, + CameraSettings.KEY_VIDEO_EFFECT, + CameraSettings.KEY_VIDEO_TIME_LAPSE_FRAME_INTERVAL, + CameraSettings.KEY_VIDEO_ENCODER, + CameraSettings.KEY_AUDIO_ENCODER, + CameraSettings.KEY_VIDEO_HDR, + CameraSettings.KEY_POWER_MODE + }; + mFrontBackSwitcher.setVisibility(View.INVISIBLE); + initSwitchItem(CameraSettings.KEY_CAMERA_ID, mFrontBackSwitcher); + } + + public boolean handleBackKey() { + if (mPreviewMenuStatus == PREVIEW_MENU_ON) { + animateSlideOut(mPreviewMenu); + return true; + } + if (mPopupStatus == POPUP_NONE) + return false; + if (mPopupStatus == POPUP_FIRST_LEVEL) { + animateSlideOut(mListMenu, 1); + } else if (mPopupStatus == POPUP_SECOND_LEVEL) { + animateFadeOut(mListSubMenu, 2); + ((ListMenu) mListMenu).resetHighlight(); + } + return true; + } + + public void closeSceneMode() { + mUI.removeSceneModeMenu(); + } + + public void tryToCloseSubList() { + if (mListMenu != null) + ((ListMenu) mListMenu).resetHighlight(); + + if (mPopupStatus == POPUP_SECOND_LEVEL) { + mUI.dismissLevel2(); + mPopupStatus = POPUP_FIRST_LEVEL; + } + } + + private void animateFadeOut(final ListView v, final int level) { + if (v == null || mPopupStatus == POPUP_IN_ANIMATION) + return; + mPopupStatus = POPUP_IN_ANIMATION; + + ViewPropertyAnimator vp = v.animate(); + vp.alpha(0f).setDuration(ANIMATION_DURATION); + vp.setListener(new AnimatorListener() { + @Override + public void onAnimationStart(Animator animation) { + } + + @Override + public void onAnimationRepeat(Animator animation) { + + } + + @Override + public void onAnimationEnd(Animator animation) { + if (level == 1) { + mUI.dismissLevel1(); + initializePopup(); + mPopupStatus = POPUP_NONE; + mUI.cleanupListview(); + } + else if (level == 2) { + mUI.dismissLevel2(); + mPopupStatus = POPUP_FIRST_LEVEL; + } + } + + @Override + public void onAnimationCancel(Animator animation) { + if (level == 1) { + mUI.dismissLevel1(); + initializePopup(); + mPopupStatus = POPUP_NONE; + mUI.cleanupListview(); + } + else if (level == 2) { + mUI.dismissLevel2(); + mPopupStatus = POPUP_FIRST_LEVEL; + } + + } + }); + vp.start(); + } + + private void animateSlideOut(final ListView v, final int level) { + if (v == null || mPopupStatus == POPUP_IN_ANIMATION) + return; + mPopupStatus = POPUP_IN_ANIMATION; + + ViewPropertyAnimator vp = v.animate(); + vp.translationX(v.getX() - v.getWidth()).setDuration(ANIMATION_DURATION); + vp.setListener(new AnimatorListener() { + @Override + public void onAnimationStart(Animator animation) { + } + + @Override + public void onAnimationRepeat(Animator animation) { + + } + + @Override + public void onAnimationEnd(Animator animation) { + if (level == 1) { + mUI.dismissLevel1(); + initializePopup(); + mPopupStatus = POPUP_NONE; + mUI.cleanupListview(); + } + else if (level == 2) { + mUI.dismissLevel2(); + mPopupStatus = POPUP_FIRST_LEVEL; + } + } + + @Override + public void onAnimationCancel(Animator animation) { + if (level == 1) { + mUI.dismissLevel1(); + initializePopup(); + mPopupStatus = POPUP_NONE; + mUI.cleanupListview(); + } + else if (level == 2) { + mUI.dismissLevel2(); + mPopupStatus = POPUP_FIRST_LEVEL; + } + + } + }); + vp.start(); + } + + public void animateFadeIn(final ListView v) { + ViewPropertyAnimator vp = v.animate(); + vp.alpha(0.85f).setDuration(ANIMATION_DURATION); + vp.start(); + } + + public void animateSlideIn(final View v, int delta, boolean settingMenu) { + int rotation = CameraUtil.getDisplayRotation(mActivity); + boolean mIsDefaultToPortrait = CameraUtil.isDefaultToPortrait(mActivity); + if (!mIsDefaultToPortrait) { + rotation = (rotation + 90) % 360; + } + boolean portrait = (rotation == 0) || (rotation == 180); + if (settingMenu) + portrait = true; + ViewPropertyAnimator vp = v.animate(); + if (portrait) { + float dest = v.getX(); + v.setX(dest - delta); + vp.translationX(dest).setDuration(ANIMATION_DURATION); + } + else { + float dest = v.getY(); + v.setY(dest + delta); + vp.translationY(dest).setDuration(ANIMATION_DURATION); + } + vp.start(); + } + + public void animateSlideOutPreviewMenu() { + if (mPreviewMenu == null) + return; + animateSlideOut(mPreviewMenu); + } + + private void animateSlideOut(final View v) { + if (v == null || mPreviewMenuStatus == PREVIEW_MENU_IN_ANIMATION) + return; + mPreviewMenuStatus = PREVIEW_MENU_IN_ANIMATION; + int rotation = CameraUtil.getDisplayRotation(mActivity); + boolean mIsDefaultToPortrait = CameraUtil.isDefaultToPortrait(mActivity); + if (!mIsDefaultToPortrait) { + rotation = (rotation + 90) % 360; + } + boolean portrait = (rotation == 0) || (rotation == 180); + ViewPropertyAnimator vp = v.animate(); + if (portrait) { + vp.translationX(v.getX() - v.getWidth()).setDuration(ANIMATION_DURATION); + + } else { + vp.translationY(v.getY() + v.getHeight()).setDuration(ANIMATION_DURATION); + + } + vp.setListener(new AnimatorListener() { + @Override + public void onAnimationStart(Animator animation) { + } + + @Override + public void onAnimationRepeat(Animator animation) { + + } + + @Override + public void onAnimationEnd(Animator animation) { + closeSceneMode(); + mPreviewMenuStatus = PREVIEW_MENU_NONE; + } + + @Override + public void onAnimationCancel(Animator animation) { + closeSceneMode(); + mPreviewMenuStatus = PREVIEW_MENU_NONE; + } + }); + vp.start(); + } + + public boolean isOverMenu(MotionEvent ev) { + if (mPopupStatus == POPUP_NONE || mPopupStatus == POPUP_IN_ANIMATION) + return false; + if (mUI.getMenuLayout() == null) + return false; + Rect rec = new Rect(); + mUI.getMenuLayout().getChildAt(0).getHitRect(rec); + return rec.contains((int) ev.getX(), (int) ev.getY()); + } + + public boolean isOverPreviewMenu(MotionEvent ev) { + if (mPreviewMenuStatus != PREVIEW_MENU_ON) + return false; + if (mUI.getPreviewMenuLayout() == null) + return false; + Rect rec = new Rect(); + mUI.getPreviewMenuLayout().getChildAt(0).getHitRect(rec); + rec.top += (int) mUI.getPreviewMenuLayout().getY(); + rec.bottom += (int) mUI.getPreviewMenuLayout().getY(); + return rec.contains((int) ev.getX(), (int) ev.getY()); + } + + public boolean isMenuBeingShown() { + return mPopupStatus != POPUP_NONE; + } + + public boolean isMenuBeingAnimated() { + return mPopupStatus == POPUP_IN_ANIMATION; + } + + public boolean isPreviewMenuBeingShown() { + return mPreviewMenuStatus == PREVIEW_MENU_ON; + } + + public boolean isPreviewMenuBeingAnimated() { + return mPreviewMenuStatus == PREVIEW_MENU_IN_ANIMATION; + } + + public boolean sendTouchToPreviewMenu(MotionEvent ev) { + return mUI.sendTouchToPreviewMenu(ev); + } + + public boolean sendTouchToMenu(MotionEvent ev) { + return mUI.sendTouchToMenu(ev); + } + + public void initSwitchItem(final String prefKey, View switcher) { + final IconListPreference pref = + (IconListPreference) mPreferenceGroup.findPreference(prefKey); + if (pref == null) + return; + + int[] iconIds = pref.getLargeIconIds(); + int resid = -1; + int index = pref.findIndexOfValue(pref.getValue()); + if (!pref.getUseSingleIcon() && iconIds != null) { + // Each entry has a corresponding icon. + resid = iconIds[index]; + } else { + // The preference only has a single icon to represent it. + resid = pref.getSingleIcon(); + } + ImageView iv = (ImageView) ((FrameLayout) switcher).getChildAt(0); + iv.setImageResource(resid); + switcher.setVisibility(View.VISIBLE); + mPreferences.add(pref); + mPreferenceMap.put(pref, switcher); + switcher.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + IconListPreference pref = (IconListPreference) mPreferenceGroup + .findPreference(prefKey); + if (pref == null) + return; + int index = pref.findIndexOfValue(pref.getValue()); + CharSequence[] values = pref.getEntryValues(); + index = (index + 1) % values.length; + pref.setValueIndex(index); + ImageView iv = (ImageView) ((FrameLayout) v).getChildAt(0); + iv.setImageResource(((IconListPreference) pref).getLargeIconIds()[index]); + if (prefKey.equals(CameraSettings.KEY_CAMERA_ID)) + mListener.onCameraPickerClicked(index); + reloadPreference(pref); + onSettingChanged(pref); + } + }); + } + + public void initFilterModeButton(View button) { + button.setVisibility(View.INVISIBLE); + final IconListPreference pref = (IconListPreference) mPreferenceGroup + .findPreference(CameraSettings.KEY_COLOR_EFFECT); + if (pref == null) + return; + + int[] iconIds = pref.getLargeIconIds(); + int resid = -1; + // The preference only has a single icon to represent it. + resid = pref.getSingleIcon(); + ImageView iv = (ImageView) ((FrameLayout) button).getChildAt(0); + iv.setImageResource(resid); + button.setVisibility(View.VISIBLE); + button.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + addFilterMode(); + View view = mUI.getPreviewMenuLayout().getChildAt(0); + animateSlideIn(view, previewMenuSize, false); + } + }); + } + + public void addModeBack() { + if (mSceneStatus == MODE_FILTER) { + addFilterMode(); + } + } + + public void addFilterMode() { + final IconListPreference pref = (IconListPreference) mPreferenceGroup + .findPreference(CameraSettings.KEY_COLOR_EFFECT); + if (pref == null) + return; + + int rotation = CameraUtil.getDisplayRotation(mActivity); + boolean mIsDefaultToPortrait = CameraUtil.isDefaultToPortrait(mActivity); + if (!mIsDefaultToPortrait) { + rotation = (rotation + 90) % 360; + } + WindowManager wm = (WindowManager) mActivity.getSystemService(Context.WINDOW_SERVICE); + Display display = wm.getDefaultDisplay(); + CharSequence[] entries = pref.getEntries(); + int gridRes = 0; + boolean portrait = (rotation == 0) || (rotation == 180); + int size = Math.min(display.getWidth(), display.getHeight()) * 35 / 100; + if (portrait) { + gridRes = R.layout.vertical_grid; + size = Math.min(display.getWidth(), display.getHeight()) * 30 / 100; + } else { + gridRes = R.layout.horiz_grid; + } + previewMenuSize = size; + mUI.hideUI(); + mPreviewMenuStatus = PREVIEW_MENU_ON; + mSceneStatus = MODE_FILTER; + + int[] thumbnails = pref.getThumbnailIds(); + + LayoutInflater inflater = (LayoutInflater) mActivity.getSystemService( + Context.LAYOUT_INFLATER_SERVICE); + FrameLayout basic = (FrameLayout) inflater.inflate( + gridRes, null, false); + + mUI.dismissSceneModeMenu(); + LinearLayout previewMenuLayout = new LinearLayout(mActivity); + mUI.setPreviewMenuLayout(previewMenuLayout); + ViewGroup.LayoutParams params = null; + if (portrait) { + params = new ViewGroup.LayoutParams(size, LayoutParams.MATCH_PARENT); + previewMenuLayout.setLayoutParams(params); + ((ViewGroup) mUI.getRootView()).addView(previewMenuLayout); + } else { + params = new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT, size); + previewMenuLayout.setLayoutParams(params); + ((ViewGroup) mUI.getRootView()).addView(previewMenuLayout); + previewMenuLayout.setY(display.getHeight() - size); + } + basic.setLayoutParams(new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, + LayoutParams.MATCH_PARENT)); + LinearLayout layout = (LinearLayout) basic.findViewById(R.id.layout); + + final View[] views = new View[entries.length]; + int init = pref.getCurrentIndex(); + for (int i = 0; i < entries.length; i++) { + LinearLayout layout2 = (LinearLayout) inflater.inflate( + R.layout.filter_mode_view, null, false); + + ImageView imageView = (ImageView) layout2.findViewById(R.id.image); + final int j = i; + + layout2.setOnTouchListener(new View.OnTouchListener() { + private long startTime; + + @Override + public boolean onTouch(View v, MotionEvent event) { + if (event.getAction() == MotionEvent.ACTION_DOWN) { + startTime = System.currentTimeMillis(); + } else if (event.getAction() == MotionEvent.ACTION_UP) { + if (System.currentTimeMillis() - startTime < CLICK_THRESHOLD) { + pref.setValueIndex(j); + for (View v1 : views) { + v1.setBackground(null); + } + ImageView image = (ImageView) v.findViewById(R.id.image); + image.setBackgroundColor(0xff33b5e5); + onSettingChanged(pref); + } + + } + return true; + } + }); + + views[j] = imageView; + if (i == init) + imageView.setBackgroundColor(0xff33b5e5); + TextView label = (TextView) layout2.findViewById(R.id.label); + imageView.setImageResource(thumbnails[i]); + label.setText(entries[i]); + layout.addView(layout2); + } + previewMenuLayout.addView(basic); + mPreviewMenu = basic; + } + + public void openFirstLevel() { + if (isMenuBeingShown() || CameraControls.isAnimating()) + return; + if (mListMenu == null || mPopupStatus != POPUP_FIRST_LEVEL) { + initializePopup(); + mPopupStatus = POPUP_FIRST_LEVEL; + } + mUI.showPopup(mListMenu, 1, true); + } + + @Override + public void overrideSettings(final String... keyvalues) { + super.overrideSettings(keyvalues); + if (((mListMenu == null)) || mPopupStatus != POPUP_FIRST_LEVEL) { + mPopupStatus = POPUP_FIRST_LEVEL; + initializePopup(); + } + mListMenu.overrideSettings(keyvalues); + + } + + @Override + // Hit when an item in the second-level popup gets selected + public void onListPrefChanged(ListPreference pref) { + if (mPopupStatus == POPUP_SECOND_LEVEL) { + mListMenu.reloadPreference(); + animateFadeOut(mListSubMenu, 2); + } + super.onSettingChanged(pref); + ((ListMenu) mListMenu).resetHighlight(); + } + + protected void initializePopup() { + LayoutInflater inflater = (LayoutInflater) mActivity.getSystemService( + Context.LAYOUT_INFLATER_SERVICE); + + ListMenu popup1 = (ListMenu) inflater.inflate( + R.layout.list_menu, null, false); + popup1.setSettingChangedListener(this); + String[] keys = mOtherKeys1; + if (mActivity.isDeveloperMenuEnabled()) + keys = mOtherKeys2; + popup1.initialize(mPreferenceGroup, keys); + if (mActivity.isSecureCamera()) { + // Prevent location preference from getting changed in secure camera + // mode + popup1.setPreferenceEnabled(CameraSettings.KEY_RECORD_LOCATION, false); + } + mListMenu = popup1; + + } + + public void popupDismissed(boolean topPopupOnly) { + // if the 2nd level popup gets dismissed + if (mPopupStatus == POPUP_SECOND_LEVEL) { + initializePopup(); + mPopupStatus = POPUP_FIRST_LEVEL; + if (topPopupOnly) { + mUI.showPopup(mListMenu, 1, false); + } + } else { + initializePopup(); + } + } + + public void hideUI() { + mFrontBackSwitcher.setVisibility(View.INVISIBLE); + mFilterModeSwitcher.setVisibility(View.INVISIBLE); + } + + public void showUI() { + mFrontBackSwitcher.setVisibility(View.VISIBLE); + mFilterModeSwitcher.setVisibility(View.VISIBLE); + } + + @Override + // Hit when an item in the first-level popup gets selected, then bring up + // the second-level popup + public void onPreferenceClicked(ListPreference pref) { + onPreferenceClicked(pref, 0); + } + + @Override + // Hit when an item in the first-level popup gets selected, then bring up + // the second-level popup + public void onPreferenceClicked(ListPreference pref, int y) { + LayoutInflater inflater = (LayoutInflater) mActivity.getSystemService( + Context.LAYOUT_INFLATER_SERVICE); + + ListSubMenu basic = (ListSubMenu) inflater.inflate( + R.layout.list_sub_menu, null, false); + basic.initialize(pref, y); + basic.setSettingChangedListener(this); + mUI.removeLevel2(); + mListSubMenu = basic; + if (mPopupStatus == POPUP_SECOND_LEVEL) { + mUI.showPopup(mListSubMenu, 2, false); + } else { + mUI.showPopup(mListSubMenu, 2, true); + } + mPopupStatus = POPUP_SECOND_LEVEL; + } + + public void onListMenuTouched() { + mUI.removeLevel2(); + } + + public void closeAllView() { + if (mUI != null) + mUI.removeLevel2(); + + if (mListMenu != null) + animateSlideOut(mListMenu, 1); + animateSlideOutPreviewMenu(); + } + + public void closeView() { + if (mUI != null) + mUI.removeLevel2(); + + if (mListMenu != null) + animateSlideOut(mListMenu, 1); + } + + @Override + public void onSettingChanged(ListPreference pref) { + super.onSettingChanged(pref); + } + +} diff --git a/src/com/android/camera/IconListPreference.java b/src/com/android/camera/IconListPreference.java index eab0d613e..9c7463eda 100644 --- a/src/com/android/camera/IconListPreference.java +++ b/src/com/android/camera/IconListPreference.java @@ -31,6 +31,7 @@ public class IconListPreference extends ListPreference { private int mIconIds[]; private int mLargeIconIds[]; private int mImageIds[]; + private int mThumbnailIds[]; private boolean mUseSingleIcon; public IconListPreference(Context context, AttributeSet attrs) { @@ -46,6 +47,8 @@ public class IconListPreference extends ListPreference { R.styleable.IconListPreference_largeIcons, 0)); mImageIds = getIds(res, a.getResourceId( R.styleable.IconListPreference_images, 0)); + mThumbnailIds = getIds(res, a.getResourceId( + R.styleable.IconListPreference_thumbnails, 0)); a.recycle(); } @@ -61,6 +64,10 @@ public class IconListPreference extends ListPreference { return mLargeIconIds; } + public int[] getThumbnailIds() { + return mThumbnailIds; + } + public int[] getImageIds() { return mImageIds; } @@ -77,6 +84,10 @@ public class IconListPreference extends ListPreference { mLargeIconIds = largeIconIds; } + public void setThumbnailIds(int[] thumbnailIds) { + mThumbnailIds = thumbnailIds; + } + public void setUseSingleIcon(boolean useSingle) { mUseSingleIcon = useSingle; } @@ -99,12 +110,14 @@ public class IconListPreference extends ListPreference { IntArray iconIds = new IntArray(); IntArray largeIconIds = new IntArray(); IntArray imageIds = new IntArray(); + IntArray thumbnailIds = new IntArray(); for (int i = 0, len = entryValues.length; i < len; i++) { if (supported.indexOf(entryValues[i].toString()) >= 0) { if (mIconIds != null) iconIds.add(mIconIds[i]); if (mLargeIconIds != null) largeIconIds.add(mLargeIconIds[i]); if (mImageIds != null) imageIds.add(mImageIds[i]); + if (mThumbnailIds != null) thumbnailIds.add(mThumbnailIds[i]); } } if (mIconIds != null) mIconIds = iconIds.toArray(new int[iconIds.size()]); @@ -112,6 +125,7 @@ public class IconListPreference extends ListPreference { mLargeIconIds = largeIconIds.toArray(new int[largeIconIds.size()]); } if (mImageIds != null) mImageIds = imageIds.toArray(new int[imageIds.size()]); + if (mThumbnailIds != null) mThumbnailIds = thumbnailIds.toArray(new int[thumbnailIds.size()]); super.filterUnsupported(supported); } } diff --git a/src/com/android/camera/MenuController.java b/src/com/android/camera/MenuController.java new file mode 100644 index 000000000..333a5f2aa --- /dev/null +++ b/src/com/android/camera/MenuController.java @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * Not a Contribution. + * + * Copyright (C) 2012 The Android Open Source 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; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import android.app.Activity; +import android.util.Log; +import android.view.View; +import android.widget.FrameLayout; +import android.widget.ImageView; + +import com.android.camera.CameraPreference.OnPreferenceChangedListener; +import com.android.camera.ui.RotateImageView; + +public class MenuController { + + private static String TAG = "CAM_menucontrol"; + + protected static final int MODE_PHOTO = 0; + protected static final int MODE_VIDEO = 1; + + protected Activity mActivity; + protected PreferenceGroup mPreferenceGroup; + protected OnPreferenceChangedListener mListener; + protected List<IconListPreference> mPreferences; + protected Map<IconListPreference, View> mPreferenceMap; + private Map<IconListPreference, String> mOverrides; + + public void setListener(OnPreferenceChangedListener listener) { + mListener = listener; + } + + public MenuController(Activity activity) { + mActivity = activity; + mPreferences = new ArrayList<IconListPreference>(); + mPreferenceMap = new HashMap<IconListPreference, View>(); + mOverrides = new HashMap<IconListPreference, String>(); + } + + public void initialize(PreferenceGroup group) { + mPreferenceMap.clear(); + setPreferenceGroup(group); + mPreferences.clear(); + mOverrides.clear(); + } + + public void onSettingChanged(ListPreference pref) { + if (mListener != null) { + mListener.onSharedPreferenceChanged(); + } + } + + protected void setCameraId(int cameraId) { + ListPreference pref = mPreferenceGroup.findPreference(CameraSettings.KEY_CAMERA_ID); + pref.setValue("" + cameraId); + } + + public void setPreferenceGroup(PreferenceGroup group) { + mPreferenceGroup = group; + } + + public void reloadPreferences() { + mPreferenceGroup.reloadValue(); + for (IconListPreference pref : mPreferences) { + reloadPreference(pref); + } + } + + protected void reloadPreference(IconListPreference pref) { + View switcher = mPreferenceMap.get(pref); + if (switcher == null) + return; + String overrideValue = mOverrides.get(pref); + int index; + if (overrideValue == null) { + index = pref.findIndexOfValue(pref.getValue()); + } else { + index = pref.findIndexOfValue(overrideValue); + if (index == -1) { + // Avoid the crash if camera driver has bugs. + Log.e(TAG, "Fail to find override value=" + overrideValue); + pref.print(); + return; + } + } + ImageView iv = (ImageView) ((FrameLayout) switcher).getChildAt(0); + iv.setImageResource(pref.getLargeIconIds()[index]); + + } + + // Scene mode may override other camera settings (ex: flash mode). + public void overrideSettings(final String... keyvalues) { + if (keyvalues.length % 2 != 0) { + throw new IllegalArgumentException(); + } + for (IconListPreference pref : mPreferences) { + override(pref, keyvalues); + } + } + + private void override(IconListPreference pref, final String... keyvalues) { + mOverrides.remove(pref); + for (int i = 0; i < keyvalues.length; i += 2) { + String key = keyvalues[i]; + String value = keyvalues[i + 1]; + if (key.equals(pref.getKey())) { + mOverrides.put(pref, value); + break; + } + } + reloadPreference(pref); + } +} diff --git a/src/com/android/camera/OnScreenIndicators.java b/src/com/android/camera/OnScreenIndicators.java index 5f5dbc311..67cbad1c9 100644 --- a/src/com/android/camera/OnScreenIndicators.java +++ b/src/com/android/camera/OnScreenIndicators.java @@ -63,6 +63,12 @@ public class OnScreenIndicators { R.id.menu_timer_indicator); mWBIndicator = (ImageView) onScreenIndicatorsView.findViewById( R.id.menu_wb_indicator); + mExposureIndicator.setVisibility(View.GONE); + mFlashIndicator.setVisibility(View.GONE); + mSceneIndicator.setVisibility(View.GONE); + mLocationIndicator.setVisibility(View.GONE); + mTimerIndicator.setVisibility(View.GONE); + mWBIndicator.setVisibility(View.GONE); } /** @@ -120,7 +126,7 @@ public class OnScreenIndicators { id = R.drawable.ic_indicator_ev_p3; break; } - mExposureIndicator.setImageResource(id); + mExposureIndicator.setImageResource(R.drawable.ic_settings); } public void updateWBIndicator(int wbIndex) { diff --git a/src/com/android/camera/PhotoModule.java b/src/com/android/camera/PhotoModule.java index 299540010..e10f4ecbb 100644 --- a/src/com/android/camera/PhotoModule.java +++ b/src/com/android/camera/PhotoModule.java @@ -951,6 +951,8 @@ public class PhotoModule return; } + mUI.doShutterAnimation(); + if (mLongshotSave) { mCameraDevice.takePicture(mHandler, new LongshotShutterCallback(), @@ -1891,6 +1893,7 @@ public class PhotoModule // 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(); } @@ -4293,6 +4296,7 @@ public class PhotoModule } skinToneSeekBar.setProgress(progress); mActivity.findViewById(R.id.linear).bringToFront(); + mActivity.findViewById(R.id.progress).setVisibility(View.GONE); skinToneSeekBar.bringToFront(); Title.setText("Skin Tone Enhancement"); Title.setVisibility(View.VISIBLE); diff --git a/src/com/android/camera/PhotoUI.java b/src/com/android/camera/PhotoUI.java index eb077c3b2..238be864a 100644 --- a/src/com/android/camera/PhotoUI.java +++ b/src/com/android/camera/PhotoUI.java @@ -17,6 +17,8 @@ package com.android.camera; +import java.util.List; + import android.app.AlertDialog; import android.content.DialogInterface; import android.content.res.Configuration; @@ -32,15 +34,20 @@ import android.os.AsyncTask; import android.util.Log; import android.view.Gravity; import android.view.TextureView; +import android.view.MotionEvent; import android.view.View; import android.view.View.OnClickListener; import android.view.View.OnLayoutChangeListener; import android.view.ViewGroup; +import android.view.ViewPropertyAnimator; import android.view.ViewStub; import android.widget.FrameLayout.LayoutParams; import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.ListView; import android.widget.PopupWindow; import android.widget.Toast; +import android.graphics.drawable.AnimationDrawable; import com.android.camera.CameraPreference.OnPreferenceChangedListener; import com.android.camera.FocusOverlayManager.FocusUI; @@ -59,8 +66,6 @@ import com.android.camera.ui.ZoomRenderer; import com.android.camera.util.CameraUtil; import org.codeaurora.snapcam.R; -import java.util.List; - public class PhotoUI implements PieListener, PreviewGestures.SingleTapListener, FocusUI, TextureView.SurfaceTextureListener, @@ -91,6 +96,7 @@ public class PhotoUI implements PieListener, private View mMenuButton; private PhotoMenu mMenu; + private CustomPhotoMenu mCustomPhotoMenu; private ModuleSwitcher mSwitcher; private CameraControls mCameraControls; private AlertDialog mLocationDialog; @@ -108,6 +114,7 @@ public class PhotoUI implements PieListener, private int mPreviewWidth = 0; private int mPreviewHeight = 0; public boolean mMenuInitialized = false; + public boolean mCustomPhotoMenuInitialized = false; private float mSurfaceTextureUncroppedWidth; private float mSurfaceTextureUncroppedHeight; @@ -124,6 +131,11 @@ public class PhotoUI implements PieListener, private boolean mPrevOrientationResize; private View mPreviewCover; private final Object mSurfaceTextureLock = new Object(); + private LinearLayout mMenuLayout; + private LinearLayout mSubMenuLayout; + private LinearLayout mPreviewMenuLayout; + private boolean mUIhidden = false; + private int mPreviewOrientation = -1; public interface SurfaceTextureSizeChangedListener { public void onSurfaceTextureSizeChanged(int uncroppedWidth, int uncroppedHeight); @@ -145,6 +157,9 @@ public class PhotoUI implements PieListener, (int) mSurfaceTextureUncroppedHeight); mAspectRatioResize = false; } + + if (mCustomPhotoMenu != null) + mCustomPhotoMenu.tryToCloseSubList(); } }; @@ -371,6 +386,13 @@ public class PhotoUI implements PieListener, mMenu.initialize(prefGroup); mMenuInitialized = true; + if (mCustomPhotoMenu == null) { + mCustomPhotoMenu = new CustomPhotoMenu(mActivity, this); + mCustomPhotoMenu.setListener(listener); + } + mCustomPhotoMenu.initialize(prefGroup); + mCustomPhotoMenuInitialized = true; + if (mZoomRenderer == null) { mZoomRenderer = new ZoomRenderer(mActivity); mRenderOverlay.addRenderer(mZoomRenderer); @@ -381,12 +403,15 @@ public class PhotoUI implements PieListener, mGestures = new PreviewGestures(mActivity, this, mZoomRenderer, mPieRenderer); mRenderOverlay.setGestures(mGestures); } + mGestures.setCustomPhotoMenu(mCustomPhotoMenu); + mGestures.setZoomEnabled(params.isZoomSupported()); mGestures.setRenderOverlay(mRenderOverlay); mRenderOverlay.requestLayout(); initializeZoom(params); updateOnScreenIndicators(params, prefGroup, prefs); + mActivity.setPreviewGestures(mGestures); } public void animateCapture(final byte[] jpegData, int orientation, boolean mirror) { @@ -411,14 +436,15 @@ public class PhotoUI implements PieListener, mPreviewThumb.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { - mActivity.gotoGallery(); + if (!CameraControls.isAnimating()) + mActivity.gotoGallery(); } }); mMenuButton = mRootView.findViewById(R.id.menu); mMenuButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { - openMenu(); + mCustomPhotoMenu.openFirstLevel(); } }); if (mController.isImageCaptureIntent()) { @@ -455,16 +481,22 @@ public class PhotoUI implements PieListener, } public void hideUI() { - mCameraControls.setVisibility(View.INVISIBLE); mSwitcher.closePopup(); + if (mUIhidden) + return; + mUIhidden = true; + mCameraControls.hideUI(); } public void showUI() { - mCameraControls.setVisibility(View.VISIBLE); + if (!mUIhidden || (mCustomPhotoMenu != null && mCustomPhotoMenu.isMenuBeingShown())) + return; + mUIhidden = false; + mCameraControls.showUI(); } public boolean arePreviewControlsVisible() { - return (mCameraControls.getVisibility() == View.VISIBLE); + return !mUIhidden; } public void hideSwitcher() { @@ -478,11 +510,27 @@ public class PhotoUI implements PieListener, // called from onResume but only the first time public void initializeFirstTime() { // Initialize shutter button. - mShutterButton.setImageResource(R.drawable.btn_new_shutter); + mShutterButton.setImageBitmap(null); + mShutterButton.setBackgroundResource(R.drawable.shutter_button_anim); + mShutterButton.setOnClickListener(new OnClickListener() + { + @Override + public void onClick(View v) { + if (!CameraControls.isAnimating()) + doShutterAnimation(); + } + }); + mShutterButton.setOnShutterButtonListener(mController); mShutterButton.setVisibility(View.VISIBLE); } + public void doShutterAnimation() { + AnimationDrawable frameAnimation = (AnimationDrawable) mShutterButton.getBackground(); + frameAnimation.stop(); + frameAnimation.start(); + } + // called from onResume every other time public void initializeSecondTime(Camera.Parameters params) { initializeZoom(params); @@ -492,6 +540,9 @@ public class PhotoUI implements PieListener, if (mMenu != null) { mMenu.reloadPreferences(); } + if (mCustomPhotoMenu != null) { + mCustomPhotoMenu.reloadPreferences(); + } } public void showLocationDialog() { @@ -545,7 +596,10 @@ public class PhotoUI implements PieListener, public void hideGpsOnScreenIndicator() { } public void overrideSettings(final String ... keyvalues) { - if (mMenu == null) return; + if (mCustomPhotoMenu != null) + mCustomPhotoMenu.overrideSettings(keyvalues); + if (mMenu == null) + return; mMenu.overrideSettings(keyvalues); } @@ -593,6 +647,10 @@ public class PhotoUI implements PieListener, } public boolean onBackPressed() { + if (mCustomPhotoMenu != null && mCustomPhotoMenu.handleBackKey()) { + return true; + } + if (mPieRenderer != null && mPieRenderer.showsItems()) { mPieRenderer.hide(); return true; @@ -606,6 +664,9 @@ public class PhotoUI implements PieListener, } else if (!mController.isCameraIdle()) { // ignore backs while we're taking a picture return true; + } if (mSwitcher != null && mSwitcher.showsPopup()) { + mSwitcher.closePopup(); + return true; } else { return false; } @@ -634,6 +695,59 @@ public class PhotoUI implements PieListener, if (!previewFocused && mCountDownView != null) mCountDownView.cancelCountDown(); } + public ViewGroup getMenuLayout() { + return mMenuLayout; + } + + public void setPreviewMenuLayout(LinearLayout layout) { + mPreviewMenuLayout = layout; + } + + public ViewGroup getPreviewMenuLayout() { + return mPreviewMenuLayout; + } + + public void showPopup(ListView popup, int level, boolean animate) { + hideUI(); + + popup.setVisibility(View.VISIBLE); + if (level == 1) { + if (mMenuLayout == null) { + mMenuLayout = new LinearLayout(mActivity); + ViewGroup.LayoutParams params = new ViewGroup.LayoutParams( + CameraActivity.SETTING_LIST_WIDTH_1, LayoutParams.WRAP_CONTENT); + mMenuLayout.setLayoutParams(params); + ((ViewGroup) mRootView).addView(mMenuLayout); + } + mMenuLayout.addView(popup); + } + if (level == 2) { + if (mSubMenuLayout == null) { + mSubMenuLayout = new LinearLayout(mActivity); + ViewGroup.LayoutParams params = new ViewGroup.LayoutParams( + CameraActivity.SETTING_LIST_WIDTH_2, LayoutParams.WRAP_CONTENT); + mSubMenuLayout.setLayoutParams(params); + ((ViewGroup) mRootView).addView(mSubMenuLayout); + } + mSubMenuLayout.addView(popup); + mSubMenuLayout.setX(CameraActivity.SETTING_LIST_WIDTH_1); + } + if (animate) { + if (level == 1) + mCustomPhotoMenu.animateSlideIn(popup, CameraActivity.SETTING_LIST_WIDTH_1, true); + if (level == 2) + mCustomPhotoMenu.animateFadeIn(popup); + } else + popup.setAlpha(0.85f); + } + + public void removeLevel2() { + if (mSubMenuLayout != null) { + View v = mSubMenuLayout.getChildAt(0); + mSubMenuLayout.removeView(v); + } + } + public void showPopup(AbstractSettingPopup popup) { hideUI(); @@ -661,6 +775,11 @@ public class PhotoUI implements PieListener, mPopup.showAtLocation(mRootView, Gravity.CENTER, 0, 0); } + public void cleanupListview() { + showUI(); + mActivity.setSystemBarsVisibility(false); + } + public void dismissPopup() { if (mPopup != null && mPopup.isShowing()) { mPopup.dismiss(); @@ -675,6 +794,44 @@ public class PhotoUI implements PieListener, } } + public void dismissLevel1() { + if (mMenuLayout != null) { + ((ViewGroup) mRootView).removeView(mMenuLayout); + mMenuLayout = null; + } + } + + public void dismissLevel2() { + if (mSubMenuLayout != null) { + ((ViewGroup) mRootView).removeView(mSubMenuLayout); + mSubMenuLayout = null; + } + } + + public boolean sendTouchToPreviewMenu(MotionEvent ev) { + return mPreviewMenuLayout.dispatchTouchEvent(ev); + } + + public boolean sendTouchToMenu(MotionEvent ev) { + View v = mMenuLayout.getChildAt(0); + return v.dispatchTouchEvent(ev); + } + + public void dismissSceneModeMenu() { + if (mPreviewMenuLayout != null) { + ((ViewGroup) mRootView).removeView(mPreviewMenuLayout); + mPreviewMenuLayout = null; + } + } + + public void removeSceneModeMenu() { + if (mPreviewMenuLayout != null) { + ((ViewGroup) mRootView).removeView(mPreviewMenuLayout); + mPreviewMenuLayout = null; + } + cleanupListview(); + } + public void onShowSwitcherPopup() { if (mPieRenderer != null && mPieRenderer.showsItems()) { mPieRenderer.hide(); @@ -685,9 +842,6 @@ public class PhotoUI implements PieListener, if (mOnScreenIndicators != null) { mOnScreenIndicators.setVisibility(show ? View.VISIBLE : View.GONE); } - if (mMenuButton != null) { - mMenuButton.setVisibility(show ? View.VISIBLE : View.GONE); - } } public boolean collapseCameraControls() { @@ -696,6 +850,9 @@ public class PhotoUI implements PieListener, mSwitcher.closePopup(); // Remove all the popups/dialog boxes boolean ret = false; + if (mCustomPhotoMenu != null) { + mCustomPhotoMenu.closeAllView(); + } if (mPopup != null) { dismissAllPopup(); ret = true; @@ -732,6 +889,12 @@ public class PhotoUI implements PieListener, if (mFaceView != null) { mFaceView.setDisplayOrientation(orientation); } + if ((mPreviewOrientation == -1 || mPreviewOrientation != orientation) + && mCustomPhotoMenu != null && mCustomPhotoMenu.isPreviewMenuBeingShown()) { + dismissSceneModeMenu(); + mCustomPhotoMenu.addModeBack(); + } + mPreviewOrientation = orientation; } // shutter button handling diff --git a/src/com/android/camera/PreviewGestures.java b/src/com/android/camera/PreviewGestures.java index 91f567530..f4f8296ab 100644 --- a/src/com/android/camera/PreviewGestures.java +++ b/src/com/android/camera/PreviewGestures.java @@ -21,6 +21,8 @@ import android.view.MotionEvent; import android.view.ScaleGestureDetector; import android.view.View; +import com.android.camera.CustomPhotoMenu; +import com.android.camera.CustomVideoMenu; import com.android.camera.ui.PieRenderer; import com.android.camera.ui.RenderOverlay; import com.android.camera.ui.ZoomRenderer; @@ -54,6 +56,10 @@ public class PreviewGestures private boolean mEnabled; private boolean mZoomOnly; private GestureDetector mGestureDetector; + private CustomPhotoMenu mCustomPhotoMenu; + private CustomVideoMenu mCustomVideoMenu; + private boolean waitUntilNextDown; + private boolean setToFalse; private GestureDetector.SimpleOnGestureListener mGestureListener = new GestureDetector.SimpleOnGestureListener() { @Override @@ -90,6 +96,23 @@ public class PreviewGestures return true; } } + + if (deltaX < 0 && Math.abs(deltaX) > 2 * Math.abs(deltaY)) { + // Open menu on swipe left + waitUntilNextDown = true; + if (mCustomPhotoMenu != null) { + if (!mCustomPhotoMenu.isMenuBeingShown()) { + mCustomPhotoMenu.openFirstLevel(); + } + } + + if (mCustomVideoMenu != null) { + if (!mCustomVideoMenu.isMenuBeingShown()) { + mCustomVideoMenu.openFirstLevel(); + } + } + return true; + } return false; } }; @@ -129,7 +152,36 @@ public class PreviewGestures return mEnabled; } + public void setCustomPhotoMenu(CustomPhotoMenu menu) { + mCustomPhotoMenu = menu; + } + + public void setCustomVideoMenu(CustomVideoMenu menu) { + mCustomVideoMenu = menu; + } + + public CustomPhotoMenu getCustomPhotoMenu() { + return mCustomPhotoMenu; + } + + public CustomVideoMenu getCustomVideoMenu() { + return mCustomVideoMenu; + } + public boolean dispatchTouch(MotionEvent m) { + if (setToFalse) { + waitUntilNextDown = false; + setToFalse = false; + } + if (waitUntilNextDown) { + if (MotionEvent.ACTION_UP != m.getActionMasked() + && MotionEvent.ACTION_CANCEL != m.getActionMasked()) + return true; + else { + setToFalse = true; + return true; + } + } if (!mEnabled) { return false; } @@ -144,6 +196,37 @@ public class PreviewGestures return sendToPie(m); } + if (mCustomPhotoMenu != null) { + if (mCustomPhotoMenu.isMenuBeingShown()) { + if (!mCustomPhotoMenu.isMenuBeingAnimated()) { + waitUntilNextDown = true; + mCustomPhotoMenu.closeView(); + } + return true; + } + if (mCustomPhotoMenu.isPreviewMenuBeingShown()) { + waitUntilNextDown = true; + mCustomPhotoMenu.animateSlideOutPreviewMenu(); + return true; + } + } + + if (mCustomVideoMenu != null) { + if (mCustomVideoMenu.isMenuBeingShown()) { + if (!mCustomVideoMenu.isMenuBeingAnimated()) { + waitUntilNextDown = true; + mCustomVideoMenu.closeView(); + } + return true; + } + + if (mCustomVideoMenu.isPreviewMenuBeingShown()) { + waitUntilNextDown = true; + mCustomVideoMenu.animateSlideOutPreviewMenu(); + return true; + } + } + // If pie is not open, send touch events to gesture detector and scale // listener to recognize the gesture. mGestureDetector.onTouchEvent(m); @@ -162,6 +245,10 @@ public class PreviewGestures return true; } + public boolean waitUntilNextDown() { + return waitUntilNextDown; + } + private MotionEvent makeCancelEvent(MotionEvent m) { MotionEvent c = MotionEvent.obtain(m); c.setAction(MotionEvent.ACTION_CANCEL); diff --git a/src/com/android/camera/VideoModule.java b/src/com/android/camera/VideoModule.java index c3fb44c29..31c071667 100755..100644 --- a/src/com/android/camera/VideoModule.java +++ b/src/com/android/camera/VideoModule.java @@ -686,8 +686,10 @@ public class VideoModule implements CameraModule, if (stop) { onStopVideoRecording(); + mUI.showUIafterRecording(); } else { startVideoRecording(); + mUI.hideUIwhileRecording(); } mUI.enableShutter(false); @@ -1026,6 +1028,7 @@ public class VideoModule implements CameraModule, private void setDisplayOrientation() { mDisplayRotation = CameraUtil.getDisplayRotation(mActivity); mCameraDisplayOrientation = CameraUtil.getDisplayOrientation(mDisplayRotation, mCameraId); + mUI.setDisplayOrientation(mCameraDisplayOrientation); // Change the camera display orientation if (mCameraDevice != null) { mCameraDevice.setDisplayOrientation(mCameraDisplayOrientation); @@ -1180,10 +1183,10 @@ public class VideoModule implements CameraModule, if (mMediaRecorderRecording) { onStopVideoRecording(); return true; - } else if (mUI.hidePieRenderer()) { + } else if (mUI.hideSwitcherPopup()) { return true; } else { - return mUI.removeTopLevelPopup(); + return mUI.onBackPressed(); } } diff --git a/src/com/android/camera/VideoUI.java b/src/com/android/camera/VideoUI.java index 899226bb4..76e072d88 100644 --- a/src/com/android/camera/VideoUI.java +++ b/src/com/android/camera/VideoUI.java @@ -16,6 +16,8 @@ package com.android.camera; +import java.util.List; + import android.content.res.Configuration; import android.graphics.Bitmap; import android.graphics.Color; @@ -31,13 +33,16 @@ import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.TextureView; import android.view.TextureView.SurfaceTextureListener; +import android.view.MotionEvent; import android.view.View; import android.view.View.OnClickListener; import android.view.View.OnLayoutChangeListener; import android.view.ViewGroup; +import android.view.ViewPropertyAnimator; import android.widget.FrameLayout.LayoutParams; import android.widget.ImageView; import android.widget.LinearLayout; +import android.widget.ListView; import android.widget.PopupWindow; import android.widget.TextView; @@ -49,13 +54,10 @@ import com.android.camera.ui.ModuleSwitcher; import com.android.camera.ui.PieRenderer; import com.android.camera.ui.RenderOverlay; import com.android.camera.ui.RotateLayout; -import com.android.camera.PauseButton.OnPauseButtonListener; import com.android.camera.ui.ZoomRenderer; import com.android.camera.util.CameraUtil; import org.codeaurora.snapcam.R; -import java.util.List; - public class VideoUI implements PieRenderer.PieListener, PreviewGestures.SingleTapListener, CameraRootView.MyDisplayListener, @@ -99,6 +101,10 @@ public class VideoUI implements PieRenderer.PieListener, private boolean mOrientationResize; private boolean mPrevOrientationResize; private boolean mIsTimeLapse = false; + private LinearLayout mMenuLayout; + private LinearLayout mSubMenuLayout; + private LinearLayout mPreviewMenuLayout; + private CustomVideoMenu mCustomVideoMenu; private View mPreviewCover; private SurfaceView mSurfaceView = null; @@ -110,6 +116,9 @@ public class VideoUI implements PieRenderer.PieListener, private boolean mAspectRatioResize; private Matrix mMatrix = null; private final AnimationManager mAnimationManager; + private boolean mUIhidden = false; + private int mPreviewOrientation = -1; + private final Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { @@ -143,6 +152,7 @@ public class VideoUI implements PieRenderer.PieListener, onScreenSizeChanged(width, height, w, h); mAspectRatioResize = false; } + mCustomVideoMenu.tryToCloseSubList(); } }; @@ -218,9 +228,7 @@ public class VideoUI implements PieRenderer.PieListener, mMenuButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { - if (mPieRenderer != null) { - mPieRenderer.showInCenter(); - } + mCustomVideoMenu.openFirstLevel(); } }); @@ -378,16 +386,22 @@ public class VideoUI implements PieRenderer.PieListener, } public void hideUI() { - mCameraControls.setVisibility(View.INVISIBLE); mSwitcher.closePopup(); + if (mUIhidden) + return; + mUIhidden = true; + mCameraControls.hideUI(); } public void showUI() { - mCameraControls.setVisibility(View.VISIBLE); + if (!mUIhidden || (mCustomVideoMenu != null && mCustomVideoMenu.isMenuBeingShown())) + return; + mUIhidden = false; + mCameraControls.showUI(); } public boolean arePreviewControlsVisible() { - return (mCameraControls.getVisibility() == View.VISIBLE); + return !mUIhidden; } public void hideSwitcher() { @@ -401,6 +415,10 @@ public class VideoUI implements PieRenderer.PieListener, public boolean collapseCameraControls() { boolean ret = false; + mSwitcher.closePopup(); + if (mCustomVideoMenu != null) { + mCustomVideoMenu.closeAllView(); + } if (mPopup != null) { dismissPopup(false); ret = true; @@ -429,6 +447,15 @@ public class VideoUI implements PieRenderer.PieListener, ((CameraRootView) mRootView).setDisplayChangeListener(this); } + public void setDisplayOrientation(int orientation) { + if ((mPreviewOrientation == -1 || mPreviewOrientation != orientation) + && mCustomVideoMenu != null && mCustomVideoMenu.isPreviewMenuBeingShown()) { + dismissSceneModeMenu(); + mCustomVideoMenu.addModeBack(); + } + mPreviewOrientation = orientation; + } + public void removeDisplayChangeListener() { ((CameraRootView) mRootView).removeDisplayChangeListener(); } @@ -475,6 +502,9 @@ public class VideoUI implements PieRenderer.PieListener, mVideoMenu = new VideoMenu(mActivity, this, mPieRenderer); mPieRenderer.setPieListener(this); } + if (mCustomVideoMenu == null) { + mCustomVideoMenu = new CustomVideoMenu(mActivity, this); + } mRenderOverlay.addRenderer(mPieRenderer); if (mZoomRenderer == null) { mZoomRenderer = new ZoomRenderer(mActivity); @@ -484,6 +514,8 @@ public class VideoUI implements PieRenderer.PieListener, mGestures = new PreviewGestures(mActivity, this, mZoomRenderer, mPieRenderer); mRenderOverlay.setGestures(mGestures); } + mGestures.setCustomVideoMenu(mCustomVideoMenu); + mGestures.setRenderOverlay(mRenderOverlay); mPreviewThumb = mRootView.findViewById(R.id.preview_thumb); @@ -491,15 +523,18 @@ public class VideoUI implements PieRenderer.PieListener, @Override public void onClick(View v) { // Do not allow navigation to filmstrip during video recording - if (!mRecordingStarted) { + if (!mRecordingStarted && !CameraControls.isAnimating()) { mActivity.gotoGallery(); } } }); + + mActivity.setPreviewGestures(mGestures); } public void setPrefChangedListener(OnPreferenceChangedListener listener) { mVideoMenu.setListener(listener); + mCustomVideoMenu.setListener(listener); } private void initializeMiscControls() { @@ -570,6 +605,115 @@ public class VideoUI implements PieRenderer.PieListener, mPopup = null; } + public boolean onBackPressed() { + if (mCustomVideoMenu != null && mCustomVideoMenu.handleBackKey()) { + return true; + } + if (hidePieRenderer()) { + return true; + } else { + return removeTopLevelPopup(); + } + } + + public void cleanupListview() { + showUI(); + mActivity.setSystemBarsVisibility(false); + } + + public void dismissLevel1() { + if (mMenuLayout != null) { + ((ViewGroup) mRootView).removeView(mMenuLayout); + mMenuLayout = null; + } + } + + public void dismissLevel2() { + if (mSubMenuLayout != null) { + ((ViewGroup) mRootView).removeView(mSubMenuLayout); + mSubMenuLayout = null; + } + } + + public boolean sendTouchToPreviewMenu(MotionEvent ev) { + return mPreviewMenuLayout.dispatchTouchEvent(ev); + } + + public boolean sendTouchToMenu(MotionEvent ev) { + View v = mMenuLayout.getChildAt(0); + return v.dispatchTouchEvent(ev); + } + + public void dismissSceneModeMenu() { + if (mPreviewMenuLayout != null) { + ((ViewGroup) mRootView).removeView(mPreviewMenuLayout); + mPreviewMenuLayout = null; + } + } + + public void removeSceneModeMenu() { + if (mPreviewMenuLayout != null) { + ((ViewGroup) mRootView).removeView(mPreviewMenuLayout); + mPreviewMenuLayout = null; + } + cleanupListview(); + } + + public void removeLevel2() { + if (mSubMenuLayout != null) { + View v = mSubMenuLayout.getChildAt(0); + mSubMenuLayout.removeView(v); + } + } + + public void showPopup(ListView popup, int level, boolean animate) { + hideUI(); + + popup.setVisibility(View.VISIBLE); + if (level == 1) { + if (mMenuLayout == null) { + mMenuLayout = new LinearLayout(mActivity); + ViewGroup.LayoutParams params = new ViewGroup.LayoutParams( + CameraActivity.SETTING_LIST_WIDTH_1, LayoutParams.WRAP_CONTENT); + mMenuLayout.setLayoutParams(params); + ((ViewGroup) mRootView).addView(mMenuLayout); + } + mMenuLayout.addView(popup); + } + if (level == 2) { + if (mSubMenuLayout == null) { + mSubMenuLayout = new LinearLayout(mActivity); + ViewGroup.LayoutParams params = new ViewGroup.LayoutParams( + CameraActivity.SETTING_LIST_WIDTH_2, LayoutParams.WRAP_CONTENT); + mSubMenuLayout.setLayoutParams(params); + + ((ViewGroup) mRootView).addView(mSubMenuLayout); + } + mSubMenuLayout.addView(popup); + mSubMenuLayout.setX(CameraActivity.SETTING_LIST_WIDTH_1); + } + if (animate) { + if (level == 1) + mCustomVideoMenu.animateSlideIn(popup, CameraActivity.SETTING_LIST_WIDTH_1, true); + if (level == 2) + mCustomVideoMenu.animateFadeIn(popup); + } + else + popup.setAlpha(0.85f); + } + + public ViewGroup getMenuLayout() { + return mMenuLayout; + } + + public void setPreviewMenuLayout(LinearLayout layout) { + mPreviewMenuLayout = layout; + } + + public ViewGroup getPreviewMenuLayout() { + return mPreviewMenuLayout; + } + public void showPopup(AbstractSettingPopup popup) { hideUI(); @@ -636,7 +780,7 @@ public class VideoUI implements PieRenderer.PieListener, mMenuButton.setVisibility(recording ? View.GONE : View.VISIBLE); mOnScreenIndicators.setVisibility(recording ? View.GONE : View.VISIBLE); if (recording) { - mShutterButton.setImageResource(R.drawable.btn_shutter_video_recording); + mShutterButton.setImageResource(R.drawable.shutter_button_video_stop); hideSwitcher(); mRecordingTimeView.setText(""); mRecordingTimeView.setVisibility(View.VISIBLE); @@ -651,6 +795,14 @@ public class VideoUI implements PieRenderer.PieListener, } } + public void hideUIwhileRecording() { + mCustomVideoMenu.hideUI(); + } + + public void showUIafterRecording() { + mCustomVideoMenu.showUI(); + } + public void showReviewImage(Bitmap bitmap) { mReviewImage.setImageBitmap(bitmap); mReviewImage.setVisibility(View.VISIBLE); @@ -681,9 +833,6 @@ public class VideoUI implements PieRenderer.PieListener, if (mOnScreenIndicators != null) { mOnScreenIndicators.setVisibility(show ? View.VISIBLE : View.GONE); } - if (mMenuButton != null) { - mMenuButton.setVisibility(show ? View.VISIBLE : View.GONE); - } } public void onPreviewFocusChanged(boolean previewFocused) { @@ -704,6 +853,7 @@ public class VideoUI implements PieRenderer.PieListener, public void initializePopup(PreferenceGroup pref) { mVideoMenu.initialize(pref); + mCustomVideoMenu.initialize(pref); } public void initializeZoom(Parameters param) { @@ -825,6 +975,10 @@ public class VideoUI implements PieRenderer.PieListener, mController.stopPreview(); } + public View getRootView() { + return mRootView; + } + @Override public void onButtonPause() { mRecordingTimeView.setCompoundDrawablesWithIntrinsicBounds( @@ -848,4 +1002,12 @@ public class VideoUI implements PieRenderer.PieListener, public void setPreference(String key, String value) { mVideoMenu.setPreference(key, value); } + + public boolean hideSwitcherPopup() { + if (mSwitcher != null && mSwitcher.showsPopup()) { + mSwitcher.closePopup(); + return true; + } + return false; + } } diff --git a/src/com/android/camera/WideAnglePanoramaModule.java b/src/com/android/camera/WideAnglePanoramaModule.java index b612ee9e8..d9f0032bb 100644 --- a/src/com/android/camera/WideAnglePanoramaModule.java +++ b/src/com/android/camera/WideAnglePanoramaModule.java @@ -1061,6 +1061,10 @@ public class WideAnglePanoramaModule // If panorama is generating low res or high res mosaic, ignore back // key. So the activity will not be destroyed. if (mThreadRunning) return true; + + if (mUI.hideSwitcherPopup()) + return true; + return false; } diff --git a/src/com/android/camera/WideAnglePanoramaUI.java b/src/com/android/camera/WideAnglePanoramaUI.java index 57b414a43..97c7d43ec 100644 --- a/src/com/android/camera/WideAnglePanoramaUI.java +++ b/src/com/android/camera/WideAnglePanoramaUI.java @@ -108,7 +108,7 @@ public class WideAnglePanoramaUI implements public void onStartCapture() { hideSwitcher(); - mShutterButton.setImageResource(R.drawable.btn_shutter_recording); + mShutterButton.setImageResource(R.drawable.shutter_button_stop); mCaptureIndicator.setVisibility(View.VISIBLE); showDirectionIndicators(PanoProgressBar.DIRECTION_NONE); } @@ -535,4 +535,12 @@ public class WideAnglePanoramaUI implements canvas.restore(); } } + + public boolean hideSwitcherPopup() { + if (mSwitcher != null && mSwitcher.showsPopup()) { + mSwitcher.closePopup(); + return true; + } + return false; + } } diff --git a/src/com/android/camera/ui/CameraControls.java b/src/com/android/camera/ui/CameraControls.java index 9e0964b4f..5c305acd8 100644 --- a/src/com/android/camera/ui/CameraControls.java +++ b/src/com/android/camera/ui/CameraControls.java @@ -16,13 +16,21 @@ package com.android.camera.ui; +import android.animation.Animator; +import android.animation.Animator.AnimatorListener; import android.content.Context; +import android.util.Log; +import android.graphics.drawable.AnimationDrawable; import android.graphics.Rect; import android.util.AttributeSet; import android.view.View; +import android.view.ViewPropertyAnimator; import android.widget.FrameLayout; +import java.util.ArrayList; import org.codeaurora.snapcam.R; +import com.android.camera.ui.ModuleSwitcher; +import com.android.camera.ShutterButton; public class CameraControls extends RotatableLayout { @@ -32,8 +40,106 @@ public class CameraControls extends RotatableLayout { private View mShutter; private View mSwitcher; private View mMenu; + private View mFrontBackSwitcher; + private View mFlashSwitcher; + private View mHdrSwitcher; private View mIndicators; private View mPreview; + private View mSceneModeSwitcher; + private View mFilterModeSwitcher; + private int mSize; + private static final int WIDTH_GRID = 5; + private static final int HEIGHT_GRID = 7; + private static boolean isAnimating = false; + private ArrayList<View> mViewList; + private static final int FRONT_BACK_INDEX = 0; + private static final int FLASH_INDEX = 1; + private static final int HDR_INDEX = 2; + private static final int SCENE_MODE_INDEX = 3; + private static final int FILTER_MODE_INDEX = 4; + private static final int SWITCHER_INDEX = 5; + private static final int SHUTTER_INDEX = 6; + private static final int MENU_INDEX = 7; + private static final int INDICATOR_INDEX = 8; + private static final int ANIME_DURATION = 300; + private float[][] mLocX = new float[4][9]; + private float[][] mLocY = new float[4][9]; + private boolean[] mTempEnabled = new boolean[9]; + private boolean mLocSet = false; + + AnimatorListener outlistener = new AnimatorListener() { + @Override + public void onAnimationStart(Animator animation) { + } + + @Override + public void onAnimationRepeat(Animator animation) { + + } + + @Override + public void onAnimationEnd(Animator animation) { + resetLocation(0, 0); + + mFrontBackSwitcher.setVisibility(View.INVISIBLE); + mFlashSwitcher.setVisibility(View.INVISIBLE); + mHdrSwitcher.setVisibility(View.INVISIBLE); + mSceneModeSwitcher.setVisibility(View.INVISIBLE); + mFilterModeSwitcher.setVisibility(View.INVISIBLE); + + mSwitcher.setVisibility(View.INVISIBLE); + mShutter.setVisibility(View.INVISIBLE); + mMenu.setVisibility(View.INVISIBLE); + mIndicators.setVisibility(View.INVISIBLE); + mPreview.setVisibility(View.INVISIBLE); + isAnimating = false; + enableTouch(true); + } + + @Override + public void onAnimationCancel(Animator animation) { + resetLocation(0, 0); + + mFrontBackSwitcher.setVisibility(View.INVISIBLE); + mFlashSwitcher.setVisibility(View.INVISIBLE); + mHdrSwitcher.setVisibility(View.INVISIBLE); + mSceneModeSwitcher.setVisibility(View.INVISIBLE); + mFilterModeSwitcher.setVisibility(View.INVISIBLE); + + mSwitcher.setVisibility(View.INVISIBLE); + mShutter.setVisibility(View.INVISIBLE); + mMenu.setVisibility(View.INVISIBLE); + mIndicators.setVisibility(View.INVISIBLE); + mPreview.setVisibility(View.INVISIBLE); + isAnimating = false; + enableTouch(true); + } + }; + + AnimatorListener inlistener = new AnimatorListener() { + @Override + public void onAnimationStart(Animator animation) { + } + + @Override + public void onAnimationRepeat(Animator animation) { + + } + + @Override + public void onAnimationEnd(Animator animation) { + isAnimating = false; + resetLocation(0, 0); + enableTouch(true); + } + + @Override + public void onAnimationCancel(Animator animation) { + isAnimating = false; + resetLocation(0, 0); + enableTouch(true); + } + }; public CameraControls(Context context, AttributeSet attrs) { super(context, attrs); @@ -45,15 +151,68 @@ public class CameraControls extends RotatableLayout { setMeasureAllChildren(true); } + public static boolean isAnimating() { + return isAnimating; + } + + public void enableTouch(boolean enable) { + if (enable) { + ((ShutterButton) mShutter).setPressed(false); + mSwitcher.setPressed(false); + mMenu.setPressed(false); + mFrontBackSwitcher.setPressed(false); + mFlashSwitcher.setPressed(false); + mHdrSwitcher.setPressed(false); + mSceneModeSwitcher.setPressed(false); + mFilterModeSwitcher.setPressed(false); + } else { + mTempEnabled[FLASH_INDEX] = mFlashSwitcher.isEnabled(); + mTempEnabled[FILTER_MODE_INDEX] = mFilterModeSwitcher.isEnabled(); + } + ((ShutterButton) mShutter).enableTouch(enable); + ((ModuleSwitcher) mSwitcher).enableTouch(enable); + mMenu.setEnabled(enable); + mFrontBackSwitcher.setEnabled(enable); + mFlashSwitcher.setEnabled(enable && mTempEnabled[FLASH_INDEX]); + mHdrSwitcher.setEnabled(enable); + mSceneModeSwitcher.setEnabled(enable); + mFilterModeSwitcher.setEnabled(enable && mTempEnabled[FILTER_MODE_INDEX]); + } + + private void markVisibility() { + mViewList = new ArrayList<View>(); + if (mFrontBackSwitcher.getVisibility() == View.VISIBLE) + mViewList.add(mFrontBackSwitcher); + if (mFlashSwitcher.getVisibility() == View.VISIBLE) + mViewList.add(mFlashSwitcher); + if (mHdrSwitcher.getVisibility() == View.VISIBLE) + mViewList.add(mHdrSwitcher); + if (mSceneModeSwitcher.getVisibility() == View.VISIBLE) + mViewList.add(mSceneModeSwitcher); + if (mFilterModeSwitcher.getVisibility() == View.VISIBLE) + mViewList.add(mFilterModeSwitcher); + if (mShutter.getVisibility() == View.VISIBLE) + mViewList.add(mShutter); + if (mMenu.getVisibility() == View.VISIBLE) + mViewList.add(mMenu); + if (mIndicators.getVisibility() == View.VISIBLE) + mViewList.add(mIndicators); + } + @Override public void onFinishInflate() { super.onFinishInflate(); mBackgroundView = findViewById(R.id.blocker); mSwitcher = findViewById(R.id.camera_switcher); mShutter = findViewById(R.id.shutter_button); + mFrontBackSwitcher = findViewById(R.id.front_back_switcher); + mFlashSwitcher = findViewById(R.id.flash_switcher); + mHdrSwitcher = findViewById(R.id.hdr_switcher); mMenu = findViewById(R.id.menu); mIndicators = findViewById(R.id.on_screen_indicators); mPreview = findViewById(R.id.preview_thumb); + mSceneModeSwitcher = findViewById(R.id.scene_mode_switcher); + mFilterModeSwitcher = findViewById(R.id.filter_mode_switcher); } @Override @@ -74,26 +233,12 @@ public class CameraControls extends RotatableLayout { } Rect shutter = new Rect(); topRight(mPreview, l, t, r, b); - if (size > 0) { - // restrict controls to size - switch (rotation) { - case 0: - case 180: - l = (l + r - size) / 2; - r = l + size; - break; - case 90: - case 270: - t = (t + b - size) / 2; - b = t + size; - break; - } - } - center(mShutter, l, t, r, b, orientation, rotation, shutter); - center(mBackgroundView, l, t, r, b, orientation, rotation, new Rect()); - toLeft(mSwitcher, shutter, rotation); - toRight(mMenu, shutter, rotation); - toRight(mIndicators, shutter, rotation); + center(mShutter, l, t, r, b, orientation, rotation, shutter, SHUTTER_INDEX); + mSize = Math.max(shutter.right - shutter.left, shutter.bottom - shutter.top); + center(mBackgroundView, l, t, r, b, orientation, rotation, new Rect(), -1); + mBackgroundView.setVisibility(View.GONE); + setLocation(r - l, b - t); + View retake = findViewById(R.id.btn_retake); if (retake != null) { center(retake, shutter, rotation); @@ -104,41 +249,240 @@ public class CameraControls extends RotatableLayout { } } - private void center(View v, int l, int t, int r, int b, int orientation, int rotation, Rect result) { + private void setLocation(int w, int h) { + int rotation = getUnifiedRotation(); + toIndex(mSwitcher, w, h, rotation, 4, 6, SWITCHER_INDEX); + toIndex(mMenu, w, h, rotation, 0, 6, MENU_INDEX); + toIndex(mIndicators, w, h, rotation, 0, 6, INDICATOR_INDEX); + toIndex(mFrontBackSwitcher, w, h, rotation, 2, 0, FRONT_BACK_INDEX); + toIndex(mFlashSwitcher, w, h, rotation, 3, 0, FLASH_INDEX); + toIndex(mHdrSwitcher, w, h, rotation, 4, 0, HDR_INDEX); + toIndex(mFilterModeSwitcher, w, h, rotation, 1, 0, FILTER_MODE_INDEX); + toIndex(mSceneModeSwitcher, w, h, rotation, 0, 0, SCENE_MODE_INDEX); + } + + private void center(View v, int l, int t, int r, int b, int orientation, int rotation, + Rect result, int idx) { FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) v.getLayoutParams(); int tw = lp.leftMargin + v.getMeasuredWidth() + lp.rightMargin; int th = lp.topMargin + v.getMeasuredHeight() + lp.bottomMargin; switch (rotation) { - case 0: - // phone portrait; controls bottom - result.left = (r + l) / 2 - tw / 2 + lp.leftMargin; - result.right = (r + l) / 2 + tw / 2 - lp.rightMargin; - result.bottom = b - lp.bottomMargin; - result.top = b - th + lp.topMargin; - break; - case 90: - // phone landscape: controls right - result.right = r - lp.rightMargin; - result.left = r - tw + lp.leftMargin; - result.top = (b + t) / 2 - th / 2 + lp.topMargin; - result.bottom = (b + t) / 2 + th / 2 - lp.bottomMargin; - break; - case 180: - // phone upside down: controls top - result.left = (r + l) / 2 - tw / 2 + lp.leftMargin; - result.right = (r + l) / 2 + tw / 2 - lp.rightMargin; - result.top = t + lp.topMargin; - result.bottom = t + th - lp.bottomMargin; - break; - case 270: - // reverse landscape: controls left - result.left = l + lp.leftMargin; - result.right = l + tw - lp.rightMargin; - result.top = (b + t) / 2 - th / 2 + lp.topMargin; - result.bottom = (b + t) / 2 + th / 2 - lp.bottomMargin; - break; + case 0: + // phone portrait; controls bottom + result.left = (r + l) / 2 - tw / 2 + lp.leftMargin; + result.right = (r + l) / 2 + tw / 2 - lp.rightMargin; + result.bottom = b - lp.bottomMargin; + result.top = b - th + lp.topMargin; + break; + case 90: + // phone landscape: controls right + result.right = r - lp.rightMargin; + result.left = r - tw + lp.leftMargin; + result.top = (b + t) / 2 - th / 2 + lp.topMargin; + result.bottom = (b + t) / 2 + th / 2 - lp.bottomMargin; + break; + case 180: + // phone upside down: controls top + result.left = (r + l) / 2 - tw / 2 + lp.leftMargin; + result.right = (r + l) / 2 + tw / 2 - lp.rightMargin; + result.top = t + lp.topMargin; + result.bottom = t + th - lp.bottomMargin; + break; + case 270: + // reverse landscape: controls left + result.left = l + lp.leftMargin; + result.right = l + tw - lp.rightMargin; + result.top = (b + t) / 2 - th / 2 + lp.topMargin; + result.bottom = (b + t) / 2 + th / 2 - lp.bottomMargin; + break; } v.layout(result.left, result.top, result.right, result.bottom); + if (idx != -1) { + int idx1 = rotation / 90; + int idx2 = idx; + mLocX[idx1][idx2] = result.left; + mLocY[idx1][idx2] = result.top; + } + } + + private void resetLocation(float x, float y) { + int rotation = getUnifiedRotation(); + int idx1 = rotation / 90; + + mFrontBackSwitcher.setX(mLocX[idx1][FRONT_BACK_INDEX] + x); + mFlashSwitcher.setX(mLocX[idx1][FLASH_INDEX] + x); + mHdrSwitcher.setX(mLocX[idx1][HDR_INDEX] + x); + mSceneModeSwitcher.setX(mLocX[idx1][SCENE_MODE_INDEX] + x); + mFilterModeSwitcher.setX(mLocX[idx1][FILTER_MODE_INDEX] + x); + mSwitcher.setX(mLocX[idx1][SWITCHER_INDEX] - x); + mShutter.setX(mLocX[idx1][SHUTTER_INDEX] - x); + mMenu.setX(mLocX[idx1][MENU_INDEX] - x); + mIndicators.setX(mLocX[idx1][INDICATOR_INDEX] - x); + + mFrontBackSwitcher.setY(mLocY[idx1][FRONT_BACK_INDEX] + y); + mFlashSwitcher.setY(mLocY[idx1][FLASH_INDEX] + y); + mHdrSwitcher.setY(mLocY[idx1][HDR_INDEX] + y); + mSceneModeSwitcher.setY(mLocY[idx1][SCENE_MODE_INDEX] + y); + mFilterModeSwitcher.setY(mLocY[idx1][FILTER_MODE_INDEX] + y); + mSwitcher.setY(mLocY[idx1][SWITCHER_INDEX] - y); + mShutter.setY(mLocY[idx1][SHUTTER_INDEX] - y); + mMenu.setY(mLocY[idx1][MENU_INDEX] - y); + mIndicators.setY(mLocY[idx1][INDICATOR_INDEX] - y); + } + + public void hideUI() { + isAnimating = true; + enableTouch(false); + int rotation = getUnifiedRotation(); + mFrontBackSwitcher.animate().cancel(); + mFlashSwitcher.animate().cancel(); + mHdrSwitcher.animate().cancel(); + mSceneModeSwitcher.animate().cancel(); + mFilterModeSwitcher.animate().cancel(); + mSwitcher.animate().cancel(); + mShutter.animate().cancel(); + mMenu.animate().cancel(); + mIndicators.animate().cancel(); + mFrontBackSwitcher.animate().setListener(outlistener); + ((ModuleSwitcher) mSwitcher).removePopup(); + resetLocation(0, 0); + markVisibility(); + switch (rotation) { + case 0: + mFrontBackSwitcher.animate().translationYBy(-mSize).setDuration(ANIME_DURATION); + mFlashSwitcher.animate().translationYBy(-mSize).setDuration(ANIME_DURATION); + mHdrSwitcher.animate().translationYBy(-mSize).setDuration(ANIME_DURATION); + mSceneModeSwitcher.animate().translationYBy(-mSize).setDuration(ANIME_DURATION); + mFilterModeSwitcher.animate().translationYBy(-mSize).setDuration(ANIME_DURATION); + + mSwitcher.animate().translationYBy(mSize).setDuration(ANIME_DURATION); + mShutter.animate().translationYBy(mSize).setDuration(ANIME_DURATION); + mMenu.animate().translationYBy(mSize).setDuration(ANIME_DURATION); + mIndicators.animate().translationYBy(mSize).setDuration(ANIME_DURATION); + break; + case 90: + mFrontBackSwitcher.animate().translationXBy(-mSize).setDuration(ANIME_DURATION); + mFlashSwitcher.animate().translationXBy(-mSize).setDuration(ANIME_DURATION); + mHdrSwitcher.animate().translationXBy(-mSize).setDuration(ANIME_DURATION); + mSceneModeSwitcher.animate().translationXBy(-mSize).setDuration(ANIME_DURATION); + mFilterModeSwitcher.animate().translationXBy(-mSize).setDuration(ANIME_DURATION); + + mSwitcher.animate().translationXBy(mSize).setDuration(ANIME_DURATION); + mShutter.animate().translationXBy(mSize).setDuration(ANIME_DURATION); + mMenu.animate().translationXBy(mSize).setDuration(ANIME_DURATION); + mIndicators.animate().translationXBy(mSize).setDuration(ANIME_DURATION); + break; + case 180: + mFrontBackSwitcher.animate().translationYBy(mSize).setDuration(ANIME_DURATION); + mFlashSwitcher.animate().translationYBy(mSize).setDuration(ANIME_DURATION); + mHdrSwitcher.animate().translationYBy(mSize).setDuration(ANIME_DURATION); + mSceneModeSwitcher.animate().translationYBy(mSize).setDuration(ANIME_DURATION); + mFilterModeSwitcher.animate().translationYBy(mSize).setDuration(ANIME_DURATION); + + mSwitcher.animate().translationYBy(-mSize).setDuration(ANIME_DURATION); + mShutter.animate().translationYBy(-mSize).setDuration(ANIME_DURATION); + mMenu.animate().translationYBy(-mSize).setDuration(ANIME_DURATION); + mIndicators.animate().translationYBy(-mSize).setDuration(ANIME_DURATION); + break; + case 270: + mFrontBackSwitcher.animate().translationXBy(mSize).setDuration(ANIME_DURATION); + mFlashSwitcher.animate().translationXBy(mSize).setDuration(ANIME_DURATION); + mHdrSwitcher.animate().translationXBy(mSize).setDuration(ANIME_DURATION); + mSceneModeSwitcher.animate().translationXBy(mSize).setDuration(ANIME_DURATION); + mFilterModeSwitcher.animate().translationXBy(mSize).setDuration(ANIME_DURATION); + + mSwitcher.animate().translationXBy(-mSize).setDuration(ANIME_DURATION); + mShutter.animate().translationXBy(-mSize).setDuration(ANIME_DURATION); + mMenu.animate().translationXBy(-mSize).setDuration(ANIME_DURATION); + mIndicators.animate().translationXBy(-mSize).setDuration(ANIME_DURATION); + break; + } + } + + public void showUI() { + isAnimating = true; + enableTouch(false); + int rotation = getUnifiedRotation(); + mFrontBackSwitcher.animate().cancel(); + mFlashSwitcher.animate().cancel(); + mHdrSwitcher.animate().cancel(); + mSceneModeSwitcher.animate().cancel(); + mFilterModeSwitcher.animate().cancel(); + mSwitcher.animate().cancel(); + mShutter.animate().cancel(); + mMenu.animate().cancel(); + mIndicators.animate().cancel(); + if (mViewList != null) + for (View v : mViewList) { + v.setVisibility(View.VISIBLE); + } + ((ModuleSwitcher) mSwitcher).removePopup(); + AnimationDrawable shutterAnim = (AnimationDrawable) mShutter.getBackground(); + if (shutterAnim != null) + shutterAnim.stop(); + + mMenu.setVisibility(View.VISIBLE); + mIndicators.setVisibility(View.VISIBLE); + + mFrontBackSwitcher.animate().setListener(inlistener); + switch (rotation) { + case 0: + resetLocation(0, -mSize); + + mFrontBackSwitcher.animate().translationYBy(mSize).setDuration(ANIME_DURATION); + mFlashSwitcher.animate().translationYBy(mSize).setDuration(ANIME_DURATION); + mHdrSwitcher.animate().translationYBy(mSize).setDuration(ANIME_DURATION); + mSceneModeSwitcher.animate().translationYBy(mSize).setDuration(ANIME_DURATION); + mFilterModeSwitcher.animate().translationYBy(mSize).setDuration(ANIME_DURATION); + + mSwitcher.animate().translationYBy(-mSize).setDuration(ANIME_DURATION); + mShutter.animate().translationYBy(-mSize).setDuration(ANIME_DURATION); + mMenu.animate().translationYBy(-mSize).setDuration(ANIME_DURATION); + mIndicators.animate().translationYBy(-mSize).setDuration(ANIME_DURATION); + break; + case 90: + resetLocation(-mSize, 0); + + mFrontBackSwitcher.animate().translationXBy(mSize).setDuration(ANIME_DURATION); + mFlashSwitcher.animate().translationXBy(mSize).setDuration(ANIME_DURATION); + mHdrSwitcher.animate().translationXBy(mSize).setDuration(ANIME_DURATION); + mSceneModeSwitcher.animate().translationXBy(mSize).setDuration(ANIME_DURATION); + mFilterModeSwitcher.animate().translationXBy(mSize).setDuration(ANIME_DURATION); + + mSwitcher.animate().translationXBy(-mSize).setDuration(ANIME_DURATION); + mShutter.animate().translationXBy(-mSize).setDuration(ANIME_DURATION); + mMenu.animate().translationXBy(-mSize).setDuration(ANIME_DURATION); + mIndicators.animate().translationXBy(-mSize).setDuration(ANIME_DURATION); + break; + case 180: + resetLocation(0, mSize); + + mFrontBackSwitcher.animate().translationYBy(-mSize).setDuration(ANIME_DURATION); + mFlashSwitcher.animate().translationYBy(-mSize).setDuration(ANIME_DURATION); + mHdrSwitcher.animate().translationYBy(-mSize).setDuration(ANIME_DURATION); + mSceneModeSwitcher.animate().translationYBy(-mSize).setDuration(ANIME_DURATION); + mFilterModeSwitcher.animate().translationYBy(-mSize).setDuration(ANIME_DURATION); + + mSwitcher.animate().translationYBy(mSize).setDuration(ANIME_DURATION); + mShutter.animate().translationYBy(mSize).setDuration(ANIME_DURATION); + mMenu.animate().translationYBy(mSize).setDuration(ANIME_DURATION); + mIndicators.animate().translationYBy(mSize).setDuration(ANIME_DURATION); + break; + case 270: + resetLocation(mSize, 0); + + mFrontBackSwitcher.animate().translationXBy(-mSize).setDuration(ANIME_DURATION); + mFlashSwitcher.animate().translationXBy(-mSize).setDuration(ANIME_DURATION); + mHdrSwitcher.animate().translationXBy(-mSize).setDuration(ANIME_DURATION); + mSceneModeSwitcher.animate().translationXBy(-mSize).setDuration(ANIME_DURATION); + mFilterModeSwitcher.animate().translationXBy(-mSize).setDuration(ANIME_DURATION); + + mSwitcher.animate().translationXBy(mSize).setDuration(ANIME_DURATION); + mShutter.animate().translationXBy(mSize).setDuration(ANIME_DURATION); + mMenu.animate().translationXBy(mSize).setDuration(ANIME_DURATION); + mIndicators.animate().translationXBy(mSize).setDuration(ANIME_DURATION); + break; + } } private void center(View v, Rect other, int rotation) { @@ -153,6 +497,65 @@ public class CameraControls extends RotatableLayout { cy + th / 2 - lp.bottomMargin); } + private void toIndex(View v, int w, int h, int rotation, int index, int index2, int index3) { + FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) v.getLayoutParams(); + int tw = v.getMeasuredWidth(); + int th = v.getMeasuredHeight(); + int l = 0, r = 0, t = 0, b = 0; + + int wnumber = WIDTH_GRID; + int hnumber = HEIGHT_GRID; + int windex = 0; + int hindex = 0; + switch (rotation) { + case 0: + // portrait, to left of anchor at bottom + wnumber = WIDTH_GRID; + hnumber = HEIGHT_GRID; + windex = index; + hindex = index2; + break; + case 90: + // phone landscape: below anchor on right + wnumber = HEIGHT_GRID; + hnumber = WIDTH_GRID; + windex = index2; + hindex = hnumber - index - 1; + break; + case 180: + // phone upside down: right of anchor at top + wnumber = WIDTH_GRID; + hnumber = HEIGHT_GRID; + windex = wnumber - index - 1; + hindex = hnumber - index2 - 1; + break; + case 270: + // reverse landscape: above anchor on left + wnumber = HEIGHT_GRID; + hnumber = WIDTH_GRID; + windex = wnumber - index2 - 1; + hindex = index; + break; + } + int boxh = h / hnumber; + int boxw = w / wnumber; + int cx = (2 * windex + 1) * boxw / 2; + int cy = (2 * hindex + 1) * boxh / 2; + + l = cx - tw / 2; + r = cx + tw / 2; + t = cy - th / 2; + b = cy + th / 2; + + if (index3 != -1) { + int idx1 = rotation / 90; + int idx2 = index3; + mLocX[idx1][idx2] = l; + mLocY[idx1][idx2] = t; + } + v.layout(l, t, r, b); + } + private void toLeft(View v, Rect other, int rotation) { FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) v.getLayoutParams(); int tw = lp.leftMargin + v.getMeasuredWidth() + lp.rightMargin; @@ -161,34 +564,34 @@ public class CameraControls extends RotatableLayout { int cy = (other.top + other.bottom) / 2; int l = 0, r = 0, t = 0, b = 0; switch (rotation) { - case 0: - // portrait, to left of anchor at bottom - l = other.left - tw + lp.leftMargin; - r = other.left - lp.rightMargin; - t = cy - th / 2 + lp.topMargin; - b = cy + th / 2 - lp.bottomMargin; - break; - case 90: - // phone landscape: below anchor on right - l = cx - tw / 2 + lp.leftMargin; - r = cx + tw / 2 - lp.rightMargin; - t = other.bottom + lp.topMargin; - b = other.bottom + th - lp.bottomMargin; - break; - case 180: - // phone upside down: right of anchor at top - l = other.right + lp.leftMargin; - r = other.right + tw - lp.rightMargin; - t = cy - th / 2 + lp.topMargin; - b = cy + th / 2 - lp.bottomMargin; - break; - case 270: - // reverse landscape: above anchor on left - l = cx - tw / 2 + lp.leftMargin; - r = cx + tw / 2 - lp.rightMargin; - t = other.top - th + lp.topMargin; - b = other.top - lp.bottomMargin; - break; + case 0: + // portrait, to left of anchor at bottom + l = other.left - tw + lp.leftMargin; + r = other.left - lp.rightMargin; + t = cy - th / 2 + lp.topMargin; + b = cy + th / 2 - lp.bottomMargin; + break; + case 90: + // phone landscape: below anchor on right + l = cx - tw / 2 + lp.leftMargin; + r = cx + tw / 2 - lp.rightMargin; + t = other.bottom + lp.topMargin; + b = other.bottom + th - lp.bottomMargin; + break; + case 180: + // phone upside down: right of anchor at top + l = other.right + lp.leftMargin; + r = other.right + tw - lp.rightMargin; + t = cy - th / 2 + lp.topMargin; + b = cy + th / 2 - lp.bottomMargin; + break; + case 270: + // reverse landscape: above anchor on left + l = cx - tw / 2 + lp.leftMargin; + r = cx + tw / 2 - lp.rightMargin; + t = other.top - th + lp.topMargin; + b = other.top - lp.bottomMargin; + break; } v.layout(l, t, r, b); } @@ -201,36 +604,37 @@ public class CameraControls extends RotatableLayout { int cy = (other.top + other.bottom) / 2; int l = 0, r = 0, t = 0, b = 0; switch (rotation) { - case 0: - l = other.right + lp.leftMargin; - r = other.right + tw - lp.rightMargin; - t = cy - th / 2 + lp.topMargin; - b = cy + th / 2 - lp.bottomMargin; - break; - case 90: - l = cx - tw / 2 + lp.leftMargin; - r = cx + tw / 2 - lp.rightMargin; - t = other.top - th + lp.topMargin; - b = other.top - lp.bottomMargin; - break; - case 180: - l = other.left - tw + lp.leftMargin; - r = other.left - lp.rightMargin; - t = cy - th / 2 + lp.topMargin; - b = cy + th / 2 - lp.bottomMargin; - break; - case 270: - l = cx - tw / 2 + lp.leftMargin; - r = cx + tw / 2 - lp.rightMargin; - t = other.bottom + lp.topMargin; - b = other.bottom + th - lp.bottomMargin; - break; + case 0: + l = other.right + lp.leftMargin; + r = other.right + tw - lp.rightMargin; + t = cy - th / 2 + lp.topMargin; + b = cy + th / 2 - lp.bottomMargin; + break; + case 90: + l = cx - tw / 2 + lp.leftMargin; + r = cx + tw / 2 - lp.rightMargin; + t = other.top - th + lp.topMargin; + b = other.top - lp.bottomMargin; + break; + case 180: + l = other.left - tw + lp.leftMargin; + r = other.left - lp.rightMargin; + t = cy - th / 2 + lp.topMargin; + b = cy + th / 2 - lp.bottomMargin; + break; + case 270: + l = cx - tw / 2 + lp.leftMargin; + r = cx + tw / 2 - lp.rightMargin; + t = other.bottom + lp.topMargin; + b = other.bottom + th - lp.bottomMargin; + break; } v.layout(l, t, r, b); } private void topRight(View v, int l, int t, int r, int b) { - // layout using the specific margins; the rotation code messes up the others + // layout using the specific margins; the rotation code messes up the + // others int mt = getContext().getResources().getDimensionPixelSize(R.dimen.capture_margin_top); int mr = getContext().getResources().getDimensionPixelSize(R.dimen.capture_margin_right); v.layout(r - v.getMeasuredWidth() - mr, t + mt, r - mr, t + mt + v.getMeasuredHeight()); @@ -242,7 +646,8 @@ public class CameraControls extends RotatableLayout { mBackgroundView.setBackgroundDrawable(null); mBackgroundView.setRotationX(0); mBackgroundView.setRotationY(0); - // if the switcher background is top aligned we need to flip the background + // if the switcher background is top aligned we need to flip the + // background // drawable vertically; if left aligned, flip horizontally switch (rotation) { case 180: diff --git a/src/com/android/camera/ui/FilmStripView.java b/src/com/android/camera/ui/FilmStripView.java index f892934e2..8da49a10a 100644 --- a/src/com/android/camera/ui/FilmStripView.java +++ b/src/com/android/camera/ui/FilmStripView.java @@ -37,10 +37,14 @@ import android.view.ViewGroup; import android.view.animation.DecelerateInterpolator; import android.widget.Scroller; +import com.android.camera.CustomPhotoMenu; +import com.android.camera.CustomVideoMenu; +import com.android.camera.PreviewGestures; import com.android.camera.CameraActivity; import com.android.camera.data.LocalData; import com.android.camera.ui.FilmStripView.ImageData.PanoramaSupportCallback; import com.android.camera.ui.FilmstripBottomControls.BottomControlsListener; +import com.android.camera.ui.RenderOverlay; import com.android.camera.util.CameraUtil; import com.android.camera.util.PhotoSphereHelper.PanoramaViewHelper; import com.android.camera.util.UsageStatistics; @@ -97,7 +101,11 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { private float mOverScaleFactor = 1f; private int mLastTotalNumber = 0; - + private RenderOverlay mRenderOverlay; + private PreviewGestures mPreviewGestures; + private boolean mSendToPreviewMenu; + private boolean mSendToMenu; + private boolean mReset; /** * Common interface for all images in the filmstrip. */ @@ -705,6 +713,13 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { } } + public void setRenderOverlay(RenderOverlay renderOverlay) { + mRenderOverlay = renderOverlay; + } + public void setPreviewGestures(PreviewGestures previewGestures) { + mPreviewGestures = previewGestures; + } + /** * Returns the controller. * @@ -1807,6 +1822,95 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { return true; } + public boolean checkSendToModeView(MotionEvent ev) { + if (mSendToPreviewMenu || mSendToMenu || mPreviewGestures == null) + return true; + CustomPhotoMenu pMenu = mPreviewGestures.getCustomPhotoMenu(); + CustomVideoMenu vMenu = mPreviewGestures.getCustomVideoMenu(); + if (pMenu != null) { + if (pMenu.isMenuBeingShown()) { + if (pMenu.isMenuBeingAnimated()) { + if (pMenu.isOverMenu(ev)) { + mSendToMenu = true; + return true; + } + } + } + + if (pMenu.isPreviewMenuBeingShown()) { + if (pMenu.isOverPreviewMenu(ev)) { + mSendToPreviewMenu = true; + return true; + } + } + } + if (vMenu != null) { + if (vMenu.isMenuBeingShown()) { + if (vMenu.isMenuBeingAnimated()) { + if (vMenu.isOverMenu(ev)) { + mSendToMenu = true; + return true; + } + } + } + + if (vMenu.isPreviewMenuBeingShown()) { + if (vMenu.isOverPreviewMenu(ev)) { + mSendToPreviewMenu = true; + return true; + } + } + } + return false; + } + + public boolean sendToModeView(MotionEvent ev) { + if (mPreviewGestures == null) { + return false; + } + if (mReset) { + mSendToPreviewMenu = false; + mSendToMenu = false; + mReset = false; + } + if (mSendToPreviewMenu || mSendToMenu) { + if (MotionEvent.ACTION_UP == ev.getActionMasked() + || MotionEvent.ACTION_CANCEL == ev.getActionMasked()) + mReset = true; + } + CustomPhotoMenu pMenu = mPreviewGestures.getCustomPhotoMenu(); + CustomVideoMenu vMenu = mPreviewGestures.getCustomVideoMenu(); + + if (pMenu != null) { + if (mSendToPreviewMenu) + return pMenu.sendTouchToPreviewMenu(ev); + if (mSendToMenu) + return pMenu.sendTouchToMenu(ev); + if (pMenu.isMenuBeingShown()) { + return pMenu.sendTouchToMenu(ev); + } + + if (pMenu.isPreviewMenuBeingShown()) { + return pMenu.sendTouchToPreviewMenu(ev); + } + } + + if (vMenu != null) { + if (mSendToPreviewMenu) + return vMenu.sendTouchToPreviewMenu(ev); + if (mSendToMenu) + return vMenu.sendTouchToMenu(ev); + if (vMenu.isMenuBeingShown()) { + return vMenu.sendTouchToMenu(ev); + } + + if (vMenu.isPreviewMenuBeingShown()) { + return vMenu.sendTouchToPreviewMenu(ev); + } + } + return false; + } + private void updateViewItem(int itemID) { ViewItem item = mViewItem[itemID]; if (item == null) { @@ -2714,6 +2818,8 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { @Override public boolean onScroll(float x, float y, float dx, float dy) { + if (mPreviewGestures != null && mPreviewGestures.waitUntilNextDown()) + return false; ViewItem currItem = mViewItem[mCurrentItem]; if (currItem == null) { return false; @@ -2779,6 +2885,8 @@ public class FilmStripView extends ViewGroup implements BottomControlsListener { @Override public boolean onFling(float velocityX, float velocityY) { + if (mPreviewGestures != null && mPreviewGestures.waitUntilNextDown()) + return false; final ViewItem currItem = mViewItem[mCurrentItem]; if (currItem == null) { return false; diff --git a/src/com/android/camera/ui/ListMenu.java b/src/com/android/camera/ui/ListMenu.java new file mode 100644 index 000000000..53cd48d9c --- /dev/null +++ b/src/com/android/camera/ui/ListMenu.java @@ -0,0 +1,221 @@ +/* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * Not a Contribution. + * + * Copyright (C) 2010 The Android Open Source 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 java.util.ArrayList; + +import android.content.Context; +import android.util.AttributeSet; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.ArrayAdapter; +import android.widget.ListView; + +import com.android.camera.ListPreference; +import com.android.camera.PreferenceGroup; +import org.codeaurora.snapcam.R; + +/* A popup window that contains several camera settings. */ +public class ListMenu extends ListView + implements ListMenuItem.Listener, + AdapterView.OnItemClickListener { + @SuppressWarnings("unused") + private static final String TAG = "ListMenu"; + private Listener mListener; + private ArrayList<ListPreference> mListItem = new ArrayList<ListPreference>(); + + // Keep track of which setting items are disabled + // e.g. White balance will be disabled when scene mode is set to non-auto + private boolean[] mEnabled; + + static public interface Listener { + public void onSettingChanged(ListPreference pref); + + public void onPreferenceClicked(ListPreference pref); + + public void onPreferenceClicked(ListPreference pref, int y); + + public void onListMenuTouched(); + } + + private class MoreSettingAdapter extends ArrayAdapter<ListPreference> { + LayoutInflater mInflater; + String mOnString; + String mOffString; + + MoreSettingAdapter() { + super(ListMenu.this.getContext(), 0, mListItem); + Context context = getContext(); + mInflater = LayoutInflater.from(context); + mOnString = context.getString(R.string.setting_on); + mOffString = context.getString(R.string.setting_off); + } + + private int getSettingLayoutId(ListPreference pref) { + return R.layout.list_menu_item; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + ListPreference pref = mListItem.get(position); + int viewLayoutId = getSettingLayoutId(pref); + ListMenuItem view = (ListMenuItem) convertView; + + view = (ListMenuItem) + mInflater.inflate(viewLayoutId, parent, false); + + view.initialize(pref); // no init for restore one + view.setSettingChangedListener(ListMenu.this); + if (position >= 0 && position < mEnabled.length) { + view.setEnabled(mEnabled[position]); + } else { + Log.w(TAG, "Invalid input: enabled list length, " + mEnabled.length + + " position " + position); + } + return view; + } + + @Override + public boolean isEnabled(int position) { + if (position >= 0 && position < mEnabled.length) { + return mEnabled[position]; + } + return true; + } + } + + public void setSettingChangedListener(Listener listener) { + mListener = listener; + } + + public ListMenu(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public void initialize(PreferenceGroup group, String[] keys) { + // Prepare the setting items. + for (int i = 0; i < keys.length; ++i) { + ListPreference pref = group.findPreference(keys[i]); + if (pref != null) + mListItem.add(pref); + } + + ArrayAdapter<ListPreference> mListItemAdapter = new MoreSettingAdapter(); + setAdapter(mListItemAdapter); + setOnItemClickListener(this); + setSelector(android.R.color.transparent); + // Initialize mEnabled + mEnabled = new boolean[mListItem.size()]; + for (int i = 0; i < mEnabled.length; i++) { + mEnabled[i] = true; + } + } + + // When preferences are disabled, we will display them grayed out. Users + // will not be able to change the disabled preferences, but they can still + // see + // the current value of the preferences + public void setPreferenceEnabled(String key, boolean enable) { + int count = mEnabled == null ? 0 : mEnabled.length; + for (int j = 0; j < count; j++) { + ListPreference pref = mListItem.get(j); + if (pref != null && key.equals(pref.getKey())) { + mEnabled[j] = enable; + break; + } + } + } + + public void onSettingChanged(ListPreference pref) { + if (mListener != null) { + mListener.onSettingChanged(pref); + } + } + + // Scene mode can override other camera settings (ex: flash mode). + public void overrideSettings(final String... keyvalues) { + int count = mEnabled == null ? 0 : mEnabled.length; + for (int i = 0; i < keyvalues.length; i += 2) { + String key = keyvalues[i]; + String value = keyvalues[i + 1]; + for (int j = 0; j < count; j++) { + ListPreference pref = mListItem.get(j); + if (pref != null && key.equals(pref.getKey())) { + // Change preference + if (value != null) + pref.setValue(value); + // If the preference is overridden, disable the preference + boolean enable = value == null; + mEnabled[j] = enable; + if (getChildCount() > j) { + getChildAt(j).setEnabled(enable); + } + } + } + } + reloadPreference(); + } + + public void resetHighlight() { + int count = getChildCount(); + for (int i = 0; i < count; i++) { + View v = getChildAt(i); + v.setBackground(null); + } + + } + + @Override + public boolean onTouchEvent(MotionEvent ev) { + if (ev.getAction() == MotionEvent.ACTION_MOVE) { + mListener.onListMenuTouched(); + resetHighlight(); + } + return super.onTouchEvent(ev); + } + + @Override + public void onItemClick(AdapterView<?> parent, View view, int position, + long id) { + if (mListener != null) { + resetHighlight(); + ListPreference pref = mListItem.get(position); + view.setBackgroundColor(getContext().getResources().getColor(R.color.setting_color)); + mListener.onPreferenceClicked(pref, (int) view.getY()); + } + + } + + public void reloadPreference() { + int count = getChildCount(); + for (int i = 0; i < count; i++) { + ListPreference pref = mListItem.get(i); + if (pref != null) { + ListMenuItem listMenuItem = + (ListMenuItem) getChildAt(i); + listMenuItem.reloadPreference(); + } + } + } +} diff --git a/src/com/android/camera/ui/ListMenuItem.java b/src/com/android/camera/ui/ListMenuItem.java new file mode 100644 index 000000000..f3c7f017e --- /dev/null +++ b/src/com/android/camera/ui/ListMenuItem.java @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * Not a Contribution. + * + * Copyright (C) 2011 The Android Open Source 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.util.AttributeSet; +import android.util.Log; +import android.view.accessibility.AccessibilityEvent; +import android.widget.RelativeLayout; +import android.widget.TextView; +import android.widget.ImageView; + +import com.android.camera.ListPreference; +import com.android.camera.IconListPreference; +import org.codeaurora.snapcam.R; + +/** + * A one-line camera setting could be one of three types: knob, switch or + * restore preference button. The setting includes a title for showing the + * preference title which is initialized in the SimpleAdapter. A knob also + * includes (ex: Picture size), a previous button, the current value (ex: 5MP), + * and a next button. A switch, i.e. the preference RecordLocationPreference, + * has only two values on and off which will be controlled in a switch button. + * Other setting popup window includes several InLineSettingItem items with + * different types if possible. + */ +public class ListMenuItem extends RelativeLayout { + private static final String TAG = "ListMenuItem"; + private Listener mListener; + protected ListPreference mPreference; + protected int mIndex; + // Scene mode can override the original preference value. + protected String mOverrideValue; + protected TextView mTitle; + private TextView mEntry; + private ImageView mIcon; + + static public interface Listener { + public void onSettingChanged(ListPreference pref); + } + + public ListMenuItem(Context context, AttributeSet attrs) { + super(context, attrs); + } + + @Override + protected void onFinishInflate() { + super.onFinishInflate(); + mEntry = (TextView) findViewById(R.id.current_setting); + mIcon = (ImageView) findViewById(R.id.list_image); + } + + protected void setTitle(ListPreference preference) { + mTitle = ((TextView) findViewById(R.id.title)); + mTitle.setText(preference.getTitle()); + } + + protected void setIcon(ListPreference preference) { + if (preference instanceof IconListPreference) { + int resId = ((IconListPreference) preference).getSingleIcon(); + mIcon.setImageResource(resId); + } + + } + + public void initialize(ListPreference preference) { + setTitle(preference); + if (preference == null) + return; + setIcon(preference); + mPreference = preference; + reloadPreference(); + } + + protected void updateView() { + if (mOverrideValue == null) { + mEntry.setText(mPreference.getEntry()); + } else { + int index = mPreference.findIndexOfValue(mOverrideValue); + if (index != -1) { + mEntry.setText(mPreference.getEntries()[index]); + } else { + // Avoid the crash if camera driver has bugs. + Log.e(TAG, "Fail to find override value=" + mOverrideValue); + mPreference.print(); + } + } + } + + protected boolean changeIndex(int index) { + if (index >= mPreference.getEntryValues().length || index < 0) + return false; + mIndex = index; + mPreference.setValueIndex(mIndex); + if (mListener != null) { + mListener.onSettingChanged(mPreference); + } + updateView(); + sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED); + return true; + } + + // The value of the preference may have changed. Update the UI. + public void reloadPreference() { + mIndex = mPreference.findIndexOfValue(mPreference.getValue()); + updateView(); + } + + public void setSettingChangedListener(Listener listener) { + mListener = listener; + } + + public void overrideSettings(String value) { + mOverrideValue = value; + updateView(); + } + + @Override + public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) { + event.getText().add(mPreference.getTitle() + mPreference.getEntry()); + return true; + } + + @Override + public void setEnabled(boolean enable) { + super.setEnabled(enable); + if (enable) + setAlpha(1f); + else + setAlpha(0.3f); + if (mTitle != null) { + mTitle.setEnabled(enable); + if (enable) + setAlpha(1f); + else + setAlpha(0.3f); + } + if (mEntry != null) { + mEntry.setEnabled(enable); + if (enable) + setAlpha(1f); + else + setAlpha(0.3f); + } + } +} diff --git a/src/com/android/camera/ui/ListSubMenu.java b/src/com/android/camera/ui/ListSubMenu.java new file mode 100644 index 000000000..af38b162a --- /dev/null +++ b/src/com/android/camera/ui/ListSubMenu.java @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * Not a Contribution. + * + * Copyright (C) 2010 The Android Open Source 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 java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import android.content.Context; +import android.graphics.Rect; +import android.util.AttributeSet; +import android.util.Log; +import android.view.View; +import android.widget.AdapterView; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.ListView; +import android.widget.SimpleAdapter; + +import com.android.camera.IconListPreference; +import com.android.camera.ListPreference; +import org.codeaurora.snapcam.R; + +// A popup window that shows one camera setting. The title is the name of the +// setting (ex: white-balance). The entries are the supported values (ex: +// daylight, incandescent, etc). If initialized with an IconListPreference, +// the entries will contain both text and icons. Otherwise, entries will be +// shown in text. +public class ListSubMenu extends ListView implements + AdapterView.OnItemClickListener { + private static final String TAG = "ListPrefSettingPopup"; + private ListPreference mPreference; + private Listener mListener; + private int mY; + + static public interface Listener { + public void onListPrefChanged(ListPreference pref); + } + + public ListSubMenu(Context context, int listRes) { + super(context); + } + + public ListSubMenu(Context context, AttributeSet attrs) { + super(context, attrs); + } + + private class ListPrefSettingAdapter extends SimpleAdapter { + ListPrefSettingAdapter(Context context, List<? extends Map<String, ?>> data, + int resource, String[] from, int[] to) { + super(context, data, resource, from, to); + } + + @Override + public void setViewImage(ImageView v, String value) { + if ("".equals(value)) { + // Some settings have no icons. Ex: exposure compensation. + v.setVisibility(View.GONE); + } else { + super.setViewImage(v, value); + } + } + } + + @Override + protected void onLayout(boolean changed, int l, int t, int r, int b) { + int screenHeight = ((LinearLayout) getParent()).getHeight(); + super.onLayout(changed, l, t, r, b); + setY(Math.max(0, mY)); + if (mY + (b - t) > screenHeight) { + setY(Math.max(0, mY - (mY + (b - t) - screenHeight))); + } + } + + public void initialize(ListPreference preference, int y) { + mPreference = preference; + Context context = getContext(); + CharSequence[] entries = mPreference.getEntries(); + int[] iconIds = null; + if (preference instanceof IconListPreference) { + iconIds = ((IconListPreference) mPreference).getImageIds(); + if (iconIds == null) { + iconIds = ((IconListPreference) mPreference).getLargeIconIds(); + } + } + mY = y; + + // Prepare the ListView. + ArrayList<HashMap<String, Object>> listItem = + new ArrayList<HashMap<String, Object>>(); + for (int i = 0; i < entries.length; ++i) { + HashMap<String, Object> map = new HashMap<String, Object>(); + map.put("text", entries[i].toString()); + if (iconIds != null) + map.put("image", iconIds[i]); + listItem.add(map); + } + SimpleAdapter listItemAdapter = new ListPrefSettingAdapter(context, listItem, + R.layout.list_sub_menu_item, + new String[] { + "text", "image" + }, + new int[] { + R.id.text, R.id.image + }); + setAdapter(listItemAdapter); + setOnItemClickListener(this); + reloadPreference(); + } + + // The value of the preference may have changed. Update the UI. + // @Override + public void reloadPreference() { + int index = mPreference.findIndexOfValue(mPreference.getValue()); + if (index != -1) { + setItemChecked(index, true); + } else { + Log.e(TAG, "Invalid preference value."); + mPreference.print(); + } + } + + public void setSettingChangedListener(Listener listener) { + mListener = listener; + } + + @Override + public void onItemClick(AdapterView<?> parent, View view, + int index, long id) { + mPreference.setValueIndex(index); + if (mListener != null) + mListener.onListPrefChanged(mPreference); + } + + @Override + protected void onFocusChanged(boolean gainFocus, int direction, Rect previouslyFocusedRect) { + super.onFocusChanged(gainFocus, direction, previouslyFocusedRect); + } +} diff --git a/src/com/android/camera/ui/ModuleSwitcher.java b/src/com/android/camera/ui/ModuleSwitcher.java index 60fed24ad..3f9ccd5ec 100644 --- a/src/com/android/camera/ui/ModuleSwitcher.java +++ b/src/com/android/camera/ui/ModuleSwitcher.java @@ -52,6 +52,7 @@ public class ModuleSwitcher extends RotateImageView public static final int WIDE_ANGLE_PANO_MODULE_INDEX = 2; public static final int LIGHTCYCLE_MODULE_INDEX = 3; public static final int GCAM_MODULE_INDEX = 4; + private boolean mTouchEnabled = true; private static final int[] DRAW_IDS = { R.drawable.ic_switch_camera, @@ -146,6 +147,20 @@ public class ModuleSwitcher extends RotateImageView } @Override + public boolean dispatchTouchEvent(MotionEvent m) { + if (mTouchEnabled) { + return super.dispatchTouchEvent(m); + } else { + setBackground(null); + return false; + } + } + + public void enableTouch(boolean enable) { + mTouchEnabled = enable; + } + + @Override public void onClick(View v) { showSwitcher(); mListener.onShowSwitcherPopup(); @@ -254,6 +269,16 @@ public class ModuleSwitcher extends RotateImageView mParent.setOnTouchListener(null); } + public void removePopup() { + mShowingPopup = false; + setVisibility(View.VISIBLE); + if (mPopup != null) { + ((ViewGroup) mParent).removeView(mPopup); + mPopup = null; + } + setAlpha(1f); + } + @Override public void onConfigurationChanged(Configuration config) { if (showsPopup()) { diff --git a/src/com/android/camera/ui/PieRenderer.java b/src/com/android/camera/ui/PieRenderer.java index 13ead421e..324e0fe98 100644 --- a/src/com/android/camera/ui/PieRenderer.java +++ b/src/com/android/camera/ui/PieRenderer.java @@ -36,6 +36,7 @@ import android.view.ViewConfiguration; import android.view.animation.Animation; import android.view.animation.Transformation; +import com.android.camera.CameraActivity; import com.android.camera.drawable.TextDrawable; import com.android.camera.ui.ProgressRenderer.VisibilityListener; import org.codeaurora.snapcam.R; @@ -636,6 +637,8 @@ public class PieRenderer extends OverlayRenderer @Override public boolean onTouchEvent(MotionEvent evt) { + if (!CameraActivity.isPieMenuEnabled()) + return false; float x = evt.getX(); float y = evt.getY(); int action = evt.getActionMasked(); |