diff --git a/uhabits-android/src/main/res/xml/widget_history_info.xml b/uhabits-android/src/main/res/xml/widget_history_info.xml index 9c446cacd..bc23f8639 100644 --- a/uhabits-android/src/main/res/xml/widget_history_info.xml +++ b/uhabits-android/src/main/res/xml/widget_history_info.xml @@ -21,11 +21,13 @@ diff --git a/uhabits-core/src/commonMain/kotlin/org/isoron/platform/time/Dates.kt b/uhabits-core/src/commonMain/kotlin/org/isoron/platform/time/Dates.kt index 6cb46a3f9..0dbc36f4e 100644 --- a/uhabits-core/src/commonMain/kotlin/org/isoron/platform/time/Dates.kt +++ b/uhabits-core/src/commonMain/kotlin/org/isoron/platform/time/Dates.kt @@ -136,6 +136,8 @@ data class LocalDate(val daysSince2000: Int) { } interface LocalDateFormatter { + fun narrowWeekdayName(weekday: DayOfWeek): String + fun narrowWeekdayName(date: LocalDate): String fun shortWeekdayName(weekday: DayOfWeek): String fun shortWeekdayName(date: LocalDate): String fun shortMonthName(date: LocalDate): String diff --git a/uhabits-core/src/jvmMain/java/org/isoron/platform/time/JavaDates.kt b/uhabits-core/src/jvmMain/java/org/isoron/platform/time/JavaDates.kt index 32c75eb8c..39ee837db 100644 --- a/uhabits-core/src/jvmMain/java/org/isoron/platform/time/JavaDates.kt +++ b/uhabits-core/src/jvmMain/java/org/isoron/platform/time/JavaDates.kt @@ -27,6 +27,7 @@ import java.util.Calendar.LONG import java.util.Calendar.MILLISECOND import java.util.Calendar.MINUTE import java.util.Calendar.MONTH +import java.util.Calendar.NARROW_FORMAT import java.util.Calendar.SECOND import java.util.Calendar.SHORT import java.util.Calendar.YEAR @@ -68,6 +69,17 @@ class JavaLocalDateFormatter(private val locale: Locale) : LocalDateFormatter { return cal.getDisplayName(DAY_OF_WEEK, SHORT, locale) } + override fun narrowWeekdayName(weekday: DayOfWeek): String { + val cal = GregorianCalendar() + cal.set(DAY_OF_WEEK, weekday.daysSinceSunday - 1) + return shortWeekdayName(LocalDate(cal.get(YEAR), cal.get(MONTH) + 1, cal.get(DAY_OF_MONTH))) + } + + override fun narrowWeekdayName(date: LocalDate): String { + val cal = date.toGregorianCalendar() + return cal.getDisplayName(DAY_OF_WEEK, NARROW_FORMAT, locale) + } + fun longFormat(date: LocalDate): String { val df = DateFormat.getDateInstance(DateFormat.LONG, locale) df.timeZone = TimeZone.getTimeZone("UTC") diff --git a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/ui/views/HistoryChart.kt b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/ui/views/HistoryChart.kt index a6bd0ae25..75b07a53f 100644 --- a/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/ui/views/HistoryChart.kt +++ b/uhabits-core/src/jvmMain/java/org/isoron/uhabits/core/ui/views/HistoryChart.kt @@ -107,11 +107,9 @@ class HistoryChart( squareSize = round((height - 2 * padding) / 8.0) canvas.setFontSize(min(14.0, height * 0.06)) - val weekdayColumnWidth = DayOfWeek.values().map { weekday -> - canvas.measureText(dateFormatter.shortWeekdayName(weekday)) + squareSize * 0.15 - }.maxOrNull() ?: 0.0 + val weekdayColumnWidth = calculateWeekdayColumnWidth(canvas) - nColumns = floor((width - 2 * padding - weekdayColumnWidth) / squareSize).toInt() + nColumns = calcNumOfColumns(weekdayColumnWidth) val firstWeekdayOffset = ( today.dayOfWeek.daysSinceSunday - firstWeekday.daysSinceSunday + 7 @@ -136,13 +134,43 @@ class HistoryChart( val date = topLeftDate.plus(row) canvas.setTextAlign(TextAlign.LEFT) canvas.drawText( - dateFormatter.shortWeekdayName(date), - padding + nColumns * squareSize + squareSize * 0.15, + weekdayDisplayName(date), + padding + nColumns * squareSize + 1.5, padding + squareSize * (row + 1) + squareSize / 2 ) } } + private fun calcNumOfColumns(weekdayColumnWidth: Double) = + floor((width - 2 * padding - weekdayColumnWidth) / squareSize).toInt() + + private fun weekdayDisplayName(weekday: DayOfWeek): String { + if (shouldUseNarrowWeekdayName()) { + return dateFormatter.narrowWeekdayName(weekday) + } + return dateFormatter.shortWeekdayName(weekday) + } + + private fun weekdayDisplayName(localDate: LocalDate): String { + if (shouldUseNarrowWeekdayName()) { + return dateFormatter.narrowWeekdayName(localDate) + } + return dateFormatter.shortWeekdayName(localDate) + } + + private fun calculateWeekdayColumnWidth(canvas: Canvas): Double { + if (shouldUseNarrowWeekdayName()) { + return 0.0 + } + return DayOfWeek.values().map { weekday -> + canvas.measureText(weekdayDisplayName(weekday)) + 1.5 + }.maxOrNull() ?: 0.0 + } + + private fun shouldUseNarrowWeekdayName(): Boolean { + // based off 80dp minWidth in widget_history_info.xml + return width < 80 + } private fun drawColumn( canvas: Canvas, column: Int,