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.appwidget.AppWidgetManager
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.graphics.Color
import android.os.Bundle import android.os.Bundle
import android.util.TypedValue import android.util.TypedValue
import android.view.View import android.view.View
import androidx.appcompat.app.AppCompatActivity
import ani.dantotsu.R
import ani.dantotsu.databinding.StatisticsWidgetConfigureBinding import ani.dantotsu.databinding.StatisticsWidgetConfigureBinding
import ani.dantotsu.themes.ThemeManager 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. * The configuration screen for the [ProfileStatsWidget] AppWidget.
*/ */
class ProfileStatsConfigure : Activity() { class ProfileStatsConfigure : AppCompatActivity(),
SimpleDialog.OnDialogResultListener {
private var appWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID private var appWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID
private var isMonetEnabled = false
private var onClickListener = View.OnClickListener { private var onClickListener = View.OnClickListener {
val context = this@ProfileStatsConfigure val context = this@ProfileStatsConfigure
@ -51,25 +58,93 @@ class ProfileStatsConfigure : Activity() {
binding = StatisticsWidgetConfigureBinding.inflate(layoutInflater) binding = StatisticsWidgetConfigureBinding.inflate(layoutInflater)
setContentView(binding.root) setContentView(binding.root)
val typedValueSurface = TypedValue() val prefs = getSharedPreferences(ProfileStatsWidget.PREFS_NAME, Context.MODE_PRIVATE)
theme.resolveAttribute(com.google.android.material.R.attr.colorSurface, typedValueSurface, true)
val backgroundColor = typedValueSurface.data
val typedValuePrimary = TypedValue() binding.topBackgroundButton.setOnClickListener {
theme.resolveAttribute(com.google.android.material.R.attr.colorPrimary, typedValuePrimary, true) val tag = ProfileStatsWidget.PREF_BACKGROUND_COLOR
val textColor = typedValuePrimary.data SimpleColorDialog().title(R.string.custom_theme)
.colorPreset(
val typedValueOutline = TypedValue() prefs.getInt(
theme.resolveAttribute(com.google.android.material.R.attr.colorOutline, typedValueOutline, true) ProfileStatsWidget.PREF_BACKGROUND_COLOR,
val subTextColor = typedValueOutline.data Color.parseColor("#80000000")
)
getSharedPreferences(ProfileStatsWidget.PREFS_NAME, Context.MODE_PRIVATE).edit().apply { )
putInt(ProfileStatsWidget.PREF_BACKGROUND_COLOR, backgroundColor) .colors(
putInt(ProfileStatsWidget.PREF_BACKGROUND_FADE, backgroundColor) this@ProfileStatsConfigure,
putInt(ProfileStatsWidget.PREF_TITLE_TEXT_COLOR, textColor) SimpleColorDialog.MATERIAL_COLOR_PALLET
apply() )
.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) binding.addButton.setOnClickListener(onClickListener)
// Find the widget id from the intent. // 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
private const val PROFILE_STATS_PREFS = "ani.dantotsu.widget.ProfileStatsWidget" val typedValuePrimary = TypedValue()
private const val PROFILE_STATS_PREFS_PREFIX = "appwidget_" 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()
}
}
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")) prefs.getInt(PREF_BACKGROUND_COLOR, Color.parseColor("#80000000"))
val backgroundFade = prefs.getInt(PREF_BACKGROUND_FADE, Color.parseColor("#00000000")) val backgroundFade = prefs.getInt(PREF_BACKGROUND_FADE, Color.parseColor("#00000000"))
val titleTextColor = prefs.getInt(PREF_TITLE_TEXT_COLOR, Color.WHITE) val titleTextColor = prefs.getInt(PREF_TITLE_TEXT_COLOR, Color.WHITE)
val statsTextColor = prefs.getInt(PREF_STATS_TEXT_COLOR, Color.WHITE)
val gradientDrawable = ResourcesCompat.getDrawable( val gradientDrawable = ResourcesCompat.getDrawable(
context.resources, context.resources,
@ -127,14 +128,26 @@ class ProfileStatsWidget : AppWidgetProvider() {
height height
) )
) )
setTextColor(R.id.topLeftItem, titleTextColor) setOnClickPendingIntent(
setTextColor(R.id.topLeftLabel, titleTextColor) R.id.userAvatar,
setTextColor(R.id.topRightItem, titleTextColor) PendingIntent.getActivity(
setTextColor(R.id.topRightLabel, titleTextColor) context,
setTextColor(R.id.bottomLeftItem, titleTextColor) 1,
setTextColor(R.id.bottomLeftLabel, titleTextColor) Intent(context, ProfileStatsConfigure::class.java).apply {
setTextColor(R.id.bottomRightItem, titleTextColor) putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId)
setTextColor(R.id.bottomRightLabel, titleTextColor) },
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( setImageViewBitmap(
R.id.userAvatar, R.id.userAvatar,
@ -241,5 +254,6 @@ class ProfileStatsWidget : AppWidgetProvider() {
const val PREF_BACKGROUND_COLOR = "background_color" const val PREF_BACKGROUND_COLOR = "background_color"
const val PREF_BACKGROUND_FADE = "background_fade" const val PREF_BACKGROUND_FADE = "background_fade"
const val PREF_TITLE_TEXT_COLOR = "title_text_color" 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 { override fun onResult(dialogTag: String, which: Int, extras: Bundle): Boolean {
if (which == SimpleDialog.OnDialogResultListener.BUTTON_POSITIVE) { if (which == SimpleDialog.OnDialogResultListener.BUTTON_POSITIVE) {
if (!isMonetEnabled) { if (!isMonetEnabled) {
@ -208,26 +230,4 @@ class UpcomingWidgetConfigureActivity : AppCompatActivity(),
} }
return true 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_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_gravity="center"
android:gravity="center"
android:fontFamily="@font/poppins_semi_bold" android:fontFamily="@font/poppins_semi_bold"
android:text="@string/anime_watched" /> android:text="@string/anime_watched" />
</LinearLayout> </LinearLayout>
@ -107,6 +108,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_gravity="center"
android:gravity="center"
android:fontFamily="@font/poppins_semi_bold" android:fontFamily="@font/poppins_semi_bold"
android:text="@string/episodes_watched"/> android:text="@string/episodes_watched"/>
</LinearLayout> </LinearLayout>
@ -147,7 +149,8 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:fontFamily="@font/poppins_semi_bold" android:fontFamily="@font/poppins_semi_bold"
android:text="@string/manga_read" android:text="@string/manga_read"
android:layout_gravity="center"/> android:layout_gravity="center"
android:gravity="center"/>
</LinearLayout> </LinearLayout>
<RelativeLayout <RelativeLayout
@ -176,6 +179,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center" android:layout_gravity="center"
android:gravity="center"
android:fontFamily="@font/poppins_semi_bold" android:fontFamily="@font/poppins_semi_bold"
android:text="@string/chapters_read"/> android:text="@string/chapters_read"/>
</LinearLayout> </LinearLayout>

View file

@ -14,6 +14,121 @@
android:fontFamily="@font/poppins_bold" android:fontFamily="@font/poppins_bold"
android:text="@string/profile_stats_widget" /> 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 <com.google.android.material.button.MaterialButton
android:id="@+id/add_button" android:id="@+id/add_button"
android:layout_width="match_parent" android:layout_width="match_parent"

View file

@ -130,7 +130,7 @@
<Button <Button
android:id="@+id/add_button" android:id="@+id/add_button"
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="8dp" android:layout_marginTop="8dp"
android:text="@string/add_widget" /> 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="bottom_background_color">Bottom Background Color</string>
<string name="countdown_text_color">Countdown Text Color</string> <string name="countdown_text_color">Countdown Text Color</string>
<string name="title_color">Title Color</string> <string name="title_color">Title Color</string>
<string name="stat_text_color">Stats Text Color</string>
<string name="placeholder">Placeholder</string> <string name="placeholder">Placeholder</string>
</resources> </resources>