feat: custom theming for stats widget

This commit is contained in:
rebelonion 2024-03-27 18:23:13 -05:00
parent f83d1d8d84
commit fbbbf41595
7 changed files with 349 additions and 53 deletions

View file

@ -4,19 +4,26 @@ import android.app.Activity
import android.appwidget.AppWidgetManager
import android.content.Context
import android.content.Intent
import android.graphics.Color
import android.os.Bundle
import android.util.TypedValue
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import ani.dantotsu.R
import ani.dantotsu.databinding.StatisticsWidgetConfigureBinding
import ani.dantotsu.themes.ThemeManager
import ani.dantotsu.widgets.upcoming.UpcomingWidget
import eltos.simpledialogfragment.SimpleDialog
import eltos.simpledialogfragment.color.SimpleColorDialog
/**
* The configuration screen for the [ProfileStatsWidget] AppWidget.
*/
class ProfileStatsConfigure : Activity() {
class ProfileStatsConfigure : AppCompatActivity(),
SimpleDialog.OnDialogResultListener {
private var appWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID
private var isMonetEnabled = false
private var onClickListener = View.OnClickListener {
val context = this@ProfileStatsConfigure
@ -51,25 +58,93 @@ class ProfileStatsConfigure : Activity() {
binding = StatisticsWidgetConfigureBinding.inflate(layoutInflater)
setContentView(binding.root)
val typedValueSurface = TypedValue()
theme.resolveAttribute(com.google.android.material.R.attr.colorSurface, typedValueSurface, true)
val backgroundColor = typedValueSurface.data
val prefs = getSharedPreferences(ProfileStatsWidget.PREFS_NAME, Context.MODE_PRIVATE)
val typedValuePrimary = TypedValue()
theme.resolveAttribute(com.google.android.material.R.attr.colorPrimary, typedValuePrimary, true)
val textColor = typedValuePrimary.data
val typedValueOutline = TypedValue()
theme.resolveAttribute(com.google.android.material.R.attr.colorOutline, typedValueOutline, true)
val subTextColor = typedValueOutline.data
getSharedPreferences(ProfileStatsWidget.PREFS_NAME, Context.MODE_PRIVATE).edit().apply {
putInt(ProfileStatsWidget.PREF_BACKGROUND_COLOR, backgroundColor)
putInt(ProfileStatsWidget.PREF_BACKGROUND_FADE, backgroundColor)
putInt(ProfileStatsWidget.PREF_TITLE_TEXT_COLOR, textColor)
apply()
binding.topBackgroundButton.setOnClickListener {
val tag = ProfileStatsWidget.PREF_BACKGROUND_COLOR
SimpleColorDialog().title(R.string.custom_theme)
.colorPreset(
prefs.getInt(
ProfileStatsWidget.PREF_BACKGROUND_COLOR,
Color.parseColor("#80000000")
)
)
.colors(
this@ProfileStatsConfigure,
SimpleColorDialog.MATERIAL_COLOR_PALLET
)
.setupColorWheelAlpha(true)
.allowCustom(true)
.showOutline(0x46000000)
.gridNumColumn(5)
.choiceMode(SimpleColorDialog.SINGLE_CHOICE)
.neg()
.show(this@ProfileStatsConfigure, tag)
}
binding.bottomBackgroundButton.setOnClickListener {
val tag = ProfileStatsWidget.PREF_BACKGROUND_FADE
SimpleColorDialog().title(R.string.custom_theme)
.colorPreset(prefs.getInt(UpcomingWidget.PREF_BACKGROUND_FADE, Color.parseColor("#00000000")))
.colors(
this@ProfileStatsConfigure,
SimpleColorDialog.MATERIAL_COLOR_PALLET
)
.setupColorWheelAlpha(true)
.allowCustom(true)
.showOutline(0x46000000)
.gridNumColumn(5)
.choiceMode(SimpleColorDialog.SINGLE_CHOICE)
.neg()
.show(this@ProfileStatsConfigure, tag)
}
binding.titleColorButton.setOnClickListener {
val tag = ProfileStatsWidget.PREF_TITLE_TEXT_COLOR
SimpleColorDialog().title(R.string.custom_theme)
.colorPreset(prefs.getInt(ProfileStatsWidget.PREF_TITLE_TEXT_COLOR, Color.WHITE))
.colors(
this@ProfileStatsConfigure,
SimpleColorDialog.MATERIAL_COLOR_PALLET
)
.setupColorWheelAlpha(true)
.allowCustom(true)
.showOutline(0x46000000)
.gridNumColumn(5)
.choiceMode(SimpleColorDialog.SINGLE_CHOICE)
.neg()
.show(this@ProfileStatsConfigure, tag)
}
binding.statsColorButton.setOnClickListener {
val tag = ProfileStatsWidget.PREF_STATS_TEXT_COLOR
SimpleColorDialog().title(R.string.custom_theme)
.colorPreset(prefs.getInt(ProfileStatsWidget.PREF_STATS_TEXT_COLOR, Color.WHITE))
.colors(
this@ProfileStatsConfigure,
SimpleColorDialog.MATERIAL_COLOR_PALLET
)
.setupColorWheelAlpha(true)
.allowCustom(true)
.showOutline(0x46000000)
.gridNumColumn(5)
.choiceMode(SimpleColorDialog.SINGLE_CHOICE)
.neg()
.show(this@ProfileStatsConfigure, tag)
}
binding.useAppTheme.setOnCheckedChangeListener { _, isChecked ->
isMonetEnabled = isChecked
if (isChecked) {
binding.topBackgroundButton.visibility = View.GONE
binding.bottomBackgroundButton.visibility = View.GONE
binding.titleColorButton.visibility = View.GONE
binding.statsColorButton.visibility = View.GONE
themeColors()
} else {
binding.topBackgroundButton.visibility = View.VISIBLE
binding.bottomBackgroundButton.visibility = View.VISIBLE
binding.titleColorButton.visibility = View.VISIBLE
binding.statsColorButton.visibility = View.VISIBLE
}
}
binding.addButton.setOnClickListener(onClickListener)
// Find the widget id from the intent.
@ -90,7 +165,94 @@ class ProfileStatsConfigure : Activity() {
}
}
private fun themeColors() {
val typedValueSurface = TypedValue()
theme.resolveAttribute(
com.google.android.material.R.attr.colorSurface,
typedValueSurface,
true
)
val backgroundColor = typedValueSurface.data
val typedValuePrimary = TypedValue()
theme.resolveAttribute(
com.google.android.material.R.attr.colorPrimary,
typedValuePrimary,
true
)
val textColor = typedValuePrimary.data
val typedValueOutline = TypedValue()
theme.resolveAttribute(
com.google.android.material.R.attr.colorOutline,
typedValueOutline,
true
)
val subTextColor = typedValueOutline.data
getSharedPreferences(ProfileStatsWidget.PREFS_NAME, Context.MODE_PRIVATE).edit().apply {
putInt(ProfileStatsWidget.PREF_BACKGROUND_COLOR, backgroundColor)
putInt(ProfileStatsWidget.PREF_BACKGROUND_FADE, backgroundColor)
putInt(ProfileStatsWidget.PREF_TITLE_TEXT_COLOR, textColor)
putInt(ProfileStatsWidget.PREF_STATS_TEXT_COLOR, subTextColor)
apply()
}
}
private const val PROFILE_STATS_PREFS = "ani.dantotsu.widget.ProfileStatsWidget"
private const val PROFILE_STATS_PREFS_PREFIX = "appwidget_"
override fun onResult(dialogTag: String, which: Int, extras: Bundle): Boolean {
if (which == SimpleDialog.OnDialogResultListener.BUTTON_POSITIVE) {
if (!isMonetEnabled) {
when (dialogTag) {
ProfileStatsWidget.PREF_BACKGROUND_COLOR -> {
getSharedPreferences(
ProfileStatsWidget.PREFS_NAME,
Context.MODE_PRIVATE
).edit()
.putInt(
ProfileStatsWidget.PREF_BACKGROUND_COLOR,
extras.getInt(SimpleColorDialog.COLOR)
)
.apply()
}
ProfileStatsWidget.PREF_BACKGROUND_FADE -> {
getSharedPreferences(
ProfileStatsWidget.PREFS_NAME,
Context.MODE_PRIVATE
).edit()
.putInt(
ProfileStatsWidget.PREF_BACKGROUND_FADE,
extras.getInt(SimpleColorDialog.COLOR)
)
.apply()
}
ProfileStatsWidget.PREF_TITLE_TEXT_COLOR -> {
getSharedPreferences(
ProfileStatsWidget.PREFS_NAME,
Context.MODE_PRIVATE
).edit()
.putInt(
ProfileStatsWidget.PREF_TITLE_TEXT_COLOR,
extras.getInt(SimpleColorDialog.COLOR)
)
.apply()
}
ProfileStatsWidget.PREF_STATS_TEXT_COLOR -> {
getSharedPreferences(
ProfileStatsWidget.PREFS_NAME,
Context.MODE_PRIVATE
).edit()
.putInt(
ProfileStatsWidget.PREF_STATS_TEXT_COLOR,
extras.getInt(SimpleColorDialog.COLOR)
)
.apply()
}
}
}
}
return true
}
}

View file

@ -94,6 +94,7 @@ class ProfileStatsWidget : AppWidgetProvider() {
prefs.getInt(PREF_BACKGROUND_COLOR, Color.parseColor("#80000000"))
val backgroundFade = prefs.getInt(PREF_BACKGROUND_FADE, Color.parseColor("#00000000"))
val titleTextColor = prefs.getInt(PREF_TITLE_TEXT_COLOR, Color.WHITE)
val statsTextColor = prefs.getInt(PREF_STATS_TEXT_COLOR, Color.WHITE)
val gradientDrawable = ResourcesCompat.getDrawable(
context.resources,
@ -127,14 +128,26 @@ class ProfileStatsWidget : AppWidgetProvider() {
height
)
)
setTextColor(R.id.topLeftItem, titleTextColor)
setTextColor(R.id.topLeftLabel, titleTextColor)
setTextColor(R.id.topRightItem, titleTextColor)
setTextColor(R.id.topRightLabel, titleTextColor)
setTextColor(R.id.bottomLeftItem, titleTextColor)
setTextColor(R.id.bottomLeftLabel, titleTextColor)
setTextColor(R.id.bottomRightItem, titleTextColor)
setTextColor(R.id.bottomRightLabel, titleTextColor)
setOnClickPendingIntent(
R.id.userAvatar,
PendingIntent.getActivity(
context,
1,
Intent(context, ProfileStatsConfigure::class.java).apply {
putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId)
},
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
)
)
setTextColor(R.id.userLabel, titleTextColor)
setTextColor(R.id.topLeftItem, statsTextColor)
setTextColor(R.id.topLeftLabel, statsTextColor)
setTextColor(R.id.topRightItem, statsTextColor)
setTextColor(R.id.topRightLabel, statsTextColor)
setTextColor(R.id.bottomLeftItem, statsTextColor)
setTextColor(R.id.bottomLeftLabel, statsTextColor)
setTextColor(R.id.bottomRightItem, statsTextColor)
setTextColor(R.id.bottomRightLabel, statsTextColor)
setImageViewBitmap(
R.id.userAvatar,
@ -241,5 +254,6 @@ class ProfileStatsWidget : AppWidgetProvider() {
const val PREF_BACKGROUND_COLOR = "background_color"
const val PREF_BACKGROUND_FADE = "background_fade"
const val PREF_TITLE_TEXT_COLOR = "title_text_color"
const val PREF_STATS_TEXT_COLOR = "stats_text_color"
}
}

View file

@ -151,6 +151,28 @@ class UpcomingWidgetConfigureActivity : AppCompatActivity(),
}
}
private fun themeColors() {
val typedValueSurface = TypedValue()
theme.resolveAttribute(com.google.android.material.R.attr.colorSurface, typedValueSurface, true)
val backgroundColor = typedValueSurface.data
val typedValuePrimary = TypedValue()
theme.resolveAttribute(com.google.android.material.R.attr.colorPrimary, typedValuePrimary, true)
val textColor = typedValuePrimary.data
val typedValueOutline = TypedValue()
theme.resolveAttribute(com.google.android.material.R.attr.colorOutline, typedValueOutline, true)
val subTextColor = typedValueOutline.data
getSharedPreferences(UpcomingWidget.PREFS_NAME, Context.MODE_PRIVATE).edit().apply {
putInt(UpcomingWidget.PREF_BACKGROUND_COLOR, backgroundColor)
putInt(UpcomingWidget.PREF_BACKGROUND_FADE, backgroundColor)
putInt(UpcomingWidget.PREF_TITLE_TEXT_COLOR, textColor)
putInt(UpcomingWidget.PREF_COUNTDOWN_TEXT_COLOR, subTextColor)
apply()
}
}
override fun onResult(dialogTag: String, which: Int, extras: Bundle): Boolean {
if (which == SimpleDialog.OnDialogResultListener.BUTTON_POSITIVE) {
if (!isMonetEnabled) {
@ -208,26 +230,4 @@ class UpcomingWidgetConfigureActivity : AppCompatActivity(),
}
return true
}
private fun themeColors() {
val typedValueSurface = TypedValue()
theme.resolveAttribute(com.google.android.material.R.attr.colorSurface, typedValueSurface, true)
val backgroundColor = typedValueSurface.data
val typedValuePrimary = TypedValue()
theme.resolveAttribute(com.google.android.material.R.attr.colorPrimary, typedValuePrimary, true)
val textColor = typedValuePrimary.data
val typedValueOutline = TypedValue()
theme.resolveAttribute(com.google.android.material.R.attr.colorOutline, typedValueOutline, true)
val subTextColor = typedValueOutline.data
getSharedPreferences(UpcomingWidget.PREFS_NAME, Context.MODE_PRIVATE).edit().apply {
putInt(UpcomingWidget.PREF_BACKGROUND_COLOR, backgroundColor)
putInt(UpcomingWidget.PREF_BACKGROUND_FADE, backgroundColor)
putInt(UpcomingWidget.PREF_TITLE_TEXT_COLOR, textColor)
putInt(UpcomingWidget.PREF_COUNTDOWN_TEXT_COLOR, subTextColor)
apply()
}
}
}

View file

@ -77,6 +77,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:fontFamily="@font/poppins_semi_bold"
android:text="@string/anime_watched" />
</LinearLayout>
@ -107,6 +108,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:fontFamily="@font/poppins_semi_bold"
android:text="@string/episodes_watched"/>
</LinearLayout>
@ -147,7 +149,8 @@
android:layout_height="wrap_content"
android:fontFamily="@font/poppins_semi_bold"
android:text="@string/manga_read"
android:layout_gravity="center"/>
android:layout_gravity="center"
android:gravity="center"/>
</LinearLayout>
<RelativeLayout
@ -176,6 +179,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:fontFamily="@font/poppins_semi_bold"
android:text="@string/chapters_read"/>
</LinearLayout>

View file

@ -14,6 +14,121 @@
android:fontFamily="@font/poppins_bold"
android:text="@string/profile_stats_widget" />
<com.google.android.material.materialswitch.MaterialSwitch
android:id="@+id/useAppTheme"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:checked="false"
android:drawableStart="@drawable/ic_round_new_releases_24"
android:drawablePadding="16dp"
android:elegantTextHeight="true"
android:fontFamily="@font/poppins_bold"
android:minHeight="64dp"
android:text="@string/use_app_theme"
android:textAlignment="viewStart"
android:textColor="?attr/colorOnBackground"
app:cornerRadius="0dp"
app:drawableTint="?attr/colorPrimary"
app:showText="false"
app:thumbTint="@color/button_switch_track" />
<Button
android:id="@+id/topBackgroundButton"
android:layout_width="match_parent"
android:layout_height="64dp"
android:layout_marginStart="-31dp"
android:layout_marginEnd="-31dp"
android:background="@drawable/ui_bg"
android:backgroundTint="?attr/colorSecondary"
android:backgroundTintMode="src_atop"
android:fontFamily="@font/poppins_bold"
android:insetTop="0dp"
android:insetBottom="0dp"
android:paddingStart="31dp"
android:paddingEnd="31dp"
android:text="@string/top_background_color"
android:textAlignment="viewStart"
android:textAllCaps="false"
android:textColor="?attr/colorOnBackground"
app:cornerRadius="0dp"
app:icon="@drawable/ic_round_color_picker_24"
app:iconPadding="16dp"
app:iconSize="24dp"
app:iconTint="?attr/colorPrimary" />
<Button
android:id="@+id/bottomBackgroundButton"
android:layout_width="match_parent"
android:layout_height="64dp"
android:layout_marginStart="-31dp"
android:layout_marginEnd="-31dp"
android:background="@drawable/ui_bg"
android:backgroundTint="?attr/colorSecondary"
android:backgroundTintMode="src_atop"
android:fontFamily="@font/poppins_bold"
android:insetTop="0dp"
android:insetBottom="0dp"
android:paddingStart="31dp"
android:paddingEnd="31dp"
android:text="@string/bottom_background_color"
android:textAlignment="viewStart"
android:textAllCaps="false"
android:textColor="?attr/colorOnBackground"
app:cornerRadius="0dp"
app:icon="@drawable/ic_round_color_picker_24"
app:iconPadding="16dp"
app:iconSize="24dp"
app:iconTint="?attr/colorPrimary" />
<Button
android:id="@+id/titleColorButton"
android:layout_width="match_parent"
android:layout_height="64dp"
android:layout_marginStart="-31dp"
android:layout_marginEnd="-31dp"
android:background="@drawable/ui_bg"
android:backgroundTint="?attr/colorSecondary"
android:backgroundTintMode="src_atop"
android:fontFamily="@font/poppins_bold"
android:insetTop="0dp"
android:insetBottom="0dp"
android:paddingStart="31dp"
android:paddingEnd="31dp"
android:text="@string/title_color"
android:textAlignment="viewStart"
android:textAllCaps="false"
android:textColor="?attr/colorOnBackground"
app:cornerRadius="0dp"
app:icon="@drawable/ic_round_color_picker_24"
app:iconPadding="16dp"
app:iconSize="24dp"
app:iconTint="?attr/colorPrimary" />
<Button
android:id="@+id/statsColorButton"
android:layout_width="match_parent"
android:layout_height="64dp"
android:layout_marginStart="-31dp"
android:layout_marginEnd="-31dp"
android:background="@drawable/ui_bg"
android:backgroundTint="?attr/colorSecondary"
android:backgroundTintMode="src_atop"
android:fontFamily="@font/poppins_bold"
android:insetTop="0dp"
android:insetBottom="0dp"
android:paddingStart="31dp"
android:paddingEnd="31dp"
android:text="@string/stat_text_color"
android:textAlignment="viewStart"
android:textAllCaps="false"
android:textColor="?attr/colorOnBackground"
app:cornerRadius="0dp"
app:icon="@drawable/ic_round_color_picker_24"
app:iconPadding="16dp"
app:iconSize="24dp"
app:iconTint="?attr/colorPrimary" />
<com.google.android.material.button.MaterialButton
android:id="@+id/add_button"
android:layout_width="match_parent"

View file

@ -130,7 +130,7 @@
<Button
android:id="@+id/add_button"
android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="@string/add_widget" />

View file

@ -835,5 +835,6 @@ Non quae tempore quo provident laudantium qui illo dolor vel quia dolor et exerc
<string name="bottom_background_color">Bottom Background Color</string>
<string name="countdown_text_color">Countdown Text Color</string>
<string name="title_color">Title Color</string>
<string name="stat_text_color">Stats Text Color</string>
<string name="placeholder">Placeholder</string>
</resources>