PointerSpeedPreference.java revision 4397f406a3c9e09ca2d5174ba46328345faa504e
1/*
2 * Copyright (C) 2011 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.settings;
18
19import android.content.ContentResolver;
20import android.content.Context;
21import android.database.ContentObserver;
22import android.hardware.input.InputManager;
23import android.os.Bundle;
24import android.os.Handler;
25import android.os.Parcel;
26import android.os.Parcelable;
27import android.preference.SeekBarDialogPreference;
28import android.provider.Settings;
29import android.util.AttributeSet;
30import android.view.View;
31import android.widget.SeekBar;
32
33public class PointerSpeedPreference extends SeekBarDialogPreference implements
34        SeekBar.OnSeekBarChangeListener {
35    private final InputManager mIm;
36    private SeekBar mSeekBar;
37
38    private int mOldSpeed;
39    private boolean mRestoredOldState;
40
41    private boolean mTouchInProgress;
42
43    private ContentObserver mSpeedObserver = new ContentObserver(new Handler()) {
44        @Override
45        public void onChange(boolean selfChange) {
46            onSpeedChanged();
47        }
48    };
49
50    public PointerSpeedPreference(Context context, AttributeSet attrs) {
51        super(context, attrs);
52        mIm = (InputManager)getContext().getSystemService(Context.INPUT_SERVICE);
53    }
54
55    @Override
56    protected void showDialog(Bundle state) {
57        super.showDialog(state);
58
59        getContext().getContentResolver().registerContentObserver(
60                Settings.System.getUriFor(Settings.System.POINTER_SPEED), true,
61                mSpeedObserver);
62
63        mRestoredOldState = false;
64    }
65
66    @Override
67    protected void onBindDialogView(View view) {
68        super.onBindDialogView(view);
69
70        mSeekBar = getSeekBar(view);
71        mSeekBar.setMax(InputManager.MAX_POINTER_SPEED - InputManager.MIN_POINTER_SPEED);
72        mOldSpeed = mIm.getPointerSpeed(getContext());
73        mSeekBar.setProgress(mOldSpeed - InputManager.MIN_POINTER_SPEED);
74        mSeekBar.setOnSeekBarChangeListener(this);
75    }
76
77    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromTouch) {
78        if (!mTouchInProgress) {
79            mIm.tryPointerSpeed(progress + InputManager.MIN_POINTER_SPEED);
80        }
81    }
82
83    public void onStartTrackingTouch(SeekBar seekBar) {
84        mTouchInProgress = true;
85    }
86
87    public void onStopTrackingTouch(SeekBar seekBar) {
88        mTouchInProgress = false;
89        mIm.tryPointerSpeed(seekBar.getProgress() + InputManager.MIN_POINTER_SPEED);
90    }
91
92    private void onSpeedChanged() {
93        int speed = mIm.getPointerSpeed(getContext());
94        mSeekBar.setProgress(speed - InputManager.MIN_POINTER_SPEED);
95    }
96
97    @Override
98    protected void onDialogClosed(boolean positiveResult) {
99        super.onDialogClosed(positiveResult);
100
101        final ContentResolver resolver = getContext().getContentResolver();
102
103        if (positiveResult) {
104            mIm.setPointerSpeed(getContext(),
105                    mSeekBar.getProgress() + InputManager.MIN_POINTER_SPEED);
106        } else {
107            restoreOldState();
108        }
109
110        resolver.unregisterContentObserver(mSpeedObserver);
111    }
112
113    private void restoreOldState() {
114        if (mRestoredOldState) return;
115
116        mIm.tryPointerSpeed(mOldSpeed);
117        mRestoredOldState = true;
118    }
119
120    @Override
121    protected Parcelable onSaveInstanceState() {
122        final Parcelable superState = super.onSaveInstanceState();
123        if (getDialog() == null || !getDialog().isShowing()) return superState;
124
125        // Save the dialog state
126        final SavedState myState = new SavedState(superState);
127        myState.progress = mSeekBar.getProgress();
128        myState.oldSpeed = mOldSpeed;
129
130        // Restore the old state when the activity or dialog is being paused
131        restoreOldState();
132        return myState;
133    }
134
135    @Override
136    protected void onRestoreInstanceState(Parcelable state) {
137        if (state == null || !state.getClass().equals(SavedState.class)) {
138            // Didn't save state for us in onSaveInstanceState
139            super.onRestoreInstanceState(state);
140            return;
141        }
142
143        SavedState myState = (SavedState) state;
144        super.onRestoreInstanceState(myState.getSuperState());
145        mOldSpeed = myState.oldSpeed;
146        mSeekBar.setProgress(myState.progress);
147        mIm.tryPointerSpeed(myState.progress + InputManager.MIN_POINTER_SPEED);
148    }
149
150    private static class SavedState extends BaseSavedState {
151        int progress;
152        int oldSpeed;
153
154        public SavedState(Parcel source) {
155            super(source);
156            progress = source.readInt();
157            oldSpeed = source.readInt();
158        }
159
160        @Override
161        public void writeToParcel(Parcel dest, int flags) {
162            super.writeToParcel(dest, flags);
163            dest.writeInt(progress);
164            dest.writeInt(oldSpeed);
165        }
166
167        public SavedState(Parcelable superState) {
168            super(superState);
169        }
170
171        public static final Parcelable.Creator<SavedState> CREATOR =
172                new Parcelable.Creator<SavedState>() {
173
174            public SavedState createFromParcel(Parcel in) {
175                return new SavedState(in);
176            }
177
178            public SavedState[] newArray(int size) {
179                return new SavedState[size];
180            }
181        };
182    }
183}
184
185