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 17 package com.android.inputmethod.latin.settings; 18 19 import android.app.AlertDialog; 20 import android.content.Context; 21 import android.content.DialogInterface; 22 import android.content.res.TypedArray; 23 import android.preference.DialogPreference; 24 import android.util.AttributeSet; 25 import android.view.View; 26 import android.widget.SeekBar; 27 import android.widget.TextView; 28 29 import com.android.inputmethod.latin.R; 30 31 public final class SeekBarDialogPreference extends DialogPreference 32 implements SeekBar.OnSeekBarChangeListener { 33 public interface ValueProxy { readValue(final String key)34 public int readValue(final String key); readDefaultValue(final String key)35 public int readDefaultValue(final String key); writeValue(final int value, final String key)36 public void writeValue(final int value, final String key); writeDefaultValue(final String key)37 public void writeDefaultValue(final String key); getValueText(final int value)38 public String getValueText(final int value); feedbackValue(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 SeekBarDialogPreference(final Context context, final AttributeSet attrs)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 setInterface(final ValueProxy proxy)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 onCreateDialogView()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 getProgressFromValue(final int value)78 private int getProgressFromValue(final int value) { 79 return value - mMinValue; 80 } 81 getValueFromProgress(final int progress)82 private int getValueFromProgress(final int progress) { 83 return progress + mMinValue; 84 } 85 clipValue(final int value)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 getClippedValueFromProgress(final int progress)94 private int getClippedValueFromProgress(final int progress) { 95 return clipValue(getValueFromProgress(progress)); 96 } 97 98 @Override onBindDialogView(final View view)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 onPrepareDialogBuilder(final AlertDialog.Builder builder)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 onClick(final DialogInterface dialog, final int which)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 onProgressChanged(final SeekBar seekBar, final int progress, final boolean fromUser)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 onStartTrackingTouch(final SeekBar seekBar)141 public void onStartTrackingTouch(final SeekBar seekBar) {} 142 143 @Override onStopTrackingTouch(final SeekBar seekBar)144 public void onStopTrackingTouch(final SeekBar seekBar) { 145 mValueProxy.feedbackValue(getClippedValueFromProgress(seekBar.getProgress())); 146 } 147 } 148