Port to C++
This commit is contained in:
parent
c19b3b776f
commit
b6aadd4601
1
.gitignore
vendored
1
.gitignore
vendored
@ -1 +1,2 @@
|
|||||||
build/
|
build/
|
||||||
|
compile_commands.json
|
||||||
|
2
Makefile
2
Makefile
@ -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
@ -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);
|
||||||
|
|
||||||
|
31
inc/events.h
31
inc/events.h
@ -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
|
||||||
|
|
||||||
|
@ -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);
|
|
||||||
|
|
||||||
|
@ -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
|
|
||||||
|
|
||||||
|
@ -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);
|
|
||||||
|
@ -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);
|
|
||||||
|
@ -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))
|
||||||
{
|
{
|
@ -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;
|
|
||||||
}
|
|
||||||
|
|
@ -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;
|
|
||||||
}
|
|
@ -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, ¶m);
|
pthread_attr_getschedparam(&attr, ¶m);
|
@ -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
255
src/ui/calendar.cpp
Normal 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);
|
||||||
|
}
|
||||||
|
|
@ -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
102
src/ui/events_panel.cpp
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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);
|
Loading…
Reference in New Issue
Block a user