1/* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 * in compliance with the License. You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software distributed under the License 10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 * or implied. See the License for the specific language governing permissions and limitations under 12 * the License. 13 */ 14package com.android.tv.quicksettings; 15 16import android.app.Activity; 17import android.app.AlertDialog; 18import android.content.DialogInterface; 19import android.content.Intent; 20import android.os.Bundle; 21import android.os.Parcelable; 22import android.support.v17.leanback.widget.OnChildSelectedListener; 23import android.support.v17.leanback.widget.VerticalGridView; 24import android.support.v7.widget.RecyclerView; 25import android.util.Log; 26import android.view.animation.AlphaAnimation; 27import android.view.animation.Animation; 28import android.view.animation.AnimationSet; 29import android.view.animation.ScaleAnimation; 30import android.view.Gravity; 31import android.view.KeyEvent; 32import android.view.LayoutInflater; 33import android.view.View; 34import android.view.ViewGroup; 35import android.view.WindowManager; 36import android.widget.SeekBar; 37import android.widget.TextView; 38 39import java.util.ArrayList; 40import java.util.Arrays; 41import java.util.List; 42 43public class SettingsDialog extends Activity { 44 45 private static final String TAG = "SettingsDialog"; 46 private static final boolean DEBUG = true; 47 48 static final String EXTRA_START_POS = "com.android.tv.quicksettings.START_POS"; 49 static final String EXTRA_SETTINGS = "com.android.tv.quicksettings.SETTINGS"; 50 static final String 51 RESULT_EXTRA_NEW_SETTINGS_VALUES = "com.android.tv.quicksettings.NEW_SETTINGS_VALUES"; 52 private static final int SETTING_INT_VALUE_MIN = 0; 53 private static final int SETTING_INT_VALUE_STEP = 10; 54 55 private VerticalGridView mPanelList; 56 private SeekBar mSeekBar; 57 private TextView mSettingValue; 58 private DialogAdapter mAdapter; 59 private SettingSelectedListener mSettingSelectedListener = new SettingSelectedListener(); 60 private Setting mFocusedSetting; 61 private ArrayList<Setting> mSettings; 62 63 @Override 64 public void onCreate(Bundle savedInstanceState) { 65 super.onCreate(savedInstanceState); 66 67 WindowManager.LayoutParams lp = getWindow().getAttributes(); 68 lp.height = WindowManager.LayoutParams.MATCH_PARENT; 69 lp.gravity = Gravity.BOTTOM | Gravity.CENTER; 70 lp.y = getResources().getDimensionPixelSize(R.dimen.panel_y_offset); 71 getWindow().setAttributes(lp); 72 73 setContentView(R.layout.main_quicksettings); 74 75 Intent intent = getIntent(); 76 int startPos = intent.getIntExtra(EXTRA_START_POS, -1); 77 if (DEBUG) 78 Log.d(TAG, "startPos=" + startPos); 79 80 mPanelList = (VerticalGridView) findViewById(R.id.main_panel_list); 81 mPanelList.setWindowAlignment(VerticalGridView.WINDOW_ALIGN_NO_EDGE); 82 mPanelList.setOnChildSelectedListener(mSettingSelectedListener); 83 84 mSettings = getIntent().getParcelableArrayListExtra(EXTRA_SETTINGS); 85 int pivotX = getResources().getDimensionPixelSize( 86 R.dimen.main_panel_text_width_minus_padding); 87 int pivotY = getResources().getDimensionPixelSize(R.dimen.main_panel_text_height_half); 88 89 mAdapter = new DialogAdapter(mSettings, pivotX, pivotY, new SettingClickedListener() { 90 @Override 91 public void onSettingClicked(Setting s) { 92 if (s.getType() != Setting.TYPE_UNKNOWN) { 93 setResult(RESULT_OK, new Intent().putExtra(RESULT_EXTRA_NEW_SETTINGS_VALUES, 94 mSettings)); 95 finish(); 96 } else { 97 new AlertDialog.Builder(SettingsDialog.this).setPositiveButton( 98 android.R.string.ok, new DialogInterface.OnClickListener() { 99 @Override 100 public void onClick(DialogInterface dialog, int id) { 101 // User clicked OK button 102 String[] presetSettingChoices = getResources().getStringArray( 103 R.array.setting_preset_choices); 104 mSettings.get(QuickSettings.PRESET_SETTING_INDEX).setValue( 105 presetSettingChoices[getResources().getInteger( 106 R.integer.standard_setting_index)]); 107 int[] newSettingValues = getResources().getIntArray( 108 R.array.standard_setting_values); 109 for (int i = 0; i < newSettingValues.length; i++) { 110 mSettings.get(i + QuickSettings.INTEGER_SETTING_START_INDEX) 111 .setValue( 112 newSettingValues[i]); 113 } 114 } 115 }).setNegativeButton(android.R.string.cancel, 116 new DialogInterface.OnClickListener() { 117 @Override 118 public void onClick(DialogInterface dialog, int id) { 119 // User cancelled the dialog - do nothing 120 } 121 }).setTitle(R.string.reset_dialog_message).create().show(); 122 } 123 } 124 }); 125 126 mPanelList.setAdapter(mAdapter); 127 mPanelList.setSelectedPosition(startPos); 128 mPanelList.requestFocus(); 129 130 mSeekBar = (SeekBar) findViewById(R.id.main_slider); 131 132 mSettingValue = (TextView) findViewById(R.id.setting_value); 133 } 134 135 private class SettingSelectedListener implements OnChildSelectedListener { 136 private static final float ALPHA_UNSELECTED = 0.3f; 137 private static final float ALPHA_SELECTED = 1.0f; 138 private static final float SCALE_UNSELECTED = 1.0f; 139 private static final float SCALE_SELECTED = 1.3f; 140 141 @Override 142 public void onChildSelected(ViewGroup parent, View view, int position, long id) { 143 mFocusedSetting = mSettings.get(position); 144 switch (mFocusedSetting.getType()) { 145 case Setting.TYPE_STRING: 146 mSettingValue.setVisibility(View.VISIBLE); 147 mSettingValue.setText(mFocusedSetting.getStringValue()); 148 mSeekBar.setVisibility(View.GONE); 149 break; 150 case Setting.TYPE_INT: 151 mSettingValue.setVisibility(View.VISIBLE); 152 mSettingValue.setText(Integer.toString(mFocusedSetting.getIntValue())); 153 mSeekBar.setMax(mFocusedSetting.getMaxValue()); 154 mSeekBar.setProgress(mFocusedSetting.getIntValue()); 155 mSeekBar.setVisibility(View.VISIBLE); 156 break; 157 default: 158 mSettingValue.setVisibility(View.GONE); 159 mSeekBar.setVisibility(View.GONE); 160 break; 161 } 162 } 163 } 164 165 @Override 166 public boolean onKeyUp(int keyCode, KeyEvent event) { 167 if (mFocusedSetting == null) { 168 return super.onKeyUp(keyCode, event); 169 } 170 switch (mFocusedSetting.getType()) { 171 case Setting.TYPE_INT: 172 return integerSettingHandleKeyCode(keyCode, event); 173 case Setting.TYPE_STRING: 174 return stringSettingHandleKeyCode(keyCode, event); 175 default: 176 return super.onKeyUp(keyCode, event); 177 } 178 } 179 180 private boolean integerSettingHandleKeyCode(int keyCode, KeyEvent event) { 181 switch (keyCode) { 182 case KeyEvent.KEYCODE_DPAD_RIGHT: 183 setFocusedSettingToValue(Math.min( 184 mFocusedSetting.getIntValue() + SETTING_INT_VALUE_STEP, 185 mFocusedSetting.getMaxValue())); 186 return true; 187 case KeyEvent.KEYCODE_DPAD_LEFT: 188 setFocusedSettingToValue(Math.max( 189 mFocusedSetting.getIntValue() - SETTING_INT_VALUE_STEP, 190 SETTING_INT_VALUE_MIN)); 191 return true; 192 default: 193 return super.onKeyUp(keyCode, event); 194 } 195 } 196 197 private void setFocusedSettingToValue(int value) { 198 mFocusedSetting.setValue(value); 199 mSeekBar.setProgress(mFocusedSetting.getIntValue()); 200 mSettingValue.setText(Integer.toString(mFocusedSetting.getIntValue())); 201 String[] presetSettingChoices = getResources().getStringArray( 202 R.array.setting_preset_choices); 203 mSettings.get(QuickSettings.PRESET_SETTING_INDEX).setValue( 204 presetSettingChoices[getResources().getInteger(R.integer.custom_setting_index)]); 205 } 206 207 private boolean stringSettingHandleKeyCode(int keyCode, KeyEvent event) { 208 if (!mFocusedSetting.getTitle().equals(getString(R.string.setting_preset_name))) { 209 return super.onKeyUp(keyCode, event); 210 } 211 212 String[] presetSettingChoices = getResources().getStringArray( 213 R.array.setting_preset_choices); 214 215 int currentIndex = Arrays.asList(presetSettingChoices).indexOf( 216 mFocusedSetting.getStringValue()); 217 switch (keyCode) { 218 case KeyEvent.KEYCODE_DPAD_RIGHT: 219 currentIndex++; 220 break; 221 case KeyEvent.KEYCODE_DPAD_LEFT: 222 currentIndex--; 223 break; 224 default: 225 return super.onKeyUp(keyCode, event); 226 } 227 int newIndex = (currentIndex + presetSettingChoices.length) % presetSettingChoices.length; 228 mFocusedSetting.setValue(presetSettingChoices[newIndex]); 229 mSettingValue.setText(mFocusedSetting.getStringValue()); 230 int[] newSettingValues = null; 231 if (newIndex == getResources().getInteger(R.integer.standard_setting_index)) { 232 newSettingValues = getResources().getIntArray(R.array.standard_setting_values); 233 } else if (newIndex == getResources().getInteger(R.integer.cinema_setting_index)) { 234 newSettingValues = getResources().getIntArray(R.array.cinema_setting_values); 235 } else if (newIndex == getResources().getInteger(R.integer.vivid_setting_index)) { 236 newSettingValues = getResources().getIntArray(R.array.vivid_setting_values); 237 } else if (newIndex == getResources().getInteger(R.integer.game_setting_index)) { 238 newSettingValues = getResources().getIntArray(R.array.game_setting_values); 239 } 240 if (newSettingValues != null) { 241 for (int i = 0; i < newSettingValues.length; i++) { 242 mSettings.get(i + QuickSettings.INTEGER_SETTING_START_INDEX).setValue( 243 newSettingValues[i]); 244 } 245 } 246 return true; 247 } 248} 249