1/* 2 * Copyright (C) 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.inputmethod.latin.settings; 18 19import android.app.AlertDialog; 20import android.content.Context; 21import android.content.DialogInterface; 22import android.content.res.TypedArray; 23import android.preference.DialogPreference; 24import android.util.AttributeSet; 25import android.view.View; 26import android.widget.SeekBar; 27import android.widget.TextView; 28 29import com.android.inputmethod.latin.R; 30 31public final class SeekBarDialogPreference extends DialogPreference 32 implements SeekBar.OnSeekBarChangeListener { 33 public interface ValueProxy { 34 public int readValue(final String key); 35 public int readDefaultValue(final String key); 36 public void writeValue(final int value, final String key); 37 public void writeDefaultValue(final String key); 38 public String getValueText(final int value); 39 public void feedbackValue(final int value); 40 } 41 42 private final int mMaxValue; 43 private final int mMinValue; 44 private final int mStepValue; 45 46 private TextView mValueView; 47 private SeekBar mSeekBar; 48 49 private ValueProxy mValueProxy; 50 51 public SeekBarDialogPreference(final Context context, final AttributeSet attrs) { 52 super(context, attrs); 53 final TypedArray a = context.obtainStyledAttributes( 54 attrs, R.styleable.SeekBarDialogPreference, 0, 0); 55 mMaxValue = a.getInt(R.styleable.SeekBarDialogPreference_maxValue, 0); 56 mMinValue = a.getInt(R.styleable.SeekBarDialogPreference_minValue, 0); 57 mStepValue = a.getInt(R.styleable.SeekBarDialogPreference_stepValue, 0); 58 a.recycle(); 59 setDialogLayoutResource(R.layout.seek_bar_dialog); 60 } 61 62 public void setInterface(final ValueProxy proxy) { 63 mValueProxy = proxy; 64 final int value = mValueProxy.readValue(getKey()); 65 setSummary(mValueProxy.getValueText(value)); 66 } 67 68 @Override 69 protected View onCreateDialogView() { 70 final View view = super.onCreateDialogView(); 71 mSeekBar = (SeekBar)view.findViewById(R.id.seek_bar_dialog_bar); 72 mSeekBar.setMax(mMaxValue - mMinValue); 73 mSeekBar.setOnSeekBarChangeListener(this); 74 mValueView = (TextView)view.findViewById(R.id.seek_bar_dialog_value); 75 return view; 76 } 77 78 private int getProgressFromValue(final int value) { 79 return value - mMinValue; 80 } 81 82 private int getValueFromProgress(final int progress) { 83 return progress + mMinValue; 84 } 85 86 private int clipValue(final int value) { 87 final int clippedValue = Math.min(mMaxValue, Math.max(mMinValue, value)); 88 if (mStepValue <= 1) { 89 return clippedValue; 90 } 91 return clippedValue - (clippedValue % mStepValue); 92 } 93 94 private int getClippedValueFromProgress(final int progress) { 95 return clipValue(getValueFromProgress(progress)); 96 } 97 98 @Override 99 protected void onBindDialogView(final View view) { 100 final int value = mValueProxy.readValue(getKey()); 101 mValueView.setText(mValueProxy.getValueText(value)); 102 mSeekBar.setProgress(getProgressFromValue(clipValue(value))); 103 } 104 105 @Override 106 protected void onPrepareDialogBuilder(final AlertDialog.Builder builder) { 107 builder.setPositiveButton(android.R.string.ok, this) 108 .setNegativeButton(android.R.string.cancel, this) 109 .setNeutralButton(R.string.button_default, this); 110 } 111 112 @Override 113 public void onClick(final DialogInterface dialog, final int which) { 114 super.onClick(dialog, which); 115 final String key = getKey(); 116 if (which == DialogInterface.BUTTON_NEUTRAL) { 117 final int value = mValueProxy.readDefaultValue(key); 118 setSummary(mValueProxy.getValueText(value)); 119 mValueProxy.writeDefaultValue(key); 120 return; 121 } 122 if (which == DialogInterface.BUTTON_POSITIVE) { 123 final int value = getClippedValueFromProgress(mSeekBar.getProgress()); 124 setSummary(mValueProxy.getValueText(value)); 125 mValueProxy.writeValue(value, key); 126 return; 127 } 128 } 129 130 @Override 131 public void onProgressChanged(final SeekBar seekBar, final int progress, 132 final boolean fromUser) { 133 final int value = getClippedValueFromProgress(progress); 134 mValueView.setText(mValueProxy.getValueText(value)); 135 if (!fromUser) { 136 mSeekBar.setProgress(getProgressFromValue(value)); 137 } 138 } 139 140 @Override 141 public void onStartTrackingTouch(final SeekBar seekBar) {} 142 143 @Override 144 public void onStopTrackingTouch(final SeekBar seekBar) { 145 mValueProxy.feedbackValue(getClippedValueFromProgress(seekBar.getProgress())); 146 } 147} 148