diff --git a/app/src/main/java/de/jrpie/android/launcher/preferences/ColorPreference.kt b/app/src/main/java/de/jrpie/android/launcher/preferences/ColorPreference.kt new file mode 100644 index 0000000..7913c31 --- /dev/null +++ b/app/src/main/java/de/jrpie/android/launcher/preferences/ColorPreference.kt @@ -0,0 +1,165 @@ +package de.jrpie.android.launcher.preferences + +import android.content.Context +import android.content.res.TypedArray +import android.graphics.Color +import android.text.Editable +import android.text.TextWatcher +import android.util.AttributeSet +import android.widget.EditText +import android.widget.SeekBar +import android.widget.TextView +import androidx.annotation.ColorInt +import androidx.appcompat.app.AlertDialog +import androidx.core.graphics.alpha +import androidx.core.graphics.blue +import androidx.core.graphics.green +import androidx.core.graphics.red +import androidx.preference.Preference +import de.jrpie.android.launcher.R + +class ColorPreference(context: Context, attrs: AttributeSet?) : + Preference(context, attrs) { + + @Suppress("unused") + constructor(context: Context) : this(context, null) + + private var selectedColor = Color.WHITE + + init { + isPersistent = true + selectedColor = getPersistedInt(selectedColor) + summary = selectedColor.getHex() + } + + override fun onClick() { + showDialog() + } + + @ColorInt + override fun onGetDefaultValue(a: TypedArray, index: Int): Int { + return a.getInt(index, selectedColor) + } + + override fun onSetInitialValue(defaultValue: Any?) { + selectedColor = getPersistedInt(selectedColor) + summary = selectedColor.getHex() + } + + private fun showDialog() { + var currentColor = getPersistedInt(selectedColor) + + AlertDialog.Builder(context, R.style.AlertDialogCustom).apply { + setView(R.layout.dialog_choose_color) + setTitle(R.string.dialog_choose_color_title) + setPositiveButton(R.string.dialog_select_color_ok) { _, _ -> + persistInt(currentColor) + summary = currentColor.getHex() + } + setNegativeButton(R.string.dialog_select_color_cancel) { _, _ -> } + }.create().also { it.show() }.apply { + val preview = findViewById(R.id.dialog_select_color_preview) + + val red = findViewById(R.id.dialog_select_color_seekbar_red) + val green = findViewById(R.id.dialog_select_color_seekbar_green) + val blue = findViewById(R.id.dialog_select_color_seekbar_blue) + val alpha = findViewById(R.id.dialog_select_color_seekbar_alpha) + + val updateColor = { updateText: Boolean -> + preview?.setTextColor(currentColor.foregroundTextColor()) + preview?.setBackgroundColor(currentColor) + if (updateText) { + preview?.setText(currentColor.getHex(), TextView.BufferType.EDITABLE) + } + red?.progress = currentColor.red + green?.progress = currentColor.green + blue?.progress = currentColor.blue + alpha?.progress = currentColor.alpha + } + updateColor(true) + + preview?.addTextChangedListener(object : TextWatcher { + override fun beforeTextChanged(text: CharSequence?, p1: Int, p2: Int, p3: Int) {} + override fun onTextChanged(text: CharSequence?, p1: Int, p2: Int, p3: Int) {} + override fun afterTextChanged(editable: Editable?) { + preview.hasFocus() || return + val newText = editable?.toString() + newText.isNullOrBlank() && return + try { + val newColor = Color.parseColor(newText.toString()) + currentColor = newColor + updateColor(false) + } catch (_: IllegalArgumentException) { + } + } + }) + red?.setOnSeekBarChangeListener(SeekBarChangeListener { + currentColor = currentColor.updateRed(it) + updateColor(true) + }) + green?.setOnSeekBarChangeListener(SeekBarChangeListener { + currentColor = currentColor.updateGreen(it) + updateColor(true) + }) + blue?.setOnSeekBarChangeListener(SeekBarChangeListener { + currentColor = currentColor.updateBlue(it) + updateColor(true) + }) + alpha?.setOnSeekBarChangeListener(SeekBarChangeListener { + currentColor = currentColor.updateAlpha(it) + updateColor(true) + }) + } + } + + + private class SeekBarChangeListener(val update: (Int) -> Unit) : + SeekBar.OnSeekBarChangeListener { + override fun onProgressChanged(seekBar: SeekBar?, v: Int, fromUser: Boolean) { + fromUser || return + update(v) + } + + override fun onStartTrackingTouch(p0: SeekBar?) {} + override fun onStopTrackingTouch(p0: SeekBar?) {} + } + + companion object { + fun @receiver:ColorInt Int.getHex(): String { + return "#%08X".format(this) + } + + @ColorInt + fun @receiver:ColorInt Int.updateRed(red: Int): Int { + return Color.argb(this.alpha, red, this.green, this.blue) + } + + @ColorInt + fun @receiver:ColorInt Int.updateGreen(green: Int): Int { + return Color.argb(this.alpha, this.red, green, this.blue) + } + + @ColorInt + fun @receiver:ColorInt Int.updateBlue(blue: Int): Int { + return Color.argb(this.alpha, this.red, this.green, blue) + } + + @ColorInt + fun @receiver:ColorInt Int.updateAlpha(alpha: Int): Int { + return Color.argb(alpha, this.red, this.green, this.blue) + } + + @ColorInt + fun @receiver:ColorInt Int.foregroundTextColor(): Int { + // https://stackoverflow.com/a/3943023 + return if ( + this.red * 0.299 + this.green * 0.587 + this.blue * 0.114 + > this.alpha / 256f * 150 + ) { + Color.BLACK + } else { + Color.WHITE + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/de/jrpie/android/launcher/preferences/LauncherPreferences$Config.java b/app/src/main/java/de/jrpie/android/launcher/preferences/LauncherPreferences$Config.java index 2090839..0ed22c9 100644 --- a/app/src/main/java/de/jrpie/android/launcher/preferences/LauncherPreferences$Config.java +++ b/app/src/main/java/de/jrpie/android/launcher/preferences/LauncherPreferences$Config.java @@ -53,6 +53,7 @@ import eu.jonahbauer.android.preference.annotations.serializer.PreferenceSeriali }), @PreferenceGroup(name = "clock", prefix = "settings_clock_", suffix = "_key", value = { @Preference(name = "font", type = Font.class, defaultValue = "HACK"), + @Preference(name = "color", type = int.class, defaultValue = "0xffffffff"), @Preference(name = "date_visible", type = boolean.class, defaultValue = "true"), @Preference(name = "time_visible", type = boolean.class, defaultValue = "true"), @Preference(name = "flip_date_time", type = boolean.class, defaultValue = "false"), diff --git a/app/src/main/java/de/jrpie/android/launcher/ui/HomeActivity.kt b/app/src/main/java/de/jrpie/android/launcher/ui/HomeActivity.kt index 5573832..f24bb65 100644 --- a/app/src/main/java/de/jrpie/android/launcher/ui/HomeActivity.kt +++ b/app/src/main/java/de/jrpie/android/launcher/ui/HomeActivity.kt @@ -142,6 +142,10 @@ class HomeActivity : UIObject, AppCompatActivity(), binding.homeUpperView.isVisible = upperVisible binding.homeLowerView.isVisible = lowerVisible + binding.homeUpperView.setTextColor(LauncherPreferences.clock().color()) + binding.homeLowerView.setTextColor(LauncherPreferences.clock().color()) + + clockTimer = fixedRateTimer("clockTimer", true, 0L, period) { this@HomeActivity.runOnUiThread { if (lowerVisible) { @@ -200,6 +204,7 @@ class HomeActivity : UIObject, AppCompatActivity(), } Gesture.VOLUME_UP(this) } + KeyEvent.KEYCODE_VOLUME_DOWN -> { if (Action.forGesture(Gesture.VOLUME_DOWN) == LauncherAction.VOLUME_DOWN) { // see above @@ -229,7 +234,6 @@ class HomeActivity : UIObject, AppCompatActivity(), val edgeActions = LauncherPreferences.enabled_gestures().edgeSwipe() val threshold = ViewConfiguration.get(this).scaledTouchSlop - val angularThreshold = tan(Math.PI / 6) var gesture = if (angularThreshold * abs(diffX) > abs(diffY)) { // horizontal swipe @@ -238,7 +242,7 @@ class HomeActivity : UIObject, AppCompatActivity(), else if (diffX < -threshold) Gesture.SWIPE_RIGHT else null - } else if (angularThreshold * abs(diffY) > abs(diffX)){ // vertical swipe + } else if (angularThreshold * abs(diffY) > abs(diffX)) { // vertical swipe // Only open if the swipe was not from the phones top edge // TODO: replace 100px by sensible dp value (e.g. twice the height of the status bar) if (diffY < -threshold && e1.y > 100) diff --git a/app/src/main/res/layout/dialog_choose_color.xml b/app/src/main/res/layout/dialog_choose_color.xml new file mode 100644 index 0000000..90d13c3 --- /dev/null +++ b/app/src/main/res/layout/dialog_choose_color.xml @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-v29/styles.xml b/app/src/main/res/values-v29/styles.xml index ac1ba6b..7c97607 100644 --- a/app/src/main/res/values-v29/styles.xml +++ b/app/src/main/res/values-v29/styles.xml @@ -7,4 +7,6 @@ false + + \ No newline at end of file diff --git a/app/src/main/res/values/donottranslate.xml b/app/src/main/res/values/donottranslate.xml index 5da4aa2..e0d9608 100644 --- a/app/src/main/res/values/donottranslate.xml +++ b/app/src/main/res/values/donottranslate.xml @@ -119,6 +119,7 @@ - --> clock.font + clock.color clock.time_visible clock.show_seconds clock.date_visible diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 365be7d..fcfb785 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -112,6 +112,7 @@ Monochrome app icons + Color Show time Show date Use localized date format @@ -289,4 +290,12 @@ Cancel Ok Rename %1$s + Red + Alpha + Blue + Green + Ok + Cancel + Color + Choose color diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index b91324a..a96b9f1 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -59,6 +59,10 @@ android:entries="@array/settings_theme_font_items" android:summary="%s" android:defaultValue="HACK"/> +