Remove color.toThemedAndroidColor

Fixes #907
pull/1050/head
Alinson S. Xavier 4 years ago
parent 271de59a94
commit b54711243f
No known key found for this signature in database
GPG Key ID: DCA0DAD4D2F58624

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

@ -23,6 +23,7 @@ import androidx.test.filters.MediumTest
import org.isoron.uhabits.BaseViewTest import org.isoron.uhabits.BaseViewTest
import org.isoron.uhabits.core.models.Habit import org.isoron.uhabits.core.models.Habit
import org.isoron.uhabits.core.ui.screens.habits.show.views.ScoreCardPresenter.Companion.buildState import org.isoron.uhabits.core.ui.screens.habits.show.views.ScoreCardPresenter.Companion.buildState
import org.isoron.uhabits.core.ui.views.LightTheme
import org.isoron.uhabits.utils.toFixedAndroidColor import org.isoron.uhabits.utils.toFixedAndroidColor
import org.junit.Before import org.junit.Before
import org.junit.Test import org.junit.Test
@ -39,7 +40,12 @@ class ScoreChartTest : BaseViewTest() {
super.setUp() super.setUp()
fixtures.purgeHabits(habitList) fixtures.purgeHabits(habitList)
habit = fixtures.createLongHabit() habit = fixtures.createLongHabit()
val state = buildState(habit, prefs.firstWeekdayInt, 0) val state = buildState(
habit = habit,
firstWeekday = prefs.firstWeekdayInt,
spinnerPosition = 0,
theme = LightTheme(),
)
view = ScoreChart(targetContext).apply { view = ScoreChart(targetContext).apply {
setScores(state.scores) setScores(state.scores)
setColor(state.color.toFixedAndroidColor()) setColor(state.color.toFixedAndroidColor())
@ -72,7 +78,7 @@ class ScoreChartTest : BaseViewTest() {
@Test @Test
@Throws(Throwable::class) @Throws(Throwable::class)
fun testRender_withMonthlyBucket() { fun testRender_withMonthlyBucket() {
val (scores, bucketSize) = buildState(habit, prefs.firstWeekdayInt, 2) val (scores, bucketSize) = buildState(habit, prefs.firstWeekdayInt, 2, LightTheme())
view.setScores(scores) view.setScores(scores)
view.setBucketSize(bucketSize) view.setBucketSize(bucketSize)
view.invalidate() view.invalidate()
@ -89,7 +95,7 @@ class ScoreChartTest : BaseViewTest() {
@Test @Test
@Throws(Throwable::class) @Throws(Throwable::class)
fun testRender_withYearlyBucket() { fun testRender_withYearlyBucket() {
val state = buildState(habit, prefs.firstWeekdayInt, 4) val state = buildState(habit, prefs.firstWeekdayInt, 4, LightTheme())
view.setScores(state.scores) view.setScores(state.scores)
view.setBucketSize(state.bucketSize) view.setBucketSize(state.bucketSize)
view.invalidate() view.invalidate()

@ -25,6 +25,7 @@ import androidx.test.filters.MediumTest
import org.isoron.uhabits.BaseViewTest import org.isoron.uhabits.BaseViewTest
import org.isoron.uhabits.R import org.isoron.uhabits.R
import org.isoron.uhabits.core.ui.screens.habits.show.views.FrequencyCardPresenter import org.isoron.uhabits.core.ui.screens.habits.show.views.FrequencyCardPresenter
import org.isoron.uhabits.core.ui.views.LightTheme
import org.junit.Before import org.junit.Before
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
@ -43,7 +44,13 @@ class FrequencyCardViewTest : BaseViewTest() {
.from(targetContext) .from(targetContext)
.inflate(R.layout.show_habit, null) .inflate(R.layout.show_habit, null)
.findViewById<View>(R.id.frequencyCard) as FrequencyCardView .findViewById<View>(R.id.frequencyCard) as FrequencyCardView
view.setState(FrequencyCardPresenter.buildState(habit = habit, firstWeekday = 0)) view.setState(
FrequencyCardPresenter.buildState(
habit = habit,
firstWeekday = 0,
theme = LightTheme(),
)
)
measureView(view, 800f, 600f) measureView(view, 800f, 600f)
} }

@ -26,6 +26,7 @@ import org.isoron.uhabits.BaseViewTest
import org.isoron.uhabits.R import org.isoron.uhabits.R
import org.isoron.uhabits.core.models.PaletteColor import org.isoron.uhabits.core.models.PaletteColor
import org.isoron.uhabits.core.ui.screens.habits.show.views.OverviewCardState import org.isoron.uhabits.core.ui.screens.habits.show.views.OverviewCardState
import org.isoron.uhabits.core.ui.views.LightTheme
import org.junit.Before import org.junit.Before
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
@ -50,6 +51,7 @@ class OverviewCardViewTest : BaseViewTest() {
scoreYearDiff = 0.74f, scoreYearDiff = 0.74f,
totalCount = 44, totalCount = 44,
color = PaletteColor(7), color = PaletteColor(7),
theme = LightTheme(),
) )
) )
measureView(view, 800f, 300f) measureView(view, 800f, 300f)

@ -25,6 +25,7 @@ import androidx.test.filters.MediumTest
import org.isoron.uhabits.BaseViewTest import org.isoron.uhabits.BaseViewTest
import org.isoron.uhabits.R import org.isoron.uhabits.R
import org.isoron.uhabits.core.ui.screens.habits.show.views.ScoreCardPresenter.Companion.buildState import org.isoron.uhabits.core.ui.screens.habits.show.views.ScoreCardPresenter.Companion.buildState
import org.isoron.uhabits.core.ui.views.LightTheme
import org.junit.Before import org.junit.Before
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
@ -43,7 +44,14 @@ class ScoreCardViewTest : BaseViewTest() {
.from(targetContext) .from(targetContext)
.inflate(R.layout.show_habit, null) .inflate(R.layout.show_habit, null)
.findViewById<View>(R.id.scoreCard) as ScoreCardView .findViewById<View>(R.id.scoreCard) as ScoreCardView
view.setState(buildState(habit = habit, firstWeekday = 0, spinnerPosition = 0)) view.setState(
buildState(
habit = habit,
firstWeekday = 0,
spinnerPosition = 0,
theme = LightTheme(),
)
)
measureView(view, 800f, 600f) measureView(view, 800f, 600f)
} }

@ -25,6 +25,7 @@ import androidx.test.filters.MediumTest
import org.isoron.uhabits.BaseViewTest import org.isoron.uhabits.BaseViewTest
import org.isoron.uhabits.R import org.isoron.uhabits.R
import org.isoron.uhabits.core.ui.screens.habits.show.views.StreakCardState import org.isoron.uhabits.core.ui.screens.habits.show.views.StreakCardState
import org.isoron.uhabits.core.ui.views.LightTheme
import org.junit.Before import org.junit.Before
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
@ -47,6 +48,7 @@ class StreakCardViewTest : BaseViewTest() {
StreakCardState( StreakCardState(
bestStreaks = habit.streaks.getBest(10), bestStreaks = habit.streaks.getBest(10),
color = habit.color, color = habit.color,
theme = LightTheme(),
) )
) )
measureView(view, 800f, 600f) measureView(view, 800f, 600f)

@ -28,6 +28,7 @@ import org.isoron.uhabits.core.models.PaletteColor
import org.isoron.uhabits.core.models.Reminder import org.isoron.uhabits.core.models.Reminder
import org.isoron.uhabits.core.models.WeekdayList.Companion.EVERY_DAY import org.isoron.uhabits.core.models.WeekdayList.Companion.EVERY_DAY
import org.isoron.uhabits.core.ui.screens.habits.show.views.SubtitleCardState import org.isoron.uhabits.core.ui.screens.habits.show.views.SubtitleCardState
import org.isoron.uhabits.core.ui.views.LightTheme
import org.junit.Before import org.junit.Before
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
@ -54,6 +55,7 @@ class SubtitleCardViewTest : BaseViewTest() {
reminder = Reminder(8, 30, EVERY_DAY), reminder = Reminder(8, 30, EVERY_DAY),
unit = "", unit = "",
targetValue = 0.0, targetValue = 0.0,
theme = LightTheme(),
) )
) )
measureView(view, 800f, 200f) measureView(view, 800f, 200f)

@ -26,6 +26,7 @@ import org.isoron.uhabits.BuildConfig
import org.isoron.uhabits.R import org.isoron.uhabits.R
import org.isoron.uhabits.core.models.PaletteColor import org.isoron.uhabits.core.models.PaletteColor
import org.isoron.uhabits.databinding.AboutBinding import org.isoron.uhabits.databinding.AboutBinding
import org.isoron.uhabits.utils.currentTheme
import org.isoron.uhabits.utils.setupToolbar import org.isoron.uhabits.utils.setupToolbar
@SuppressLint("ViewConstructor") @SuppressLint("ViewConstructor")
@ -41,7 +42,8 @@ class AboutView(
setupToolbar( setupToolbar(
toolbar = binding.toolbar, toolbar = binding.toolbar,
color = PaletteColor(11), color = PaletteColor(11),
title = resources.getString(R.string.about) title = resources.getString(R.string.about),
theme = currentTheme(),
) )
val version = resources.getString(R.string.version_n) val version = resources.getString(R.string.version_n)
binding.tvContributors.setOnClickListener { screen.showCodeContributorsWebsite() } binding.tvContributors.setOnClickListener { screen.showCodeContributorsWebsite() }

@ -19,20 +19,21 @@
package org.isoron.uhabits.activities.common.dialogs package org.isoron.uhabits.activities.common.dialogs
import android.content.Context import android.content.Context
import org.isoron.platform.gui.toInt
import org.isoron.uhabits.R import org.isoron.uhabits.R
import org.isoron.uhabits.core.models.PaletteColor import org.isoron.uhabits.core.models.PaletteColor
import org.isoron.uhabits.core.ui.views.Theme
import org.isoron.uhabits.inject.ActivityContext import org.isoron.uhabits.inject.ActivityContext
import org.isoron.uhabits.inject.ActivityScope import org.isoron.uhabits.inject.ActivityScope
import org.isoron.uhabits.utils.StyledResources import org.isoron.uhabits.utils.StyledResources
import org.isoron.uhabits.utils.toThemedAndroidColor
import javax.inject.Inject import javax.inject.Inject
@ActivityScope @ActivityScope
class ColorPickerDialogFactory @Inject constructor(@param:ActivityContext private val context: Context) { class ColorPickerDialogFactory @Inject constructor(@param:ActivityContext private val context: Context) {
fun create(color: PaletteColor): ColorPickerDialog { fun create(color: PaletteColor, theme: Theme): ColorPickerDialog {
val dialog = ColorPickerDialog() val dialog = ColorPickerDialog()
val res = StyledResources(context) val res = StyledResources(context)
val androidColor = color.toThemedAndroidColor(context) val androidColor = theme.color(color).toInt()
dialog.initialize( dialog.initialize(
R.string.color_picker_default_title, R.string.color_picker_default_title,
res.getPalette(), res.getPalette(),

@ -40,6 +40,7 @@ import kotlinx.android.synthetic.main.activity_edit_habit.notesInput
import kotlinx.android.synthetic.main.activity_edit_habit.questionInput import kotlinx.android.synthetic.main.activity_edit_habit.questionInput
import kotlinx.android.synthetic.main.activity_edit_habit.targetInput import kotlinx.android.synthetic.main.activity_edit_habit.targetInput
import kotlinx.android.synthetic.main.activity_edit_habit.unitInput import kotlinx.android.synthetic.main.activity_edit_habit.unitInput
import org.isoron.platform.gui.toInt
import org.isoron.uhabits.HabitsApplication import org.isoron.uhabits.HabitsApplication
import org.isoron.uhabits.R import org.isoron.uhabits.R
import org.isoron.uhabits.activities.AndroidThemeSwitcher import org.isoron.uhabits.activities.AndroidThemeSwitcher
@ -58,7 +59,6 @@ import org.isoron.uhabits.databinding.ActivityEditHabitBinding
import org.isoron.uhabits.utils.ColorUtils import org.isoron.uhabits.utils.ColorUtils
import org.isoron.uhabits.utils.formatTime import org.isoron.uhabits.utils.formatTime
import org.isoron.uhabits.utils.toFormattedString import org.isoron.uhabits.utils.toFormattedString
import org.isoron.uhabits.utils.toThemedAndroidColor
fun formatFrequency(freqNum: Int, freqDen: Int, resources: Resources) = when { fun formatFrequency(freqNum: Int, freqDen: Int, resources: Resources) = when {
freqNum == 1 && (freqDen == 30 || freqDen == 31) -> resources.getString(R.string.every_month) freqNum == 1 && (freqDen == 30 || freqDen == 31) -> resources.getString(R.string.every_month)
@ -148,7 +148,7 @@ class EditHabitActivity : AppCompatActivity() {
val colorPickerDialogFactory = ColorPickerDialogFactory(this) val colorPickerDialogFactory = ColorPickerDialogFactory(this)
binding.colorButton.setOnClickListener { binding.colorButton.setOnClickListener {
val dialog = colorPickerDialogFactory.create(color) val dialog = colorPickerDialogFactory.create(color, themeSwitcher.currentTheme)
dialog.setListener { paletteColor -> dialog.setListener { paletteColor ->
this.color = paletteColor this.color = paletteColor
updateColors() updateColors()
@ -320,7 +320,7 @@ class EditHabitActivity : AppCompatActivity() {
} }
private fun updateColors() { private fun updateColors() {
androidColor = color.toThemedAndroidColor(this) androidColor = themeSwitcher.currentTheme.color(color).toInt()
binding.colorButton.backgroundTintList = ColorStateList.valueOf(androidColor) binding.colorButton.backgroundTintList = ColorStateList.valueOf(androidColor)
if (!themeSwitcher.isNightMode) { if (!themeSwitcher.isNightMode) {
val darkerAndroidColor = ColorUtils.mixColors(Color.BLACK, androidColor, 0.15f) val darkerAndroidColor = ColorUtils.mixColors(Color.BLACK, androidColor, 0.15f)

@ -44,6 +44,7 @@ import org.isoron.uhabits.utils.addAtBottom
import org.isoron.uhabits.utils.addAtTop import org.isoron.uhabits.utils.addAtTop
import org.isoron.uhabits.utils.addBelow import org.isoron.uhabits.utils.addBelow
import org.isoron.uhabits.utils.buildToolbar import org.isoron.uhabits.utils.buildToolbar
import org.isoron.uhabits.utils.currentTheme
import org.isoron.uhabits.utils.dim import org.isoron.uhabits.utils.dim
import org.isoron.uhabits.utils.dp import org.isoron.uhabits.utils.dp
import org.isoron.uhabits.utils.setupToolbar import org.isoron.uhabits.utils.setupToolbar
@ -93,6 +94,7 @@ class ListHabitsRootView @Inject constructor(
title = resources.getString(R.string.main_activity_title), title = resources.getString(R.string.main_activity_title),
color = PaletteColor(17), color = PaletteColor(17),
displayHomeAsUpEnabled = false, displayHomeAsUpEnabled = false,
theme = currentTheme(),
) )
addView(rootView, MATCH_PARENT, MATCH_PARENT) addView(rootView, MATCH_PARENT, MATCH_PARENT)
listAdapter.setListView(listView) listAdapter.setListView(listView)

@ -217,7 +217,7 @@ class ListHabitsScreen
} }
override fun showColorPicker(defaultColor: PaletteColor, callback: OnColorPickedCallback) { override fun showColorPicker(defaultColor: PaletteColor, callback: OnColorPickedCallback) {
val picker = colorPickerFactory.create(defaultColor) val picker = colorPickerFactory.create(defaultColor, themeSwitcher.currentTheme!!)
picker.setListener(callback) picker.setListener(callback)
picker.show(activity.supportFragmentManager, "picker") picker.show(activity.supportFragmentManager, "picker")
} }

@ -33,6 +33,7 @@ import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
import android.widget.FrameLayout import android.widget.FrameLayout
import android.widget.LinearLayout import android.widget.LinearLayout
import android.widget.TextView import android.widget.TextView
import org.isoron.platform.gui.toInt
import org.isoron.uhabits.R import org.isoron.uhabits.R
import org.isoron.uhabits.activities.common.views.RingView import org.isoron.uhabits.activities.common.views.RingView
import org.isoron.uhabits.core.models.Habit import org.isoron.uhabits.core.models.Habit
@ -41,9 +42,9 @@ import org.isoron.uhabits.core.models.Timestamp
import org.isoron.uhabits.core.ui.screens.habits.list.ListHabitsBehavior import org.isoron.uhabits.core.ui.screens.habits.list.ListHabitsBehavior
import org.isoron.uhabits.core.utils.DateUtils import org.isoron.uhabits.core.utils.DateUtils
import org.isoron.uhabits.inject.ActivityContext import org.isoron.uhabits.inject.ActivityContext
import org.isoron.uhabits.utils.currentTheme
import org.isoron.uhabits.utils.dp import org.isoron.uhabits.utils.dp
import org.isoron.uhabits.utils.sres import org.isoron.uhabits.utils.sres
import org.isoron.uhabits.utils.toThemedAndroidColor
import javax.inject.Inject import javax.inject.Inject
class HabitCardViewFactory class HabitCardViewFactory
@ -213,7 +214,7 @@ class HabitCardView(
fun getActiveColor(habit: Habit): Int { fun getActiveColor(habit: Habit): Int {
return when (habit.isArchived) { return when (habit.isArchived) {
true -> sres.getColor(R.attr.contrast60) true -> sres.getColor(R.attr.contrast60)
false -> habit.color.toThemedAndroidColor(context) false -> currentTheme().color(habit.color).toInt()
} }
} }

@ -35,7 +35,12 @@ class ShowHabitView(context: Context) : FrameLayout(context) {
} }
fun setState(data: ShowHabitState) { fun setState(data: ShowHabitState) {
setupToolbar(binding.toolbar, title = data.title, color = data.color) setupToolbar(
binding.toolbar,
title = data.title,
color = data.color,
theme = data.theme,
)
binding.subtitleCard.setState(data.subtitle) binding.subtitleCard.setState(data.subtitle)
binding.overviewCard.setState(data.overview) binding.overviewCard.setState(data.overview)
binding.notesCard.setState(data.notes) binding.notesCard.setState(data.notes)

@ -24,12 +24,12 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.widget.AdapterView import android.widget.AdapterView
import android.widget.LinearLayout import android.widget.LinearLayout
import org.isoron.platform.gui.toInt
import org.isoron.platform.time.JavaLocalDateFormatter import org.isoron.platform.time.JavaLocalDateFormatter
import org.isoron.uhabits.core.ui.screens.habits.show.views.BarCardPresenter import org.isoron.uhabits.core.ui.screens.habits.show.views.BarCardPresenter
import org.isoron.uhabits.core.ui.screens.habits.show.views.BarCardState import org.isoron.uhabits.core.ui.screens.habits.show.views.BarCardState
import org.isoron.uhabits.core.ui.views.BarChart import org.isoron.uhabits.core.ui.views.BarChart
import org.isoron.uhabits.databinding.ShowHabitBarBinding import org.isoron.uhabits.databinding.ShowHabitBarBinding
import org.isoron.uhabits.utils.toThemedAndroidColor
import java.util.Locale import java.util.Locale
class BarCardView(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) { class BarCardView(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) {
@ -37,7 +37,7 @@ class BarCardView(context: Context, attrs: AttributeSet) : LinearLayout(context,
private var binding = ShowHabitBarBinding.inflate(LayoutInflater.from(context), this) private var binding = ShowHabitBarBinding.inflate(LayoutInflater.from(context), this)
fun setState(state: BarCardState) { fun setState(state: BarCardState) {
val androidColor = state.color.toThemedAndroidColor(context) val androidColor = state.theme.color(state.color).toInt()
binding.chart.view = BarChart(state.theme, JavaLocalDateFormatter(Locale.US)).apply { binding.chart.view = BarChart(state.theme, JavaLocalDateFormatter(Locale.US)).apply {
series = mutableListOf(state.entries.map { it.value / 1000.0 }) series = mutableListOf(state.entries.map { it.value / 1000.0 })
colors = mutableListOf(theme.color(state.color.paletteIndex)) colors = mutableListOf(theme.color(state.color.paletteIndex))

@ -22,16 +22,16 @@ import android.content.Context
import android.util.AttributeSet import android.util.AttributeSet
import android.view.LayoutInflater import android.view.LayoutInflater
import android.widget.LinearLayout import android.widget.LinearLayout
import org.isoron.platform.gui.toInt
import org.isoron.uhabits.core.ui.screens.habits.show.views.FrequencyCardState import org.isoron.uhabits.core.ui.screens.habits.show.views.FrequencyCardState
import org.isoron.uhabits.databinding.ShowHabitFrequencyBinding import org.isoron.uhabits.databinding.ShowHabitFrequencyBinding
import org.isoron.uhabits.utils.toThemedAndroidColor
class FrequencyCardView(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) { class FrequencyCardView(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) {
private var binding = ShowHabitFrequencyBinding.inflate(LayoutInflater.from(context), this) private var binding = ShowHabitFrequencyBinding.inflate(LayoutInflater.from(context), this)
fun setState(state: FrequencyCardState) { fun setState(state: FrequencyCardState) {
val androidColor = state.color.toThemedAndroidColor(context) val androidColor = state.theme.color(state.color).toInt()
binding.frequencyChart.setFrequency(state.frequency) binding.frequencyChart.setFrequency(state.frequency)
binding.frequencyChart.setFirstWeekday(state.firstWeekday) binding.frequencyChart.setFirstWeekday(state.firstWeekday)
binding.title.setTextColor(androidColor) binding.title.setTextColor(androidColor)

@ -22,12 +22,12 @@ import android.content.Context
import android.util.AttributeSet import android.util.AttributeSet
import android.view.LayoutInflater import android.view.LayoutInflater
import android.widget.LinearLayout import android.widget.LinearLayout
import org.isoron.platform.gui.toInt
import org.isoron.platform.time.JavaLocalDateFormatter import org.isoron.platform.time.JavaLocalDateFormatter
import org.isoron.uhabits.core.ui.screens.habits.show.views.HistoryCardPresenter import org.isoron.uhabits.core.ui.screens.habits.show.views.HistoryCardPresenter
import org.isoron.uhabits.core.ui.screens.habits.show.views.HistoryCardState import org.isoron.uhabits.core.ui.screens.habits.show.views.HistoryCardState
import org.isoron.uhabits.core.ui.views.HistoryChart import org.isoron.uhabits.core.ui.views.HistoryChart
import org.isoron.uhabits.databinding.ShowHabitHistoryBinding import org.isoron.uhabits.databinding.ShowHabitHistoryBinding
import org.isoron.uhabits.utils.toThemedAndroidColor
import java.util.Locale import java.util.Locale
class HistoryCardView(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) { class HistoryCardView(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) {
@ -35,7 +35,7 @@ class HistoryCardView(context: Context, attrs: AttributeSet) : LinearLayout(cont
private var binding = ShowHabitHistoryBinding.inflate(LayoutInflater.from(context), this) private var binding = ShowHabitHistoryBinding.inflate(LayoutInflater.from(context), this)
fun setState(state: HistoryCardState) { fun setState(state: HistoryCardState) {
val androidColor = state.color.toThemedAndroidColor(context) val androidColor = state.theme.color(state.color).toInt()
binding.title.setTextColor(androidColor) binding.title.setTextColor(androidColor)
binding.chart.view = HistoryChart( binding.chart.view = HistoryChart(
today = state.today, today = state.today,

@ -22,11 +22,11 @@ import android.content.Context
import android.util.AttributeSet import android.util.AttributeSet
import android.view.LayoutInflater import android.view.LayoutInflater
import android.widget.LinearLayout import android.widget.LinearLayout
import org.isoron.platform.gui.toInt
import org.isoron.uhabits.R import org.isoron.uhabits.R
import org.isoron.uhabits.core.ui.screens.habits.show.views.OverviewCardState import org.isoron.uhabits.core.ui.screens.habits.show.views.OverviewCardState
import org.isoron.uhabits.databinding.ShowHabitOverviewBinding import org.isoron.uhabits.databinding.ShowHabitOverviewBinding
import org.isoron.uhabits.utils.StyledResources import org.isoron.uhabits.utils.StyledResources
import org.isoron.uhabits.utils.toThemedAndroidColor
import kotlin.math.abs import kotlin.math.abs
class OverviewCardView(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) { class OverviewCardView(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) {
@ -42,7 +42,7 @@ class OverviewCardView(context: Context, attrs: AttributeSet) : LinearLayout(con
} }
fun setState(state: OverviewCardState) { fun setState(state: OverviewCardState) {
val androidColor = state.color.toThemedAndroidColor(context) val androidColor = state.theme.color(state.color).toInt()
val res = StyledResources(context) val res = StyledResources(context)
val inactiveColor = res.getColor(R.attr.contrast60) val inactiveColor = res.getColor(R.attr.contrast60)
binding.monthDiffLabel.setTextColor(if (state.scoreMonthDiff >= 0) androidColor else inactiveColor) binding.monthDiffLabel.setTextColor(if (state.scoreMonthDiff >= 0) androidColor else inactiveColor)

@ -24,16 +24,16 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.widget.AdapterView import android.widget.AdapterView
import android.widget.LinearLayout import android.widget.LinearLayout
import org.isoron.platform.gui.toInt
import org.isoron.uhabits.core.ui.screens.habits.show.views.ScoreCardPresenter import org.isoron.uhabits.core.ui.screens.habits.show.views.ScoreCardPresenter
import org.isoron.uhabits.core.ui.screens.habits.show.views.ScoreCardState import org.isoron.uhabits.core.ui.screens.habits.show.views.ScoreCardState
import org.isoron.uhabits.databinding.ShowHabitScoreBinding import org.isoron.uhabits.databinding.ShowHabitScoreBinding
import org.isoron.uhabits.utils.toThemedAndroidColor
class ScoreCardView(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) { class ScoreCardView(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) {
private var binding = ShowHabitScoreBinding.inflate(LayoutInflater.from(context), this) private var binding = ShowHabitScoreBinding.inflate(LayoutInflater.from(context), this)
fun setState(state: ScoreCardState) { fun setState(state: ScoreCardState) {
val androidColor = state.color.toThemedAndroidColor(context) val androidColor = state.theme.color(state.color).toInt()
binding.title.setTextColor(androidColor) binding.title.setTextColor(androidColor)
binding.spinner.setSelection(state.spinnerPosition) binding.spinner.setSelection(state.spinnerPosition)
binding.scoreView.setScores(state.scores) binding.scoreView.setScores(state.scores)

@ -22,16 +22,16 @@ import android.content.Context
import android.util.AttributeSet import android.util.AttributeSet
import android.view.LayoutInflater import android.view.LayoutInflater
import android.widget.LinearLayout import android.widget.LinearLayout
import org.isoron.platform.gui.toInt
import org.isoron.uhabits.core.ui.screens.habits.show.views.StreakCardState import org.isoron.uhabits.core.ui.screens.habits.show.views.StreakCardState
import org.isoron.uhabits.databinding.ShowHabitStreakBinding import org.isoron.uhabits.databinding.ShowHabitStreakBinding
import org.isoron.uhabits.utils.toThemedAndroidColor
class StreakCardView(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) { class StreakCardView(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) {
private val binding = ShowHabitStreakBinding.inflate(LayoutInflater.from(context), this) private val binding = ShowHabitStreakBinding.inflate(LayoutInflater.from(context), this)
fun setState(state: StreakCardState) { fun setState(state: StreakCardState) {
val color = state.color.toThemedAndroidColor(context) val androidColor = state.theme.color(state.color).toInt()
binding.title.setTextColor(color) binding.title.setTextColor(androidColor)
binding.streakChart.setColor(color) binding.streakChart.setColor(androidColor)
binding.streakChart.setStreaks(state.bestStreaks) binding.streakChart.setStreaks(state.bestStreaks)
postInvalidate() postInvalidate()
} }

@ -24,6 +24,7 @@ import android.util.AttributeSet
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.widget.LinearLayout import android.widget.LinearLayout
import org.isoron.platform.gui.toInt
import org.isoron.uhabits.R import org.isoron.uhabits.R
import org.isoron.uhabits.activities.habits.edit.formatFrequency import org.isoron.uhabits.activities.habits.edit.formatFrequency
import org.isoron.uhabits.activities.habits.list.views.toShortString import org.isoron.uhabits.activities.habits.list.views.toShortString
@ -31,7 +32,6 @@ import org.isoron.uhabits.core.ui.screens.habits.show.views.SubtitleCardState
import org.isoron.uhabits.databinding.ShowHabitSubtitleBinding import org.isoron.uhabits.databinding.ShowHabitSubtitleBinding
import org.isoron.uhabits.utils.InterfaceUtils import org.isoron.uhabits.utils.InterfaceUtils
import org.isoron.uhabits.utils.formatTime import org.isoron.uhabits.utils.formatTime
import org.isoron.uhabits.utils.toThemedAndroidColor
class SubtitleCardView(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) { class SubtitleCardView(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) {
@ -46,7 +46,7 @@ class SubtitleCardView(context: Context, attrs: AttributeSet) : LinearLayout(con
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
fun setState(state: SubtitleCardState) { fun setState(state: SubtitleCardState) {
val color = state.color.toThemedAndroidColor(context) val color = state.theme.color(state.color).toInt()
val reminder = state.reminder val reminder = state.reminder
binding.frequencyLabel.text = formatFrequency( binding.frequencyLabel.text = formatFrequency(
state.frequency.numerator, state.frequency.numerator,

@ -23,15 +23,15 @@ import android.content.res.Resources
import android.util.AttributeSet import android.util.AttributeSet
import android.view.LayoutInflater import android.view.LayoutInflater
import android.widget.LinearLayout import android.widget.LinearLayout
import org.isoron.platform.gui.toInt
import org.isoron.uhabits.R import org.isoron.uhabits.R
import org.isoron.uhabits.core.ui.screens.habits.show.views.TargetCardState import org.isoron.uhabits.core.ui.screens.habits.show.views.TargetCardState
import org.isoron.uhabits.databinding.ShowHabitTargetBinding import org.isoron.uhabits.databinding.ShowHabitTargetBinding
import org.isoron.uhabits.utils.toThemedAndroidColor
class TargetCardView(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) { class TargetCardView(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) {
private val binding = ShowHabitTargetBinding.inflate(LayoutInflater.from(context), this) private val binding = ShowHabitTargetBinding.inflate(LayoutInflater.from(context), this)
fun setState(state: TargetCardState) { fun setState(state: TargetCardState) {
val androidColor = state.color.toThemedAndroidColor(context) val androidColor = state.theme.color(state.color).toInt()
binding.targetChart.setValues(state.values) binding.targetChart.setValues(state.values)
binding.targetChart.setTargets(state.targets) binding.targetChart.setTargets(state.targets)
binding.targetChart.setLabels(state.intervals.map { intervalToLabel(resources, it) }) binding.targetChart.setLabels(state.intervals.map { intervalToLabel(resources, it) })

@ -32,13 +32,15 @@ class SettingsActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
val component = (application as HabitsApplication).component val component = (application as HabitsApplication).component
AndroidThemeSwitcher(this, component.preferences).apply() val themeSwitcher = AndroidThemeSwitcher(this, component.preferences)
themeSwitcher.apply()
val binding = SettingsActivityBinding.inflate(LayoutInflater.from(this)) val binding = SettingsActivityBinding.inflate(LayoutInflater.from(this))
binding.root.setupToolbar( binding.root.setupToolbar(
toolbar = binding.toolbar, toolbar = binding.toolbar,
title = resources.getString(R.string.settings), title = resources.getString(R.string.settings),
color = PaletteColor(11), color = PaletteColor(11),
theme = themeSwitcher.currentTheme,
) )
setContentView(binding.root) setContentView(binding.root)
} }

@ -33,6 +33,7 @@ import org.isoron.uhabits.core.models.Habit
import org.isoron.uhabits.core.models.HabitList import org.isoron.uhabits.core.models.HabitList
import org.isoron.uhabits.core.models.PaletteColor import org.isoron.uhabits.core.models.PaletteColor
import org.isoron.uhabits.databinding.AutomationBinding import org.isoron.uhabits.databinding.AutomationBinding
import org.isoron.uhabits.utils.currentTheme
import org.isoron.uhabits.utils.setupToolbar import org.isoron.uhabits.utils.setupToolbar
import java.util.LinkedList import java.util.LinkedList
@ -53,6 +54,7 @@ class EditSettingRootView(
title = resources.getString(R.string.app_name), title = resources.getString(R.string.app_name),
color = PaletteColor(11), color = PaletteColor(11),
displayHomeAsUpEnabled = false, displayHomeAsUpEnabled = false,
theme = currentTheme(),
) )
populateHabitSpinner() populateHabitSpinner()
binding.habitSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { binding.habitSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {

@ -28,6 +28,7 @@ import android.widget.AdapterView.OnItemClickListener
import androidx.fragment.app.FragmentActivity import androidx.fragment.app.FragmentActivity
import com.android.datetimepicker.time.RadialPickerLayout import com.android.datetimepicker.time.RadialPickerLayout
import com.android.datetimepicker.time.TimePickerDialog import com.android.datetimepicker.time.TimePickerDialog
import org.isoron.platform.gui.toInt
import org.isoron.uhabits.HabitsApplication import org.isoron.uhabits.HabitsApplication
import org.isoron.uhabits.R import org.isoron.uhabits.R
import org.isoron.uhabits.activities.AndroidThemeSwitcher import org.isoron.uhabits.activities.AndroidThemeSwitcher
@ -35,14 +36,13 @@ import org.isoron.uhabits.core.models.Habit
import org.isoron.uhabits.core.ui.ThemeSwitcher.Companion.THEME_LIGHT import org.isoron.uhabits.core.ui.ThemeSwitcher.Companion.THEME_LIGHT
import org.isoron.uhabits.receivers.ReminderController import org.isoron.uhabits.receivers.ReminderController
import org.isoron.uhabits.utils.SystemUtils import org.isoron.uhabits.utils.SystemUtils
import org.isoron.uhabits.utils.toThemedAndroidColor
import java.util.Calendar import java.util.Calendar
class SnoozeDelayPickerActivity : FragmentActivity(), OnItemClickListener { class SnoozeDelayPickerActivity : FragmentActivity(), OnItemClickListener {
private var habit: Habit? = null private var habit: Habit? = null
private var reminderController: ReminderController? = null private var reminderController: ReminderController? = null
private var dialog: AlertDialog? = null private var dialog: AlertDialog? = null
private var color: Int = 0 private var androidColor: Int = 0
override fun onCreate(bundle: Bundle?) { override fun onCreate(bundle: Bundle?) {
super.onCreate(bundle) super.onCreate(bundle)
@ -63,7 +63,7 @@ class SnoozeDelayPickerActivity : FragmentActivity(), OnItemClickListener {
habit = appComponent.habitList.getById(ContentUris.parseId(data)) habit = appComponent.habitList.getById(ContentUris.parseId(data))
} }
if (habit == null) finish() if (habit == null) finish()
color = habit!!.color.toThemedAndroidColor(this) androidColor = themeSwitcher.currentTheme.color(habit!!.color).toInt()
reminderController = appComponent.reminderController reminderController = appComponent.reminderController
dialog = AlertDialog.Builder(this) dialog = AlertDialog.Builder(this)
.setTitle(R.string.select_snooze_delay) .setTitle(R.string.select_snooze_delay)
@ -85,7 +85,7 @@ class SnoozeDelayPickerActivity : FragmentActivity(), OnItemClickListener {
calendar[Calendar.HOUR_OF_DAY], calendar[Calendar.HOUR_OF_DAY],
calendar[Calendar.MINUTE], calendar[Calendar.MINUTE],
DateFormat.is24HourFormat(this), DateFormat.is24HourFormat(this),
color androidColor
) )
dialog.show(supportFragmentManager, "timePicker") dialog.show(supportFragmentManager, "timePicker")
} }

@ -21,7 +21,6 @@ package org.isoron.uhabits.utils
import android.content.Context import android.content.Context
import android.graphics.Color import android.graphics.Color
import android.util.Log
import org.isoron.uhabits.core.models.PaletteColor import org.isoron.uhabits.core.models.PaletteColor
object PaletteUtils { object PaletteUtils {
@ -29,16 +28,6 @@ object PaletteUtils {
fun getAndroidTestColor(index: Int) = PaletteColor(index).toFixedAndroidColor() fun getAndroidTestColor(index: Int) = PaletteColor(index).toFixedAndroidColor()
} }
fun PaletteColor.toThemedAndroidColor(context: Context): Int {
val palette = StyledResources(context).getPalette()
return if (paletteIndex in palette.indices) {
palette[paletteIndex]
} else {
Log.w("ColorHelper", "Invalid color: $paletteIndex. Returning default.")
palette[0]
}
}
fun PaletteColor.toFixedAndroidColor(): Int { fun PaletteColor.toFixedAndroidColor(): Int {
return intArrayOf( return intArrayOf(
Color.parseColor("#D32F2F"), // 0 red Color.parseColor("#D32F2F"), // 0 red

@ -40,8 +40,12 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar import androidx.appcompat.widget.Toolbar
import androidx.core.content.FileProvider import androidx.core.content.FileProvider
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
import org.isoron.platform.gui.toInt
import org.isoron.uhabits.HabitsApplication
import org.isoron.uhabits.R import org.isoron.uhabits.R
import org.isoron.uhabits.activities.AndroidThemeSwitcher
import org.isoron.uhabits.core.models.PaletteColor import org.isoron.uhabits.core.models.PaletteColor
import org.isoron.uhabits.core.ui.views.Theme
import java.io.File import java.io.File
fun RelativeLayout.addBelow( fun RelativeLayout.addBelow(
@ -157,6 +161,7 @@ fun View.setupToolbar(
toolbar: Toolbar, toolbar: Toolbar,
title: String, title: String,
color: PaletteColor, color: PaletteColor,
theme: Theme,
displayHomeAsUpEnabled: Boolean = true, displayHomeAsUpEnabled: Boolean = true,
) { ) {
toolbar.elevation = InterfaceUtils.dpToPixels(context, 2f) toolbar.elevation = InterfaceUtils.dpToPixels(context, 2f)
@ -165,7 +170,7 @@ fun View.setupToolbar(
val toolbarColor = if (!res.getBoolean(R.attr.useHabitColorAsPrimary)) { val toolbarColor = if (!res.getBoolean(R.attr.useHabitColorAsPrimary)) {
StyledResources(context).getColor(R.attr.colorPrimary) StyledResources(context).getColor(R.attr.colorPrimary)
} else { } else {
color.toThemedAndroidColor(context) theme.color(color).toInt()
} }
val darkerColor = ColorUtils.mixColors(toolbarColor, Color.BLACK, 0.75f) val darkerColor = ColorUtils.mixColors(toolbarColor, Color.BLACK, 0.75f)
toolbar.background = ColorDrawable(toolbarColor) toolbar.background = ColorDrawable(toolbarColor)
@ -175,6 +180,13 @@ fun View.setupToolbar(
activity.supportActionBar?.setDisplayHomeAsUpEnabled(displayHomeAsUpEnabled) activity.supportActionBar?.setDisplayHomeAsUpEnabled(displayHomeAsUpEnabled)
} }
fun View.currentTheme(): Theme {
val component = (context.applicationContext as HabitsApplication).component
val themeSwitcher = AndroidThemeSwitcher(context, component.preferences)
themeSwitcher.apply()
return themeSwitcher.currentTheme
}
fun Int.toMeasureSpec(mode: Int) = fun Int.toMeasureSpec(mode: Int) =
View.MeasureSpec.makeMeasureSpec(this, mode) View.MeasureSpec.makeMeasureSpec(this, mode)

@ -24,10 +24,11 @@ import android.content.Context
import android.os.Build import android.os.Build
import android.view.View import android.view.View
import androidx.annotation.RequiresApi import androidx.annotation.RequiresApi
import org.isoron.platform.gui.toInt
import org.isoron.uhabits.core.models.Entry import org.isoron.uhabits.core.models.Entry
import org.isoron.uhabits.core.models.Habit import org.isoron.uhabits.core.models.Habit
import org.isoron.uhabits.core.ui.views.WidgetTheme
import org.isoron.uhabits.core.utils.DateUtils import org.isoron.uhabits.core.utils.DateUtils
import org.isoron.uhabits.utils.toThemedAndroidColor
import org.isoron.uhabits.widgets.views.CheckmarkWidgetView import org.isoron.uhabits.widgets.views.CheckmarkWidgetView
open class CheckmarkWidget( open class CheckmarkWidget(
@ -53,7 +54,7 @@ open class CheckmarkWidget(
(widgetView as CheckmarkWidgetView).apply { (widgetView as CheckmarkWidgetView).apply {
val today = DateUtils.getTodayWithOffset() val today = DateUtils.getTodayWithOffset()
setBackgroundAlpha(preferedBackgroundAlpha) setBackgroundAlpha(preferedBackgroundAlpha)
activeColor = habit.color.toThemedAndroidColor(context) activeColor = WidgetTheme().color(habit.color).toInt()
name = habit.name name = habit.name
entryValue = habit.computedEntries.get(today).value entryValue = habit.computedEntries.get(today).value
if (habit.isNumerical) { if (habit.isNumerical) {

@ -22,9 +22,10 @@ package org.isoron.uhabits.widgets
import android.app.PendingIntent import android.app.PendingIntent
import android.content.Context import android.content.Context
import android.view.View import android.view.View
import org.isoron.platform.gui.toInt
import org.isoron.uhabits.activities.common.views.FrequencyChart import org.isoron.uhabits.activities.common.views.FrequencyChart
import org.isoron.uhabits.core.models.Habit import org.isoron.uhabits.core.models.Habit
import org.isoron.uhabits.utils.toThemedAndroidColor import org.isoron.uhabits.core.ui.views.WidgetTheme
import org.isoron.uhabits.widgets.views.GraphWidgetView import org.isoron.uhabits.widgets.views.GraphWidgetView
class FrequencyWidget( class FrequencyWidget(
@ -47,7 +48,7 @@ class FrequencyWidget(
if (preferedBackgroundAlpha >= 255) widgetView.setShadowAlpha(0x4f) if (preferedBackgroundAlpha >= 255) widgetView.setShadowAlpha(0x4f)
(widgetView.dataView as FrequencyChart).apply { (widgetView.dataView as FrequencyChart).apply {
setFirstWeekday(firstWeekday) setFirstWeekday(firstWeekday)
setColor(habit.color.toThemedAndroidColor(context)) setColor(WidgetTheme().color(habit.color).toInt())
setFrequency(habit.originalEntries.computeWeekdayFrequency(habit.isNumerical)) setFrequency(habit.originalEntries.computeWeekdayFrequency(habit.isNumerical))
} }
} }

@ -22,10 +22,11 @@ package org.isoron.uhabits.widgets
import android.app.PendingIntent import android.app.PendingIntent
import android.content.Context import android.content.Context
import android.view.View import android.view.View
import org.isoron.platform.gui.toInt
import org.isoron.uhabits.activities.common.views.ScoreChart import org.isoron.uhabits.activities.common.views.ScoreChart
import org.isoron.uhabits.core.models.Habit import org.isoron.uhabits.core.models.Habit
import org.isoron.uhabits.core.ui.screens.habits.show.views.ScoreCardPresenter import org.isoron.uhabits.core.ui.screens.habits.show.views.ScoreCardPresenter
import org.isoron.uhabits.utils.toThemedAndroidColor import org.isoron.uhabits.core.ui.views.WidgetTheme
import org.isoron.uhabits.widgets.views.GraphWidgetView import org.isoron.uhabits.widgets.views.GraphWidgetView
class ScoreWidget( class ScoreWidget(
@ -44,7 +45,8 @@ class ScoreWidget(
val viewModel = ScoreCardPresenter.buildState( val viewModel = ScoreCardPresenter.buildState(
habit = habit, habit = habit,
firstWeekday = prefs.firstWeekdayInt, firstWeekday = prefs.firstWeekdayInt,
spinnerPosition = prefs.scoreCardSpinnerPosition spinnerPosition = prefs.scoreCardSpinnerPosition,
theme = WidgetTheme(),
) )
val widgetView = view as GraphWidgetView val widgetView = view as GraphWidgetView
widgetView.setBackgroundAlpha(preferedBackgroundAlpha) widgetView.setBackgroundAlpha(preferedBackgroundAlpha)
@ -52,7 +54,7 @@ class ScoreWidget(
(widgetView.dataView as ScoreChart).apply { (widgetView.dataView as ScoreChart).apply {
setIsTransparencyEnabled(true) setIsTransparencyEnabled(true)
setBucketSize(viewModel.bucketSize) setBucketSize(viewModel.bucketSize)
setColor(habit.color.toThemedAndroidColor(context)) setColor(WidgetTheme().color(habit.color).toInt())
setScores(viewModel.scores) setScores(viewModel.scores)
} }
} }

@ -24,9 +24,10 @@ import android.content.Context
import android.view.View import android.view.View
import android.view.ViewGroup.LayoutParams import android.view.ViewGroup.LayoutParams
import android.view.ViewGroup.LayoutParams.MATCH_PARENT import android.view.ViewGroup.LayoutParams.MATCH_PARENT
import org.isoron.platform.gui.toInt
import org.isoron.uhabits.activities.common.views.StreakChart import org.isoron.uhabits.activities.common.views.StreakChart
import org.isoron.uhabits.core.models.Habit import org.isoron.uhabits.core.models.Habit
import org.isoron.uhabits.utils.toThemedAndroidColor import org.isoron.uhabits.core.ui.views.WidgetTheme
import org.isoron.uhabits.widgets.views.GraphWidgetView import org.isoron.uhabits.widgets.views.GraphWidgetView
class StreakWidget( class StreakWidget(
@ -46,7 +47,7 @@ class StreakWidget(
widgetView.setBackgroundAlpha(preferedBackgroundAlpha) widgetView.setBackgroundAlpha(preferedBackgroundAlpha)
if (preferedBackgroundAlpha >= 255) widgetView.setShadowAlpha(0x4f) if (preferedBackgroundAlpha >= 255) widgetView.setShadowAlpha(0x4f)
(widgetView.dataView as StreakChart).apply { (widgetView.dataView as StreakChart).apply {
setColor(habit.color.toThemedAndroidColor(context)) setColor(WidgetTheme().color(habit.color).toInt())
setStreaks(habit.streaks.getBest(maxStreakCount)) setStreaks(habit.streaks.getBest(maxStreakCount))
} }
} }

@ -25,11 +25,12 @@ import android.view.View
import android.view.ViewGroup.LayoutParams import android.view.ViewGroup.LayoutParams
import android.view.ViewGroup.LayoutParams.MATCH_PARENT import android.view.ViewGroup.LayoutParams.MATCH_PARENT
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import org.isoron.platform.gui.toInt
import org.isoron.uhabits.activities.common.views.TargetChart import org.isoron.uhabits.activities.common.views.TargetChart
import org.isoron.uhabits.activities.habits.show.views.TargetCardView.Companion.intervalToLabel import org.isoron.uhabits.activities.habits.show.views.TargetCardView.Companion.intervalToLabel
import org.isoron.uhabits.core.models.Habit import org.isoron.uhabits.core.models.Habit
import org.isoron.uhabits.core.ui.screens.habits.show.views.TargetCardPresenter import org.isoron.uhabits.core.ui.screens.habits.show.views.TargetCardPresenter
import org.isoron.uhabits.utils.toThemedAndroidColor import org.isoron.uhabits.core.ui.views.WidgetTheme
import org.isoron.uhabits.widgets.views.GraphWidgetView import org.isoron.uhabits.widgets.views.GraphWidgetView
class TargetWidget( class TargetWidget(
@ -49,8 +50,12 @@ class TargetWidget(
widgetView.setBackgroundAlpha(preferedBackgroundAlpha) widgetView.setBackgroundAlpha(preferedBackgroundAlpha)
if (preferedBackgroundAlpha >= 255) widgetView.setShadowAlpha(0x4f) if (preferedBackgroundAlpha >= 255) widgetView.setShadowAlpha(0x4f)
val chart = (widgetView.dataView as TargetChart) val chart = (widgetView.dataView as TargetChart)
val data = TargetCardPresenter.buildState(habit, prefs.firstWeekdayInt) val data = TargetCardPresenter.buildState(
chart.setColor(data.color.toThemedAndroidColor(context)) habit = habit,
firstWeekday = prefs.firstWeekdayInt,
theme = WidgetTheme(),
)
chart.setColor(WidgetTheme().color(habit.color).toInt())
chart.setTargets(data.targets) chart.setTargets(data.targets)
chart.setLabels(data.intervals.map { intervalToLabel(context.resources, it) }) chart.setLabels(data.intervals.map { intervalToLabel(context.resources, it) })
chart.setValues(data.values) chart.setValues(data.values)

@ -57,6 +57,7 @@ data class ShowHabitState(
val frequency: FrequencyCardState, val frequency: FrequencyCardState,
val history: HistoryCardState, val history: HistoryCardState,
val bar: BarCardState, val bar: BarCardState,
val theme: Theme,
) )
class ShowHabitPresenter( class ShowHabitPresenter(
@ -94,11 +95,14 @@ class ShowHabitPresenter(
title = habit.name, title = habit.name,
color = habit.color, color = habit.color,
isNumerical = habit.isNumerical, isNumerical = habit.isNumerical,
theme = theme,
subtitle = SubtitleCardPresenter.buildState( subtitle = SubtitleCardPresenter.buildState(
habit = habit, habit = habit,
theme = theme,
), ),
overview = OverviewCardPresenter.buildState( overview = OverviewCardPresenter.buildState(
habit = habit, habit = habit,
theme = theme,
), ),
notes = NotesCardPresenter.buildState( notes = NotesCardPresenter.buildState(
habit = habit, habit = habit,
@ -106,18 +110,22 @@ class ShowHabitPresenter(
target = TargetCardPresenter.buildState( target = TargetCardPresenter.buildState(
habit = habit, habit = habit,
firstWeekday = preferences.firstWeekdayInt, firstWeekday = preferences.firstWeekdayInt,
theme = theme,
), ),
streaks = StreakCartPresenter.buildState( streaks = StreakCartPresenter.buildState(
habit = habit, habit = habit,
theme = theme,
), ),
scores = ScoreCardPresenter.buildState( scores = ScoreCardPresenter.buildState(
spinnerPosition = preferences.scoreCardSpinnerPosition, spinnerPosition = preferences.scoreCardSpinnerPosition,
habit = habit, habit = habit,
firstWeekday = preferences.firstWeekdayInt, firstWeekday = preferences.firstWeekdayInt,
theme = theme,
), ),
frequency = FrequencyCardPresenter.buildState( frequency = FrequencyCardPresenter.buildState(
habit = habit, habit = habit,
firstWeekday = preferences.firstWeekdayInt, firstWeekday = preferences.firstWeekdayInt,
theme = theme,
), ),
history = HistoryCardPresenter.buildState( history = HistoryCardPresenter.buildState(
habit = habit, habit = habit,

@ -22,12 +22,14 @@ package org.isoron.uhabits.core.ui.screens.habits.show.views
import org.isoron.uhabits.core.models.Habit import org.isoron.uhabits.core.models.Habit
import org.isoron.uhabits.core.models.PaletteColor import org.isoron.uhabits.core.models.PaletteColor
import org.isoron.uhabits.core.models.Timestamp import org.isoron.uhabits.core.models.Timestamp
import org.isoron.uhabits.core.ui.views.Theme
import java.util.HashMap import java.util.HashMap
data class FrequencyCardState( data class FrequencyCardState(
val color: PaletteColor, val color: PaletteColor,
val firstWeekday: Int, val firstWeekday: Int,
val frequency: HashMap<Timestamp, Array<Int>>, val frequency: HashMap<Timestamp, Array<Int>>,
val theme: Theme,
) )
class FrequencyCardPresenter { class FrequencyCardPresenter {
@ -35,12 +37,14 @@ class FrequencyCardPresenter {
fun buildState( fun buildState(
habit: Habit, habit: Habit,
firstWeekday: Int, firstWeekday: Int,
theme: Theme
) = FrequencyCardState( ) = FrequencyCardState(
color = habit.color, color = habit.color,
frequency = habit.originalEntries.computeWeekdayFrequency( frequency = habit.originalEntries.computeWeekdayFrequency(
isNumerical = habit.isNumerical isNumerical = habit.isNumerical
), ),
firstWeekday = firstWeekday, firstWeekday = firstWeekday,
theme = theme,
) )
} }
} }

@ -22,6 +22,7 @@ package org.isoron.uhabits.core.ui.screens.habits.show.views
import org.isoron.uhabits.core.models.Entry import org.isoron.uhabits.core.models.Entry
import org.isoron.uhabits.core.models.Habit import org.isoron.uhabits.core.models.Habit
import org.isoron.uhabits.core.models.PaletteColor import org.isoron.uhabits.core.models.PaletteColor
import org.isoron.uhabits.core.ui.views.Theme
import org.isoron.uhabits.core.utils.DateUtils import org.isoron.uhabits.core.utils.DateUtils
data class OverviewCardState( data class OverviewCardState(
@ -30,11 +31,12 @@ data class OverviewCardState(
val scoreYearDiff: Float, val scoreYearDiff: Float,
val scoreToday: Float, val scoreToday: Float,
val totalCount: Long, val totalCount: Long,
val theme: Theme,
) )
class OverviewCardPresenter { class OverviewCardPresenter {
companion object { companion object {
fun buildState(habit: Habit): OverviewCardState { fun buildState(habit: Habit, theme: Theme): OverviewCardState {
val today = DateUtils.getTodayWithOffset() val today = DateUtils.getTodayWithOffset()
val lastMonth = today.minus(30) val lastMonth = today.minus(30)
val lastYear = today.minus(365) val lastYear = today.minus(365)
@ -52,6 +54,7 @@ class OverviewCardPresenter {
scoreMonthDiff = scoreToday - scoreLastMonth, scoreMonthDiff = scoreToday - scoreLastMonth,
scoreYearDiff = scoreToday - scoreLastYear, scoreYearDiff = scoreToday - scoreLastYear,
totalCount = totalCount, totalCount = totalCount,
theme = theme,
) )
} }
} }

@ -23,6 +23,7 @@ import org.isoron.uhabits.core.models.Habit
import org.isoron.uhabits.core.models.PaletteColor import org.isoron.uhabits.core.models.PaletteColor
import org.isoron.uhabits.core.models.Score import org.isoron.uhabits.core.models.Score
import org.isoron.uhabits.core.preferences.Preferences import org.isoron.uhabits.core.preferences.Preferences
import org.isoron.uhabits.core.ui.views.Theme
import org.isoron.uhabits.core.utils.DateUtils import org.isoron.uhabits.core.utils.DateUtils
data class ScoreCardState( data class ScoreCardState(
@ -30,6 +31,7 @@ data class ScoreCardState(
val bucketSize: Int, val bucketSize: Int,
val spinnerPosition: Int, val spinnerPosition: Int,
val color: PaletteColor, val color: PaletteColor,
val theme: Theme,
) )
class ScoreCardPresenter( class ScoreCardPresenter(
@ -53,6 +55,7 @@ class ScoreCardPresenter(
habit: Habit, habit: Habit,
firstWeekday: Int, firstWeekday: Int,
spinnerPosition: Int, spinnerPosition: Int,
theme: Theme,
): ScoreCardState { ): ScoreCardState {
val bucketSize = BUCKET_SIZES[spinnerPosition] val bucketSize = BUCKET_SIZES[spinnerPosition]
val today = DateUtils.getTodayWithOffset() val today = DateUtils.getTodayWithOffset()
@ -77,6 +80,7 @@ class ScoreCardPresenter(
scores = scores, scores = scores,
bucketSize = bucketSize, bucketSize = bucketSize,
spinnerPosition = spinnerPosition, spinnerPosition = spinnerPosition,
theme = theme,
) )
} }
} }

@ -22,18 +22,21 @@ package org.isoron.uhabits.core.ui.screens.habits.show.views
import org.isoron.uhabits.core.models.Habit import org.isoron.uhabits.core.models.Habit
import org.isoron.uhabits.core.models.PaletteColor import org.isoron.uhabits.core.models.PaletteColor
import org.isoron.uhabits.core.models.Streak import org.isoron.uhabits.core.models.Streak
import org.isoron.uhabits.core.ui.views.Theme
data class StreakCardState( data class StreakCardState(
val color: PaletteColor, val color: PaletteColor,
val bestStreaks: List<Streak> val bestStreaks: List<Streak>,
val theme: Theme,
) )
class StreakCartPresenter { class StreakCartPresenter {
companion object { companion object {
fun buildState(habit: Habit): StreakCardState { fun buildState(habit: Habit, theme: Theme): StreakCardState {
return StreakCardState( return StreakCardState(
color = habit.color, color = habit.color,
bestStreaks = habit.streaks.getBest(10), bestStreaks = habit.streaks.getBest(10),
theme = theme,
) )
} }
} }

@ -23,6 +23,7 @@ import org.isoron.uhabits.core.models.Frequency
import org.isoron.uhabits.core.models.Habit import org.isoron.uhabits.core.models.Habit
import org.isoron.uhabits.core.models.PaletteColor import org.isoron.uhabits.core.models.PaletteColor
import org.isoron.uhabits.core.models.Reminder import org.isoron.uhabits.core.models.Reminder
import org.isoron.uhabits.core.ui.views.Theme
data class SubtitleCardState( data class SubtitleCardState(
val color: PaletteColor, val color: PaletteColor,
@ -32,12 +33,14 @@ data class SubtitleCardState(
val reminder: Reminder?, val reminder: Reminder?,
val targetValue: Double, val targetValue: Double,
val unit: String, val unit: String,
val theme: Theme,
) )
class SubtitleCardPresenter { class SubtitleCardPresenter {
companion object { companion object {
fun buildState( fun buildState(
habit: Habit, habit: Habit,
theme: Theme,
): SubtitleCardState = SubtitleCardState( ): SubtitleCardState = SubtitleCardState(
color = habit.color, color = habit.color,
frequency = habit.frequency, frequency = habit.frequency,
@ -46,6 +49,7 @@ class SubtitleCardPresenter {
reminder = habit.reminder, reminder = habit.reminder,
targetValue = habit.targetValue, targetValue = habit.targetValue,
unit = habit.unit, unit = habit.unit,
theme = theme,
) )
} }
} }

@ -22,6 +22,7 @@ package org.isoron.uhabits.core.ui.screens.habits.show.views
import org.isoron.uhabits.core.models.Habit import org.isoron.uhabits.core.models.Habit
import org.isoron.uhabits.core.models.PaletteColor import org.isoron.uhabits.core.models.PaletteColor
import org.isoron.uhabits.core.models.groupedSum import org.isoron.uhabits.core.models.groupedSum
import org.isoron.uhabits.core.ui.views.Theme
import org.isoron.uhabits.core.utils.DateUtils import org.isoron.uhabits.core.utils.DateUtils
import java.util.ArrayList import java.util.ArrayList
import java.util.Calendar import java.util.Calendar
@ -31,6 +32,7 @@ data class TargetCardState(
val values: List<Double> = listOf(), val values: List<Double> = listOf(),
val targets: List<Double> = listOf(), val targets: List<Double> = listOf(),
val intervals: List<Int> = listOf(), val intervals: List<Int> = listOf(),
val theme: Theme,
) )
class TargetCardPresenter { class TargetCardPresenter {
@ -38,6 +40,7 @@ class TargetCardPresenter {
fun buildState( fun buildState(
habit: Habit, habit: Habit,
firstWeekday: Int, firstWeekday: Int,
theme: Theme,
): TargetCardState { ): TargetCardState {
val today = DateUtils.getTodayWithOffset() val today = DateUtils.getTodayWithOffset()
val oldest = habit.computedEntries.getKnown().lastOrNull()?.timestamp ?: today val oldest = habit.computedEntries.getKnown().lastOrNull()?.timestamp ?: today
@ -106,6 +109,7 @@ class TargetCardPresenter {
values = values, values = values,
targets = targets, targets = targets,
intervals = intervals, intervals = intervals,
theme = theme,
) )
} }
} }

@ -20,6 +20,7 @@
package org.isoron.uhabits.core.ui.views package org.isoron.uhabits.core.ui.views
import org.isoron.platform.gui.Color import org.isoron.platform.gui.Color
import org.isoron.uhabits.core.models.PaletteColor
abstract class Theme { abstract class Theme {
open val appBackgroundColor = Color(0xf4f4f4) open val appBackgroundColor = Color(0xf4f4f4)
@ -35,6 +36,10 @@ abstract class Theme {
open val toolbarBackgroundColor = Color(0xf4f4f4) open val toolbarBackgroundColor = Color(0xf4f4f4)
open val toolbarColor = Color(0xffffff) open val toolbarColor = Color(0xffffff)
fun color(paletteColor: PaletteColor): Color {
return color(paletteColor.paletteIndex)
}
open fun color(paletteIndex: Int): Color { open fun color(paletteIndex: Int): Color {
return when (paletteIndex) { return when (paletteIndex) {
0 -> Color(0xD32F2F) 0 -> Color(0xD32F2F)

Loading…
Cancel
Save