diff --git a/res/layout/preference_custom_seekbar.xml b/res/layout/preference_custom_seekbar.xml deleted file mode 100644 index 05d1a28..0000000 --- a/res/layout/preference_custom_seekbar.xml +++ /dev/null @@ -1,138 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/org/evolution/settings/preferences/CustomSeekBarPreference.java b/src/org/evolution/settings/preferences/CustomSeekBarPreference.java index 5ae2af1..9a944b7 100644 --- a/src/org/evolution/settings/preferences/CustomSeekBarPreference.java +++ b/src/org/evolution/settings/preferences/CustomSeekBarPreference.java @@ -1,359 +1,376 @@ /* - * Copyright (C) 2016-2023 crDroid Android Project - * SPDX-License-Identifier: Apache-2.0 + * Copyright (C) 2016-2025 crDroid Android 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 org.evolution.settings.preferences; import android.content.Context; import android.content.res.TypedArray; -import android.graphics.PorterDuff; -import androidx.core.content.res.TypedArrayUtils; -import androidx.preference.*; +import android.graphics.drawable.Drawable; import android.util.AttributeSet; -import android.util.Log; import android.view.View; +import android.view.MotionEvent; import android.view.ViewGroup; -import android.view.ViewParent; import android.widget.ImageView; -import android.widget.SeekBar; import android.widget.TextView; -import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.core.content.res.ResourcesCompat; +import androidx.core.view.ViewCompat; +import androidx.preference.Preference; +import androidx.preference.PreferenceViewHolder; import com.android.settings.R; -import com.android.settings.Utils; +import com.android.settingslib.widget.SliderPreference; + +import com.google.android.material.slider.LabelFormatter; +import com.google.android.material.slider.Slider; + +public class CustomSeekBarPreference extends SliderPreference { -public class CustomSeekBarPreference extends Preference implements SeekBar.OnSeekBarChangeListener { - protected final String TAG = getClass().getName(); private static final String SETTINGS_NS = "http://schemas.android.com/apk/res/com.android.settings"; - protected static final String ANDROIDNS = "http://schemas.android.com/apk/res/android"; + private static final String ANDROIDNS = "http://schemas.android.com/apk/res/android"; - protected int mInterval = 1; - protected boolean mShowSign = false; - protected String mUnits = ""; - protected boolean mContinuousUpdates = false; + private boolean mShowSign; + @Nullable + private String mUnits = ""; + @Nullable + private String mDefaultValueText; + private boolean mDefaultValueTextExists; + private boolean mDefaultValueExists; + private int mDefaultValue; - protected int mMinValue = 0; - protected int mMaxValue = 100; - protected boolean mDefaultValueExists = false; - protected int mDefaultValue; - protected boolean mDefaultValueTextExists = false; - protected String mDefaultValueText; + private CharSequence mUserSummary; - protected int mValue; - - protected TextView mValueTextView; - protected ImageView mResetImageView; - protected ImageView mMinusImageView; - protected ImageView mPlusImageView; - protected SeekBar mSeekBar; - - protected boolean mTrackingTouch = false; - protected int mTrackingValue; - - public CustomSeekBarPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { - super(context, attrs, defStyleAttr, defStyleRes); - - TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CustomSeekBarPreference); - try { - mShowSign = a.getBoolean(R.styleable.CustomSeekBarPreference_showSign, mShowSign); - String units = a.getString(R.styleable.CustomSeekBarPreference_units); - if (units != null) - mUnits = " " + units; - mContinuousUpdates = a.getBoolean(R.styleable.CustomSeekBarPreference_continuousUpdates, mContinuousUpdates); - String defaultValueText = a.getString(R.styleable.CustomSeekBarPreference_defaultValueText); - mDefaultValueTextExists = defaultValueText != null && !defaultValueText.isEmpty(); - if (mDefaultValueTextExists) { - mDefaultValueText = defaultValueText; - } - } finally { - a.recycle(); - } - - try { - String newInterval = attrs.getAttributeValue(SETTINGS_NS, "interval"); - if (newInterval != null) - mInterval = Integer.parseInt(newInterval); - } catch (Exception e) { - Log.e(TAG, "Invalid interval value", e); - } - mMinValue = attrs.getAttributeIntValue(SETTINGS_NS, "min", mMinValue); - mMaxValue = attrs.getAttributeIntValue(ANDROIDNS, "max", mMaxValue); - if (mMaxValue < mMinValue) - mMaxValue = mMinValue; - String defaultValue = attrs.getAttributeValue(ANDROIDNS, "defaultValue"); - mDefaultValueExists = defaultValue != null && !defaultValue.isEmpty(); - if (mDefaultValueExists) { - mDefaultValue = getLimitedValue(Integer.parseInt(defaultValue)); - mValue = mDefaultValue; - } else { - mValue = mMinValue; - } - - mSeekBar = new SeekBar(context, attrs); - setLayoutResource(R.layout.preference_custom_seekbar); - } - - public CustomSeekBarPreference(Context context, AttributeSet attrs, int defStyleAttr) { - this(context, attrs, defStyleAttr, 0); - } + private boolean mInUserDrag = false; public CustomSeekBarPreference(Context context, AttributeSet attrs) { - this(context, attrs, TypedArrayUtils.getAttr(context, - androidx.preference.R.attr.seekBarPreferenceStyle, - com.android.internal.R.attr.seekBarPreferenceStyle)); + super(context, attrs); + readLegacyAttrs(context, attrs); + initDefaults(); + mUserSummary = super.getSummary(); + updateSummaryNow(); } public CustomSeekBarPreference(Context context) { - this(context, null); + super(context, null); + initDefaults(); + mUserSummary = super.getSummary(); + updateSummaryNow(); } - @Override - public void onDependencyChanged(Preference dependency, boolean disableDependent) { - super.onDependencyChanged(dependency, disableDependent); - this.setShouldDisableView(true); - if (mSeekBar != null) - mSeekBar.setEnabled(!disableDependent); - if (mResetImageView != null) - mResetImageView.setEnabled(!disableDependent); - if (mPlusImageView != null) - mPlusImageView.setEnabled(!disableDependent); - if (mMinusImageView != null) - mMinusImageView.setEnabled(!disableDependent); + private void initDefaults() { + setShowSliderValue(true); + setHapticFeedbackMode(HAPTIC_FEEDBACK_MODE_ON_TICKS); + setLabelFormater(new LabelFormatter() { + @Override public String getFormattedValue(float value) { + return formatValueForSummary((int) value); + } + }); } - @Override - public void onBindViewHolder(PreferenceViewHolder holder) { - super.onBindViewHolder(holder); - try - { - // move our seekbar to the new view we've been given - ViewParent oldContainer = mSeekBar.getParent(); - ViewGroup newContainer = (ViewGroup) holder.findViewById(R.id.seekbar); - if (oldContainer != newContainer) { - // remove the seekbar from the old view - if (oldContainer != null) { - ((ViewGroup) oldContainer).removeView(mSeekBar); + private void readLegacyAttrs(Context c, AttributeSet attrs) { + if (attrs == null) return; + final TypedArray a = c.obtainStyledAttributes(attrs, R.styleable.CustomSeekBarPreference); + try { + mShowSign = a.getBoolean(R.styleable.CustomSeekBarPreference_showSign, false); + final String units = a.getString(R.styleable.CustomSeekBarPreference_units); + if (units != null) mUnits = units; + + final boolean continuous = a.getBoolean( + R.styleable.CustomSeekBarPreference_continuousUpdates, false); + setUpdatesContinuously(continuous); + + mDefaultValueText = a.getString( + R.styleable.CustomSeekBarPreference_defaultValueText); + mDefaultValueTextExists = mDefaultValueText != null && !mDefaultValueText.isEmpty(); + + String defaultValue = attrs.getAttributeValue(ANDROIDNS, "defaultValue"); + if (defaultValue == null) { + defaultValue = attrs.getAttributeValue(SETTINGS_NS, "defaultValue"); + } + if (defaultValue != null && !defaultValue.isEmpty()) { + try { + mDefaultValue = Integer.parseInt(defaultValue); + mDefaultValueExists = true; + } catch (NumberFormatException ignored) { + mDefaultValueExists = false; } - // remove the existing seekbar (there may not be one) and add ours - newContainer.removeAllViews(); - newContainer.addView(mSeekBar, ViewGroup.LayoutParams.FILL_PARENT, - ViewGroup.LayoutParams.WRAP_CONTENT); } - } catch (Exception ex) { - Log.e(TAG, "Error binding view: " + ex.toString()); + + int interval = attrs.getAttributeIntValue(SETTINGS_NS, "interval", 0); + if (interval == 0) { + interval = attrs.getAttributeIntValue(ANDROIDNS, "interval", 0); + } + if (interval > 0) setSliderIncrement(interval); + + // Guard against improper slider increment + int min = getMin(); + int max = getMax(); + int span = Math.max(0, max - min); + + int step = getSliderIncrement(); + if (step <= 0 || span == 0) { + setSliderIncrement(1); // Always use discrete steps for CustomSeekBarPreference + } else if ((span % step) != 0) { + int gcd = gcd(span, step); + if (gcd <= 0) gcd = 1; + setSliderIncrement(gcd); + } + } catch (Throwable ignored) { + // keep safe defaults + } finally { + a.recycle(); } - - mSeekBar.setMax(getSeekValue(mMaxValue)); - mSeekBar.setProgress(getSeekValue(mValue)); - mSeekBar.setEnabled(isEnabled()); - - mValueTextView = (TextView) holder.findViewById(R.id.value); - mResetImageView = (ImageView) holder.findViewById(R.id.reset); - mMinusImageView = (ImageView) holder.findViewById(R.id.minus); - mPlusImageView = (ImageView) holder.findViewById(R.id.plus); - - updateValueViews(); - - mSeekBar.setOnSeekBarChangeListener(this); - mResetImageView.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - Toast.makeText(getContext(), getContext().getString(R.string.custom_seekbar_default_value_to_set, getTextValue(mDefaultValue)), - Toast.LENGTH_LONG).show(); - } - }); - mResetImageView.setOnLongClickListener(new View.OnLongClickListener() { - @Override - public boolean onLongClick(View view) { - setValue(mDefaultValue, true); - return true; - } - }); - mMinusImageView.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - setValue(mValue - mInterval, true); - } - }); - mMinusImageView.setOnLongClickListener(new View.OnLongClickListener() { - @Override - public boolean onLongClick(View view) { - setValue(mMaxValue - mMinValue > mInterval * 2 && mMaxValue + mMinValue < mValue * 2 ? Math.floorDiv(mMaxValue + mMinValue, 2) : mMinValue, true); - return true; - } - }); - mPlusImageView.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - setValue(mValue + mInterval, true); - } - }); - mPlusImageView.setOnLongClickListener(new View.OnLongClickListener() { - @Override - public boolean onLongClick(View view) { - setValue(mMaxValue - mMinValue > mInterval * 2 && mMaxValue + mMinValue > mValue * 2 ? -1 * Math.floorDiv(-1 * (mMaxValue + mMinValue), 2) : mMaxValue, true); - return true; - } - }); } - protected int getLimitedValue(int v) { - return v < mMinValue ? mMinValue : (v > mMaxValue ? mMaxValue : v); + @Override + public void setSummary(CharSequence summary) { + mUserSummary = summary; + updateSummaryNow(); } - protected int getSeekValue(int v) { - return 0 - Math.floorDiv(mMinValue - v, mInterval); + @Override + public void setValue(int sliderValue) { + super.setValue(sliderValue); + if (!mInUserDrag) updateSummaryNow(); } - protected String getTextValue(int v) { - if (mDefaultValueTextExists && mDefaultValueExists && v == mDefaultValue) { + private void updateSummaryNow() { + CharSequence composed = composeSummary(mUserSummary, getValue()); + super.setSummary(composed); + } + + private String formatValueForSummary(int v) { + if (mDefaultValueExists && mDefaultValueTextExists && v == mDefaultValue) { return mDefaultValueText; } - return (mShowSign && v > 0 ? "+" : "") + String.valueOf(v) + mUnits; + String s = String.valueOf(v); + if (mShowSign && v > 0) s = "+" + s; + if (mUnits != null && !mUnits.isEmpty()) s = s + " " + mUnits; + return s; } - protected void updateValueViews() { - if (mValueTextView != null) { - if (!mTrackingTouch || mContinuousUpdates) { - if (mDefaultValueTextExists && mDefaultValueExists && mValue == mDefaultValue) { - mValueTextView.setText(mDefaultValueText + " (" + - getContext().getString(R.string.custom_seekbar_default_value) + ")"); - } else { - mValueTextView.setText(getContext().getString(R.string.custom_seekbar_value, getTextValue(mValue)) + - (mDefaultValueExists && mValue == mDefaultValue ? " (" + - getContext().getString(R.string.custom_seekbar_default_value) + ")" : "")); - } - } else { - if (mDefaultValueTextExists && mDefaultValueExists && mTrackingValue == mDefaultValue) { - mValueTextView.setText("[" + mDefaultValueText + "]"); - } else { - mValueTextView.setText(getContext().getString(R.string.custom_seekbar_value, "[" + getTextValue(mTrackingValue) + "]")); - } - } - } - if (mResetImageView != null) { - if (!mDefaultValueExists || mValue == mDefaultValue || mTrackingTouch) - mResetImageView.setVisibility(View.INVISIBLE); - else - mResetImageView.setVisibility(View.VISIBLE); - } - if (mMinusImageView != null) { - if (mValue == mMinValue || mTrackingTouch) { - mMinusImageView.setClickable(false); - mMinusImageView.setColorFilter(Utils.getColorAttrDefaultColor(getContext(), android.R.attr.textColorTertiary), - PorterDuff.Mode.SRC_IN); - } else { - mMinusImageView.setClickable(true); - mMinusImageView.clearColorFilter(); - } - } - if (mPlusImageView != null) { - if (mValue == mMaxValue || mTrackingTouch) { - mPlusImageView.setClickable(false); - mPlusImageView.setColorFilter(Utils.getColorAttrDefaultColor(getContext(), android.R.attr.textColorTertiary), - PorterDuff.Mode.SRC_IN); - } else { - mPlusImageView.setClickable(true); - mPlusImageView.clearColorFilter(); - } - } - } - - protected void changeValue(int newValue) { - // for subclasses - } - - @Override - public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { - int newValue = getLimitedValue(mMinValue + (progress * mInterval)); - if (mTrackingTouch && !mContinuousUpdates) { - mTrackingValue = newValue; - updateValueViews(); - } else if (mValue != newValue) { - // change rejected, revert to the previous value - if (!callChangeListener(newValue)) { - mSeekBar.setProgress(getSeekValue(mValue)); - return; - } - // change accepted, store it - changeValue(newValue); - persistInt(newValue); - - mValue = newValue; - updateValueViews(); - } - } - - @Override - public void onStartTrackingTouch(SeekBar seekBar) { - mTrackingValue = mValue; - mTrackingTouch = true; - } - - @Override - public void onStopTrackingTouch(SeekBar seekBar) { - mTrackingTouch = false; - if (!mContinuousUpdates) - onProgressChanged(mSeekBar, getSeekValue(mTrackingValue), false); - notifyChanged(); - } - - @Override - protected void onSetInitialValue(boolean restoreValue, Object defaultValue) { - if (restoreValue) - mValue = getPersistedInt(mValue); + private CharSequence composeSummary(CharSequence userSummary, int v) { + final String valueText = formatValueForSummary(v); + if (userSummary == null || userSummary.length() == 0) return valueText; + return valueText + " \u2022 " + userSummary; } @Override public void setDefaultValue(Object defaultValue) { - if (defaultValue instanceof Integer) - setDefaultValue((Integer) defaultValue, mSeekBar != null); - else - setDefaultValue(defaultValue == null ? (String) null : defaultValue.toString(), mSeekBar != null); - } - - public void setDefaultValue(int newValue, boolean update) { - newValue = getLimitedValue(newValue); - if (!mDefaultValueExists || mDefaultValue != newValue) { + if (defaultValue instanceof Integer) { mDefaultValueExists = true; - mDefaultValue = newValue; - if (update) - updateValueViews(); + mDefaultValue = (Integer) defaultValue; + } + super.setDefaultValue(defaultValue); + updateSummaryNow(); + } + + @Override + public void onBindViewHolder(@NonNull PreferenceViewHolder holder) { + super.onBindViewHolder(holder); + + final TextView summaryView = (TextView) holder.findViewById(android.R.id.summary); + if (summaryView != null) { + summaryView.setText(composeSummary(mUserSummary, getValue())); + } + + final View labelFrame = holder.findViewById( + com.android.settingslib.widget.preference.slider.R.id.label_frame); + final TextView startText = (TextView) holder.findViewById(android.R.id.text1); + final TextView endText = (TextView) holder.findViewById(android.R.id.text2); + + if (labelFrame != null) { + boolean hasStart = startText != null && startText.getText() != null + && startText.getText().length() > 0; + boolean hasEnd = endText != null && endText.getText() != null + && endText.getText().length() > 0; + boolean parentWantsLabels = hasStart || hasEnd; + + labelFrame.setVisibility((parentWantsLabels || mDefaultValueExists) ? View.VISIBLE : View.GONE); + } + + if (endText != null) { + attachResetIcon(endText); + } + + ViewGroup minusFrame = (ViewGroup) holder.findViewById( + com.android.settingslib.widget.preference.slider.R.id.icon_start_frame); + ImageView minusIcon = (ImageView) holder.findViewById( + com.android.settingslib.widget.preference.slider.R.id.icon_start); + + ViewGroup plusFrame = (ViewGroup) holder.findViewById( + com.android.settingslib.widget.preference.slider.R.id.icon_end_frame); + ImageView plusIcon = (ImageView) holder.findViewById( + com.android.settingslib.widget.preference.slider.R.id.icon_end); + + final Slider slider = (Slider) holder.findViewById( + com.android.settingslib.widget.preference.slider.R.id.slider); + + int stepForClicks = Math.max(1, getSliderIncrement()); + + if (minusFrame != null && minusIcon != null) { + minusFrame.setVisibility(View.VISIBLE); + minusIcon.setImageResource(R.drawable.ic_custom_seekbar_minus); + minusFrame.setOnClickListener(v -> { + if (!isEnabled()) return; + int base = slider != null ? Math.round(slider.getValue()) : getValue(); + int newVal = Math.max(getMin(), base - stepForClicks); + applyUserValue(newVal, slider); + updatePlusMinusEnabledStates(holder); + }); + } + + if (plusFrame != null && plusIcon != null) { + plusFrame.setVisibility(View.VISIBLE); + plusIcon.setImageResource(R.drawable.ic_custom_seekbar_plus); + plusFrame.setOnClickListener(v -> { + if (!isEnabled()) return; + int base = slider != null ? Math.round(slider.getValue()) : getValue(); + int newVal = Math.min(getMax(), base + stepForClicks); + applyUserValue(newVal, slider); + updatePlusMinusEnabledStates(holder); + }); + } + + updatePlusMinusEnabledStates(holder); + + if (slider != null && summaryView != null) { + slider.addOnChangeListener((s, value, fromUser) -> { + if (fromUser) { + summaryView.setText(composeSummary(mUserSummary, (int) value)); + updatePlusMinusEnabledStates(holder); + } + }); + slider.addOnSliderTouchListener(new Slider.OnSliderTouchListener() { + @Override + public void onStartTrackingTouch(@NonNull Slider s) { + mInUserDrag = true; + } + + @Override + public void onStopTrackingTouch(@NonNull Slider s) { + mInUserDrag = false; + applyUserValue(Math.round(s.getValue()), s); + updatePlusMinusEnabledStates(holder); + } + }); } } - public void setDefaultValue(String newValue, boolean update) { - if (mDefaultValueExists && (newValue == null || newValue.isEmpty())) { - mDefaultValueExists = false; - if (update) - updateValueViews(); - } else if (newValue != null && !newValue.isEmpty()) { - setDefaultValue(Integer.parseInt(newValue), update); + @Override + public void onDependencyChanged(@NonNull Preference dependency, boolean disableDependent) { + super.onDependencyChanged(dependency, disableDependent); + notifyChanged(); + } + + private void applyUserValue(int newVal, @Nullable Slider slider) { + if (newVal == getValue()) return; + if (!callChangeListener(newVal)) { + if (slider != null) slider.setValue(getValue()); + return; + } + setValue(newVal); + updateSummaryNow(); + notifyChanged(); + } + + private static int gcd(int a, int b) { + a = Math.abs(a); b = Math.abs(b); + if (a == 0) return b; + if (b == 0) return a; + while (b != 0) { + int t = b; b = a % b; a = t; + } + return a; + } + + private void updatePlusMinusEnabledStates(PreferenceViewHolder holder) { + View minusFrame = holder.findViewById( + com.android.settingslib.widget.preference.slider.R.id.icon_start_frame); + ImageView minusIcon = (ImageView) holder.findViewById( + com.android.settingslib.widget.preference.slider.R.id.icon_start); + View plusFrame = holder.findViewById( + com.android.settingslib.widget.preference.slider.R.id.icon_end_frame); + ImageView plusIcon = (ImageView) holder.findViewById( + com.android.settingslib.widget.preference.slider.R.id.icon_end); + boolean enabled = isEnabled(); + int value = getValue(); + + if (minusFrame != null && minusIcon != null) { + int min = getMin(); + minusFrame.setEnabled(enabled && (value > min)); + minusIcon.setEnabled(enabled && (value > min)); + } + if (plusFrame != null && plusIcon != null) { + int max = getMax(); + plusFrame.setEnabled(enabled && (value < max)); + plusIcon.setEnabled(enabled && (value < max)); } } - public void setValue(int newValue) { - mValue = getLimitedValue(newValue); - if (mSeekBar != null) mSeekBar.setProgress(getSeekValue(mValue)); + private void attachResetIcon(TextView tv) { + if (!mDefaultValueExists) { + tv.setCompoundDrawablesRelativeWithIntrinsicBounds(null, null, null, null); + tv.setOnTouchListener(null); + tv.setClickable(false); + return; + } + + final Drawable icon = ResourcesCompat.getDrawable( + tv.getResources(), R.drawable.ic_custom_seekbar_reset, tv.getContext().getTheme()); + if (icon == null) return; + + tv.setCompoundDrawablesRelativeWithIntrinsicBounds(null, null, icon, null); + tv.setCompoundDrawablePadding(dp(tv, 6)); + tv.setClickable(isEnabled()); + tv.setFocusable(isEnabled()); + + final int tapSlop = dp(tv, 8); + + tv.setOnTouchListener((v, ev) -> { + if (!isEnabled() || ev.getAction() != MotionEvent.ACTION_UP) return false; + + final boolean isRtl = ViewCompat.getLayoutDirection(tv) == ViewCompat.LAYOUT_DIRECTION_RTL; + final Drawable[] drs = tv.getCompoundDrawablesRelative(); + final Drawable end = drs[2]; + if (end == null) return false; + + final int iconW = end.getIntrinsicWidth(); + final int x = (int) ev.getX(); + + if (!isRtl) { + final int left = tv.getWidth() - ViewCompat.getPaddingEnd(tv) - iconW - tapSlop; + if (x >= left) { performReset(); return true; } + } else { + final int right = ViewCompat.getPaddingStart(tv) + iconW + tapSlop; + if (x <= right) { performReset(); return true; } + } + return false; + }); } - public void setValue(int newValue, boolean update) { - newValue = getLimitedValue(newValue); - if (mValue != newValue) { - if (update) - mSeekBar.setProgress(getSeekValue(newValue)); - else - mValue = newValue; + private void performReset() { + if (mDefaultValueExists) { + applyUserValue(mDefaultValue, null); } } - public int getValue() { - return mValue; - } - - public void refresh(int newValue) { - // this will ... - setValue(newValue, mSeekBar != null); + private static int dp(TextView v, int dp) { + return Math.round(dp * v.getResources().getDisplayMetrics().density); } } diff --git a/src/org/evolution/settings/preferences/GlobalSettingSeekBarPreference.java b/src/org/evolution/settings/preferences/GlobalSettingSeekBarPreference.java index 77e6db3..7e428f9 100644 --- a/src/org/evolution/settings/preferences/GlobalSettingSeekBarPreference.java +++ b/src/org/evolution/settings/preferences/GlobalSettingSeekBarPreference.java @@ -1,6 +1,17 @@ /* - * Copyright (C) 2016-2019 crDroid Android Project - * SPDX-License-Identifier: Apache-2.0 + * Copyright (C) 2016-2025 crDroid Android 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 org.evolution.settings.preferences; @@ -10,11 +21,6 @@ import android.util.AttributeSet; public class GlobalSettingSeekBarPreference extends CustomSeekBarPreference { - public GlobalSettingSeekBarPreference(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - setPreferenceDataStore(new GlobalSettingsStore(context.getContentResolver())); - } - public GlobalSettingSeekBarPreference(Context context, AttributeSet attrs) { super(context, attrs); setPreferenceDataStore(new GlobalSettingsStore(context.getContentResolver())); diff --git a/src/org/evolution/settings/preferences/LineageSecureSettingSeekBarPreference.java b/src/org/evolution/settings/preferences/LineageSecureSettingSeekBarPreference.java index 8166f94..f3bd08c 100644 --- a/src/org/evolution/settings/preferences/LineageSecureSettingSeekBarPreference.java +++ b/src/org/evolution/settings/preferences/LineageSecureSettingSeekBarPreference.java @@ -1,6 +1,17 @@ /* - * Copyright (C) 2016-2022 crDroid Android Project - * SPDX-License-Identifier: Apache-2.0 + * Copyright (C) 2016-2025 crDroid Android 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 org.evolution.settings.preferences; @@ -10,11 +21,6 @@ import android.util.AttributeSet; public class LineageSecureSettingSeekBarPreference extends CustomSeekBarPreference { - public LineageSecureSettingSeekBarPreference(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - setPreferenceDataStore(new LineageSecureSettingsStore(context.getContentResolver())); - } - public LineageSecureSettingSeekBarPreference(Context context, AttributeSet attrs) { super(context, attrs); setPreferenceDataStore(new LineageSecureSettingsStore(context.getContentResolver())); diff --git a/src/org/evolution/settings/preferences/LineageSystemSettingSeekBarPreference.java b/src/org/evolution/settings/preferences/LineageSystemSettingSeekBarPreference.java index 35249d0..83102c5 100644 --- a/src/org/evolution/settings/preferences/LineageSystemSettingSeekBarPreference.java +++ b/src/org/evolution/settings/preferences/LineageSystemSettingSeekBarPreference.java @@ -1,6 +1,17 @@ /* - * Copyright (C) 2016-2019 crDroid Android Project - * SPDX-License-Identifier: Apache-2.0 + * Copyright (C) 2016-2025 crDroid Android 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 org.evolution.settings.preferences; @@ -10,11 +21,6 @@ import android.util.AttributeSet; public class LineageSystemSettingSeekBarPreference extends CustomSeekBarPreference { - public LineageSystemSettingSeekBarPreference(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - setPreferenceDataStore(new LineageSystemSettingsStore(context.getContentResolver())); - } - public LineageSystemSettingSeekBarPreference(Context context, AttributeSet attrs) { super(context, attrs); setPreferenceDataStore(new LineageSystemSettingsStore(context.getContentResolver())); diff --git a/src/org/evolution/settings/preferences/SecureSettingSeekBarPreference.java b/src/org/evolution/settings/preferences/SecureSettingSeekBarPreference.java index 4d53c3f..211897d 100644 --- a/src/org/evolution/settings/preferences/SecureSettingSeekBarPreference.java +++ b/src/org/evolution/settings/preferences/SecureSettingSeekBarPreference.java @@ -1,6 +1,17 @@ /* - * Copyright (C) 2016-2019 crDroid Android Project - * SPDX-License-Identifier: Apache-2.0 + * Copyright (C) 2016-2025 crDroid Android 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 org.evolution.settings.preferences; @@ -10,11 +21,6 @@ import android.util.AttributeSet; public class SecureSettingSeekBarPreference extends CustomSeekBarPreference { - public SecureSettingSeekBarPreference(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - setPreferenceDataStore(new SecureSettingsStore(context.getContentResolver())); - } - public SecureSettingSeekBarPreference(Context context, AttributeSet attrs) { super(context, attrs); setPreferenceDataStore(new SecureSettingsStore(context.getContentResolver())); diff --git a/src/org/evolution/settings/preferences/SystemSettingSeekBarPreference.java b/src/org/evolution/settings/preferences/SystemSettingSeekBarPreference.java index a3a6d55..598d7f9 100644 --- a/src/org/evolution/settings/preferences/SystemSettingSeekBarPreference.java +++ b/src/org/evolution/settings/preferences/SystemSettingSeekBarPreference.java @@ -1,6 +1,17 @@ /* - * Copyright (C) 2018-2019 crDroid Android Project - * SPDX-License-Identifier: Apache-2.0 + * Copyright (C) 2016-2025 crDroid Android 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 org.evolution.settings.preferences; @@ -10,11 +21,6 @@ import android.util.AttributeSet; public class SystemSettingSeekBarPreference extends CustomSeekBarPreference { - public SystemSettingSeekBarPreference(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - setPreferenceDataStore(new SystemSettingsStore(context.getContentResolver())); - } - public SystemSettingSeekBarPreference(Context context, AttributeSet attrs) { super(context, attrs); setPreferenceDataStore(new SystemSettingsStore(context.getContentResolver()));