diff --git a/app/src/main/java/com/drdisagree/colorblendr/ui/fragments/ThemeFragment.java b/app/src/main/java/com/drdisagree/colorblendr/ui/fragments/ThemeFragment.java index 97ba0b1c..da601148 100644 --- a/app/src/main/java/com/drdisagree/colorblendr/ui/fragments/ThemeFragment.java +++ b/app/src/main/java/com/drdisagree/colorblendr/ui/fragments/ThemeFragment.java @@ -15,6 +15,7 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.SeekBar; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -28,7 +29,6 @@ import com.drdisagree.colorblendr.utils.MiscUtil; import com.drdisagree.colorblendr.utils.OverlayManager; import com.drdisagree.colorblendr.utils.SystemUtil; -import com.google.android.material.slider.Slider; import java.util.ArrayList; @@ -54,21 +54,22 @@ public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, binding.colorNeutral2.title.setText(R.string.neutral_2); // Monet primary accent saturation - binding.accentSaturation.setSliderValue(RPrefs.getInt(MONET_ACCENT_SATURATION, 100)); - - binding.accentSaturation.setOnSliderChangeListener((slider, value, fromUser) -> { - monetAccentSaturation[0] = (int) value; - updatePreviewColors(); - }); + binding.accentSaturation.setSeekbarProgress(RPrefs.getInt(MONET_ACCENT_SATURATION, 100)); + binding.accentSaturation.setOnSeekbarChangeListener(new SeekBar.OnSeekBarChangeListener() { + @Override + public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { + binding.accentSaturation.setSelectedProgress(); + monetAccentSaturation[0] = progress; + updatePreviewColors(); + } - binding.accentSaturation.setOnSliderTouchListener(new Slider.OnSliderTouchListener() { @Override - public void onStartTrackingTouch(@NonNull Slider slider) { + public void onStartTrackingTouch(SeekBar seekBar) { } @Override - public void onStopTrackingTouch(@NonNull Slider slider) { - monetAccentSaturation[0] = (int) slider.getValue(); + public void onStopTrackingTouch(SeekBar seekBar) { + monetAccentSaturation[0] = seekBar.getProgress(); RPrefs.putInt(MONET_ACCENT_SATURATION, monetAccentSaturation[0]); RPrefs.putLong(MONET_LAST_UPDATED, System.currentTimeMillis()); new Handler(Looper.getMainLooper()).postDelayed(() -> { @@ -96,21 +97,22 @@ public void onStopTrackingTouch(@NonNull Slider slider) { }); // Monet background saturation - binding.backgroundSaturation.setSliderValue(RPrefs.getInt(MONET_BACKGROUND_SATURATION, 100)); - - binding.backgroundSaturation.setOnSliderChangeListener((slider, value, fromUser) -> { - monetBackgroundSaturation[0] = (int) value; - updatePreviewColors(); - }); + binding.backgroundSaturation.setSeekbarProgress(RPrefs.getInt(MONET_BACKGROUND_SATURATION, 100)); + binding.backgroundSaturation.setOnSeekbarChangeListener(new SeekBar.OnSeekBarChangeListener() { + @Override + public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { + binding.backgroundSaturation.setSelectedProgress(); + monetBackgroundSaturation[0] = progress; + updatePreviewColors(); + } - binding.backgroundSaturation.setOnSliderTouchListener(new Slider.OnSliderTouchListener() { @Override - public void onStartTrackingTouch(@NonNull Slider slider) { + public void onStartTrackingTouch(SeekBar seekBar) { } @Override - public void onStopTrackingTouch(@NonNull Slider slider) { - monetBackgroundSaturation[0] = (int) slider.getValue(); + public void onStopTrackingTouch(@NonNull SeekBar seekBar) { + monetBackgroundSaturation[0] = seekBar.getProgress(); RPrefs.putInt(MONET_BACKGROUND_SATURATION, monetBackgroundSaturation[0]); RPrefs.putLong(MONET_LAST_UPDATED, System.currentTimeMillis()); new Handler(Looper.getMainLooper()).postDelayed(() -> { @@ -138,21 +140,22 @@ public void onStopTrackingTouch(@NonNull Slider slider) { }); // Monet background lightness - binding.backgroundLightness.setSliderValue(RPrefs.getInt(MONET_BACKGROUND_LIGHTNESS, 100)); - - binding.backgroundLightness.setOnSliderChangeListener((slider, value, fromUser) -> { - monetBackgroundLightness[0] = (int) value; - updatePreviewColors(); - }); + binding.backgroundLightness.setSeekbarProgress(RPrefs.getInt(MONET_BACKGROUND_LIGHTNESS, 100)); + binding.backgroundLightness.setOnSeekbarChangeListener(new SeekBar.OnSeekBarChangeListener() { + @Override + public void onProgressChanged(@NonNull SeekBar seekBar, int progress, boolean fromUser) { + binding.backgroundLightness.setSelectedProgress(); + monetBackgroundLightness[0] = progress; + updatePreviewColors(); + } - binding.backgroundLightness.setOnSliderTouchListener(new Slider.OnSliderTouchListener() { @Override - public void onStartTrackingTouch(@NonNull Slider slider) { + public void onStartTrackingTouch(@NonNull SeekBar seekBar) { } @Override - public void onStopTrackingTouch(@NonNull Slider slider) { - monetBackgroundLightness[0] = (int) slider.getValue(); + public void onStopTrackingTouch(@NonNull SeekBar seekBar) { + monetBackgroundLightness[0] = seekBar.getProgress(); RPrefs.putInt(MONET_BACKGROUND_LIGHTNESS, monetBackgroundLightness[0]); RPrefs.putLong(MONET_LAST_UPDATED, System.currentTimeMillis()); new Handler(Looper.getMainLooper()).postDelayed(() -> { diff --git a/app/src/main/java/com/drdisagree/colorblendr/ui/widgets/SliderWidget.java b/app/src/main/java/com/drdisagree/colorblendr/ui/widgets/SeekbarWidget.java similarity index 51% rename from app/src/main/java/com/drdisagree/colorblendr/ui/widgets/SliderWidget.java rename to app/src/main/java/com/drdisagree/colorblendr/ui/widgets/SeekbarWidget.java index a7c50277..8ed46d36 100644 --- a/app/src/main/java/com/drdisagree/colorblendr/ui/widgets/SliderWidget.java +++ b/app/src/main/java/com/drdisagree/colorblendr/ui/widgets/SeekbarWidget.java @@ -7,25 +7,23 @@ import android.util.AttributeSet; import android.view.View; import android.widget.ImageView; -import android.widget.LinearLayout; import android.widget.RelativeLayout; +import android.widget.SeekBar; import android.widget.TextView; - -import androidx.annotation.NonNull; +import android.widget.Toast; import com.drdisagree.colorblendr.R; import com.google.android.material.card.MaterialCardView; -import com.google.android.material.slider.Slider; import java.text.DecimalFormat; import java.util.Objects; -public class SliderWidget extends RelativeLayout { +public class SeekbarWidget extends RelativeLayout { private MaterialCardView container; private TextView titleTextView; private TextView summaryTextView; - private Slider materialSlider; + private SeekBar seekBar; private ImageView resetIcon; private String valueFormat; private int defaultValue; @@ -33,42 +31,40 @@ public class SliderWidget extends RelativeLayout { private boolean isDecimalFormat = false; private String decimalFormat = "#.#"; private OnLongClickListener resetClickListener; - private Slider.OnSliderTouchListener onSliderTouchListener; - public SliderWidget(Context context) { + public SeekbarWidget(Context context) { super(context); init(context, null); } - public SliderWidget(Context context, AttributeSet attrs) { + public SeekbarWidget(Context context, AttributeSet attrs) { super(context, attrs); init(context, attrs); } - public SliderWidget(Context context, AttributeSet attrs, int defStyleAttr) { + public SeekbarWidget(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(context, attrs); } private void init(Context context, AttributeSet attrs) { - inflate(context, R.layout.view_widget_slider, this); + inflate(context, R.layout.view_widget_seekbar, this); initializeId(); - TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.SliderWidget); - valueFormat = typedArray.getString(R.styleable.SliderWidget_valueFormat); - defaultValue = typedArray.getInt(R.styleable.SliderWidget_sliderDefaultValue, Integer.MAX_VALUE); - setTitle(typedArray.getString(R.styleable.SliderWidget_titleText)); - setSliderValueFrom(typedArray.getInt(R.styleable.SliderWidget_sliderValueFrom, 0)); - setSliderValueTo(typedArray.getInt(R.styleable.SliderWidget_sliderValueTo, 100)); - setSliderStepSize(typedArray.getInt(R.styleable.SliderWidget_sliderStepSize, 1)); - setSliderValue(typedArray.getInt( - R.styleable.SliderWidget_sliderValue, - typedArray.getInt(R.styleable.SliderWidget_sliderDefaultValue, 50) + TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.SeekbarWidget); + valueFormat = typedArray.getString(R.styleable.SeekbarWidget_progressFormat); + defaultValue = typedArray.getInt(R.styleable.SeekbarWidget_seekbarDefaultProgress, Integer.MAX_VALUE); + setTitle(typedArray.getString(R.styleable.SeekbarWidget_titleText)); + setSeekbarMinProgress(typedArray.getInt(R.styleable.SeekbarWidget_seekbarMinProgress, 0)); + setSeekbarMaxProgress(typedArray.getInt(R.styleable.SeekbarWidget_seekbarMaxProgress, 100)); + setSeekbarProgress(typedArray.getInt( + R.styleable.SeekbarWidget_seekbarProgress, + typedArray.getInt(R.styleable.SeekbarWidget_seekbarDefaultProgress, 50) )); - isDecimalFormat = typedArray.getBoolean(R.styleable.SliderWidget_isDecimalFormat, false); - decimalFormat = typedArray.getString(R.styleable.SliderWidget_decimalFormat); - outputScale = typedArray.getFloat(R.styleable.SliderWidget_outputScale, 1f); + isDecimalFormat = typedArray.getBoolean(R.styleable.SeekbarWidget_isDecimalFormat, false); + decimalFormat = typedArray.getString(R.styleable.SeekbarWidget_decimalFormat); + outputScale = typedArray.getFloat(R.styleable.SeekbarWidget_outputScale, 1f); typedArray.recycle(); if (valueFormat == null) { @@ -79,9 +75,9 @@ private void init(Context context, AttributeSet attrs) { decimalFormat = "#.#"; } - setSelectedText(); + setSelectedProgress(); handleResetVisibility(); - setOnSliderTouchListener(null); + setOnSeekbarChangeListener(null); setResetClickListener(null); } @@ -93,109 +89,84 @@ public void setTitle(String title) { titleTextView.setText(title); } - public void setSelectedText() { + public void setSelectedProgress() { summaryTextView.setText( (valueFormat.isBlank() || valueFormat.isEmpty() ? getContext().getString( R.string.opt_selected1, String.valueOf( !isDecimalFormat ? - (int) (materialSlider.getValue() / outputScale) : + (int) (seekBar.getProgress() / outputScale) : new DecimalFormat(decimalFormat) - .format(materialSlider.getValue() / outputScale) + .format(seekBar.getProgress() / outputScale) ) ) : getContext().getString( R.string.opt_selected2, !isDecimalFormat ? - String.valueOf((int) materialSlider.getValue()) : + String.valueOf((int) seekBar.getProgress()) : new DecimalFormat(decimalFormat) - .format(materialSlider.getValue() / outputScale), + .format(seekBar.getProgress() / outputScale), valueFormat ) ) ); } - public void setSliderStepSize(int value) { - materialSlider.setStepSize(value); - } - - public int getSliderValue() { - return (int) materialSlider.getValue(); + public int getSeekbarProgress() { + return (int) seekBar.getProgress(); } - public void setSliderValue(int value) { - materialSlider.setValue(value); - setSelectedText(); + public void setSeekbarProgress(int value) { + seekBar.setProgress(value); + setSelectedProgress(); handleResetVisibility(); } - public void setSliderValueFrom(int value) { - materialSlider.setValueFrom(value); + public void setSeekbarMinProgress(int value) { + seekBar.setMin(value); } - public void setSliderValueTo(int value) { - materialSlider.setValueTo(value); + public void setSeekbarMaxProgress(int value) { + seekBar.setMax(value); } public void setIsDecimalFormat(boolean isDecimalFormat) { this.isDecimalFormat = isDecimalFormat; - setSelectedText(); + setSelectedProgress(); } public void setDecimalFormat(String decimalFormat) { this.decimalFormat = Objects.requireNonNullElse(decimalFormat, "#.#"); - setSelectedText(); + setSelectedProgress(); } public void setOutputScale(float scale) { this.outputScale = scale; - setSelectedText(); - } - - public void setOnSliderTouchListener(Slider.OnSliderTouchListener listener) { - onSliderTouchListener = listener; - - materialSlider.addOnSliderTouchListener(new Slider.OnSliderTouchListener() { - @Override - public void onStartTrackingTouch(@NonNull Slider slider) { - notifyOnSliderTouchStarted(slider); - } - - @Override - public void onStopTrackingTouch(@NonNull Slider slider) { - setSelectedText(); - handleResetVisibility(); - notifyOnSliderTouchStopped(slider); - } - }); - - materialSlider.setLabelFormatter(value -> (valueFormat.isBlank() || valueFormat.isEmpty() ? - (!isDecimalFormat ? - (int) (materialSlider.getValue() / outputScale) : - new DecimalFormat(decimalFormat) - .format(materialSlider.getValue() / outputScale)) + valueFormat : - (!isDecimalFormat ? - String.valueOf((int) materialSlider.getValue()) : - new DecimalFormat(decimalFormat) - .format(materialSlider.getValue() / outputScale)) + valueFormat - )); + setSelectedProgress(); } - public void setOnSliderChangeListener(Slider.OnChangeListener listener) { - materialSlider.addOnChangeListener(listener); + public void setOnSeekbarChangeListener(SeekBar.OnSeekBarChangeListener listener) { + seekBar.setOnSeekBarChangeListener(listener); } public void setResetClickListener(OnLongClickListener listener) { resetClickListener = listener; + resetIcon.setOnClickListener(v -> { + if (defaultValue == Integer.MAX_VALUE) { + return; + } + + Toast.makeText(getContext(), R.string.long_press_to_reset, Toast.LENGTH_SHORT).show(); + }); + resetIcon.setOnLongClickListener(v -> { if (defaultValue == Integer.MAX_VALUE) { return false; } - setSliderValue(defaultValue); + setSeekbarProgress(defaultValue); handleResetVisibility(); notifyOnResetClicked(v); @@ -203,22 +174,10 @@ public void setResetClickListener(OnLongClickListener listener) { }); } - public void resetSlider() { + public void resetSeekbar() { resetIcon.performLongClick(); } - private void notifyOnSliderTouchStarted(@NonNull Slider slider) { - if (onSliderTouchListener != null) { - onSliderTouchListener.onStartTrackingTouch(slider); - } - } - - private void notifyOnSliderTouchStopped(@NonNull Slider slider) { - if (onSliderTouchListener != null) { - onSliderTouchListener.onStopTrackingTouch(slider); - } - } - private void notifyOnResetClicked(View v) { if (resetClickListener != null) { resetClickListener.onLongClick(v); @@ -226,7 +185,7 @@ private void notifyOnResetClicked(View v) { } private void handleResetVisibility() { - if (defaultValue != Integer.MAX_VALUE && materialSlider.getValue() != defaultValue) { + if (defaultValue != Integer.MAX_VALUE && seekBar.getProgress() != defaultValue) { resetIcon.setVisibility(VISIBLE); } else { resetIcon.setVisibility(GONE); @@ -241,7 +200,7 @@ public void setEnabled(boolean enabled) { titleTextView.setEnabled(enabled); summaryTextView.setEnabled(enabled); resetIcon.setEnabled(enabled); - materialSlider.setEnabled(enabled); + seekBar.setEnabled(enabled); } // to avoid listener bug, we need to re-generate unique id for each view @@ -249,13 +208,13 @@ private void initializeId() { container = findViewById(R.id.container); titleTextView = findViewById(R.id.title); summaryTextView = findViewById(R.id.summary); - materialSlider = findViewById(R.id.slider_widget); + seekBar = findViewById(R.id.seekbar_widget); resetIcon = findViewById(R.id.reset); container.setId(View.generateViewId()); titleTextView.setId(View.generateViewId()); summaryTextView.setId(View.generateViewId()); - materialSlider.setId(View.generateViewId()); + seekBar.setId(View.generateViewId()); resetIcon.setId(View.generateViewId()); } @@ -264,7 +223,7 @@ protected Parcelable onSaveInstanceState() { Parcelable superState = super.onSaveInstanceState(); SavedState ss = new SavedState(superState); - ss.sliderValue = materialSlider.getValue(); + ss.seekbarProgress = seekBar.getProgress(); return ss; } @@ -278,13 +237,13 @@ protected void onRestoreInstanceState(Parcelable state) { super.onRestoreInstanceState(ss.getSuperState()); - materialSlider.setValue(ss.sliderValue); - setSelectedText(); + seekBar.setProgress(ss.seekbarProgress); + setSelectedProgress(); handleResetVisibility(); } private static class SavedState extends BaseSavedState { - float sliderValue; + int seekbarProgress; SavedState(Parcelable superState) { super(superState); @@ -292,22 +251,22 @@ private static class SavedState extends BaseSavedState { private SavedState(Parcel in) { super(in); - sliderValue = in.readFloat(); + seekbarProgress = in.readInt(); } @Override public void writeToParcel(Parcel dest, int flags) { super.writeToParcel(dest, flags); - dest.writeFloat(sliderValue); + dest.writeFloat(seekbarProgress); } - public static final Parcelable.Creator CREATOR = new Parcelable.Creator<>() { - public SavedState createFromParcel(Parcel in) { - return new SavedState(in); + public static final Creator CREATOR = new Creator<>() { + public SeekbarWidget.SavedState createFromParcel(Parcel in) { + return new SeekbarWidget.SavedState(in); } - public SavedState[] newArray(int size) { - return new SavedState[size]; + public SeekbarWidget.SavedState[] newArray(int size) { + return new SeekbarWidget.SavedState[size]; } }; } diff --git a/app/src/main/res/color/color_seekbar_progress.xml b/app/src/main/res/color/color_seekbar_progress.xml new file mode 100644 index 00000000..47212512 --- /dev/null +++ b/app/src/main/res/color/color_seekbar_progress.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/seekbar_track.xml b/app/src/main/res/drawable/seekbar_track.xml new file mode 100644 index 00000000..daa663b5 --- /dev/null +++ b/app/src/main/res/drawable/seekbar_track.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_theme.xml b/app/src/main/res/layout/fragment_theme.xml index 333eaca2..269c77d3 100644 --- a/app/src/main/res/layout/fragment_theme.xml +++ b/app/src/main/res/layout/fragment_theme.xml @@ -73,50 +73,47 @@ - - - + + - - + + + app:progressFormat="x" + app:seekbarDefaultProgress="100" + app:seekbarMaxProgress="200" + app:seekbarMinProgress="0" + app:seekbarProgress="100" + app:titleText="@string/background_lightness" /> diff --git a/app/src/main/res/layout/view_widget_seekbar.xml b/app/src/main/res/layout/view_widget_seekbar.xml new file mode 100644 index 00000000..4448f1a3 --- /dev/null +++ b/app/src/main/res/layout/view_widget_seekbar.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/view_widget_slider.xml b/app/src/main/res/layout/view_widget_slider.xml deleted file mode 100644 index ea0d6be1..00000000 --- a/app/src/main/res/layout/view_widget_slider.xml +++ /dev/null @@ -1,72 +0,0 @@ - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/values/attrs.xml b/app/src/main/res/values/attrs.xml index 9816217e..9e006ddb 100644 --- a/app/src/main/res/values/attrs.xml +++ b/app/src/main/res/values/attrs.xml @@ -29,15 +29,14 @@ - + - - - - - - + + + + + diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index 69cab41b..1f817e3a 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -5,4 +5,5 @@ 12dp 16dp 12dp + 80dp \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 10868cfc..5305828a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -142,4 +142,5 @@ Tertiary Neutral 1 Neutral 2 + Long press to reset \ No newline at end of file diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index 71d6a1a4..0b7cea87 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -36,4 +36,11 @@ \ No newline at end of file