mirror of
https://github.com/jrpie/Launcher.git
synced 2025-02-23 14:31:30 +01:00
parent
3c59ad4c41
commit
a9f3196f8e
8 changed files with 270 additions and 2 deletions
|
@ -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<EditText>(R.id.dialog_select_color_preview)
|
||||||
|
|
||||||
|
val red = findViewById<SeekBar>(R.id.dialog_select_color_seekbar_red)
|
||||||
|
val green = findViewById<SeekBar>(R.id.dialog_select_color_seekbar_green)
|
||||||
|
val blue = findViewById<SeekBar>(R.id.dialog_select_color_seekbar_blue)
|
||||||
|
val alpha = findViewById<SeekBar>(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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -53,6 +53,7 @@ import eu.jonahbauer.android.preference.annotations.serializer.PreferenceSeriali
|
||||||
}),
|
}),
|
||||||
@PreferenceGroup(name = "clock", prefix = "settings_clock_", suffix = "_key", value = {
|
@PreferenceGroup(name = "clock", prefix = "settings_clock_", suffix = "_key", value = {
|
||||||
@Preference(name = "font", type = Font.class, defaultValue = "HACK"),
|
@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 = "date_visible", type = boolean.class, defaultValue = "true"),
|
||||||
@Preference(name = "time_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"),
|
@Preference(name = "flip_date_time", type = boolean.class, defaultValue = "false"),
|
||||||
|
|
|
@ -142,6 +142,10 @@ class HomeActivity : UIObject, AppCompatActivity(),
|
||||||
binding.homeUpperView.isVisible = upperVisible
|
binding.homeUpperView.isVisible = upperVisible
|
||||||
binding.homeLowerView.isVisible = lowerVisible
|
binding.homeLowerView.isVisible = lowerVisible
|
||||||
|
|
||||||
|
binding.homeUpperView.setTextColor(LauncherPreferences.clock().color())
|
||||||
|
binding.homeLowerView.setTextColor(LauncherPreferences.clock().color())
|
||||||
|
|
||||||
|
|
||||||
clockTimer = fixedRateTimer("clockTimer", true, 0L, period) {
|
clockTimer = fixedRateTimer("clockTimer", true, 0L, period) {
|
||||||
this@HomeActivity.runOnUiThread {
|
this@HomeActivity.runOnUiThread {
|
||||||
if (lowerVisible) {
|
if (lowerVisible) {
|
||||||
|
@ -200,6 +204,7 @@ class HomeActivity : UIObject, AppCompatActivity(),
|
||||||
}
|
}
|
||||||
Gesture.VOLUME_UP(this)
|
Gesture.VOLUME_UP(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
KeyEvent.KEYCODE_VOLUME_DOWN -> {
|
KeyEvent.KEYCODE_VOLUME_DOWN -> {
|
||||||
if (Action.forGesture(Gesture.VOLUME_DOWN) == LauncherAction.VOLUME_DOWN) {
|
if (Action.forGesture(Gesture.VOLUME_DOWN) == LauncherAction.VOLUME_DOWN) {
|
||||||
// see above
|
// see above
|
||||||
|
@ -229,7 +234,6 @@ class HomeActivity : UIObject, AppCompatActivity(),
|
||||||
val edgeActions = LauncherPreferences.enabled_gestures().edgeSwipe()
|
val edgeActions = LauncherPreferences.enabled_gestures().edgeSwipe()
|
||||||
|
|
||||||
val threshold = ViewConfiguration.get(this).scaledTouchSlop
|
val threshold = ViewConfiguration.get(this).scaledTouchSlop
|
||||||
|
|
||||||
val angularThreshold = tan(Math.PI / 6)
|
val angularThreshold = tan(Math.PI / 6)
|
||||||
|
|
||||||
var gesture = if (angularThreshold * abs(diffX) > abs(diffY)) { // horizontal swipe
|
var gesture = if (angularThreshold * abs(diffX) > abs(diffY)) { // horizontal swipe
|
||||||
|
@ -238,7 +242,7 @@ class HomeActivity : UIObject, AppCompatActivity(),
|
||||||
else if (diffX < -threshold)
|
else if (diffX < -threshold)
|
||||||
Gesture.SWIPE_RIGHT
|
Gesture.SWIPE_RIGHT
|
||||||
else null
|
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
|
// 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)
|
// TODO: replace 100px by sensible dp value (e.g. twice the height of the status bar)
|
||||||
if (diffY < -threshold && e1.y > 100)
|
if (diffY < -threshold && e1.y > 100)
|
||||||
|
|
82
app/src/main/res/layout/dialog_choose_color.xml
Normal file
82
app/src/main/res/layout/dialog_choose_color.xml
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
style="@style/AlertDialogCustom"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="20dp">
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:inputType="textNoSuggestions"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:hint="@string/dialog_select_color_color_hex"
|
||||||
|
android:autofillHints="color"
|
||||||
|
android:id="@+id/dialog_select_color_preview"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center|center_horizontal"
|
||||||
|
android:padding="5dp"
|
||||||
|
android:textSize="20sp"
|
||||||
|
tools:text="#ffbb00" />
|
||||||
|
|
||||||
|
<Space
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="10dp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/dialog_select_color_red" />
|
||||||
|
|
||||||
|
<SeekBar
|
||||||
|
android:id="@+id/dialog_select_color_seekbar_red"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:max="255" />
|
||||||
|
|
||||||
|
<Space
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="10dp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/dialog_select_color_green" />
|
||||||
|
|
||||||
|
<SeekBar
|
||||||
|
android:id="@+id/dialog_select_color_seekbar_green"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:max="255" />
|
||||||
|
|
||||||
|
<Space
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="10dp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/dialog_select_color_blue" />
|
||||||
|
|
||||||
|
<SeekBar
|
||||||
|
android:id="@+id/dialog_select_color_seekbar_blue"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:max="255" />
|
||||||
|
|
||||||
|
<Space
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="10dp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/dialog_select_color_alpha" />
|
||||||
|
|
||||||
|
<SeekBar
|
||||||
|
android:id="@+id/dialog_select_color_seekbar_alpha"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:max="255" />
|
||||||
|
</LinearLayout>
|
|
@ -7,4 +7,6 @@
|
||||||
<item name="android:enforceNavigationBarContrast">false</item>
|
<item name="android:enforceNavigationBarContrast">false</item>
|
||||||
<!--<item name="android:windowDrawsSystemBarBackgrounds">true</item>-->
|
<!--<item name="android:windowDrawsSystemBarBackgrounds">true</item>-->
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|
||||||
</resources>
|
</resources>
|
|
@ -119,6 +119,7 @@
|
||||||
-
|
-
|
||||||
-->
|
-->
|
||||||
<string name="settings_clock_font_key" translatable="false">clock.font</string>
|
<string name="settings_clock_font_key" translatable="false">clock.font</string>
|
||||||
|
<string name="settings_clock_color_key" translatable="false">clock.color</string>
|
||||||
<string name="settings_clock_time_visible_key" translatable="false">clock.time_visible</string>
|
<string name="settings_clock_time_visible_key" translatable="false">clock.time_visible</string>
|
||||||
<string name="settings_clock_show_seconds_key" translatable="false">clock.show_seconds</string>
|
<string name="settings_clock_show_seconds_key" translatable="false">clock.show_seconds</string>
|
||||||
<string name="settings_clock_date_visible_key" translatable="false">clock.date_visible</string>
|
<string name="settings_clock_date_visible_key" translatable="false">clock.date_visible</string>
|
||||||
|
|
|
@ -112,6 +112,7 @@
|
||||||
<string name="settings_theme_monochrome_icons">Monochrome app icons</string>
|
<string name="settings_theme_monochrome_icons">Monochrome app icons</string>
|
||||||
|
|
||||||
<string name="settings_launcher_section_date_time"><![CDATA[Date & time]]></string>
|
<string name="settings_launcher_section_date_time"><![CDATA[Date & time]]></string>
|
||||||
|
<string name="settings_clock_color">Color</string>
|
||||||
<string name="settings_clock_time_visible">Show time</string>
|
<string name="settings_clock_time_visible">Show time</string>
|
||||||
<string name="settings_clock_date_visible">Show date</string>
|
<string name="settings_clock_date_visible">Show date</string>
|
||||||
<string name="settings_clock_localized">Use localized date format</string>
|
<string name="settings_clock_localized">Use localized date format</string>
|
||||||
|
@ -289,4 +290,12 @@
|
||||||
<string name="dialog_rename_cancel">Cancel</string>
|
<string name="dialog_rename_cancel">Cancel</string>
|
||||||
<string name="dialog_rename_ok">Ok</string>
|
<string name="dialog_rename_ok">Ok</string>
|
||||||
<string name="dialog_rename_title">Rename %1$s</string>
|
<string name="dialog_rename_title">Rename %1$s</string>
|
||||||
|
<string name="dialog_select_color_red">Red</string>
|
||||||
|
<string name="dialog_select_color_alpha">Alpha</string>
|
||||||
|
<string name="dialog_select_color_blue">Blue</string>
|
||||||
|
<string name="dialog_select_color_green">Green</string>
|
||||||
|
<string name="dialog_select_color_ok">Ok</string>
|
||||||
|
<string name="dialog_select_color_cancel">Cancel</string>
|
||||||
|
<string name="dialog_select_color_color_hex">Color</string>
|
||||||
|
<string name="dialog_choose_color_title">Choose color</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -59,6 +59,10 @@
|
||||||
android:entries="@array/settings_theme_font_items"
|
android:entries="@array/settings_theme_font_items"
|
||||||
android:summary="%s"
|
android:summary="%s"
|
||||||
android:defaultValue="HACK"/>
|
android:defaultValue="HACK"/>
|
||||||
|
<de.jrpie.android.launcher.preferences.ColorPreference
|
||||||
|
android:key="@string/settings_clock_color_key"
|
||||||
|
android:title="@string/settings_clock_color"
|
||||||
|
/>
|
||||||
<SwitchPreference
|
<SwitchPreference
|
||||||
android:key="@string/settings_clock_localized_key"
|
android:key="@string/settings_clock_localized_key"
|
||||||
android:defaultValue="false"
|
android:defaultValue="false"
|
||||||
|
|
Loading…
Add table
Reference in a new issue