HistoryChart: Fix transparency

pull/707/head
Alinson S. Xavier 5 years ago
parent 93a2ec3186
commit de3668db96

@ -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())
)
}

@ -20,7 +20,8 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:background="#ffff00">
<org.isoron.platform.gui.AndroidTestView
android:layout_width="500dp"

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

@ -52,9 +52,16 @@ interface Canvas {
fun setTextAlign(align: TextAlign)
fun toImage(): Image
/**
* Fills entire canvas with the current color.
*/
fun fill() {
fillRect(0.0, 0.0, getWidth(), getHeight())
}
fun drawTestImage() {
// Draw grey background
setColor(Color(0x303030))
// Draw transparent background
setColor(Color(0.1, 0.1, 0.1, 0.5))
fillRect(0.0, 0.0, 500.0, 400.0)
// Draw center rectangle
@ -63,7 +70,7 @@ interface Canvas {
drawRect(100.0, 100.0, 300.0, 200.0)
// Draw squares, circles and arcs
setColor(Color(0xFFFF00))
setColor(Color.YELLOW)
setStrokeWidth(1.0)
drawRect(0.0, 0.0, 100.0, 100.0)
fillCircle(50.0, 50.0, 30.0)
@ -75,7 +82,7 @@ interface Canvas {
fillArc(50.0, 350.0, 30.0, 45.0, 90.0)
// Draw two red crossing lines
setColor(Color(0xFF0000))
setColor(Color.RED)
setStrokeWidth(2.0)
drawLine(0.0, 0.0, 500.0, 400.0)
drawLine(500.0, 0.0, 0.0, 400.0)
@ -83,7 +90,7 @@ interface Canvas {
// Draw text
setFont(Font.BOLD)
setFontSize(50.0)
setColor(Color(0x00FF00))
setColor(Color.GREEN)
setTextAlign(TextAlign.CENTER)
drawText("HELLO", 250.0, 100.0)
setTextAlign(TextAlign.RIGHT)

@ -23,9 +23,8 @@ data class Color(
val red: Double,
val green: Double,
val blue: Double,
val alpha: Double
val alpha: Double,
) {
val luminosity: Double
get() {
return 0.21 * red + 0.72 * green + 0.07 * blue
@ -53,4 +52,18 @@ data class Color(
val relativeLuminosity = (l1 + 0.05) / (l2 + 0.05)
return if (relativeLuminosity >= 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)
}
}

@ -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)

@ -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 textColor = if (theme.cardBackgroundColor == Color.TRANSPARENT) {
theme.highContrastTextColor
} else {
val c1 = squareColor.contrast(theme.cardBackgroundColor)
val c2 = squareColor.contrast(theme.mediumContrastTextColor)
val textColor = if (c1 > c2) theme.cardBackgroundColor else theme.mediumContrastTextColor
if (c1 > c2) theme.cardBackgroundColor else theme.mediumContrastTextColor
}
canvas.setColor(textColor)
canvas.setTextAlign(TextAlign.CENTER)

@ -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)
}

@ -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

@ -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

Loading…
Cancel
Save