diff XposedLibrary/src/de/robv/android/xposed/library/ui/ValueSeekBarPreference.java @ 0:3da8a7a621cd

Initial commit
author Brad Greco <brad@bgreco.net>
date Mon, 20 Jan 2014 22:56:13 -0600
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/XposedLibrary/src/de/robv/android/xposed/library/ui/ValueSeekBarPreference.java	Mon Jan 20 22:56:13 2014 -0600
@@ -0,0 +1,273 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package de.robv.android.xposed.library.ui;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.preference.Preference;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.SeekBar;
+import android.widget.SeekBar.OnSeekBarChangeListener;
+import android.widget.TextView;
+import de.robv.android.xposed.library.R;
+
+public class ValueSeekBarPreference extends Preference implements OnSeekBarChangeListener {
+
+    private int mProgress;
+    private int mStep;
+    private int mMin;
+    private int mMax;
+    private String valueDisplayFormat;
+    private boolean mTrackingTouch;
+    private TextView tvValue;
+
+    public ValueSeekBarPreference(
+            Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+        
+        if (attrs != null) {
+	        setStep(attrs.getAttributeIntValue(null, "step", 1));
+	        setMin(attrs.getAttributeIntValue(null, "min", 0));
+	        setMax(attrs.getAttributeIntValue(null, "max", 100));
+	        valueDisplayFormat = attrs.getAttributeValue(null, "displayFormat");
+	        if (valueDisplayFormat == null)
+	        	valueDisplayFormat = "%d";
+        }
+    }
+
+    public ValueSeekBarPreference(Context context, AttributeSet attrs) {
+        this(context, attrs, android.R.attr.preferenceStyle);
+    }
+
+    public ValueSeekBarPreference(Context context) {
+        this(context, null);
+    }
+    
+    @Override
+    protected View onCreateView(ViewGroup parent) {
+    	ViewGroup originalView = (ViewGroup) super.onCreateView(parent);
+    	
+        final LayoutInflater layoutInflater =
+                (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+            
+        ViewGroup newlayout = (ViewGroup) layoutInflater.inflate(R.layout.preference_valueseekbar_extension, null);
+        newlayout.addView(originalView, 0);
+        
+        tvValue = (TextView) newlayout.findViewById(R.id.valueseekbar_preference_value);
+        
+    	return newlayout;
+    }
+
+    @Override
+    protected void onBindView(View view) {
+        super.onBindView(view);
+        SeekBar seekBar = (SeekBar) view.findViewById(R.id.valueseekbar_preference_seekbar);
+        seekBar.setOnSeekBarChangeListener(this);
+        seekBar.setMax((mMax - mMin) / mStep);
+        seekBar.setProgress((mProgress - mMin) / mStep);
+        tvValue.setText(String.format(valueDisplayFormat, mProgress));
+        seekBar.setEnabled(isEnabled());
+    }
+
+    @Override
+    protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
+        setProgress(restoreValue ? getPersistedInt(mProgress)
+                : (Integer) defaultValue);
+    }
+
+    @Override
+    protected Object onGetDefaultValue(TypedArray a, int index) {
+        return a.getInt(index, 0);
+    }
+    
+    public void setStep(int step) {
+        if (step != mStep) {
+            mStep = step;
+            notifyChanged();
+        }
+    }
+    
+    public void setMin(int min) {
+        if (min != mMin) {
+            mMin = min;
+            notifyChanged();
+        }
+    }
+
+    public void setMax(int max) {
+        if (max != mMax) {
+            mMax = max;
+            notifyChanged();
+        }
+    }
+
+    public void setProgress(int progress) {
+        setProgress(progress, true);
+    }
+
+    private void setProgress(int progress, boolean notifyChanged) {
+        if (progress > mMax) {
+            progress = mMax;
+        }
+        if (progress < mMin) {
+            progress = mMin;
+        }
+        if (progress != mProgress) {
+            mProgress = progress;
+            persistInt(progress);
+            if (notifyChanged) {
+                notifyChanged();
+            }
+        }
+    }
+
+    public int getProgress() {
+        return mProgress;
+    }
+
+    /**
+     * Persist the seekBar's progress value if callChangeListener
+     * returns true, otherwise set the seekBar's progress to the stored value
+     */
+    void syncProgress(SeekBar seekBar) {
+        int progress = seekBar.getProgress() * mStep + mMin;
+        if (progress != mProgress) {
+            if (callChangeListener(progress)) {
+                setProgress(progress, false);
+            } else {
+                seekBar.setProgress((mProgress - mMin) / mStep);
+            }
+        }
+    }
+
+    @Override
+    public void onProgressChanged(
+            SeekBar seekBar, int progress, boolean fromUser) {
+        if (fromUser && !mTrackingTouch) {
+            syncProgress(seekBar);
+        }
+        tvValue.setText(String.format(valueDisplayFormat, progress * mStep + mMin));
+    }
+
+    @Override
+    public void onStartTrackingTouch(SeekBar seekBar) {
+        mTrackingTouch = true;
+    }
+
+    @Override
+    public void onStopTrackingTouch(SeekBar seekBar) {
+        mTrackingTouch = false;
+        if (seekBar.getProgress() * mStep + mMin != mProgress) {
+            syncProgress(seekBar);
+        }
+    }
+
+    @Override
+    protected Parcelable onSaveInstanceState() {
+        /*
+         * Suppose a client uses this preference type without persisting. We
+         * must save the instance state so it is able to, for example, survive
+         * orientation changes.
+         */
+
+        final Parcelable superState = super.onSaveInstanceState();
+        if (isPersistent()) {
+            // No need to save instance state since it's persistent
+            return superState;
+        }
+
+        // Save the instance state
+        final SavedState myState = new SavedState(superState);
+        myState.progress = mProgress;
+        myState.step = mStep;
+        myState.min = mMin;
+        myState.max = mMax;
+        return myState;
+    }
+
+    @Override
+    protected void onRestoreInstanceState(Parcelable state) {
+        if (!state.getClass().equals(SavedState.class)) {
+            // Didn't save state for us in onSaveInstanceState
+            super.onRestoreInstanceState(state);
+            return;
+        }
+
+        // Restore the instance state
+        SavedState myState = (SavedState) state;
+        super.onRestoreInstanceState(myState.getSuperState());
+        mProgress = myState.progress;
+        mStep = myState.step;
+        mMin = myState.min;
+        mMax = myState.max;
+        notifyChanged();
+    }
+
+    /**
+     * SavedState, a subclass of {@link BaseSavedState}, will store the state
+     * of MyPreference, a subclass of Preference.
+     * <p>
+     * It is important to always call through to super methods.
+     */
+    private static class SavedState extends BaseSavedState {
+        int progress;
+        int step;
+        int min;
+        int max;
+
+        public SavedState(Parcel source) {
+            super(source);
+
+            // Restore the click counter
+            progress = source.readInt();
+            step = source.readInt();
+            min = source.readInt();
+            max = source.readInt();
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            super.writeToParcel(dest, flags);
+
+            dest.writeInt(progress);
+            dest.writeInt(step);
+            dest.writeInt(min);
+            dest.writeInt(max);
+        }
+
+        public SavedState(Parcelable superState) {
+            super(superState);
+        }
+
+        @SuppressWarnings("unused")
+        public static final Parcelable.Creator<SavedState> CREATOR =
+                new Parcelable.Creator<SavedState>() {
+            public SavedState createFromParcel(Parcel in) {
+                return new SavedState(in);
+            }
+
+            public SavedState[] newArray(int size) {
+                return new SavedState[size];
+            }
+        };
+    }
+}