Port to C++

This commit is contained in:
Cameron Reed 2024-02-22 21:45:19 -07:00
parent c19b3b776f
commit b6aadd4601
18 changed files with 490 additions and 8008 deletions

1
.gitignore vendored
View File

@ -1 +1,2 @@
build/ build/
compile_commands.json

View File

@ -25,7 +25,7 @@ OFILES := $(addprefix $(OFILE_DIR)/, $(notdir $(C_SOURCES:.c=.o) $(CXX_SOUR
OPT := -O2 OPT := -O2
CPPFLAGS := $(INCLUDES) -MMD CPPFLAGS := $(INCLUDES) -MMD
CFLAGS := $(OPT) -Wall -Wextra -Wpedantic CFLAGS := $(OPT) -Wall -Wextra -Wpedantic
CXXFLAGS := $(OPT) -std=c++17 -Wall -Wextra -Wpedantic CXXFLAGS := $(OPT) -std=c++17 -Wall -Wextra #-Wpedantic
LDFLAGS := LDFLAGS :=

File diff suppressed because it is too large Load Diff

View File

@ -7,23 +7,7 @@
#define MAX_DAYS_IN_MONTH 31 #define MAX_DAYS_IN_MONTH 31
typedef enum {
JANUARY = 0,
FEBRUARY,
MARCH,
APRIL,
MAY,
JUNE,
JULY,
AUGUST,
SEPTEMBER,
OCTOBER,
NOVEMBER,
DECEMBER,
} MONTH;
bool isLeapYear(int year); bool isLeapYear(int year);
uint8_t firstDayOfMonth(MONTH month, int year); uint8_t firstDayOfMonth(int month, int year);
uint8_t daysInMonth(MONTH month, int year); uint8_t daysInMonth(int month, int year);

View File

@ -11,16 +11,19 @@
#define STR_MAX_NAME_LEN "99" #define STR_MAX_NAME_LEN "99"
typedef enum { namespace Events {
enum EVENT_TYPE {
EVENTS_MEETING = 0, EVENTS_MEETING = 0,
EVENTS_CASCADE, EVENTS_CASCADE,
EVENTS_SETUP, EVENTS_SETUP,
EVENTS_APPOINTMENT, EVENTS_APPOINTMENT,
EVENTS_OTHER, EVENTS_OTHER,
EVENTS_COUNT, EVENTS_COUNT,
} EVENT_TYPE; };
typedef struct { struct event_type_counts {
uint8_t counts[EVENTS_COUNT]; uint8_t counts[EVENTS_COUNT];
// uint8_t other; // uint8_t other;
// uint8_t meetings; // uint8_t meetings;
@ -28,27 +31,23 @@ typedef struct {
// uint8_t cascades; // uint8_t cascades;
// uint8_t setups; // uint8_t setups;
// uint8_t appointments // uint8_t appointments
} event_type_counts_t; };
typedef struct { struct Event {
int s_hour; int s_hour;
int s_min; int s_min;
int e_hour; int e_hour;
int e_min; int e_min;
EVENT_TYPE type; EVENT_TYPE type;
char name[MAX_NAME_LEN]; char name[MAX_NAME_LEN];
} event_t; };
typedef struct {
event_t* events;
size_t size;
size_t capacity;
} events_t;
void unregisterAllUpdates(void); void unregisterCallbacks(void);
void registerUpdateOnEventChange(uint8_t day, lv_obj_t* object); void registerCallback(uint8_t day, lv_obj_t* object);
void register_update_on_detailed_events_change(lv_obj_t* object); void registerDetailedCallback(lv_obj_t* object);
void updateEvents(uint8_t today, MONTH month, uint32_t year); void update(uint8_t today, int month, uint32_t year);
} // namespace Events

View File

@ -12,8 +12,7 @@ struct framebuf {
uint16_t* buf; uint16_t* buf;
}; };
int open_fb(struct framebuf* fb, const char* const dev); int open_fb(framebuf* fb, const char* const dev);
void close_fb(struct framebuf* fb); void close_fb(framebuf* fb);
void clear_fb(struct framebuf* fb); void clear_fb(framebuf* fb);
void set_pixel(struct framebuf* fb, uint32_t x, uint32_t y, uint16_t color);

View File

@ -5,10 +5,6 @@
#include <lvgl.h> #include <lvgl.h>
#ifdef __cplusplus
extern "C" {
#endif
extern uint32_t disp_height; extern uint32_t disp_height;
extern uint32_t disp_width; extern uint32_t disp_width;
@ -18,7 +14,3 @@ uint32_t disp_hpercent_to_px(uint32_t percent);
uint32_t disp_vpercent_to_px(uint32_t percent); uint32_t disp_vpercent_to_px(uint32_t percent);
int lvgl_fb_run(const char* const fb_dev); int lvgl_fb_run(const char* const fb_dev);
#ifdef __cplusplus
} // extern "C"
#endif

View File

@ -1,5 +1,6 @@
#pragma once #pragma once
#include <cstdint>
#include <stdint.h> #include <stdint.h>
#include <lvgl.h> #include <lvgl.h>
@ -11,30 +12,55 @@
#define CALENDAR_ROWS 5 #define CALENDAR_ROWS 5
typedef struct lvc_calendar_box { struct CalendarBox {
public:
CalendarBox(lv_obj_t* parent);
~CalendarBox();
void Style(uint32_t width, uint32_t height, int day, int wday, bool today, int days_in_month);
public:
lv_obj_t* box; lv_obj_t* box;
private:
static void DrawEvents_cb(lv_event_t* event);
private:
lv_obj_t* label; lv_obj_t* label;
lv_obj_t* event_count_labels[EVENTS_COUNT]; lv_obj_t* event_count_labels[Events::EVENTS_COUNT];
} lvc_calendar_box_t; };
typedef struct lvc_calendar_row {
lvc_calendar_box_t* boxes[DAYS_IN_WEEK];
} lvc_calendar_row_t;
typedef struct lvc_calendar { struct CalendarRow {
public:
CalendarRow(lv_obj_t* parent);
~CalendarRow();
int Style(lv_obj_t* last_row, uint32_t box_width, uint32_t box_height, int day, int current_day, int days_in_month);
public:
CalendarBox* boxes[DAYS_IN_WEEK];
};
class Calendar {
public:
Calendar(lv_obj_t* parent, uint32_t width);
~Calendar();
void Style(const struct tm* const ct);
public:
lv_obj_t* calendar; lv_obj_t* calendar;
private:
lv_obj_t* title_bar; lv_obj_t* title_bar;
lv_obj_t* title_label; lv_obj_t* title_label;
lvc_calendar_row_t* rows[CALENDAR_ROWS]; CalendarRow* rows[CALENDAR_ROWS];
uint32_t width; uint32_t width;
uint32_t box_width; uint32_t box_width;
uint32_t box_height; uint32_t box_height;
};
} lvc_calendar_t;
lvc_calendar_t* create_calendar(lv_obj_t* parent, uint32_t width);
void destroy_calendar(lvc_calendar_t* cal);

View File

@ -1,13 +1,21 @@
#include <lvgl.h> #include <lvgl.h>
#include <vector>
typedef struct { class EventsPanel {
public:
EventsPanel(lv_obj_t* parent);
~EventsPanel();
void Style();
public:
lv_obj_t* panel; lv_obj_t* panel;
private:
static void DrawEventList_cb(lv_event_t* event);
private:
lv_obj_t* header; lv_obj_t* header;
lv_obj_t** event_labels; std::vector<lv_obj_t*> event_labels;
uint16_t event_labels_count; };
} lvc_events_panel_t;
lvc_events_panel_t* create_events_panel(lv_obj_t* parent);
void destroy_events_panel(lvc_events_panel_t* panel);

View File

@ -18,7 +18,7 @@ bool isLeapYear(int year)
return (year % 4 == 0) && (year % 100 != 0 || year % 400 == 0); return (year % 4 == 0) && (year % 100 != 0 || year % 400 == 0);
} }
uint8_t firstDayOfMonth(MONTH month, int year) uint8_t firstDayOfMonth(int month, int year)
{ {
int d = year % 100; int d = year % 100;
uint8_t first_of_year = (century_start[(year / 100) % 4] + d + (d / 4) - isLeapYear(year) + 7) % 7; uint8_t first_of_year = (century_start[(year / 100) % 4] + d + (d / 4) - isLeapYear(year) + 7) % 7;
@ -29,7 +29,7 @@ uint8_t firstDayOfMonth(MONTH month, int year)
return (first_of_year + offsets[month]) % 7; return (first_of_year + offsets[month]) % 7;
} }
uint8_t daysInMonth(MONTH month, int year) uint8_t daysInMonth(int month, int year)
{ {
if (isLeapYear(year)) if (isLeapYear(year))
{ {

View File

@ -1,4 +1,5 @@
#include <time.h> #include <time.h>
#include <vector>
#include <stdio.h> #include <stdio.h>
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
@ -12,29 +13,29 @@
#include "events.h" #include "events.h"
#define MAX_FILE_NAME_LEN 36 #define MAX_FILE_NAME_LEN 42
#define MAX_LINE_LEN 200 #define MAX_LINE_LEN 200
#define FILE_PATH_FMT "/var/lib/calzone/%02d_%d.csv" #define FILE_PATH_FMT "/var/lib/calzone/%02d_%d.csv"
#define FILE_LINE_FMT "%d,%d,%d,%d,%d,%u,%" STR_MAX_NAME_LEN "[^\t\n]" #define FILE_LINE_FMT "%d,%d,%d,%d,%d,%u,%" STR_MAX_NAME_LEN "[^\t\n]"
#define FILE_LINE_FMT_QUOTE "%d,%d,%d,%d,%d,%u,\"%" STR_MAX_NAME_LEN "[^\t\n\"]\"" #define FILE_LINE_FMT_QUOTE "%d,%d,%d,%d,%d,%u,\"%" STR_MAX_NAME_LEN "[^\t\n\"]\""
namespace Events {
static time_t modified_time = 0; static time_t modified_time = 0;
static event_type_counts_t event_counts[MAX_DAYS_IN_MONTH]; static event_type_counts event_counts[MAX_DAYS_IN_MONTH];
static lv_obj_t* objects_to_update[MAX_DAYS_IN_MONTH]; static lv_obj_t* objects_to_update[MAX_DAYS_IN_MONTH];
static lv_obj_t* detailed_events_object = NULL; static lv_obj_t* detailed_events_object = nullptr;
static events_t event_array; static std::vector<Event> events;
void clearEvents(void); void clearEvents(void);
void sendEventsToObjects(void); void dispatchCallbacks(void);
bool wasModified(const char* const file_name); bool wasModified(const char* const file_name);
int readEventsFromFile(const char* const file_name, int today); int readEventsFromFile(const char* const file_name, int today);
int addEvent(event_t* event);
void registerUpdateOnEventChange(uint8_t day, lv_obj_t* object) void registerCallback(uint8_t day, lv_obj_t* object)
{ {
day -= 1; day -= 1;
if (day >= MAX_DAYS_IN_MONTH) { if (day >= MAX_DAYS_IN_MONTH) {
@ -44,19 +45,19 @@ void registerUpdateOnEventChange(uint8_t day, lv_obj_t* object)
objects_to_update[day] = object; objects_to_update[day] = object;
} }
void register_update_on_detailed_events_change(lv_obj_t* object) void registerDetailedCallback(lv_obj_t* object)
{ {
detailed_events_object = object; detailed_events_object = object;
} }
void unregisterAllUpdates(void) void unregisterCallbacks(void)
{ {
for (size_t i = 0; i < MAX_DAYS_IN_MONTH; i++) { for (size_t i = 0; i < MAX_DAYS_IN_MONTH; i++) {
objects_to_update[i] = NULL; objects_to_update[i] = NULL;
} }
} }
void updateEvents(uint8_t today, MONTH month, uint32_t year) void update(uint8_t today, int month, uint32_t year)
{ {
// No real reason to have the limit at year 100 000 000 since the pi zero's time will die in 2038, // No real reason to have the limit at year 100 000 000 since the pi zero's time will die in 2038,
// but I just pushed nine a bunch of times and now this is how it is // but I just pushed nine a bunch of times and now this is how it is
@ -70,28 +71,28 @@ void updateEvents(uint8_t today, MONTH month, uint32_t year)
// Check if file exists // Check if file exists
if (access(file_name, F_OK) != 0) { if (access(file_name, F_OK) != 0) {
clearEvents(); clearEvents();
sendEventsToObjects(); dispatchCallbacks();
return; return;
} }
if (wasModified(file_name)) { if (wasModified(file_name)) {
clearEvents(); clearEvents();
if (readEventsFromFile(file_name, today) != 0) { if (readEventsFromFile(file_name, today) != 0) {
sendEventsToObjects(); dispatchCallbacks();
} }
} }
} }
void sendEventsToObjects(void) void dispatchCallbacks(void)
{ {
for (size_t i = 0; i < MAX_DAYS_IN_MONTH; i++) { for (size_t i = 0; i < MAX_DAYS_IN_MONTH; i++) {
if (objects_to_update[i] != NULL) { if (objects_to_update[i] != nullptr) {
lv_obj_send_event(objects_to_update[i], LV_EVENT_REFRESH, &event_counts[i]); lv_obj_send_event(objects_to_update[i], LV_EVENT_REFRESH, &event_counts[i]);
} }
} }
if (detailed_events_object != NULL) { if (detailed_events_object != nullptr) {
lv_obj_send_event(detailed_events_object, LV_EVENT_REFRESH, &event_array); lv_obj_send_event(detailed_events_object, LV_EVENT_REFRESH, &events);
} }
} }
@ -109,7 +110,7 @@ bool wasModified(const char* const file_name)
void clearEvents(void) void clearEvents(void)
{ {
event_array.size = 0; events.clear();
modified_time = 0; modified_time = 0;
for (size_t i = 0; i < MAX_DAYS_IN_MONTH; i++) { for (size_t i = 0; i < MAX_DAYS_IN_MONTH; i++) {
@ -122,7 +123,7 @@ void clearEvents(void)
int readEventsFromFile(const char* const file_name, int today) int readEventsFromFile(const char* const file_name, int today)
{ {
FILE* f = fopen(file_name, "r"); FILE* f = fopen(file_name, "r");
if (f == NULL) { if (f == nullptr) {
printf("Failed to acces file %s\n", file_name); printf("Failed to acces file %s\n", file_name);
return 0; return 0;
} }
@ -132,11 +133,11 @@ int readEventsFromFile(const char* const file_name, int today)
int day; int day;
int num_events = 0; int num_events = 0;
event_t event; Event event;
while (1) { while (1) {
char* b = fgets(buf, MAX_LINE_LEN, f); char* b = fgets(buf, MAX_LINE_LEN, f);
if (b == NULL) { if (b == nullptr) {
// Error or EOF // Error or EOF
break; break;
} }
@ -146,11 +147,12 @@ int readEventsFromFile(const char* const file_name, int today)
continue; continue;
} }
unsigned int event_type_int;
int num = sscanf(buf, FILE_LINE_FMT_QUOTE, int num = sscanf(buf, FILE_LINE_FMT_QUOTE,
&event.s_hour, &event.s_min, &event.e_hour, &event.e_min, &day, &event.type, event.name); &event.s_hour, &event.s_min, &event.e_hour, &event.e_min, &day, &event_type_int, event.name);
if (num != 7) { if (num != 7) {
num = sscanf(buf, FILE_LINE_FMT, num = sscanf(buf, FILE_LINE_FMT,
&event.s_hour, &event.s_min, &event.e_hour, &event.e_min, &day, &event.type, event.name); &event.s_hour, &event.s_min, &event.e_hour, &event.e_min, &day, &event_type_int, event.name);
if (num != 7) { if (num != 7) {
printf("Malformed line in events list file\n"); printf("Malformed line in events list file\n");
continue; continue;
@ -161,12 +163,13 @@ int readEventsFromFile(const char* const file_name, int today)
printf("Invalid day %d\n", day); printf("Invalid day %d\n", day);
} }
event.type = static_cast<EVENT_TYPE>(event_type_int);
if (event.type >= EVENTS_COUNT) { if (event.type >= EVENTS_COUNT) {
event.type = EVENTS_OTHER; event.type = EVENTS_OTHER;
} }
if (day == today) { if (day == today) {
addEvent(&event); events.push_back(event);
} }
event_counts[day - 1].counts[event.type] += 1; event_counts[day - 1].counts[event.type] += 1;
@ -178,20 +181,5 @@ int readEventsFromFile(const char* const file_name, int today)
return num_events; return num_events;
} }
int addEvent(event_t* event) } // namespace Events
{
if (event_array.size + 1 > event_array.capacity) {
size_t newCapacity = event_array.capacity < 2 ? 4 : event_array.capacity * 2;
event_t* newMem = reallocarray(event_array.events, newCapacity, sizeof(event_t));
if (newMem == NULL) {
printf("Call to reallocarray failed. Unable to load more event_array");
return -1;
}
event_array.events = newMem;
event_array.capacity = newCapacity;
}
memcpy(&event_array.events[event_array.size++], event, sizeof(event_t));
return 0;
}

View File

@ -8,7 +8,7 @@
#include "fbd.h" #include "fbd.h"
int open_fb(struct framebuf* fb, const char* const dev) int open_fb(framebuf* fb, const char* const dev)
{ {
fb->fd = open(dev, O_RDWR); fb->fd = open(dev, O_RDWR);
if (fb->fd < 0) { if (fb->fd < 0) {
@ -16,17 +16,17 @@ int open_fb(struct framebuf* fb, const char* const dev)
return -1; return -1;
} }
// struct fb_fix_screeninfo fix_info; // fb_fix_screeninfo fix_info;
// ioctl(fd, FBIOGET_FSCREENINFO, &fix_info); // ioctl(fd, FBIOGET_FSCREENINFO, &fix_info);
struct fb_var_screeninfo var_info; fb_var_screeninfo var_info;
ioctl(fb->fd, FBIOGET_VSCREENINFO, &var_info); ioctl(fb->fd, FBIOGET_VSCREENINFO, &var_info);
fb->xres = var_info.xres; fb->xres = var_info.xres;
fb->yres = var_info.yres; fb->yres = var_info.yres;
fb->size = fb->xres * fb->yres * (var_info.bits_per_pixel / 8); fb->size = fb->xres * fb->yres * (var_info.bits_per_pixel / 8);
fb->buf = mmap(0, fb->size, PROT_READ | PROT_WRITE, MAP_SHARED, fb->fd, 0); fb->buf = (uint16_t*) mmap(0, fb->size, PROT_READ | PROT_WRITE, MAP_SHARED, fb->fd, 0);
if (fb->buf == MAP_FAILED) { if (fb->buf == MAP_FAILED) {
printf("Failed to map framebuf\n"); printf("Failed to map framebuf\n");
return -2; return -2;
@ -35,7 +35,7 @@ int open_fb(struct framebuf* fb, const char* const dev)
return 0; return 0;
} }
void close_fb(struct framebuf* fb) void close_fb(framebuf* fb)
{ {
// memset(fb->buf, 0, fb->size); // memset(fb->buf, 0, fb->size);
munmap(fb->buf, fb->size); munmap(fb->buf, fb->size);
@ -48,14 +48,8 @@ void close_fb(struct framebuf* fb)
fb->fd = -1; fb->fd = -1;
} }
void clear_fb(struct framebuf* fb) void clear_fb(framebuf* fb)
{ {
memset(fb->buf, 0, fb->size); memset(fb->buf, 0, fb->size);
} }
void set_pixel(struct framebuf* fb, uint32_t x, uint32_t y, uint16_t color)
{
uint32_t idx = (y * fb->xres) + x;
fb->buf[idx] = color;
}

View File

@ -27,7 +27,7 @@ void* tick_thread(void* arg);
void fb_flush_cb(lv_display_t* display, const lv_area_t* area, uint8_t* px_map) void fb_flush_cb(lv_display_t* display, const lv_area_t* area, uint8_t* px_map)
{ {
struct framebuf* fb = (struct framebuf*)lv_display_get_user_data(display); framebuf* fb = (framebuf*)lv_display_get_user_data(display);
int32_t area_width_b = (area->x2 - area->x1 + 1) * 2; // Two bytes per pixel int32_t area_width_b = (area->x2 - area->x1 + 1) * 2; // Two bytes per pixel
@ -58,7 +58,7 @@ int lvgl_fb_run(const char* const fb_dev)
sigaction(SIGINT, &act, NULL); sigaction(SIGINT, &act, NULL);
struct framebuf fb; framebuf fb;
int ret = open_fb(&fb, fb_dev); int ret = open_fb(&fb, fb_dev);
if (ret != 0) { if (ret != 0) {
printf("Failed to open framebuf. Error: %d\n", ret); printf("Failed to open framebuf. Error: %d\n", ret);
@ -78,7 +78,7 @@ int lvgl_fb_run(const char* const fb_dev)
lv_display_set_flush_cb(display, fb_flush_cb); lv_display_set_flush_cb(display, fb_flush_cb);
lv_display_set_user_data(display, &fb); lv_display_set_user_data(display, &fb);
uint16_t* buf1 = (uint16_t*)malloc(fb.size); uint16_t* buf1 = new uint16_t[fb.size];
lv_display_set_buffers(display, buf1, NULL, fb.size, LV_DISPLAY_RENDER_MODE_PARTIAL); lv_display_set_buffers(display, buf1, NULL, fb.size, LV_DISPLAY_RENDER_MODE_PARTIAL);
@ -86,7 +86,7 @@ int lvgl_fb_run(const char* const fb_dev)
// Copied from https://stackoverflow.com/a/27558789 // Copied from https://stackoverflow.com/a/27558789
pthread_attr_t attr; pthread_attr_t attr;
struct sched_param param; sched_param param;
pthread_attr_init(&attr); pthread_attr_init(&attr);
pthread_attr_getschedparam(&attr, &param); pthread_attr_getschedparam(&attr, &param);

View File

@ -1,279 +0,0 @@
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <time.h>
#include <lvgl.h>
#include "date_utils.h"
#include "calendar.h"
#include "fonts.h"
static lv_style_t box_style;
static lv_style_t box_style_active;
static lv_style_t box_style_inactive;
static const char* const month_list[] = {
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December",
};
static const char* const event_format_strs[] = {
NF_SYMBOL_CAMERA " %d meeting(s)",
NF_SYMBOL_UPDATE " %d cascade(s)",
NF_SYMBOL_LAPTOP " %d setup(s)",
NF_SYMBOL_CALENDAR " %d appointment(s)",
NF_SYMBOL_CALENDAR_QUESTION " %d other event(s)",
};
lvc_calendar_row_t* create_row(lv_obj_t* parent);
lvc_calendar_box_t* create_box(lv_obj_t* parent);
void destroy_row(lvc_calendar_row_t* row);
void destroy_box(lvc_calendar_box_t* row);
void style_calendar(lvc_calendar_t* cal, const struct tm* const ct);
int style_row(lvc_calendar_row_t* row, lv_obj_t* last_row, uint32_t box_width, uint32_t box_height, int day, int current_day, int days_in_month);
void style_box(lvc_calendar_box_t* box, uint32_t width, uint32_t height, int day, int wday, bool today, int days_in_month);
void draw_event_list_cb(lv_event_t* event);
void calendar_refresh_event(lv_event_t* event);
static inline void init_style(uint32_t box_width, uint32_t box_height)
{
lv_style_init(&box_style);
lv_style_set_width(&box_style, box_width);
lv_style_set_height(&box_style, box_height);
lv_style_set_radius(&box_style, 0);
lv_style_set_bg_color(&box_style, lv_color_hex(0xffffff));
lv_style_set_bg_opa(&box_style, LV_OPA_COVER);
lv_style_set_border_width(&box_style, 2);
lv_style_set_border_color(&box_style, lv_color_hex(0x333333));
lv_style_set_pad_all(&box_style, 5);
lv_style_init(&box_style_active);
lv_style_set_bg_color(&box_style_active, lv_color_hex(0xbbbbbb));
lv_style_set_text_color(&box_style_active, lv_color_hex(0x000000));
lv_style_init(&box_style_inactive);
lv_style_set_bg_color(&box_style_inactive, lv_color_hex(0x646464));
}
lvc_calendar_t* create_calendar(lv_obj_t* parent, uint32_t width)
{
time_t t = time(NULL);
struct tm* ct = localtime(&t);
lvc_calendar_t* cal = malloc(sizeof(lvc_calendar_t));
cal->calendar = lv_obj_create(parent);
cal->title_bar = lv_obj_create(cal->calendar);
cal->title_label = lv_label_create(cal->title_bar);
cal->width = width - (width % 7);
cal->box_width = cal->width / 7;
cal->box_height = cal->box_width * 0.8;
init_style(cal->box_width, cal->box_height);
for (uint8_t i = 0; i < CALENDAR_ROWS; i++) {
cal->rows[i] = create_row(cal->calendar);
}
style_calendar(cal, ct);
lv_obj_add_event_cb(cal->calendar, calendar_refresh_event, LV_EVENT_REFRESH, cal);
return cal;
}
lvc_calendar_row_t* create_row(lv_obj_t* parent)
{
lvc_calendar_row_t* row = malloc(sizeof(lvc_calendar_row_t));
for (uint8_t i = 0; i < DAYS_IN_WEEK; i++) {
row->boxes[i] = create_box(parent);
}
return row;
}
lvc_calendar_box_t* create_box(lv_obj_t* parent)
{
lvc_calendar_box_t* box = malloc(sizeof(lvc_calendar_box_t));
box->box = lv_obj_create(parent);
box->label = lv_label_create(box->box);
for (size_t i = 0; i < EVENTS_COUNT; i++) {
box->event_count_labels[i] = lv_label_create(box->box);
}
return box;
}
void destroy_calendar(lvc_calendar_t* cal)
{
for (uint8_t i = 0; i < CALENDAR_ROWS; i++) {
destroy_row(cal->rows[i]);
}
lv_obj_delete(cal->title_label);
lv_obj_delete(cal->title_bar);
lv_obj_delete(cal->calendar);
free(cal);
}
void destroy_row(lvc_calendar_row_t* row)
{
for (uint8_t i = 0; i < DAYS_IN_WEEK; i++) {
destroy_box(row->boxes[i]);
}
free(row);
}
void destroy_box(lvc_calendar_box_t* box)
{
lv_obj_delete(box->label);
for (size_t i = 0; i < EVENTS_COUNT; i++) {
lv_obj_delete(box->event_count_labels[i]);
}
lv_obj_delete(box->box);
free(box);
}
void style_calendar(lvc_calendar_t* cal, const struct tm* const ct)
{
int days = daysInMonth(ct->tm_mon, ct->tm_year + 1900);
int start_day = 1 - firstDayOfMonth(ct->tm_mon, ct->tm_year + 1900);
if (start_day == -5 && days == 31) {
start_day += 7;
}
lv_obj_set_size(cal->calendar, cal->width, cal->box_height * 6);
lv_obj_set_style_pad_all(cal->calendar, 0, LV_PART_MAIN);
lv_obj_set_style_border_width(cal->calendar, 0, LV_PART_MAIN);
lv_obj_remove_style_all(cal->title_bar);
lv_obj_set_size(cal->title_bar, cal->width, cal->box_height);
lv_obj_align(cal->title_bar, LV_ALIGN_TOP_MID, 0, 0);
lv_obj_set_style_pad_all(cal->title_bar, 0, LV_PART_MAIN);
lv_obj_add_style(cal->title_bar, &box_style, LV_PART_MAIN);
lv_obj_remove_style_all(cal->title_label);
lv_label_set_text_fmt(cal->title_label, "%s %d", month_list[ct->tm_mon], ct->tm_year + 1900);
lv_obj_set_style_text_font(cal->title_label, &lv_font_montserrat_48, LV_PART_MAIN);
lv_obj_center(cal->title_label);
unregisterAllUpdates();
lv_obj_t* last_row = cal->title_bar;
for (uint8_t r = 0; r < CALENDAR_ROWS; r++) {
start_day = style_row(cal->rows[r], last_row, cal->box_width, cal->box_height, start_day, ct->tm_mday, days);
last_row = cal->rows[r]->boxes[0]->box;
}
// Update events, so it will call our callbacks set in style_box to show the list of events
updateEvents(ct->tm_mday, ct->tm_mon, ct->tm_year + 1900);
}
int style_row(lvc_calendar_row_t* row, lv_obj_t* last_row, uint32_t box_width, uint32_t box_height, int day, int current_day, int days_in_month)
{
style_box(row->boxes[0], box_width, box_height, day, 0, day == current_day, days_in_month);
lv_obj_align_to(row->boxes[0]->box, last_row, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 0);
day++;
lv_obj_t* last = row->boxes[0]->box;
for (uint8_t i = 1; i < DAYS_IN_WEEK; i++) {
style_box(row->boxes[i], box_width, box_height, day, i, day == current_day, days_in_month);
lv_obj_align_to(row->boxes[i]->box, last, LV_ALIGN_OUT_RIGHT_TOP, 0, 0);
last = row->boxes[i]->box;
day++;
}
return day;
}
void style_box(lvc_calendar_box_t* box, uint32_t width, uint32_t height, int day, int wday, bool today, int days_in_month)
{
lv_obj_remove_style_all(box->box);
lv_obj_set_size(box->box, width, height);
lv_obj_add_style(box->box, &box_style, LV_PART_MAIN);
if (today) {
lv_obj_add_style(box->box, &box_style_active, LV_PART_MAIN);
}
if (wday == 6) {
lv_obj_set_style_border_side(box->box, LV_BORDER_SIDE_BOTTOM | LV_BORDER_SIDE_LEFT | LV_BORDER_SIDE_RIGHT, LV_PART_MAIN);
} else {
lv_obj_set_style_border_side(box->box, LV_BORDER_SIDE_BOTTOM | LV_BORDER_SIDE_LEFT, LV_PART_MAIN);
}
lv_obj_align(box->label, LV_ALIGN_TOP_LEFT, 0, 0);
if (day > 0 && day <= days_in_month) {
lv_label_set_text_fmt(box->label, "%d", day);
lv_obj_set_style_pad_bottom(box->label, 8, LV_PART_MAIN);
lv_obj_add_event_cb(box->box, draw_event_list_cb, LV_EVENT_REFRESH, box);
registerUpdateOnEventChange(day, box->box);
} else {
lv_obj_add_style(box->box, &box_style_inactive, LV_PART_MAIN);
lv_label_set_text(box->label, "");
}
for (size_t i = 0; i < EVENTS_COUNT; i++) {
lv_label_set_text(box->event_count_labels[i], "");
}
}
void draw_event_list_cb(lv_event_t* event)
{
event_type_counts_t* counts = lv_event_get_param(event);
lvc_calendar_box_t* box = lv_event_get_user_data(event);
int c = 0;
lv_obj_t* label = NULL;
lv_obj_t* last = box->label;
for (size_t i = 0; i < EVENTS_COUNT; i++) {
c = counts->counts[i];
label = box->event_count_labels[i];
if (c != 0) {
lv_label_set_text_fmt(label, event_format_strs[i], c);
lv_obj_align_to(label, last, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 0);
lv_obj_set_style_text_font(label, &nerdfonts_arimo_14, LV_PART_MAIN);
last = label;
} else {
lv_label_set_text(label, "");
}
}
}
void calendar_refresh_event(lv_event_t* event)
{
struct tm* ct = lv_event_get_param(event);
lvc_calendar_t* cal = lv_event_get_user_data(event);
style_calendar(cal, ct);
}

255
src/ui/calendar.cpp Normal file
View File

@ -0,0 +1,255 @@
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <time.h>
#include <lvgl.h>
#include "date_utils.h"
#include "calendar.h"
#include "fonts.h"
static lv_style_t box_style;
static lv_style_t box_style_active;
static lv_style_t box_style_inactive;
static const char* const month_list[] = {
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December",
};
static const char* const event_format_strs[] = {
NF_SYMBOL_CAMERA " %d meeting(s)",
NF_SYMBOL_UPDATE " %d cascade(s)",
NF_SYMBOL_LAPTOP " %d setup(s)",
NF_SYMBOL_CALENDAR " %d appointment(s)",
NF_SYMBOL_CALENDAR_QUESTION " %d other event(s)",
};
void draw_event_list_cb(lv_event_t* event);
void calendar_refresh_event(lv_event_t* event);
static inline void init_style(uint32_t box_width, uint32_t box_height)
{
lv_style_init(&box_style);
lv_style_set_width(&box_style, box_width);
lv_style_set_height(&box_style, box_height);
lv_style_set_radius(&box_style, 0);
lv_style_set_bg_color(&box_style, lv_color_hex(0xffffff));
lv_style_set_bg_opa(&box_style, LV_OPA_COVER);
lv_style_set_border_width(&box_style, 2);
lv_style_set_border_color(&box_style, lv_color_hex(0x333333));
lv_style_set_pad_all(&box_style, 5);
lv_style_init(&box_style_active);
lv_style_set_bg_color(&box_style_active, lv_color_hex(0xbbbbbb));
lv_style_set_text_color(&box_style_active, lv_color_hex(0x000000));
lv_style_init(&box_style_inactive);
lv_style_set_bg_color(&box_style_inactive, lv_color_hex(0x646464));
}
Calendar::Calendar(lv_obj_t* parent, uint32_t width)
: width(width - (width % 7))
{
time_t t = time(NULL);
struct tm* ct = localtime(&t);
calendar = lv_obj_create(parent);
title_bar = lv_obj_create(calendar);
title_label = lv_label_create(title_bar);
box_width = width / 7;
box_height = box_width * 0.8;
init_style(box_width, box_height);
for (uint8_t i = 0; i < CALENDAR_ROWS; i++) {
rows[i] = new CalendarRow(calendar);
}
Style(ct);
lv_obj_add_event_cb(calendar, calendar_refresh_event, LV_EVENT_REFRESH, this);
}
CalendarRow::CalendarRow(lv_obj_t* parent)
{
for (uint8_t i = 0; i < DAYS_IN_WEEK; i++) {
boxes[i] = new CalendarBox(parent);
}
}
CalendarBox::CalendarBox(lv_obj_t* parent)
{
box = lv_obj_create(parent);
label = lv_label_create(box);
for (size_t i = 0; i < Events::EVENTS_COUNT; i++) {
event_count_labels[i] = lv_label_create(box);
}
}
Calendar::~Calendar()
{
for (uint8_t i = 0; i < CALENDAR_ROWS; i++) {
delete rows[i];
}
lv_obj_delete(title_label);
lv_obj_delete(title_bar);
lv_obj_delete(calendar);
}
CalendarRow::~CalendarRow()
{
for (uint8_t i = 0; i < DAYS_IN_WEEK; i++) {
delete boxes[i];
}
}
CalendarBox::~CalendarBox()
{
lv_obj_delete(label);
for (size_t i = 0; i < Events::EVENTS_COUNT; i++) {
lv_obj_delete(event_count_labels[i]);
}
lv_obj_delete(box);
}
void Calendar::Style(const struct tm* const ct)
{
int days = daysInMonth(ct->tm_mon, ct->tm_year + 1900);
int start_day = 1 - firstDayOfMonth(ct->tm_mon, ct->tm_year + 1900);
if (start_day == -5 && days == 31) {
start_day += 7;
}
lv_obj_set_size(calendar, width, box_height * 6);
lv_obj_set_style_pad_all(calendar, 0, LV_PART_MAIN);
lv_obj_set_style_border_width(calendar, 0, LV_PART_MAIN);
lv_obj_remove_style_all(title_bar);
lv_obj_set_size(title_bar, width, box_height);
lv_obj_align(title_bar, LV_ALIGN_TOP_MID, 0, 0);
lv_obj_set_style_pad_all(title_bar, 0, LV_PART_MAIN);
lv_obj_add_style(title_bar, &box_style, LV_PART_MAIN);
lv_obj_remove_style_all(title_label);
lv_label_set_text_fmt(title_label, "%s %d", month_list[ct->tm_mon], ct->tm_year + 1900);
lv_obj_set_style_text_font(title_label, &lv_font_montserrat_48, LV_PART_MAIN);
lv_obj_center(title_label);
Events::unregisterCallbacks();
lv_obj_t* last_row = title_bar;
for (uint8_t r = 0; r < CALENDAR_ROWS; r++) {
start_day = rows[r]->Style(last_row, box_width, box_height, start_day, ct->tm_mday, days);
last_row = rows[r]->boxes[0]->box;
}
// Update events, so it will call our callbacks set in style_box to show the list of events
Events::update(ct->tm_mday, ct->tm_mon, ct->tm_year + 1900);
}
int CalendarRow::Style(lv_obj_t* last_row, uint32_t box_width, uint32_t box_height, int day, int current_day, int days_in_month)
{
boxes[0]->Style(box_width, box_height, day, 0, day == current_day, days_in_month);
lv_obj_align_to(boxes[0]->box, last_row, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 0);
day++;
lv_obj_t* last = boxes[0]->box;
for (uint8_t i = 1; i < DAYS_IN_WEEK; i++) {
boxes[i]->Style(box_width, box_height, day, i, day == current_day, days_in_month);
lv_obj_align_to(boxes[i]->box, last, LV_ALIGN_OUT_RIGHT_TOP, 0, 0);
last = boxes[i]->box;
day++;
}
return day;
}
void CalendarBox::Style(uint32_t width, uint32_t height, int day, int wday, bool today, int days_in_month)
{
lv_obj_remove_style_all(box);
lv_obj_set_size(box, width, height);
lv_obj_add_style(box, &box_style, LV_PART_MAIN);
if (today) {
lv_obj_add_style(box, &box_style_active, LV_PART_MAIN);
}
if (wday == 6) {
lv_obj_set_style_border_side(box, LV_BORDER_SIDE_BOTTOM | LV_BORDER_SIDE_LEFT | LV_BORDER_SIDE_RIGHT, LV_PART_MAIN);
} else {
lv_obj_set_style_border_side(box, LV_BORDER_SIDE_BOTTOM | LV_BORDER_SIDE_LEFT, LV_PART_MAIN);
}
lv_obj_align(label, LV_ALIGN_TOP_LEFT, 0, 0);
if (day > 0 && day <= days_in_month) {
lv_label_set_text_fmt(label, "%d", day);
lv_obj_set_style_pad_bottom(label, 8, LV_PART_MAIN);
lv_obj_add_event_cb(box, CalendarBox::DrawEvents_cb, LV_EVENT_REFRESH, this);
Events::registerCallback(day, box);
} else {
lv_obj_add_style(box, &box_style_inactive, LV_PART_MAIN);
lv_label_set_text(label, "");
}
for (size_t i = 0; i < Events::EVENTS_COUNT; i++) {
lv_label_set_text(event_count_labels[i], "");
}
}
void CalendarBox::DrawEvents_cb(lv_event_t* event)
{
Events::event_type_counts* counts = (Events::event_type_counts*) lv_event_get_param(event);
CalendarBox* box = (CalendarBox*) lv_event_get_user_data(event);
int c = 0;
lv_obj_t* label = NULL;
lv_obj_t* last = box->label;
for (size_t i = 0; i < Events::EVENTS_COUNT; i++) {
c = counts->counts[i];
label = box->event_count_labels[i];
if (c != 0) {
lv_label_set_text_fmt(label, event_format_strs[i], c);
lv_obj_align_to(label, last, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 0);
lv_obj_set_style_text_font(label, &nerdfonts_arimo_14, LV_PART_MAIN);
last = label;
} else {
lv_label_set_text(label, "");
}
}
}
void calendar_refresh_event(lv_event_t* event)
{
struct tm* ct = (struct tm*) lv_event_get_param(event);
Calendar* cal = (Calendar*) lv_event_get_user_data(event);
cal->Style(ct);
}

View File

@ -1,123 +0,0 @@
#include <unistd.h>
#include <stdint.h>
#include <stdio.h>
#include <time.h>
#include <lvgl.h>
#include "events.h"
#include "events_panel.h"
int add_event_labels(lvc_events_panel_t* panel, unsigned int count);
void draw_events_list_cb(lv_event_t* event);
void event_label_set_text(lv_obj_t* label, event_t* event);
lvc_events_panel_t* create_events_panel(lv_obj_t* parent)
{
lvc_events_panel_t* panel = malloc(sizeof(lvc_events_panel_t));
panel->panel = lv_obj_create(parent);
panel->header = lv_label_create(panel->panel);
panel->event_labels = NULL;
panel->event_labels_count = 0;
lv_obj_set_style_pad_all(panel->panel, 10, LV_PART_MAIN);
lv_obj_set_scrollbar_mode(panel->panel, LV_SCROLLBAR_MODE_OFF);
lv_label_set_text(panel->header, "Events");
lv_obj_set_style_text_font(panel->header, &lv_font_montserrat_36, LV_PART_MAIN);
lv_obj_align(panel->header, LV_ALIGN_TOP_LEFT, 0, 0);
lv_obj_add_event_cb(panel->panel, draw_events_list_cb, LV_EVENT_REFRESH, panel);
register_update_on_detailed_events_change(panel->panel);
return panel;
}
void destroy_events_panel(lvc_events_panel_t* panel)
{
lv_obj_delete(panel->header);
for (size_t i = 0; i < panel->event_labels_count; i++) {
lv_obj_delete(panel->event_labels[i]);
}
lv_obj_delete(panel->panel);
free(panel);
}
int add_event_labels(lvc_events_panel_t* panel, unsigned int count)
{
uint16_t newCapacity = panel->event_labels_count + count;
lv_obj_t** newMem = reallocarray(panel->event_labels, newCapacity, sizeof(lv_obj_t*));
if (newMem == NULL) {
printf("Call to reallocarray failed. Unable to create more labels to display events");
return -1;
}
panel->event_labels = newMem;
for (size_t i = panel->event_labels_count; i < newCapacity; i++) {
panel->event_labels[i] = lv_label_create(panel->panel);
}
panel->event_labels_count = newCapacity;
return 0;
}
void draw_events_list_cb(lv_event_t* event)
{
lvc_events_panel_t* panel = lv_event_get_user_data(event);
events_t* events = lv_event_get_param(event);
if (panel->event_labels_count < events->size) {
// More events than labels. Create new labels for events
if (add_event_labels(panel, events->size - panel->event_labels_count) != 0) {
printf("Failed to create new labels for event panel\n");
return;
}
}
lv_obj_t* last = panel->header;
size_t i = 0;
for (; i < events->size; i++) {
event_label_set_text(panel->event_labels[i], &events->events[i]);
lv_obj_set_style_text_font(panel->event_labels[i], &lv_font_montserrat_18, LV_PART_MAIN);
lv_obj_align_to(panel->event_labels[i], last, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 10);
last = panel->event_labels[i];
}
const uint16_t len = panel->event_labels_count;
for (;i < len; i++) {
lv_obj_delete(panel->event_labels[i]);
panel->event_labels_count -= 1;
}
}
void event_label_set_text(lv_obj_t* label, event_t* event)
{
int s_hour = event->s_hour;
const char* const s_time_suffix = s_hour >= 12 ? "PM" : "AM";
if (s_hour > 12) {
s_hour -= 12;
}
if (event->e_hour < 0) {
lv_label_set_text_fmt(label, "%s\n%d:%02d %s",
event->name, s_hour, event->s_min, s_time_suffix);
} else {
int e_hour = event->e_hour;
const char* const e_time_suffix = e_hour >= 12 ? "PM" : "AM";
if (e_hour > 12) {
e_hour -= 12;
}
lv_label_set_text_fmt(label, "%s\n%d:%02d %s - %d:%02d %s",
event->name, s_hour, event->s_min, s_time_suffix, e_hour, event->e_min, e_time_suffix);
}
}

102
src/ui/events_panel.cpp Normal file
View File

@ -0,0 +1,102 @@
#include <cstddef>
#include <unistd.h>
#include <iostream>
#include <stdio.h>
#include <time.h>
#include <lvgl.h>
#include <vector>
#include "events.h"
#include "events_panel.h"
void setEventLabelText(lv_obj_t* label, Events::Event* event);
EventsPanel::EventsPanel(lv_obj_t* parent)
{
panel = lv_obj_create(parent);
header = lv_label_create(panel);
lv_obj_set_style_pad_all(panel, 10, LV_PART_MAIN);
lv_obj_set_scrollbar_mode(panel, LV_SCROLLBAR_MODE_OFF);
lv_label_set_text(header, "Events");
lv_obj_set_style_text_font(header, &lv_font_montserrat_36, LV_PART_MAIN);
lv_obj_align(header, LV_ALIGN_TOP_LEFT, 0, 0);
lv_obj_add_event_cb(panel, EventsPanel::DrawEventList_cb, LV_EVENT_REFRESH, this);
Events::registerDetailedCallback(panel);
}
EventsPanel::~EventsPanel()
{
lv_obj_delete(header);
for (size_t i = 0; i < event_labels.size(); i++) {
lv_obj_delete(event_labels[i]);
}
lv_obj_delete(panel);
}
void EventsPanel::DrawEventList_cb(lv_event_t* event)
{
EventsPanel* panel = (EventsPanel*) lv_event_get_user_data(event);
std::vector<Events::Event>* events = (std::vector<Events::Event>*) lv_event_get_param(event);
if (panel->event_labels.size() < events->size()) {
panel->event_labels.reserve(events->size());
while (panel->event_labels.size() < events->size()) {
panel->event_labels.push_back(lv_label_create(panel->panel));
}
}
lv_obj_t* last = panel->header;
size_t i = 0;
for (; i < events->size(); i++) {
setEventLabelText(panel->event_labels[i], &events->at(i));
lv_obj_set_style_text_font(panel->event_labels[i], &lv_font_montserrat_18, LV_PART_MAIN);
lv_obj_align_to(panel->event_labels[i], last, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 10);
last = panel->event_labels[i];
}
if (events->size() < panel->event_labels.size()) {
for (size_t j = events->size(); j < panel->event_labels.size(); j++) {
lv_obj_delete(panel->event_labels[j]);
}
panel->event_labels.erase(std::next(panel->event_labels.begin(), i), panel->event_labels.end());
}
}
void setEventLabelText(lv_obj_t* label, Events::Event* event)
{
int s_hour = event->s_hour;
const char* const s_time_suffix = s_hour >= 12 ? "PM" : "AM";
if (s_hour > 12) {
s_hour -= 12;
}
if (event->e_hour < 0) {
lv_label_set_text_fmt(label, "%s\n%d:%02d %s",
event->name, s_hour, event->s_min, s_time_suffix);
} else {
int e_hour = event->e_hour;
const char* const e_time_suffix = e_hour >= 12 ? "PM" : "AM";
if (e_hour > 12) {
e_hour -= 12;
}
lv_label_set_text_fmt(label, "%s\n%d:%02d %s - %d:%02d %s",
event->name, s_hour, event->s_min, s_time_suffix, e_hour, event->e_min, e_time_suffix);
}
}

View File

@ -21,8 +21,8 @@
static lv_obj_t* screen; static lv_obj_t* screen;
static lv_obj_t* time_label; static lv_obj_t* time_label;
static lv_obj_t* ip_label; static lv_obj_t* ip_label;
static lvc_calendar_t* calendar; static Calendar* calendar;
static lvc_events_panel_t* events_panel; static EventsPanel* events_panel;
static lv_style_t test_style; static lv_style_t test_style;
static char ip_addr[INET_ADDRSTRLEN]; static char ip_addr[INET_ADDRSTRLEN];
@ -60,7 +60,7 @@ void create_widgets(void)
lv_label_set_text_fmt(ip_label, "IP: %s", ip_addr); lv_label_set_text_fmt(ip_label, "IP: %s", ip_addr);
lv_obj_align(ip_label, LV_ALIGN_BOTTOM_LEFT, 5, -5); lv_obj_align(ip_label, LV_ALIGN_BOTTOM_LEFT, 5, -5);
events_panel = create_events_panel(screen); events_panel = new EventsPanel(screen);
lv_obj_set_size(events_panel->panel, disp_hpercent_to_px(20), disp_height); lv_obj_set_size(events_panel->panel, disp_hpercent_to_px(20), disp_height);
lv_obj_align(events_panel->panel, LV_ALIGN_RIGHT_MID, 0, 0); lv_obj_align(events_panel->panel, LV_ALIGN_RIGHT_MID, 0, 0);
lv_obj_set_style_border_width(events_panel->panel, 2, LV_PART_MAIN); lv_obj_set_style_border_width(events_panel->panel, 2, LV_PART_MAIN);
@ -69,7 +69,7 @@ void create_widgets(void)
// Calendar must be created last. It calls the function to update the events // Calendar must be created last. It calls the function to update the events
uint32_t cal_width = disp_hpercent_to_px(70); uint32_t cal_width = disp_hpercent_to_px(70);
calendar = create_calendar(screen, cal_width); calendar = new Calendar(screen, cal_width);
lv_obj_align(calendar->calendar, LV_ALIGN_LEFT_MID, disp_hpercent_to_px(5), 0); lv_obj_align(calendar->calendar, LV_ALIGN_LEFT_MID, disp_hpercent_to_px(5), 0);
@ -84,8 +84,8 @@ void create_widgets(void)
void destroy_widgets(void) void destroy_widgets(void)
{ {
destroy_calendar(calendar); delete calendar;
destroy_events_panel(events_panel); delete events_panel;
lv_obj_clean(screen); lv_obj_clean(screen);
} }
@ -119,7 +119,7 @@ void check_time_timer(lv_timer_t* timer)
lv_obj_send_event(calendar->calendar, LV_EVENT_REFRESH, ct); lv_obj_send_event(calendar->calendar, LV_EVENT_REFRESH, ct);
} else if (min != ct->tm_min) { } else if (min != ct->tm_min) {
min = ct->tm_min; min = ct->tm_min;
updateEvents(ct->tm_mday, ct->tm_mon, ct->tm_year + 1900); Events::update(ct->tm_mday, ct->tm_mon, ct->tm_year + 1900);
get_ip(ip_addr, INET_ADDRSTRLEN); get_ip(ip_addr, INET_ADDRSTRLEN);
lv_label_set_text_fmt(ip_label, "IP: %s", ip_addr); lv_label_set_text_fmt(ip_label, "IP: %s", ip_addr);
@ -133,13 +133,13 @@ void update_events_timer(lv_timer_t* timer)
time_t t = time(NULL); time_t t = time(NULL);
struct tm* ct = localtime(&t); struct tm* ct = localtime(&t);
updateEvents(ct->tm_mday, ct->tm_mon, ct->tm_year + 1900); Events::update(ct->tm_mday, ct->tm_mon, ct->tm_year + 1900);
} }
void update_time_label(lv_event_t* event) void update_time_label(lv_event_t* event)
{ {
struct tm* ct = lv_event_get_param(event); struct tm* ct = (struct tm*) lv_event_get_param(event);
char time_str[TIME_BUF_LEN]; char time_str[TIME_BUF_LEN];
strftime(time_str, TIME_BUF_LEN, "%I:%M:%S %p", ct); strftime(time_str, TIME_BUF_LEN, "%I:%M:%S %p", ct);