18872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb/* 28872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * Copyright (C) 2012 The Android Open Source Project 38872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * 48872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * Licensed under the Apache License, Version 2.0 (the "License"); 58872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * you may not use this file except in compliance with the License. 68872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * You may obtain a copy of the License at 78872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * 88872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * http://www.apache.org/licenses/LICENSE-2.0 98872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * 108872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * Unless required by applicable law or agreed to in writing, software 118872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * distributed under the License is distributed on an "AS IS" BASIS, 128872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * See the License for the specific language governing permissions and 148872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * limitations under the License. 158872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb */ 168872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbpackage com.android.camera.ui; 178872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 188872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.content.Context; 198872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.content.res.Resources; 208872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.util.AttributeSet; 218872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.util.Log; 228872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.view.View; 238872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.widget.Button; 248872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.widget.CompoundButton; 258872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.widget.NumberPicker; 268872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.widget.Switch; 278872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport android.widget.TextView; 288872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 298872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport com.android.camera.IconListPreference; 308872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbimport com.android.camera.ListPreference; 318e963a5a6016d246184ed65906f9d103e92b17e2Sascha Haeberlingimport com.android.camera2.R; 328872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 333e058558dc0aaea971d084bf9c72e1cfa0c5ebd9Sascha Haeberlingimport java.text.NumberFormat; 343e058558dc0aaea971d084bf9c72e1cfa0c5ebd9Sascha Haeberlingimport java.util.Locale; 353e058558dc0aaea971d084bf9c72e1cfa0c5ebd9Sascha Haeberling 368872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb/** 378872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * This is a popup window that allows users to turn on/off time lapse feature, 388872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb * and to select a time interval for taking a time lapse video. 398872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb */ 408872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolbpublic class TimeIntervalPopup extends AbstractSettingPopup { 418872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb private static final String TAG = "TimeIntervalPopup"; 428872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb private NumberPicker mNumberSpinner; 438872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb private NumberPicker mUnitSpinner; 448872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb private Switch mTimeLapseSwitch; 458872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb private final String[] mUnits; 468872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb private final String[] mDurations; 478872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb private IconListPreference mPreference; 488872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb private Listener mListener; 498872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb private Button mConfirmButton; 508872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb private TextView mHelpText; 518872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb private View mTimePicker; 528872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 538872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb static public interface Listener { 548872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public void onListPrefChanged(ListPreference pref); 558872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 568872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 578872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public void setSettingChangedListener(Listener listener) { 588872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mListener = listener; 598872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 608872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 618872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public TimeIntervalPopup(Context context, AttributeSet attrs) { 628872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb super(context, attrs); 638872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 648872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb Resources res = context.getResources(); 658872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mUnits = res.getStringArray(R.array.pref_video_time_lapse_frame_interval_units); 663e058558dc0aaea971d084bf9c72e1cfa0c5ebd9Sascha Haeberling mDurations = localizeNumbers(res 673e058558dc0aaea971d084bf9c72e1cfa0c5ebd9Sascha Haeberling .getStringArray(R.array.pref_video_time_lapse_frame_interval_duration_values)); 683e058558dc0aaea971d084bf9c72e1cfa0c5ebd9Sascha Haeberling } 693e058558dc0aaea971d084bf9c72e1cfa0c5ebd9Sascha Haeberling 703e058558dc0aaea971d084bf9c72e1cfa0c5ebd9Sascha Haeberling /** 713e058558dc0aaea971d084bf9c72e1cfa0c5ebd9Sascha Haeberling * Localizes an array of US formatted numbers. 723e058558dc0aaea971d084bf9c72e1cfa0c5ebd9Sascha Haeberling */ 733e058558dc0aaea971d084bf9c72e1cfa0c5ebd9Sascha Haeberling private static String[] localizeNumbers(String[] mDurations) { 743e058558dc0aaea971d084bf9c72e1cfa0c5ebd9Sascha Haeberling NumberFormat format = NumberFormat.getInstance(Locale.getDefault()); 753e058558dc0aaea971d084bf9c72e1cfa0c5ebd9Sascha Haeberling String[] result = new String[mDurations.length]; 763e058558dc0aaea971d084bf9c72e1cfa0c5ebd9Sascha Haeberling for (int i = 0; i < mDurations.length; ++i) { 773e058558dc0aaea971d084bf9c72e1cfa0c5ebd9Sascha Haeberling double value = Double.valueOf(mDurations[i]); 783e058558dc0aaea971d084bf9c72e1cfa0c5ebd9Sascha Haeberling result[i] = format.format(value); 793e058558dc0aaea971d084bf9c72e1cfa0c5ebd9Sascha Haeberling } 803e058558dc0aaea971d084bf9c72e1cfa0c5ebd9Sascha Haeberling return result; 818872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 828872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 838872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public void initialize(IconListPreference preference) { 848872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mPreference = preference; 858872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 868872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // Set title. 878872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mTitle.setText(mPreference.getTitle()); 888872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 898872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // Duration 908872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb int durationCount = mDurations.length; 918872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mNumberSpinner = (NumberPicker) findViewById(R.id.duration); 928872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mNumberSpinner.setMinValue(0); 938872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mNumberSpinner.setMaxValue(durationCount - 1); 948872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mNumberSpinner.setDisplayedValues(mDurations); 958872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mNumberSpinner.setWrapSelectorWheel(false); 968872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 978872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // Units for duration (i.e. seconds, minutes, etc) 988872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mUnitSpinner = (NumberPicker) findViewById(R.id.duration_unit); 998872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mUnitSpinner.setMinValue(0); 1008872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mUnitSpinner.setMaxValue(mUnits.length - 1); 1018872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mUnitSpinner.setDisplayedValues(mUnits); 1028872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mUnitSpinner.setWrapSelectorWheel(false); 1038872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 1048872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mTimePicker = findViewById(R.id.time_interval_picker); 1058872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mTimeLapseSwitch = (Switch) findViewById(R.id.time_lapse_switch); 1068872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mHelpText = (TextView) findViewById(R.id.set_time_interval_help_text); 1078872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mConfirmButton = (Button) findViewById(R.id.time_lapse_interval_set_button); 1088872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 1098872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // Disable focus on the spinners to prevent keyboard from coming up 1108872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mNumberSpinner.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS); 1118872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mUnitSpinner.setDescendantFocusability(NumberPicker.FOCUS_BLOCK_DESCENDANTS); 1128872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 1138872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mTimeLapseSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 1148872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 1158872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb setTimeSelectionEnabled(isChecked); 1168872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 1178872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb }); 1188872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mConfirmButton.setOnClickListener(new View.OnClickListener() { 1198872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public void onClick(View v) { 1208872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb updateInputState(); 1218872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 1228872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb }); 1238872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 1248872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 1258872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb private void restoreSetting() { 1268872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb int index = mPreference.findIndexOfValue(mPreference.getValue()); 1278872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb if (index == -1) { 1288872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb Log.e(TAG, "Invalid preference value."); 1298872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mPreference.print(); 1308872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb throw new IllegalArgumentException(); 1318872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } else if (index == 0) { 1328872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // default choice: time lapse off 1338872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mTimeLapseSwitch.setChecked(false); 1348872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb setTimeSelectionEnabled(false); 1358872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } else { 1368872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mTimeLapseSwitch.setChecked(true); 1378872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb setTimeSelectionEnabled(true); 1388872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb int durationCount = mNumberSpinner.getMaxValue() + 1; 1398872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb int unit = (index - 1) / durationCount; 1408872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb int number = (index - 1) % durationCount; 1418872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mUnitSpinner.setValue(unit); 1428872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mNumberSpinner.setValue(number); 1438872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 1448872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 1458872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 1468872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb @Override 1478872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public void setVisibility(int visibility) { 1488872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb if (visibility == View.VISIBLE) { 1498872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb if (getVisibility() != View.VISIBLE) { 1508872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // Set the number pickers and on/off switch to be consistent 1518872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb // with the preference 1528872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb restoreSetting(); 1538872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 1548872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 1558872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb super.setVisibility(visibility); 1568872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 1578872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 1588872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb protected void setTimeSelectionEnabled(boolean enabled) { 1598872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mHelpText.setVisibility(enabled ? GONE : VISIBLE); 1608872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mTimePicker.setVisibility(enabled ? VISIBLE : GONE); 1618872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 1628872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 1638872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb @Override 1648872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb public void reloadPreference() { 1658872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 1668872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 1678872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb private void updateInputState() { 1688872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb if (mTimeLapseSwitch.isChecked()) { 1698872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb int newId = mUnitSpinner.getValue() * (mNumberSpinner.getMaxValue() + 1) 1708872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb + mNumberSpinner.getValue() + 1; 1718872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mPreference.setValueIndex(newId); 1728872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } else { 1738872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mPreference.setValueIndex(0); 1748872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 1758872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb 1768872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb if (mListener != null) { 1778872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb mListener.onListPrefChanged(mPreference); 1788872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 1798872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb } 1808872c23e739de38d74f04a8c852ebb5199c905f6Michael Kolb} 181