Add custom widget theme with color picker

This commit introduces a new "Custom" theme option for the widget,
allowing users to select a custom background color.

Changes include:
- Added "Custom" theme to widget_themes array in arrays.xml.
- Introduced new string resources for custom theme color in strings.xml.
- Modified preferences_widget.xml to include a color picker preference
for the custom theme.
- Updated WidgetSettings.kt to manage the visibility and functionality
of the custom color picker based on theme selection.
- Extended WidgetPreferences.kt to store and retrieve the custom theme
color, and to apply it to the widget's background.
- Implemented a isLight utility function in Theme.kt to determine text
color based on the custom background color.
pull/3687/head
Samuel Born 6 months ago
parent a299363fe8
commit b0f1b54403
No known key found for this signature in database

@ -44,6 +44,7 @@ class WidgetSettings : InjectingPreferenceFragment() {
companion object {
private const val REQUEST_THEME_SELECTION = 1006
private const val REQUEST_COLOR_SELECTION = 1007
private const val REQUEST_CUSTOM_THEME_COLOR_SELECTION = 1009
private const val REQUEST_SORT = 1008
const val EXTRA_WIDGET_ID = "extra_widget_id"
@ -163,6 +164,13 @@ class WidgetSettings : InjectingPreferenceFragment() {
updateFilter()
updateTheme()
updateColor()
val customThemeColor = findPreference(R.string.p_widget_custom_theme_color)
customThemeColor.onPreferenceClickListener = Preference.OnPreferenceClickListener {
newColorPalette(this, REQUEST_CUSTOM_THEME_COLOR_SELECTION, widgetPreferences.customThemeColor, Palette.WIDGET)
.show(parentFragmentManager, FRAG_TAG_COLOR_PICKER)
false
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
@ -182,6 +190,12 @@ class WidgetSettings : InjectingPreferenceFragment() {
)
updateColor()
}
REQUEST_CUSTOM_THEME_COLOR_SELECTION -> if (resultCode == Activity.RESULT_OK) {
widgetPreferences.setCustomThemeColor(
data!!.getIntExtra(ColorWheelPicker.EXTRA_SELECTED, 0)
)
updateCustomThemeColor()
}
REQUEST_SORT -> if (resultCode == Activity.RESULT_OK) updateSort()
else -> super.onActivityResult(requestCode, resultCode, data)
}
@ -198,12 +212,17 @@ class WidgetSettings : InjectingPreferenceFragment() {
val widgetNames = resources.getStringArray(R.array.widget_themes)
findPreference(R.string.p_widget_theme).summary = widgetNames[index]
findPreference(R.string.p_widget_color_v2).isVisible = index != 4
findPreference(R.string.p_widget_custom_theme_color).isVisible = index == 5
}
private fun updateColor() {
tintColorPreference(R.string.p_widget_color_v2, widgetPreferences.color)
}
private fun updateCustomThemeColor() {
tintColorPreference(R.string.p_widget_custom_theme_color, widgetPreferences.customThemeColor)
}
private fun updateFilter() = lifecycleScope.launch {
findPreference(R.string.p_widget_filter).summary = getFilter().title
updateSort()

@ -1,6 +1,7 @@
package org.tasks.themes
import android.app.Activity
import androidx.core.graphics.ColorUtils
import javax.inject.Inject
class Theme @Inject constructor(
@ -15,4 +16,10 @@ class Theme @Inject constructor(
fun applyTheme(activity: Activity) {
themeBase.set(activity)
}
companion object {
fun isLight(color: Int): Boolean {
return ColorUtils.calculateLuminance(color) > 0.5
}
}
}

@ -13,6 +13,8 @@ import org.tasks.preferences.QueryPreferences
import org.tasks.tasklist.SectionedDataSource.Companion.HEADER_COMPLETED
import timber.log.Timber
import org.tasks.themes.Theme
class WidgetPreferences(
private val context: Context,
private val preferences: Preferences,
@ -92,18 +94,18 @@ class WidgetPreferences(
get() = when (themeIndex) {
0 -> false
3, 4 -> context.isNightMode
5 -> !Theme.isLight(backgroundColor)
else -> true
}
private val backgroundColor: Int
get() = context.getColor(
when (themeIndex) {
1 -> android.R.color.black
2 -> R.color.md_background_dark
3, 4 -> R.color.widget_background_follow_system
else -> android.R.color.white
}
)
get() = when (themeIndex) {
1 -> context.getColor(android.R.color.black)
2 -> context.getColor(R.color.md_background_dark)
3, 4 -> context.getColor(R.color.widget_background_follow_system)
5 -> customThemeColor
else -> context.getColor(android.R.color.white)
}
var collapsed: Set<Long>
get() {
@ -160,6 +162,13 @@ class WidgetPreferences(
fun setColor(color: Int) {
setInt(R.string.p_widget_color_v2, color)
}
val customThemeColor: Int
get() = getInt(R.string.p_widget_custom_theme_color, 0)
fun setCustomThemeColor(color: Int) {
setInt(R.string.p_widget_custom_theme_color, color)
}
val footerOpacity: Int
get() = getAlphaValue(R.string.p_widget_footer_opacity)
val rowOpacity: Int

@ -35,7 +35,8 @@
<item>@string/theme_black</item>
<item>@string/theme_dark</item>
<item>@string/theme_system_default</item>
<item>@string/theme_dynamic</item>
<item>@string/theme_dynamic</item>
<item>@string/theme_custom</item>
</string-array>
<string-array name="EPr_default_urgency">

@ -386,11 +386,14 @@ File %1$s contained %2$s.\n\n
<string name="launcher_icon">Launcher icon</string>
<string name="theme_black">Black</string>
<string name="theme_light">Light</string>
<string name="theme_custom">Custom</string>
<string name="theme_dark">Dark</string>
<string name="theme_wallpaper">Wallpaper</string>
<string name="theme_day_night">Day/Night</string>
<string name="theme_system_default">System default</string>
<string name="theme_dynamic">Dynamic</string>
<string name="p_widget_custom_theme_color" translatable="false">p_widget_custom_theme_color</string>
<string name="custom_theme_color">Custom theme color</string>
<string name="language">Language</string>
<string name="restart_required">Restart Tasks for this change to take effect</string>
<string name="restart_now">Restart now</string>

@ -10,6 +10,10 @@
android:key="@string/p_widget_theme"
android:title="@string/theme" />
<Preference
android:key="@string/p_widget_custom_theme_color"
android:title="@string/custom_theme_color" />
<Preference
android:key="@string/p_widget_sort"
android:title="@string/TLA_menu_sort" />

Loading…
Cancel
Save