summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/calendar.cpp133
-rw-r--r--src/main.cpp28
2 files changed, 142 insertions, 19 deletions
diff --git a/src/calendar.cpp b/src/calendar.cpp
new file mode 100644
index 0000000..d743718
--- /dev/null
+++ b/src/calendar.cpp
@@ -0,0 +1,133 @@
+#include <GxEPD2_BW.h>
+#include <Fonts/FreeSansBold12pt7b.h>
+#include <Fonts/FreeSansBold9pt7b.h>
+#include <Fonts/FreeSans9pt7b.h>
+#include <ctime>
+
+#define CELL_SPACING 10
+
+static const char *week_days[] {
+ "Mo", "Di", "Mi", "Do", "Fr", "Sa", "So",
+};
+
+static const char *months[] {
+ "Januar", "Februar", "Maerz", "April", "Mai", "Juni", "Juli",
+ "August", "September", "Oktober", "November", "Dezember",
+};
+
+enum month_t {
+ JANUARY = 0,
+ FEBRUARY,
+ MARCH,
+ APRIL,
+ MAY,
+ JUNE,
+ JULY,
+ AUGUST,
+ SEPTEMBER,
+ OCTOBER,
+ NOVEMBER,
+ DECEMBER,
+};
+
+static int days_in_month(int month, int year) {
+ switch (month) {
+ case JANUARY:
+ case MARCH:
+ case MAY:
+ case JULY:
+ case AUGUST:
+ case OCTOBER:
+ case DECEMBER:
+ return 31;
+ case APRIL:
+ case JUNE:
+ case SEPTEMBER:
+ case NOVEMBER:
+ return 30;
+ case FEBRUARY:
+ if (year % 400 == 0) return 29;
+ if (year % 100 == 0) return 28;
+ if (year % 4 == 0) return 29;
+ }
+ assert(month >= 0 && month < 12);
+ return 0;
+}
+
+/*
+ * @display where to draw on
+ * @x0 absolute initial X coord
+ * @y0 absolute initial Y coord
+ * @w0 width of a cell
+ * @h0 height of a cell
+ * @xoff X pos of cell
+ * @yoff Y pos of cell
+ * @text text to draw
+ * @highlight whether text should be highlighted
+ */
+static void draw_cell_content(GxEPD2_GFX_BASE_CLASS &display, int16_t x0, int16_t y0, uint16_t w0, uint16_t h0, uint8_t xoff, uint8_t yoff, String &text, bool highlight = false) {
+ int16_t x, y;
+ uint16_t w, h;
+
+ display.getTextBounds(text, 0, 0, &x, &y, &w, &h);
+
+ int16_t w_diff = w0 - w;
+ int x2 = x0 + xoff * w0 + w_diff/2 - x;
+ int y2 = y0 + yoff * h0 - y;
+
+ display.setCursor(x2, y2);
+ display.print(text);
+ if (highlight) {
+ display.drawCircle(x2 + x + w/2, y2 - h/2, (w0 - CELL_SPACING) / 2, GxEPD_BLACK);
+ }
+}
+
+void draw_calendar(GxEPD2_GFX_BASE_CLASS &display, int16_t x0, int16_t y0) {
+ struct tm now;
+ if (!getLocalTime(&now)) {
+ return;
+ }
+
+ uint8_t n_days = days_in_month(now.tm_mon, now.tm_year);
+
+ /* on which weekday is the 1st? */
+ int8_t day_of_1st = ((1 - 7 - (now.tm_mday - now.tm_wday)) % 7) + 7;
+
+ /* remap days from So-Sa = 0..6 to Mo-So = 0..6 */
+ day_of_1st = (day_of_1st - 1 + 7) % 7;
+
+ /* determine sizes */
+ int16_t x, y;
+ uint16_t w, h, cell_width, cell_height;
+ display.getTextBounds(week_days[0], 0, 0, &x, &y, &w, &h);
+ cell_width = w + CELL_SPACING;
+ cell_height = h + CELL_SPACING;
+
+ /* draw title with month and year */
+ display.setFont(&FreeSansBold12pt7b);
+ String title_text = String(months[now.tm_mon]) + " " + String(1900 + now.tm_year);
+ draw_cell_content(display, x0, y0, cell_width * 7, h, 0, 0, title_text);
+ y0 += h + 2 * CELL_SPACING;
+
+ /* draw table header with week days */
+ display.setFont(&FreeSansBold9pt7b);
+ for (int i=0; i<7; i++) {
+ String week_day = String(week_days[i]);
+ draw_cell_content(display, x0, y0, cell_width, cell_height, i, 0, week_day);
+ }
+
+ /* draw days */
+ display.setFont(&FreeSans9pt7b);
+ int8_t wday = day_of_1st;
+ uint8_t row = 1;
+ for (uint8_t day = 1; day <= n_days; day++) {
+ String day_str = String(day);
+ draw_cell_content(display, x0, y0, cell_width, cell_height, wday, row, day_str, day == now.tm_mday);
+
+ wday++;
+ if (wday > 6) {
+ wday = 0;
+ row++;
+ }
+ }
+}
diff --git a/src/main.cpp b/src/main.cpp
index a4f80a8..b8cb0c1 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1,10 +1,9 @@
-#define ENABLE_GxEPD2_GFX 0
-
#include <GxEPD2_BW.h>
-#include <Fonts/FreeMonoBold9pt7b.h>
+#include <Fonts/FreeSansBold9pt7b.h>
+#include <Fonts/FreeSans9pt7b.h>
#include <WiFi.h>
-#include "tux.h"
+#include "calendar.h"
#include "secrets.h"
/*
@@ -36,16 +35,13 @@ void display_setup() {
void draw() {
display.setRotation(1);
- display.setFont(&FreeMonoBold9pt7b);
+ display.setFont(&FreeSans9pt7b);
display.setTextColor(GxEPD_BLACK);
display.firstPage();
do {
display.fillScreen(GxEPD_WHITE);
- display.setCursor(30, 30);
- display.print("Hello World!");
-
- display.drawInvertedBitmap(10, 30, tux_280x370, 280, 370, GxEPD_BLACK);
+ draw_calendar(display, 30, 30);
} while(display.nextPage());
}
@@ -70,21 +66,15 @@ void update_time() {
void setup() {
Serial.begin(115200);
- //display_setup();
- //draw();
- //display.powerOff();
-
wifi_connect();
update_time();
wifi_disconnect();
+
+ display_setup();
+ draw();
+ display.powerOff();
}
void loop() {
- struct tm timeinfo;
- if (getLocalTime(&timeinfo)) {
- Serial.println(&timeinfo);
- } else {
- Serial.println("Unknown time");
- }
delay(1000);
}