Repository navigation
Expand file tree
/
Copy pathcalendar.cpp
More file actions
133 lines (110 loc) · 3.26 KB
/
Copy pathcalendar.cpp
File metadata and controls
133 lines (110 loc) · 3.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#include "calendar.h"
#include <time.h>
#include <ArduinoJson.h>
#define COLS 7
#define ROWS 6
const char* daysHeader[7] = {"M","T","W","T","F","S","S"};
const char* months[12] = {
"January","February","March","April","May","June",
"July","August","September","October","November","December"
};
int daysInMonth(int year,int month)
{
if(month==2)
{
if((year%4==0 && year%100!=0) || (year%400==0))
return 29;
return 28;
}
const int days[]={31,28,31,30,31,30,31,31,30,31,30,31};
return days[month-1];
}
int weekdayMonday(struct tm *t)
{
int w=t->tm_wday;
if(w==0) return 6;
return w-1;
}
void drawCalendar(LayoutItem* item)
{
time_t now = time(nullptr);
struct tm *t = localtime(&now);
int year = t->tm_year + 1900;
int month = t->tm_mon + 1;
int today = t->tm_mday;
int headerH = 28;
int cellW = item->Width / COLS;
int cellH = (item->Height - headerH) / ROWS;
// ---- Month Title ----
char title[24];
sprintf(title, "%s %d", months[month - 1], year);
drawSparseStringCentered(&epaperFont, item->PosX + item->Width / 2, item->PosY + textSpace, title, GxEPD_BLACK);
// ---- Weekday headers ----
for (int i = 0; i < 7; i++)
{
int x = item->PosX + i * cellW + cellW / 2;
drawSparseStringCentered(&epaperFont, x, item->PosY + 20 + textSpace, daysHeader[i], GxEPD_BLACK);
}
// ---- First weekday of month ----
struct tm firstDay = *t;
firstDay.tm_mday = 1;
mktime(&firstDay);
int start = weekdayMonday(&firstDay);
int total = daysInMonth(year, month);
int d = 1;
for (int r = 0; r < ROWS; r++)
{
for (int c = 0; c < COLS; c++)
{
int index = r * COLS + c;
if (index >= start && d <= total)
{
int x = item->PosX + c * cellW + cellW / 2;
int y = item->PosY + headerH + r * cellH + cellH / 2 + 10;
char buf[4];
sprintf(buf, "%d", d);
bool isToday = (d == today);
bool hasEvent = false;
// ---- Check if this day has an event ----
for (int i = 0; i < cal.daysCount; i++)
{
if ((int)cal.daysWithEvents[i] == d)
{
hasEvent = true;
break;
}
}
int radius = cellH / 2 -2;
if (hasEvent)
{
// Event day: filled marker.
int fillRadius = radius;
if (isToday && radius > 6) {
fillRadius = radius - 2;
}
display.fillCircle(x, y - 5, fillRadius, GxEPD_BLACK);
if (isToday)
{
// Today + event: filled black center, visible white gap,
// then the normal double black outline outside.
display.fillCircle(x, y - 5, radius - 1, GxEPD_WHITE);
display.fillCircle(x, y - 5, fillRadius, GxEPD_BLACK);
display.drawCircle(x, y - 5, radius, GxEPD_BLACK);
display.drawCircle(x, y - 5, radius + 1, GxEPD_BLACK);
}
drawSparseStringCentered(&epaperFont, x, y, buf, GxEPD_WHITE);
}
else
{
drawSparseStringCentered(&epaperFont, x, y, buf, GxEPD_BLACK);
if (isToday)
{
display.drawCircle(x, y - 5, radius, GxEPD_BLACK);
display.drawCircle(x, y - 5, radius + 1, GxEPD_BLACK);
}
}
d++;
}
}
}
}