Permalink
Browse files

Settings: Use seekbar to allow setting arbitrary animation values

@dwitherell updated to incorporate support friendly internal approach
KreAch3R - AnimationScalePreference: better max/default/digits values

Change-Id: Icd4678651fc6a6b48b66d167fec5d4c663cb6e08
  • Loading branch information...
cyanogen authored and xlxfoxxlx committed Oct 25, 2016
1 parent 5b125db commit bee01709309045bb96c424a7b46be082e6002097
@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2014 The CyanogenMod 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.
-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:settings="http://schemas.android.com/apk/res/com.android.settings"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="12dp">
<!-- Static height enough to accommodate the text views in their biggest possible size,
without having the dialog resize itself at any point. -->
<LinearLayout android:id="@+id/container"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="64dp"
android:gravity="center_horizontal|center_vertical">
<TextView android:id="@+id/scale"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:textAppearanceLarge" />
</LinearLayout>
<com.android.settings.IntervalSeekBar android:id="@+id/scale_seekbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp"
android:layout_below="@+id/container"
settings:minI="0"
settings:maxI="3"
settings:defaultValue="0.75"
settings:digits="2" />
</RelativeLayout>
View
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2016 Krexus
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.
-->
<resources>
<declare-styleable name="IntervalSeekBar">
<attr name="minI" format="float" />
<attr name="maxI" format="float" />
<attr name="defaultValuePure" format="float" />
<attr name="digits" format="integer" />
</declare-styleable>
</resources>
@@ -251,19 +251,19 @@
android:title="@string/force_rtl_layout_all_locales"
android:summary="@string/force_rtl_layout_all_locales_summary"/>
<ListPreference
<com.android.settings.AnimationScalePreference
android:key="window_animation_scale"
android:title="@string/window_animation_scale_title"
android:entries="@array/window_animation_scale_entries_aosp"
android:entryValues="@array/window_animation_scale_values_aosp" />
<ListPreference
<com.android.settings.AnimationScalePreference
android:key="transition_animation_scale"
android:title="@string/transition_animation_scale_title"
android:entries="@array/transition_animation_scale_entries_aosp"
android:entryValues="@array/transition_animation_scale_values_aosp" />
<ListPreference
<com.android.settings.AnimationScalePreference
android:key="animator_duration_scale"
android:title="@string/animator_duration_scale_title"
android:entries="@array/animator_duration_scale_entries_aosp"
@@ -0,0 +1,88 @@
/*
* Copyright (C) 2014 The CyanogenMod 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 com.android.settings;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.SeekBar;
import android.widget.TextView;
public class AnimationScalePreference extends CustomDialogPreference
implements SeekBar.OnSeekBarChangeListener {
private TextView mScaleText;
private IntervalSeekBar mSeekBar;
private float mScale = 1.0f;
public AnimationScalePreference(Context context, AttributeSet attrs) {
super(context, attrs);
setPositiveButtonText(android.R.string.ok);
setNegativeButtonText(android.R.string.cancel);
setDialogLayoutResource(R.layout.preference_dialog_animation_scale);
}
@Override
protected void onBindDialogView(View view) {
super.onBindDialogView(view);
mScaleText = (TextView) view.findViewById(R.id.scale);
mScaleText.setText(String.valueOf(mScale) + "x");
mSeekBar = (IntervalSeekBar) view.findViewById(R.id.scale_seekbar);
mSeekBar.setProgressFloat(mScale);
mSeekBar.setOnSeekBarChangeListener(this);
}
public void setScale(float scale) {
mScale = scale;
setSummary(String.valueOf(scale) + "x");
}
@Override
protected void onDialogClosed(boolean positiveResult) {
if (positiveResult) {
callChangeListener(mSeekBar.getProgressFloat());
}
}
@Override
protected void onClick() {
// Ignore this until an explicit call to click()
}
public void click() {
super.onClick();
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
mScaleText.setText(String.valueOf(mSeekBar.getProgressFloat()) + "x");
}
// Not used
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
}
@@ -65,6 +65,7 @@
import android.support.v7.preference.ListPreference;
import android.support.v7.preference.Preference;
import android.support.v7.preference.Preference.OnPreferenceChangeListener;
import android.support.v7.preference.Preference.OnPreferenceClickListener;
import android.support.v7.preference.PreferenceGroup;
import android.support.v7.preference.PreferenceScreen;
import android.telephony.TelephonyManager;
@@ -105,7 +106,8 @@
*/
public class DevelopmentSettings extends RestrictedSettingsFragment
implements DialogInterface.OnClickListener, DialogInterface.OnDismissListener,
OnPreferenceChangeListener, SwitchBar.OnSwitchChangeListener, Indexable {
OnPreferenceChangeListener, SwitchBar.OnSwitchChangeListener, Indexable,
OnPreferenceClickListener {
private static final String TAG = "DevelopmentSettings";
/**
@@ -301,9 +303,9 @@
private ListPreference mUsbConfiguration;
private ListPreference mTrackFrameTime;
private ListPreference mShowNonRectClip;
private ListPreference mWindowAnimationScale;
private ListPreference mTransitionAnimationScale;
private ListPreference mAnimatorDurationScale;
private AnimationScalePreference mWindowAnimationScale;
private AnimationScalePreference mTransitionAnimationScale;
private AnimationScalePreference mAnimatorDurationScale;
private ListPreference mOverlayDisplayDevices;
private SwitchPreference mWebViewMultiprocess;
@@ -474,14 +476,15 @@ public void onCreate(Bundle icicle) {
mWebViewMultiprocess = findAndInitSwitchPref(WEBVIEW_MULTIPROCESS_KEY);
mBluetoothDisableAbsVolume = findAndInitSwitchPref(BLUETOOTH_DISABLE_ABSOLUTE_VOLUME_KEY);
mWindowAnimationScale = addListPreference(WINDOW_ANIMATION_SCALE_KEY);
mTransitionAnimationScale = addListPreference(TRANSITION_ANIMATION_SCALE_KEY);
mAnimatorDurationScale = addListPreference(ANIMATOR_DURATION_SCALE_KEY);
mOverlayDisplayDevices = addListPreference(OVERLAY_DISPLAY_DEVICES_KEY);
mSimulateColorSpace = addListPreference(SIMULATE_COLOR_SPACE);
mUSBAudio = findAndInitSwitchPref(USB_AUDIO_KEY);
mForceResizable = findAndInitSwitchPref(FORCE_RESIZABLE_KEY);
mWindowAnimationScale = findAndInitAnimationScalePreference(WINDOW_ANIMATION_SCALE_KEY);
mTransitionAnimationScale = findAndInitAnimationScalePreference(TRANSITION_ANIMATION_SCALE_KEY);
mAnimatorDurationScale = findAndInitAnimationScalePreference(ANIMATOR_DURATION_SCALE_KEY);
mImmediatelyDestroyActivities = (SwitchPreference) findPreference(
IMMEDIATELY_DESTROY_ACTIVITIES_KEY);
mAllPrefs.add(mImmediatelyDestroyActivities);
@@ -555,6 +558,14 @@ private void disableForUser(Preference pref) {
}
}
private AnimationScalePreference findAndInitAnimationScalePreference(String key) {
AnimationScalePreference pref = (AnimationScalePreference) findPreference(key);
pref.setOnPreferenceChangeListener(this);
pref.setOnPreferenceClickListener(this);
mAllPrefs.add(pref);
return pref;
}
private SwitchPreference findAndInitSwitchPref(String key) {
SwitchPreference pref = (SwitchPreference) findPreference(key);
if (pref == null) {
@@ -1801,23 +1812,13 @@ private void updateImmediatelyDestroyActivitiesOptions() {
getActivity().getContentResolver(), Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0);
}
private void updateAnimationScaleValue(int which, ListPreference pref) {
private void updateAnimationScaleValue(int which, AnimationScalePreference pref) {
try {
float scale = mWindowManager.getAnimationScale(which);
if (scale != 1) {
if (scale != 0.75) {
mHaveDebugSettings = true;
}
CharSequence[] values = pref.getEntryValues();
for (int i=0; i<values.length; i++) {
float val = Float.parseFloat(values[i].toString());
if (scale <= val) {
pref.setValueIndex(i);
pref.setSummary(pref.getEntries()[i]);
return;
}
}
pref.setValueIndex(values.length-1);
pref.setSummary(pref.getEntries()[0]);
pref.setScale(scale);
} catch (RemoteException e) {
}
}
@@ -1828,7 +1829,8 @@ private void updateAnimationScaleOptions() {
updateAnimationScaleValue(2, mAnimatorDurationScale);
}
private void writeAnimationScaleOption(int which, ListPreference pref, Object newValue) {
private void writeAnimationScaleOption(int which, AnimationScalePreference pref,
Object newValue) {
try {
float scale = newValue != null ? Float.parseFloat(newValue.toString()) : 0.75f;
mWindowManager.setAnimationScale(which, scale);
@@ -1989,6 +1991,16 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) {
}
}
@Override
public boolean onPreferenceClick(Preference preference) {
if (preference == mWindowAnimationScale ||
preference == mTransitionAnimationScale ||
preference == mAnimatorDurationScale) {
((AnimationScalePreference) preference).click();
}
return false;
}
@Override
public boolean onPreferenceTreeClick(Preference preference) {
if (Utils.isMonkeyRunning()) {
@@ -0,0 +1,87 @@
package com.android.settings;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.SeekBar;
/**
* Custom SeekBar that allows setting both a minimum and maximum value.
* This also handles floating point values (to 2 decimal places) through
* integer conversions.
*/
public class IntervalSeekBar extends SeekBar {
private float mMin;
private float mMax;
private float mDefault;
private float mMultiplier;
public IntervalSeekBar(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray seekBarType = context.obtainStyledAttributes(attrs,
R.styleable.IntervalSeekBar, 0, 0);
mMax = seekBarType.getFloat(R.styleable.IntervalSeekBar_maxI, 1.5f);
mMin = seekBarType.getFloat(R.styleable.IntervalSeekBar_minI, 0.5f);
mDefault = seekBarType.getFloat(R.styleable.IntervalSeekBar_defaultValuePure, 1.0f);
int digits = seekBarType.getInt(R.styleable.IntervalSeekBar_digits, 0);
mMultiplier = (float) Math.pow(10, digits);
if (mMin > mMax) {
float temp = mMax;
mMax = mMin;
mMin = temp;
}
setMax(convertFloatToProgress(mMax));
setProgressFloat(mDefault);
seekBarType.recycle();
}
/*
* Converts from SeekBar units (which the SeekBar uses), to scale units
* (which are saved).
* This operation is the inverse of setFontScaling.
*/
public float getProgressFloat() {
return (getProgress() / mMultiplier) + mMin;
}
/*
* Converts from scale units (which are saved), to SeekBar units
* (which the SeekBar uses). This also sets the SeekBar progress.
* This operation is the inverse of getProgressFloat.
*/
public void setProgressFloat(float progress) {
setProgress(convertFloatToProgress(progress));
}
private int convertFloatToProgress(float value) {
return Math.round((value - mMin) * mMultiplier);
}
public float getMinimum() {
return mMin;
}
public float getMaximum() {
return mMax;
}
public float getDefault() {
return mDefault;
}
public void setMaximum(float max) {
mMax = max;
setMax(convertFloatToProgress(mMax));
}
public void setMinimum(float min) {
mMin = min;
}
}

0 comments on commit bee0170

Please sign in to comment.