diff --git a/android/uhabits-android/src/main/java/org/isoron/uhabits/widgets/HistoryWidget.kt b/android/uhabits-android/src/main/java/org/isoron/uhabits/widgets/HistoryWidget.kt index 5f69d9b53..353f382f8 100644 --- a/android/uhabits-android/src/main/java/org/isoron/uhabits/widgets/HistoryWidget.kt +++ b/android/uhabits-android/src/main/java/org/isoron/uhabits/widgets/HistoryWidget.kt @@ -26,8 +26,8 @@ import org.isoron.platform.gui.AndroidDataView import org.isoron.platform.time.JavaLocalDateFormatter import org.isoron.uhabits.core.models.Habit import org.isoron.uhabits.core.ui.screens.habits.show.views.HistoryCardPresenter -import org.isoron.uhabits.core.ui.views.DarkTheme import org.isoron.uhabits.core.ui.views.HistoryChart +import org.isoron.uhabits.core.ui.views.WidgetTheme import org.isoron.uhabits.core.utils.DateUtils import org.isoron.uhabits.widgets.views.GraphWidgetView import java.util.Locale @@ -51,7 +51,7 @@ class HistoryWidget( habit = habit, isSkipEnabled = prefs.isSkipEnabled, firstWeekday = prefs.firstWeekday, - theme = DarkTheme(), + theme = WidgetTheme(), ) (widgetView.dataView as AndroidDataView).apply { (this.view as HistoryChart).series = model.series @@ -65,7 +65,7 @@ class HistoryWidget( view = HistoryChart( today = DateUtils.getTodayWithOffset().toLocalDate(), paletteColor = habit.color, - theme = DarkTheme(), + theme = WidgetTheme(), dateFormatter = JavaLocalDateFormatter(Locale.getDefault()) ) } diff --git a/android/uhabits-android/src/main/res/layout/canvas_test.xml b/android/uhabits-android/src/main/res/layout/canvas_test.xml index 6faa0df2e..41c8c2909 100644 --- a/android/uhabits-android/src/main/res/layout/canvas_test.xml +++ b/android/uhabits-android/src/main/res/layout/canvas_test.xml @@ -20,7 +20,8 @@ + android:layout_height="match_parent" + android:background="#ffff00"> = 1) relativeLuminosity else 1 / relativeLuminosity } + + fun withAlpha(newAlpha: Double) = Color(red, green, blue, newAlpha) + + companion object { + val TRANSPARENT = Color(0.0, 0.0, 0.0, 0.0) + val RED = Color(1.0, 0.0, 0.0, 1.0) + val GREEN = Color(0.0, 1.0, 0.0, 1.0) + val BLUE = Color(1.0, 0.0, 1.0, 1.0) + val YELLOW = Color(1.0, 1.0, 0.0, 1.0) + val MAGENTA = Color(1.0, 0.0, 1.0, 1.0) + val CYAN = Color(0.0, 1.0, 1.0, 1.0) + val WHITE = Color(1.0, 1.0, 1.0, 1.0) + val BLACK = Color(0.0, 0.0, 0.0, 1.0) + } } diff --git a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/views/BarChart.kt b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/views/BarChart.kt index 533b3a69e..c272e937e 100644 --- a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/views/BarChart.kt +++ b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/views/BarChart.kt @@ -49,7 +49,6 @@ class BarChart( var barMargin = 3.0 var barWidth = 12.0 var nGridlines = 6 - var backgroundColor = theme.cardBackgroundColor override val dataColumnWidth: Double get() = barWidth + barMargin * 2 @@ -67,8 +66,8 @@ class BarChart( var maxValue = series.map { it.max()!! }.max()!! maxValue = max(maxValue, 1.0) - canvas.setColor(backgroundColor) - canvas.fillRect(0.0, 0.0, width, height) + canvas.setColor(theme.cardBackgroundColor) + canvas.fill() fun barGroupOffset(c: Int) = marginLeft + paddingLeft + (c) * barGroupWidth @@ -97,13 +96,6 @@ class BarChart( canvas.fillCircle(x + barWidth - r, y + r, r) canvas.setFontSize(theme.smallTextSize) canvas.setTextAlign(TextAlign.CENTER) - canvas.setColor(backgroundColor) - canvas.fillRect( - x - barMargin, - y - theme.smallTextSize * 1.25, - barWidth + 2 * barMargin, - theme.smallTextSize * 1.0 - ) canvas.setColor(colors[s]) canvas.drawText( value.toShortString(), @@ -119,12 +111,7 @@ class BarChart( fun drawMajorGrid() { canvas.setStrokeWidth(1.0) if (nSeries > 1) { - canvas.setColor( - backgroundColor.blendWith( - theme.lowContrastTextColor, - 0.5 - ) - ) + canvas.setColor(theme.lowContrastTextColor.withAlpha(0.5)) for (c in 0 until nColumns - 1) { val x = barGroupOffset(c) canvas.drawLine(x, paddingTop, x, paddingTop + maxBarHeight) @@ -141,8 +128,6 @@ class BarChart( fun drawAxis() { val y = paddingTop + maxBarHeight - canvas.setColor(backgroundColor) - canvas.fillRect(0.0, y, width, height - y) canvas.setColor(theme.lowContrastTextColor) canvas.drawLine(0.0, y, width, y) canvas.setColor(theme.mediumContrastTextColor) diff --git a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/views/HistoryChart.kt b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/views/HistoryChart.kt index 193b7011c..4455bda28 100644 --- a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/views/HistoryChart.kt +++ b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/views/HistoryChart.kt @@ -33,7 +33,7 @@ class HistoryChart( var today: LocalDate, var paletteColor: PaletteColor, var theme: Theme, - var dateFormatter: LocalDateFormatter + var dateFormatter: LocalDateFormatter, ) : DataView { enum class Square { @@ -61,8 +61,10 @@ class HistoryChart( override fun draw(canvas: Canvas) { val width = canvas.getWidth() val height = canvas.getHeight() + canvas.setColor(theme.cardBackgroundColor) - canvas.fillRect(0.0, 0.0, width, height) + canvas.fill() + squareSize = round((height - 2 * padding) / 8.0) canvas.setFontSize(height * 0.06) @@ -98,7 +100,7 @@ class HistoryChart( canvas: Canvas, column: Int, topDate: LocalDate, - topOffset: Int + topOffset: Int, ) { drawHeader(canvas, column, topDate) repeat(7) { row -> @@ -150,7 +152,7 @@ class HistoryChart( width: Double, height: Double, date: LocalDate, - offset: Int + offset: Int, ) { val value = if (offset >= series.size) Square.OFF else series[offset] @@ -187,9 +189,13 @@ class HistoryChart( } } - val c1 = squareColor.contrast(theme.cardBackgroundColor) - val c2 = squareColor.contrast(theme.mediumContrastTextColor) - val textColor = if (c1 > c2) theme.cardBackgroundColor else theme.mediumContrastTextColor + val textColor = if (theme.cardBackgroundColor == Color.TRANSPARENT) { + theme.highContrastTextColor + } else { + val c1 = squareColor.contrast(theme.cardBackgroundColor) + val c2 = squareColor.contrast(theme.mediumContrastTextColor) + if (c1 > c2) theme.cardBackgroundColor else theme.mediumContrastTextColor + } canvas.setColor(textColor) canvas.setTextAlign(TextAlign.CENTER) diff --git a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/views/Themes.kt b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/views/Themes.kt index 525977858..5d46b9fcd 100644 --- a/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/views/Themes.kt +++ b/android/uhabits-core/src/main/java/org/isoron/uhabits/core/ui/views/Themes.kt @@ -66,9 +66,9 @@ abstract class Theme { val regularTextSize = 17.0 } -class LightTheme : Theme() +open class LightTheme : Theme() -class DarkTheme : Theme() { +open class DarkTheme : Theme() { override val appBackgroundColor = Color(0x212121) override val cardBackgroundColor = Color(0x303030) override val headerBackgroundColor = Color(0x212121) @@ -108,3 +108,10 @@ class DarkTheme : Theme() { } } } + +class WidgetTheme : LightTheme() { + override val cardBackgroundColor = Color.TRANSPARENT + override val highContrastTextColor = Color.WHITE + override val mediumContrastTextColor = Color.WHITE.withAlpha(0.50) + override val lowContrastTextColor = Color.WHITE.withAlpha(0.10) +} \ No newline at end of file diff --git a/android/uhabits-core/src/test/java/org/isoron/uhabits/core/ui/views/BarChartTest.kt b/android/uhabits-core/src/test/java/org/isoron/uhabits/core/ui/views/BarChartTest.kt index 97ac8a601..1b414b32a 100644 --- a/android/uhabits-core/src/test/java/org/isoron/uhabits/core/ui/views/BarChartTest.kt +++ b/android/uhabits-core/src/test/java/org/isoron/uhabits/core/ui/views/BarChartTest.kt @@ -46,6 +46,18 @@ class BarChartTest { assertRenders(300, 200, "$base/base.png", component) } + @Test + fun testDrawDarkTheme() = runBlocking { + component.theme = DarkTheme() + assertRenders(300, 200, "$base/themeDark.png", component) + } + + @Test + fun testDrawWidgetTheme() = runBlocking { + component.theme = WidgetTheme() + assertRenders(300, 200, "$base/themeWidget.png", component) + } + @Test fun testDrawWithOffset() = runBlocking { component.dataOffset = 5 diff --git a/android/uhabits-core/src/test/java/org/isoron/uhabits/core/ui/views/HistoryChartTest.kt b/android/uhabits-core/src/test/java/org/isoron/uhabits/core/ui/views/HistoryChartTest.kt index 277659709..e9d8a8e87 100644 --- a/android/uhabits-core/src/test/java/org/isoron/uhabits/core/ui/views/HistoryChartTest.kt +++ b/android/uhabits-core/src/test/java/org/isoron/uhabits/core/ui/views/HistoryChartTest.kt @@ -31,6 +31,7 @@ import org.isoron.uhabits.core.ui.views.HistoryChart.Square.HATCHED import org.isoron.uhabits.core.ui.views.HistoryChart.Square.OFF import org.isoron.uhabits.core.ui.views.HistoryChart.Square.ON import org.isoron.uhabits.core.ui.views.LightTheme +import org.isoron.uhabits.core.ui.views.WidgetTheme import org.junit.Test import java.util.Locale @@ -70,7 +71,6 @@ class HistoryChartTest { } // TODO: Label overflow - // TODO: Transparent // TODO: onClick // TODO: HistoryEditorDialog // TODO: Remove excessive padding on widgets @@ -89,7 +89,13 @@ class HistoryChartTest { @Test fun testDrawDarkTheme() = runBlocking { view.theme = DarkTheme() - assertRenders(400, 200, "$base/dark.png", view) + assertRenders(400, 200, "$base/themeDark.png", view) + } + + @Test + fun testDrawWidgetTheme() = runBlocking { + view.theme = WidgetTheme() + assertRenders(400, 200, "$base/themeWidget.png", view) } @Test