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.content.SharedPreferences; 17import android.preference.PreferenceManager; 18import android.support.annotation.NonNull; 19import android.app.Activity; 20import android.app.AlertDialog; 21import android.content.DialogInterface; 22import android.content.Intent; 23import android.os.Bundle; 24import android.support.v17.leanback.widget.OnChildSelectedListener; 25import android.support.v17.leanback.widget.VerticalGridView; 26import android.util.Log; 27import android.view.Gravity; 28import android.view.KeyEvent; 29import android.view.View; 30import android.view.ViewGroup; 31import android.view.WindowManager; 32import android.widget.SeekBar; 33import android.widget.TextView; 34 35import java.util.ArrayList; 36import java.util.Arrays; 37 38public class SettingsDialog extends Activity { 39 40 private static final int PRESET_SETTING_INDEX = 0; 41 private static final int INTEGER_SETTING_START_INDEX = 1; 42 43 private static final String TAG = "SettingsDialog"; 44 private static final boolean DEBUG = true; 45 46 static final String EXTRA_START_POS = "com.android.tv.quicksettings.START_POS"; 47 private static final int SETTING_INT_VALUE_MIN = 0; 48 private static final int SETTING_INT_VALUE_STEP = 10; 49 50 private VerticalGridView mPanelList; 51 private SeekBar mSeekBar; 52 private TextView mSettingValue; 53 private DialogAdapter mAdapter; 54 private final SettingSelectedListener mSettingSelectedListener = new SettingSelectedListener(); 55 private Setting mFocusedSetting; 56 private ArrayList<Setting> mSettings; 57 private SharedPreferences mSharedPreferences; 58 59 private PresetSettingsListener mPresetSettingsListener; 60 61 @Override 62 public void onCreate(Bundle savedInstanceState) { 63 super.onCreate(savedInstanceState); 64 65 mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); 66 mPresetSettingsListener = new PresetSettingsListener(this); 67 68 WindowManager.LayoutParams lp = getWindow().getAttributes(); 69 lp.height = WindowManager.LayoutParams.MATCH_PARENT; 70 lp.gravity = Gravity.BOTTOM | Gravity.CENTER; 71 lp.y = getResources().getDimensionPixelSize(R.dimen.panel_y_offset); 72 getWindow().setAttributes(lp); 73 74 setContentView(R.layout.main_quicksettings); 75 76 Intent intent = getIntent(); 77 int startPos = intent.getIntExtra(EXTRA_START_POS, -1); 78 if (DEBUG) 79 Log.d(TAG, "startPos=" + startPos); 80 81 mPanelList = (VerticalGridView) findViewById(R.id.main_panel_list); 82 mPanelList.setWindowAlignment(VerticalGridView.WINDOW_ALIGN_NO_EDGE); 83 mPanelList.setOnChildSelectedListener(mSettingSelectedListener); 84 85 mSettings = getSettings(); 86 87 final int pivotX; 88 if (getResources().getConfiguration().getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) { 89 pivotX = getResources().getDimensionPixelSize(R.dimen.slider_horizontal_padding); 90 } else { 91 pivotX = getResources().getDimensionPixelSize( 92 R.dimen.main_panel_text_width_minus_padding); 93 } 94 final int pivotY = getResources().getDimensionPixelSize(R.dimen.main_panel_text_height_half); 95 96 mAdapter = new DialogAdapter(mSettings, pivotX, pivotY, new SettingClickedListener() { 97 @Override 98 public void onSettingClicked(Setting s) { 99 if (s.getType() != Setting.TYPE_UNKNOWN) { 100 finish(); 101 } else { 102 new AlertDialog.Builder(SettingsDialog.this).setPositiveButton( 103 android.R.string.ok, new DialogInterface.OnClickListener() { 104 @Override 105 public void onClick(DialogInterface dialog, int id) { 106 // User clicked OK button 107 String[] presetSettingValues = getResources().getStringArray( 108 R.array.setting_preset_values); 109 mSettings.get(PRESET_SETTING_INDEX).setValue( 110 presetSettingValues[getResources().getInteger( 111 R.integer.standard_setting_index)]); 112 } 113 }).setNegativeButton(android.R.string.cancel, 114 new DialogInterface.OnClickListener() { 115 @Override 116 public void onClick(DialogInterface dialog, int id) { 117 // User cancelled the dialog - do nothing 118 } 119 }).setTitle(R.string.reset_dialog_message).create().show(); 120 } 121 } 122 }); 123 124 mPanelList.setAdapter(mAdapter); 125 mPanelList.setSelectedPosition(startPos + 1); 126 mPanelList.requestFocus(); 127 128 mSeekBar = (SeekBar) findViewById(R.id.main_slider); 129 130 mSettingValue = (TextView) findViewById(R.id.setting_value); 131 } 132 133 @Override 134 protected void onResume() { 135 super.onResume(); 136 137 mSharedPreferences.registerOnSharedPreferenceChangeListener(mPresetSettingsListener); 138 } 139 140 @Override 141 protected void onPause() { 142 super.onPause(); 143 144 mSharedPreferences.unregisterOnSharedPreferenceChangeListener(mPresetSettingsListener); 145 } 146 147 private ArrayList<Setting> getSettings() { 148 ArrayList<Setting> settings = new ArrayList<>(); 149 150 settings.add(new Setting(mSharedPreferences, "preset", 151 getString(R.string.setting_preset_name))); 152 153 String[] settingNames = getResources().getStringArray(R.array.setting_names); 154 String[] settingKeys = getResources().getStringArray(R.array.setting_keys); 155 int[] maxSettingValues = getResources().getIntArray(R.array.setting_max_values); 156 for (int i = 0; i < settingNames.length; i++) { 157 settings.add( 158 new Setting(mSharedPreferences, settingKeys[i], settingNames[i], 159 maxSettingValues[i])); 160 } 161 settings.add(new Setting(getString(R.string.setting_reset_defaults_name))); 162 163 return settings; 164 } 165 166 private class SettingSelectedListener implements OnChildSelectedListener { 167 @Override 168 public void onChildSelected(ViewGroup parent, View view, int position, long id) { 169 mFocusedSetting = mSettings.get(position); 170 switch (mFocusedSetting.getType()) { 171 case Setting.TYPE_STRING: 172 mSettingValue.setVisibility(View.VISIBLE); 173 mSettingValue.setText(mFocusedSetting.getStringValue()); 174 mSeekBar.setVisibility(View.GONE); 175 break; 176 case Setting.TYPE_INT: 177 mSettingValue.setVisibility(View.VISIBLE); 178 mSettingValue.setText(Integer.toString(mFocusedSetting.getIntValue())); 179 mSeekBar.setMax(mFocusedSetting.getMaxValue()); 180 mSeekBar.setProgress(mFocusedSetting.getIntValue()); 181 mSeekBar.setVisibility(View.VISIBLE); 182 break; 183 default: 184 mSettingValue.setVisibility(View.GONE); 185 mSeekBar.setVisibility(View.GONE); 186 break; 187 } 188 } 189 } 190 191 @Override 192 public boolean onKeyUp(int keyCode, @NonNull KeyEvent event) { 193 if (mFocusedSetting == null) { 194 return super.onKeyUp(keyCode, event); 195 } 196 switch (mFocusedSetting.getType()) { 197 case Setting.TYPE_INT: 198 return integerSettingHandleKeyCode(keyCode, event); 199 case Setting.TYPE_STRING: 200 return stringSettingHandleKeyCode(keyCode, event); 201 default: 202 return super.onKeyUp(keyCode, event); 203 } 204 } 205 206 private boolean integerSettingHandleKeyCode(int keyCode, KeyEvent event) { 207 switch (keyCode) { 208 case KeyEvent.KEYCODE_DPAD_RIGHT: 209 setFocusedSettingToValue(Math.min( 210 mFocusedSetting.getIntValue() + SETTING_INT_VALUE_STEP, 211 mFocusedSetting.getMaxValue())); 212 return true; 213 case KeyEvent.KEYCODE_DPAD_LEFT: 214 setFocusedSettingToValue(Math.max( 215 mFocusedSetting.getIntValue() - SETTING_INT_VALUE_STEP, 216 SETTING_INT_VALUE_MIN)); 217 return true; 218 default: 219 return super.onKeyUp(keyCode, event); 220 } 221 } 222 223 private void setFocusedSettingToValue(int value) { 224 mFocusedSetting.setValue(value); 225 mSeekBar.setProgress(mFocusedSetting.getIntValue()); 226 mSettingValue.setText(Integer.toString(mFocusedSetting.getIntValue())); 227 String[] presetSettingChoices = getResources().getStringArray( 228 R.array.setting_preset_values); 229 mSettings.get(PRESET_SETTING_INDEX).setValue( 230 presetSettingChoices[getResources().getInteger(R.integer.custom_setting_index)]); 231 } 232 233 private boolean stringSettingHandleKeyCode(int keyCode, KeyEvent event) { 234 if (!mFocusedSetting.getTitle().equals(getString(R.string.setting_preset_name))) { 235 return super.onKeyUp(keyCode, event); 236 } 237 238 String[] presetSettingChoices = getResources().getStringArray( 239 R.array.setting_preset_choices); 240 String[] presetSettingValues = getResources().getStringArray(R.array.setting_preset_values); 241 242 int currentIndex = Arrays.asList(presetSettingValues).indexOf( 243 mFocusedSetting.getStringValue()); 244 switch (keyCode) { 245 case KeyEvent.KEYCODE_DPAD_RIGHT: 246 currentIndex++; 247 break; 248 case KeyEvent.KEYCODE_DPAD_LEFT: 249 currentIndex--; 250 break; 251 default: 252 return super.onKeyUp(keyCode, event); 253 } 254 int newIndex = (currentIndex + presetSettingValues.length) % presetSettingValues.length; 255 mFocusedSetting.setValue(presetSettingValues[newIndex]); 256 mSettingValue.setText(presetSettingChoices[newIndex]); 257 int[] newSettingValues = null; 258 if (newIndex == getResources().getInteger(R.integer.standard_setting_index)) { 259 newSettingValues = getResources().getIntArray(R.array.standard_setting_values); 260 } else if (newIndex == getResources().getInteger(R.integer.cinema_setting_index)) { 261 newSettingValues = getResources().getIntArray(R.array.cinema_setting_values); 262 } else if (newIndex == getResources().getInteger(R.integer.vivid_setting_index)) { 263 newSettingValues = getResources().getIntArray(R.array.vivid_setting_values); 264 } else if (newIndex == getResources().getInteger(R.integer.game_setting_index)) { 265 newSettingValues = getResources().getIntArray(R.array.game_setting_values); 266 } 267 if (newSettingValues != null) { 268 for (int i = 0; i < newSettingValues.length; i++) { 269 mSettings.get(i + INTEGER_SETTING_START_INDEX).setValue( 270 newSettingValues[i]); 271 } 272 } 273 return true; 274 } 275} 276