/* * Copyright (c) 2016, 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.text.TextUtils; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewPropertyAnimator; import android.widget.ImageView; import android.widget.ListView; import android.widget.Toast; import com.android.camera.ui.CameraControls; import com.android.camera.ui.CountdownTimerPopup; import com.android.camera.ui.ListMenu; import com.android.camera.ui.ListSubMenu; import com.android.camera.ui.ModuleSwitcher; import com.android.camera.ui.RotateTextToast; import org.codeaurora.snapcam.R; import java.util.Locale; public class CaptureMenu extends MenuController implements ListMenu.Listener, CountdownTimerPopup.Listener, ListSubMenu.Listener { 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_SLIDE = 3; private static final int POPUP_IN_ANIMATION_FADE = 4; private static final int DEVELOPER_MENU_TOUCH_COUNT = 10; private static final int ANIMATION_DURATION = 300; private static final String TAG = "SnapCam_CaptureMenu"; private String[] mOtherKeys1; private String[] mOtherKeys2; private ListMenu mListMenu; private CaptureUI mUI; private int mPopupStatus; private ListSubMenu mListSubMenu; private CameraActivity mActivity; private int privateCounter = 0; public CaptureMenu(CameraActivity activity, CaptureUI ui) { super(activity); mUI = ui; mActivity = activity; } // 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())); } // Return true if the preference has the specified key and the value. private static boolean same(ListPreference pref, String key, String value) { return (key.equals(pref.getKey()) && value.equals(pref.getValue())); } public void initialize(PreferenceGroup group) { super.initialize(group); mListSubMenu = null; mListMenu = null; mPopupStatus = POPUP_NONE; mOtherKeys1 = new String[]{ CameraSettings.KEY_FLASH_MODE, CameraSettings.KEY_CAMERA2, CameraSettings.KEY_DUAL_CAMERA }; mOtherKeys2 = new String[]{ CameraSettings.KEY_FLASH_MODE, CameraSettings.KEY_CAMERA2, CameraSettings.KEY_DUAL_CAMERA }; } @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 (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 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_FADE) return; mPopupStatus = POPUP_IN_ANIMATION_FADE; 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_SLIDE) return; mPopupStatus = POPUP_IN_ANIMATION_SLIDE; ViewPropertyAnimator vp = v.animate(); if (View.LAYOUT_DIRECTION_RTL == TextUtils .getLayoutDirectionFromLocale(Locale.getDefault())) { switch (mUI.getOrientation()) { case 0: vp.translationXBy(v.getWidth()); break; case 90: vp.translationYBy(-2 * v.getHeight()); break; case 180: vp.translationXBy(-2 * v.getWidth()); break; case 270: vp.translationYBy(v.getHeight()); break; } } else { switch (mUI.getOrientation()) { case 0: vp.translationXBy(-v.getWidth()); break; case 90: vp.translationYBy(2 * v.getHeight()); break; case 180: vp.translationXBy(2 * v.getWidth()); break; case 270: vp.translationYBy(-v.getHeight()); break; } } 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.setDuration(ANIMATION_DURATION).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 forcePortrait) { int orientation = mUI.getOrientation(); if (!forcePortrait) orientation = 0; ViewPropertyAnimator vp = v.animate(); float dest; if (View.LAYOUT_DIRECTION_RTL == TextUtils .getLayoutDirectionFromLocale(Locale.getDefault())) { switch (orientation) { case 0: dest = v.getX(); v.setX(-(dest - delta)); vp.translationX(dest); break; case 90: dest = v.getY(); v.setY(-(dest + delta)); vp.translationY(dest); break; case 180: dest = v.getX(); v.setX(-(dest + delta)); vp.translationX(dest); break; case 270: dest = v.getY(); v.setY(-(dest - delta)); vp.translationY(dest); break; } } else { switch (orientation) { case 0: dest = v.getX(); v.setX(dest - delta); vp.translationX(dest); break; case 90: dest = v.getY(); v.setY(dest + delta); vp.translationY(dest); break; case 180: dest = v.getX(); v.setX(dest + delta); vp.translationX(dest); break; case 270: dest = v.getY(); v.setY(dest - delta); vp.translationY(dest); break; } } vp.setDuration(ANIMATION_DURATION).start(); } public boolean isOverMenu(MotionEvent ev) { if (mPopupStatus == POPUP_NONE || mPopupStatus == POPUP_IN_ANIMATION_SLIDE || mPopupStatus == POPUP_IN_ANIMATION_FADE) 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) { return false; } public boolean isMenuBeingShown() { return mPopupStatus != POPUP_NONE; } public boolean isMenuBeingAnimated() { return mPopupStatus == POPUP_IN_ANIMATION_SLIDE || mPopupStatus == POPUP_IN_ANIMATION_FADE; } public boolean isPreviewMenuBeingShown() { return false; } public boolean isPreviewMenuBeingAnimated() { return false; } 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) { super.overrideSettings(keyvalues); if ((mListMenu == null)) initializePopup(); mListMenu.overrideSettings(keyvalues); } protected void initializePopup() { LayoutInflater inflater = (LayoutInflater) mActivity.getSystemService( Context.LAYOUT_INFLATER_SERVICE); ListMenu listMenu = (ListMenu) inflater.inflate( R.layout.list_menu, null, false); listMenu.setSettingChangedListener(this); String[] keys = mOtherKeys1; if (mActivity.isDeveloperMenuEnabled()) keys = mOtherKeys2; listMenu.initialize(mPreferenceGroup, keys); mListMenu = listMenu; 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) switcher).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) v).setImageResource( ((IconListPreference) pref).getLargeIconIds()[index]); if (prefKey.equals(CameraSettings.KEY_CAMERA_ID)) mListener.onCameraPickerClicked(index); reloadPreference(pref); onSettingChanged(pref); } }); } 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 // 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(); RotateTextToast.makeText(mActivity, "Camera developer option is enabled now", Toast.LENGTH_SHORT).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 removeAllView() { if (mUI != null) mUI.removeLevel2(); if (mListMenu != null) { mUI.dismissLevel1(); mPopupStatus = POPUP_NONE; } mUI.cleanupListview(); } public void closeView() { if (mUI != null) mUI.removeLevel2(); if (mListMenu != null && mPopupStatus != POPUP_NONE) animateSlideOut(mListMenu, 1); } public 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) { super.onSettingChanged(pref); if (same(pref, CameraSettings.KEY_CAMERA2, "enable")) { SharedPreferences prefs = PreferenceManager .getDefaultSharedPreferences(mActivity); prefs.edit().putBoolean(CameraSettings.KEY_CAMERA2, true).apply(); CameraActivity.CAMERA_2_ON = true; mActivity.onModuleSelected(ModuleSwitcher.CAPTURE_MODULE_INDEX); } else if (notSame(pref, CameraSettings.KEY_CAMERA2, "enable")) { SharedPreferences prefs = PreferenceManager .getDefaultSharedPreferences(mActivity); prefs.edit().putBoolean(CameraSettings.KEY_CAMERA2, false).apply(); CameraActivity.CAMERA_2_ON = false; mActivity.onModuleSelected(ModuleSwitcher.PHOTO_MODULE_INDEX); } } public int getOrientation() { return mUI == null ? 0 : mUI.getOrientation(); } }