diff --git a/res/drawable/color_picker_preview_background.xml b/res/drawable/color_picker_preview_background.xml
new file mode 100644
index 0000000..b1cedc5
--- /dev/null
+++ b/res/drawable/color_picker_preview_background.xml
@@ -0,0 +1,5 @@
+
+
+
+
\ No newline at end of file
diff --git a/res/drawable/color_picker_seekbar_background.xml b/res/drawable/color_picker_seekbar_background.xml
new file mode 100644
index 0000000..36076ab
--- /dev/null
+++ b/res/drawable/color_picker_seekbar_background.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/res/drawable/color_picker_seekbar_thumb.xml b/res/drawable/color_picker_seekbar_thumb.xml
new file mode 100644
index 0000000..2c58a6a3
--- /dev/null
+++ b/res/drawable/color_picker_seekbar_thumb.xml
@@ -0,0 +1,11 @@
+
+
+ -
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/layout/color_picker_layout.xml b/res/layout/color_picker_layout.xml
new file mode 100644
index 0000000..858d209
--- /dev/null
+++ b/res/layout/color_picker_layout.xml
@@ -0,0 +1,135 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/res/values-night/styles.xml b/res/values-night/styles.xml
new file mode 100644
index 0000000..3087a13
--- /dev/null
+++ b/res/values-night/styles.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
diff --git a/res/values/cherish_dimens.xml b/res/values/cherish_dimens.xml
index 27f18ae..077cd9b 100644
--- a/res/values/cherish_dimens.xml
+++ b/res/values/cherish_dimens.xml
@@ -22,6 +22,8 @@
20dp
18dip
18dip
+
+ 80dp
70dip
diff --git a/res/values/cherish_strings.xml b/res/values/cherish_strings.xml
index 312a65f..72d192f 100644
--- a/res/values/cherish_strings.xml
+++ b/res/values/cherish_strings.xml
@@ -96,6 +96,13 @@
Power menu
+
+ RGB
+ HSL
+ HSV
+ Confirm
+ Invalid color!
+
diff --git a/res/values/cherish_styles.xml b/res/values/cherish_styles.xml
index be0f7b7..28ba04c 100644
--- a/res/values/cherish_styles.xml
+++ b/res/values/cherish_styles.xml
@@ -23,4 +23,46 @@
20dp
#5f6368
+
+
+
+
+
+
+
+
+
+
diff --git a/src/com/cherish/settings/fragments/CherishDashboardFragment.kt b/src/com/cherish/settings/fragments/CherishDashboardFragment.kt
index 3b5b65d..555cc99 100644
--- a/src/com/cherish/settings/fragments/CherishDashboardFragment.kt
+++ b/src/com/cherish/settings/fragments/CherishDashboardFragment.kt
@@ -20,15 +20,26 @@ import androidx.preference.Preference
import com.android.internal.logging.nano.MetricsProto
import com.android.settings.dashboard.DashboardFragment
+import com.cherish.settings.fragments.ColorPickerFragment
+import com.cherish.settings.preferences.ColorPickerPreference
abstract class CherishDashboardFragment: DashboardFragment() {
override fun getMetricsCategory(): Int = MetricsProto.MetricsEvent.CHERISH_SETTINGS
override fun onDisplayPreferenceDialog(preference: Preference) {
- super.onDisplayPreferenceDialog(preference)
+ if (preference is ColorPickerPreference) {
+ ColorPickerFragment(preference.color).apply {
+ setOnConfirmListener {
+ preference.setColor(it)
+ }
+ }.show(childFragmentManager, COLOR_PICKER_DIALOG_KEY)
+ } else {
+ super.onDisplayPreferenceDialog(preference)
+ }
}
companion object {
const val REQUEST_KEY = "CherishDashboardFragment#RequestKey"
+ const val COLOR_PICKER_DIALOG_KEY = "color_picker_dialog"
}
}
\ No newline at end of file
diff --git a/src/com/cherish/settings/fragments/ColorPickerFragment.kt b/src/com/cherish/settings/fragments/ColorPickerFragment.kt
new file mode 100644
index 0000000..4f6addb
--- /dev/null
+++ b/src/com/cherish/settings/fragments/ColorPickerFragment.kt
@@ -0,0 +1,418 @@
+/*
+ * Copyright (C) 2022 FlamingoOS 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.cherish.settings.fragments
+
+import android.annotation.ColorInt
+import android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
+import android.content.res.ColorStateList
+import android.graphics.Color
+import android.graphics.drawable.Drawable
+import android.graphics.drawable.GradientDrawable
+import android.os.Bundle
+import android.text.Editable
+import android.text.Spanned
+import android.text.InputFilter
+import android.view.HapticFeedbackConstants.KEYBOARD_PRESS
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.Button
+import android.widget.EditText
+import android.widget.RadioGroup
+import android.widget.SeekBar
+import android.widget.TextView
+import android.widget.Toast
+
+import androidx.core.graphics.ColorUtils
+import androidx.core.widget.doAfterTextChanged
+import androidx.fragment.app.DialogFragment.STYLE_NORMAL
+
+import com.google.android.material.bottomsheet.BottomSheetDialogFragment
+import com.android.settings.R
+
+class ColorPickerFragment(
+ defaultColor: String? = "#FFFFFF",
+) : BottomSheetDialogFragment(),
+ RadioGroup.OnCheckedChangeListener,
+ SeekBar.OnSeekBarChangeListener {
+
+ private lateinit var colorPreview: View
+ private lateinit var colorInput: EditText
+ private lateinit var seekBarOne: SeekBar
+ private lateinit var seekBarTwo: SeekBar
+ private lateinit var seekBarThree: SeekBar
+
+ private var colorModel = ColorModel.RGB
+ private var textInputChangedInternal = false // Internal variable to prevent loops with TextWatcher
+ private var confirmListener: (String) -> Unit = {}
+
+ @ColorInt
+ private var color: Int
+
+ init {
+ color = if (defaultColor == null || defaultColor.isEmpty()) {
+ Color.WHITE
+ } else {
+ try {
+ Color.parseColor(defaultColor)
+ } catch (e: IllegalArgumentException) {
+ Color.WHITE
+ }
+ }
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ activity?.requestedOrientation = SCREEN_ORIENTATION_PORTRAIT
+ setStyle(STYLE_NORMAL, R.style.ColorPickerStyle)
+ }
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View = inflater.inflate(R.layout.color_picker_layout, container, false)
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ colorPreview = view.findViewById(R.id.color_preview)
+ colorInput = view.findViewById(R.id.color_input)
+
+ colorInput.doAfterTextChanged {
+ if (textInputChangedInternal) {
+ // Reset it here
+ textInputChangedInternal = false
+ return@doAfterTextChanged
+ }
+ if (it?.length != 7) return@doAfterTextChanged
+ color = try {
+ Color.parseColor(it.toString())
+ } catch (e: IllegalArgumentException) {
+ Toast.makeText(
+ context,
+ R.string.invalid_color,
+ Toast.LENGTH_SHORT
+ )
+ Color.WHITE
+ }
+ updateSliders()
+ updateSliderGradients(false)
+ previewColor(true)
+ }
+
+ colorInput.filters = arrayOf(
+ InputFilter.LengthFilter(7),
+ InputFilter filter@ { source, start, end, _, dstart, dend ->
+ // Deletion
+ if (start == 0 && end == 0) {
+ return@filter null
+ }
+ if (dstart == 0) {
+ // First character has to be # and rest of them
+ // (if present) be a valid hex char
+ if (!source.startsWith("#")) {
+ return@filter ""
+ }
+ // Just a single char
+ if (dstart == dend) return@filter null
+ if (!HEX_PATTERN.matches(source.subSequence(1, end))) {
+ return@filter ""
+ }
+ } else {
+ // Does not start from 0, so every char has to be valid hex
+ if (!HEX_PATTERN.matches(source)) {
+ return@filter ""
+ }
+ }
+ if ((end - start) == 7) { // Full hex input
+ if (!COLOR_HEX_PATTERN.matches(source)) {
+ return@filter ""
+ }
+ }
+ null
+ }
+ )
+
+ view.findViewById