mirror of
https://github.com/HASwitchPlate/openHASP.git
synced 2025-07-24 11:46:34 +00:00
Add hasp_object
This commit is contained in:
parent
db47ce798b
commit
296e61c8e6
493
src/hasp.cpp
493
src/hasp.cpp
@ -14,6 +14,7 @@
|
||||
#include "lv_fs_if.h"
|
||||
#include "hasp_debug.h"
|
||||
#include "hasp_config.h"
|
||||
#include "hasp_object.h"
|
||||
#include "hasp_dispatch.h"
|
||||
//#include "hasp_filesystem.h" included in hasp_conf.h
|
||||
#include "hasp_wifi.h"
|
||||
@ -133,131 +134,6 @@ bool get_page_id(lv_obj_t * obj, uint8_t * pageid)
|
||||
return false;
|
||||
}
|
||||
|
||||
lv_obj_t * hasp_find_obj_from_id(lv_obj_t * parent, uint8_t objid)
|
||||
{
|
||||
if(objid == 0 || parent == nullptr) return parent;
|
||||
|
||||
lv_obj_t * child;
|
||||
child = lv_obj_get_child(parent, NULL);
|
||||
while(child) {
|
||||
if(child->user_data && (lv_obj_user_data_t)objid == child->user_data) return child; // object found
|
||||
|
||||
/* check grandchildren */
|
||||
lv_obj_t * grandchild = hasp_find_obj_from_id(child, objid);
|
||||
if(grandchild) return grandchild;
|
||||
|
||||
/* check tabs */
|
||||
if(check_obj_type(child, LV_HASP_TABVIEW)) {
|
||||
uint16_t tabcount = lv_tabview_get_tab_count(child);
|
||||
for(uint16_t i = 0; i < tabcount; i++) {
|
||||
lv_obj_t * tab = lv_tabview_get_tab(child, i);
|
||||
Log.verbose(TAG_HASP, "Found tab %i", i);
|
||||
if(tab->user_data && (lv_obj_user_data_t)objid == tab->user_data) return tab; // object found
|
||||
|
||||
grandchild = hasp_find_obj_from_id(tab, objid);
|
||||
if(grandchild) return grandchild;
|
||||
}
|
||||
}
|
||||
|
||||
/* next sibling */
|
||||
child = lv_obj_get_child(parent, child);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lv_obj_t * hasp_find_obj_from_id(uint8_t pageid, uint8_t objid)
|
||||
{
|
||||
return hasp_find_obj_from_id(get_page_obj(pageid), objid);
|
||||
}
|
||||
|
||||
bool FindIdFromObj(lv_obj_t * obj, uint8_t * pageid, lv_obj_user_data_t * objid)
|
||||
{
|
||||
if(!get_page_id(obj, pageid)) return false;
|
||||
if(!(obj->user_data > 0)) return false;
|
||||
memcpy(objid, &obj->user_data, sizeof(lv_obj_user_data_t));
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void hasp_send_obj_attribute_str(lv_obj_t * obj, const char * attribute, const char * data)
|
||||
{
|
||||
uint8_t pageid;
|
||||
uint8_t objid;
|
||||
|
||||
if(FindIdFromObj(obj, &pageid, &objid)) {
|
||||
dispatch_send_obj_attribute_str(pageid, objid, attribute, data);
|
||||
}
|
||||
}
|
||||
|
||||
void hasp_send_obj_attribute_int(lv_obj_t * obj, const char * attribute, int32_t val)
|
||||
{
|
||||
char data[64];
|
||||
itoa(val, data, 10);
|
||||
hasp_send_obj_attribute_str(obj, attribute, data);
|
||||
}
|
||||
|
||||
void hasp_send_obj_attribute_color(lv_obj_t * obj, const char * attribute, lv_color_t color)
|
||||
{
|
||||
char buffer[128];
|
||||
lv_color32_t c32;
|
||||
c32.full = lv_color_to32(color);
|
||||
snprintf(buffer, sizeof(buffer), PSTR("#%02x%02x%02x"), c32.ch.red, c32.ch.green, c32.ch.blue);
|
||||
hasp_send_obj_attribute_str(obj, attribute, buffer);
|
||||
}
|
||||
|
||||
/** Senders for event handlers **/
|
||||
|
||||
static void hasp_send_obj_attribute_P(lv_obj_t * obj, const char * attr, const char * data)
|
||||
{
|
||||
char * buffer;
|
||||
buffer = (char *)malloc(strlen_P(attr) + 1);
|
||||
strcpy_P(buffer, attr);
|
||||
hasp_send_obj_attribute_str(obj, buffer, data);
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
static inline void hasp_send_obj_attribute_val(lv_obj_t * obj, int32_t val)
|
||||
{
|
||||
char data[64];
|
||||
itoa(val, data, 10);
|
||||
hasp_send_obj_attribute_P(obj, PSTR("val"), data);
|
||||
}
|
||||
|
||||
/*static inline void hasp_send_obj_attribute_val(lv_obj_t * obj, int16_t val)
|
||||
{
|
||||
char data[64];
|
||||
itoa(val, data, 10);
|
||||
hasp_send_obj_attribute_P(obj, PSTR("val"), data);
|
||||
}*/
|
||||
|
||||
static inline void hasp_send_obj_attribute_event(lv_obj_t * obj, const char * event)
|
||||
{
|
||||
hasp_send_obj_attribute_P(obj, PSTR("event"), event);
|
||||
}
|
||||
|
||||
static inline void hasp_send_obj_attribute_txt(lv_obj_t * obj, const char * txt)
|
||||
{
|
||||
hasp_send_obj_attribute_P(obj, PSTR("txt"), txt);
|
||||
}
|
||||
|
||||
/*static void hasp_send_obj_attribute_txt(lv_obj_t * obj, String & txt)
|
||||
{
|
||||
hasp_send_obj_attribute_P(obj, PSTR("txt"), txt.c_str());
|
||||
}*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Used in the dispatcher
|
||||
void hasp_process_attribute(uint8_t pageid, uint8_t objid, const char * attr, const char * payload)
|
||||
{
|
||||
if(lv_obj_t * obj = hasp_find_obj_from_id(pageid, objid)) {
|
||||
hasp_process_obj_attribute(obj, attr, payload, strlen(payload) > 0);
|
||||
} else {
|
||||
Log.warning(TAG_HASP, F("Unknown object p[%d].b[%d]"), pageid, objid);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
@ -599,125 +475,6 @@ void hasp_background(uint16_t pageid, uint16_t imageid)
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Called when a a list button is clicked on the List tab
|
||||
* @param btn pointer to a list button
|
||||
* @param event type of event that occured
|
||||
*/
|
||||
void IRAM_ATTR btn_event_handler(lv_obj_t * obj, lv_event_t event)
|
||||
{
|
||||
uint8_t eventid;
|
||||
char buffer[64];
|
||||
|
||||
switch(event) {
|
||||
case LV_EVENT_PRESSED:
|
||||
eventid = HASP_EVENT_DOWN;
|
||||
memcpy_P(buffer, PSTR("DOWN"), sizeof(buffer));
|
||||
break;
|
||||
case LV_EVENT_CLICKED:
|
||||
// UP = the same object was release then was pressed and press was not lost!
|
||||
eventid = HASP_EVENT_UP;
|
||||
memcpy_P(buffer, PSTR("UP"), sizeof(buffer));
|
||||
break;
|
||||
case LV_EVENT_SHORT_CLICKED:
|
||||
eventid = HASP_EVENT_SHORT;
|
||||
memcpy_P(buffer, PSTR("SHORT"), sizeof(buffer));
|
||||
break;
|
||||
case LV_EVENT_LONG_PRESSED:
|
||||
eventid = HASP_EVENT_LONG;
|
||||
memcpy_P(buffer, PSTR("LONG"), sizeof(buffer));
|
||||
break;
|
||||
case LV_EVENT_LONG_PRESSED_REPEAT:
|
||||
eventid = HASP_EVENT_HOLD;
|
||||
memcpy_P(buffer, PSTR("HOLD"), sizeof(buffer));
|
||||
break;
|
||||
case LV_EVENT_PRESS_LOST:
|
||||
eventid = HASP_EVENT_LOST;
|
||||
memcpy_P(buffer, PSTR("LOST"), sizeof(buffer));
|
||||
break;
|
||||
case LV_EVENT_PRESSING:
|
||||
case LV_EVENT_FOCUSED:
|
||||
case LV_EVENT_DEFOCUSED:
|
||||
case LV_EVENT_RELEASED:
|
||||
return;
|
||||
|
||||
case LV_EVENT_VALUE_CHANGED:
|
||||
Log.warning(TAG_HASP, F("Value changed Event %d occured"), event);
|
||||
return;
|
||||
|
||||
case LV_EVENT_DELETE:
|
||||
Log.verbose(TAG_HASP, F("Object deleted Event %d occured"), event);
|
||||
return;
|
||||
default:
|
||||
Log.warning(TAG_HASP, F("Unknown Event %d occured"), event);
|
||||
return;
|
||||
}
|
||||
|
||||
if(obj == lv_disp_get_layer_sys(NULL)) {
|
||||
#if HASP_USE_MQTT > 0
|
||||
mqtt_send_state(F("wakeuptouch"), buffer);
|
||||
#endif
|
||||
} else {
|
||||
// hasp_send_obj_attribute_event(obj, buffer);
|
||||
dispatch_send_object_event(current_page, (uint8_t)obj->user_data, eventid);
|
||||
}
|
||||
}
|
||||
|
||||
// ##################### Event Handlers by Version ########################################################
|
||||
|
||||
/*static void btnmap_event_handler(lv_obj_t * obj, lv_event_t event)
|
||||
{
|
||||
if(event == LV_EVENT_VALUE_CHANGED) haspSendNewValue(obj, lv_btnmatrix_get_pressed_btn(obj));
|
||||
}*/
|
||||
|
||||
void IRAM_ATTR toggle_event_handler(lv_obj_t * obj, lv_event_t event)
|
||||
{
|
||||
bool toggled =
|
||||
lv_btn_get_state(obj) == LV_BTN_STATE_CHECKED_PRESSED || lv_btn_get_state(obj) == LV_BTN_STATE_CHECKED_RELEASED;
|
||||
if(event == LV_EVENT_VALUE_CHANGED) hasp_send_obj_attribute_val(obj, toggled);
|
||||
}
|
||||
|
||||
static void switch_event_handler(lv_obj_t * obj, lv_event_t event)
|
||||
{
|
||||
if(event == LV_EVENT_VALUE_CHANGED) hasp_send_obj_attribute_val(obj, lv_switch_get_state(obj));
|
||||
}
|
||||
|
||||
static void checkbox_event_handler(lv_obj_t * obj, lv_event_t event)
|
||||
{
|
||||
if(event == LV_EVENT_VALUE_CHANGED) hasp_send_obj_attribute_val(obj, lv_checkbox_is_checked(obj));
|
||||
}
|
||||
|
||||
static void ddlist_event_handler(lv_obj_t * obj, lv_event_t event)
|
||||
{
|
||||
if(event == LV_EVENT_VALUE_CHANGED) {
|
||||
hasp_send_obj_attribute_val(obj, lv_dropdown_get_selected(obj));
|
||||
char buffer[128];
|
||||
lv_dropdown_get_selected_str(obj, buffer, sizeof(buffer));
|
||||
hasp_send_obj_attribute_txt(obj, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
static void slider_event_handler(lv_obj_t * obj, lv_event_t event)
|
||||
{
|
||||
if(event == LV_EVENT_VALUE_CHANGED) hasp_send_obj_attribute_val(obj, lv_slider_get_value(obj));
|
||||
}
|
||||
|
||||
static void cpicker_event_handler(lv_obj_t * obj, lv_event_t event)
|
||||
{
|
||||
if(event == LV_EVENT_VALUE_CHANGED)
|
||||
hasp_send_obj_attribute_color(obj, "color", lv_cpicker_get_color(obj)); // Literial string
|
||||
}
|
||||
|
||||
static void roller_event_handler(lv_obj_t * obj, lv_event_t event)
|
||||
{
|
||||
if(event == LV_EVENT_VALUE_CHANGED) {
|
||||
hasp_send_obj_attribute_val(obj, lv_roller_get_selected(obj));
|
||||
char buffer[128];
|
||||
lv_roller_get_selected_str(obj, buffer, sizeof(buffer));
|
||||
hasp_send_obj_attribute_txt(obj, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
String haspGetVersion()
|
||||
@ -775,250 +532,6 @@ void hasp_set_group_objects(uint8_t groupid, uint8_t eventid, lv_obj_t * src_obj
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void haspNewObject(const JsonObject & config, uint8_t & saved_page_id)
|
||||
{
|
||||
/* Validate page */
|
||||
uint8_t pageid = config[F("page")].isNull() ? current_page : config[F("page")].as<uint8_t>();
|
||||
|
||||
/* Page selection */
|
||||
lv_obj_t * page = get_page_obj(pageid);
|
||||
if(!page) {
|
||||
Log.warning(TAG_HASP, F("Page ID %u not defined"), pageid);
|
||||
return;
|
||||
}
|
||||
/* save the current pageid */
|
||||
saved_page_id = pageid;
|
||||
|
||||
/* Validate type */
|
||||
if(config[F("objid")].isNull()) return; // comments
|
||||
|
||||
lv_obj_t * parent_obj = page;
|
||||
if(!config[F("parentid")].isNull()) {
|
||||
uint8_t parentid = config[F("parentid")].as<uint8_t>();
|
||||
parent_obj = hasp_find_obj_from_id(page, parentid);
|
||||
if(!parent_obj) {
|
||||
Log.warning(TAG_HASP, F("Parent ID p[%u].b[%u] not found"), pageid, parentid);
|
||||
parent_obj = page; // create on the page instead ??
|
||||
} else {
|
||||
Log.verbose(TAG_HASP, F("Parent ID p[%u].b[%u] found"), pageid, parentid);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t objid = config[F("objid")].as<uint8_t>();
|
||||
uint8_t id = config[F("id")].as<uint8_t>();
|
||||
|
||||
/* Define Objects*/
|
||||
lv_obj_t * obj = hasp_find_obj_from_id(parent_obj, id);
|
||||
if(obj) {
|
||||
Log.warning(TAG_HASP, F("Object ID %u already exists!"), id);
|
||||
return;
|
||||
}
|
||||
|
||||
switch(objid) {
|
||||
/* ----- Basic Objects ------ */
|
||||
case LV_HASP_BUTTON: {
|
||||
obj = lv_btn_create(parent_obj, NULL);
|
||||
lv_label_create(obj, NULL);
|
||||
lv_obj_set_event_cb(obj, btn_event_handler);
|
||||
break;
|
||||
}
|
||||
case LV_HASP_CHECKBOX: {
|
||||
obj = lv_checkbox_create(parent_obj, NULL);
|
||||
lv_obj_set_event_cb(obj, checkbox_event_handler);
|
||||
break;
|
||||
}
|
||||
case LV_HASP_LABEL: {
|
||||
obj = lv_label_create(parent_obj, NULL);
|
||||
/* click area padding */
|
||||
uint8_t padh = config[F("padh")].as<uint8_t>();
|
||||
uint8_t padv = config[F("padv")].as<uint8_t>();
|
||||
/* text align */
|
||||
if(padh > 0 || padv > 0) {
|
||||
lv_obj_set_ext_click_area(obj, padh, padh, padv, padv);
|
||||
}
|
||||
if(!config[F("align")].isNull()) {
|
||||
lv_label_set_align(obj, LV_LABEL_ALIGN_CENTER);
|
||||
}
|
||||
lv_obj_set_event_cb(obj, btn_event_handler);
|
||||
break;
|
||||
}
|
||||
case LV_HASP_IMAGE: {
|
||||
obj = lv_img_create(parent_obj, NULL);
|
||||
lv_obj_set_event_cb(obj, btn_event_handler);
|
||||
break;
|
||||
}
|
||||
case LV_HASP_ARC: {
|
||||
obj = lv_arc_create(parent_obj, NULL);
|
||||
lv_obj_set_event_cb(obj, btn_event_handler);
|
||||
break;
|
||||
}
|
||||
case LV_HASP_CONTAINER: {
|
||||
obj = lv_cont_create(parent_obj, NULL);
|
||||
lv_obj_set_event_cb(obj, btn_event_handler);
|
||||
break;
|
||||
}
|
||||
case LV_HASP_OBJECT: {
|
||||
obj = lv_obj_create(parent_obj, NULL);
|
||||
lv_obj_set_event_cb(obj, btn_event_handler);
|
||||
break;
|
||||
}
|
||||
case LV_HASP_PAGE: {
|
||||
obj = lv_page_create(parent_obj, NULL);
|
||||
break;
|
||||
}
|
||||
case LV_HASP_TABVIEW: {
|
||||
obj = lv_tabview_create(parent_obj, NULL);
|
||||
lv_obj_t * tab;
|
||||
tab = lv_tabview_add_tab(obj, "tab 1");
|
||||
lv_obj_set_user_data(tab, id + 1);
|
||||
tab = lv_tabview_add_tab(obj, "tab 2");
|
||||
lv_obj_set_user_data(tab, id + 2);
|
||||
tab = lv_tabview_add_tab(obj, "tab 3");
|
||||
lv_obj_set_user_data(tab, id + 3);
|
||||
break;
|
||||
}
|
||||
case LV_HASP_TILEVIEW: {
|
||||
obj = lv_tileview_create(parent_obj, NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
/* ----- Color Objects ------ */
|
||||
case LV_HASP_CPICKER: {
|
||||
obj = lv_cpicker_create(parent_obj, NULL);
|
||||
lv_obj_set_event_cb(obj, cpicker_event_handler);
|
||||
break;
|
||||
}
|
||||
|
||||
#if LV_USE_PRELOAD != 0
|
||||
case LV_HASP_PRELOADER: {
|
||||
obj = lv_spinner_create(parent_obj, NULL);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
/* ----- Range Objects ------ */
|
||||
case LV_HASP_SLIDER: {
|
||||
obj = lv_slider_create(parent_obj, NULL);
|
||||
lv_slider_set_range(obj, 0, 100);
|
||||
lv_obj_set_event_cb(obj, slider_event_handler);
|
||||
// bool knobin = config[F("knobin")].as<bool>() | true;
|
||||
// lv_slider_set_knob_in(obj, knobin);
|
||||
break;
|
||||
}
|
||||
case LV_HASP_GAUGE: {
|
||||
obj = lv_gauge_create(parent_obj, NULL);
|
||||
lv_gauge_set_range(obj, 0, 100);
|
||||
lv_obj_set_event_cb(obj, btn_event_handler);
|
||||
break;
|
||||
}
|
||||
case LV_HASP_BAR: {
|
||||
obj = lv_bar_create(parent_obj, NULL);
|
||||
lv_bar_set_range(obj, 0, 100);
|
||||
lv_obj_set_event_cb(obj, btn_event_handler);
|
||||
break;
|
||||
}
|
||||
case LV_HASP_LMETER: {
|
||||
obj = lv_linemeter_create(parent_obj, NULL);
|
||||
lv_linemeter_set_range(obj, 0, 100);
|
||||
lv_obj_set_event_cb(obj, btn_event_handler);
|
||||
break;
|
||||
}
|
||||
case LV_HASP_CHART: {
|
||||
obj = lv_chart_create(parent_obj, NULL);
|
||||
lv_chart_set_range(obj, 0, 100);
|
||||
lv_obj_set_event_cb(obj, btn_event_handler);
|
||||
|
||||
lv_chart_add_series(obj, LV_COLOR_RED);
|
||||
lv_chart_add_series(obj, LV_COLOR_GREEN);
|
||||
lv_chart_add_series(obj, LV_COLOR_BLUE);
|
||||
|
||||
lv_chart_series_t * ser = lv_chart_get_series(obj, 2);
|
||||
lv_chart_set_next(obj, ser, 10);
|
||||
lv_chart_set_next(obj, ser, 20);
|
||||
lv_chart_set_next(obj, ser, 30);
|
||||
lv_chart_set_next(obj, ser, 40);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/* ----- On/Off Objects ------ */
|
||||
case LV_HASP_SWITCH: {
|
||||
obj = lv_switch_create(parent_obj, NULL);
|
||||
lv_obj_set_event_cb(obj, switch_event_handler);
|
||||
break;
|
||||
}
|
||||
case LV_HASP_LED: {
|
||||
obj = lv_led_create(parent_obj, NULL);
|
||||
lv_obj_set_event_cb(obj, btn_event_handler);
|
||||
break;
|
||||
}
|
||||
/**/
|
||||
case LV_HASP_DDLIST: {
|
||||
obj = lv_dropdown_create(parent_obj, NULL);
|
||||
// lv_dropdown_set_fix_width(obj, width);
|
||||
lv_dropdown_set_draw_arrow(obj, true);
|
||||
// lv_dropdown_set_anim_time(obj, 200);
|
||||
lv_obj_set_top(obj, true);
|
||||
// lv_obj_align(obj, NULL, LV_ALIGN_IN_TOP_MID, 0, 20);
|
||||
lv_obj_set_event_cb(obj, ddlist_event_handler);
|
||||
break;
|
||||
}
|
||||
case LV_HASP_ROLLER: {
|
||||
obj = lv_roller_create(parent_obj, NULL);
|
||||
// lv_roller_set_fix_width(obj, width);
|
||||
// lv_obj_align(obj, NULL, LV_ALIGN_IN_TOP_MID, 0, 20);
|
||||
lv_obj_set_event_cb(obj, roller_event_handler);
|
||||
break;
|
||||
}
|
||||
|
||||
/* ----- Other Object ------ */
|
||||
default:
|
||||
Log.warning(TAG_HASP, F("Unsupported Object ID %u"), objid);
|
||||
return;
|
||||
}
|
||||
|
||||
if(!obj) {
|
||||
Log.warning(TAG_HASP, F("Object is NULL, skipping..."));
|
||||
return;
|
||||
}
|
||||
|
||||
lv_obj_set_user_data(obj, id);
|
||||
|
||||
/* do not process these attributes */
|
||||
config.remove(F("page"));
|
||||
config.remove(F("id"));
|
||||
config.remove(F("objid"));
|
||||
config.remove(F("parentid"));
|
||||
String v;
|
||||
|
||||
for(JsonPair keyValue : config) {
|
||||
v = keyValue.value().as<String>();
|
||||
hasp_process_obj_attribute(obj, keyValue.key().c_str(), v.c_str(), true);
|
||||
// Log.verbose(TAG_HASP,F(" * %s => %s"), keyValue.key().c_str(), v.c_str());
|
||||
}
|
||||
|
||||
/** testing start **/
|
||||
lv_obj_user_data_t temp;
|
||||
if(!FindIdFromObj(obj, &pageid, &temp)) {
|
||||
Log.error(TAG_HASP, F("Lost track of the created object, not found!"));
|
||||
return;
|
||||
}
|
||||
/** testing end **/
|
||||
|
||||
lv_obj_type_t list;
|
||||
lv_obj_get_type(obj, &list);
|
||||
Log.verbose(TAG_HASP, F(" * p[%u].b[%u] = %s"), pageid, temp, list.type[0]);
|
||||
|
||||
/* Double-check */
|
||||
lv_obj_t * test = hasp_find_obj_from_id(pageid, (uint8_t)temp);
|
||||
if(test != obj) {
|
||||
Log.error(TAG_HASP, F("Objects DO NOT match!"));
|
||||
} else {
|
||||
// Log.verbose(TAG_HASP,F("Objects match!"));
|
||||
}
|
||||
}
|
||||
|
||||
void haspLoadPage(const char * pages)
|
||||
{
|
||||
#if HASP_USE_SPIFFS > 0 || HASP_USE_LITTLEFS > 0
|
||||
@ -1047,7 +560,7 @@ void haspLoadPage(const char * pages)
|
||||
Log.notice(TAG_HASP, F("Loading jsonl from EEPROM..."));
|
||||
EepromStream eepromStream(4096, 1024);
|
||||
dispatchJsonl(eepromStream);
|
||||
Log.tr (TAG_HASP, F("Loaded jsonl from EEPROM"));
|
||||
Log.tr(TAG_HASP, F("Loaded jsonl from EEPROM"));
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@ -1077,7 +590,7 @@ bool haspGetConfig(const JsonObject & settings)
|
||||
if(strcmp(haspPagesPath, settings[FPSTR(F_CONFIG_PAGES)].as<String>().c_str()) != 0) changed = true;
|
||||
settings[FPSTR(F_CONFIG_PAGES)] = haspPagesPath;
|
||||
|
||||
if(changed) configOutput(settings,TAG_HASP);
|
||||
if(changed) configOutput(settings, TAG_HASP);
|
||||
return changed;
|
||||
}
|
||||
|
||||
|
53
src/hasp.h
53
src/hasp.h
@ -42,47 +42,6 @@ enum hasp_event_t { // even = released, odd = pressed
|
||||
HASP_EVENT_DOUBLE = 8
|
||||
};
|
||||
|
||||
enum lv_hasp_obj_type_t {
|
||||
LV_HASP_BTNMATRIX = 1,
|
||||
LV_HASP_TABLE = 2,
|
||||
|
||||
LV_HASP_BUTTON = 10,
|
||||
LV_HASP_CHECKBOX = 11,
|
||||
LV_HASP_LABEL = 12,
|
||||
|
||||
LV_HASP_CPICKER = 20,
|
||||
LV_HASP_PRELOADER = 21,
|
||||
LV_HASP_ARC = 22,
|
||||
|
||||
LV_HASP_SLIDER = 30,
|
||||
LV_HASP_GAUGE = 31,
|
||||
LV_HASP_BAR = 32,
|
||||
LV_HASP_LMETER = 33,
|
||||
|
||||
LV_HASP_SWITCH = 40,
|
||||
LV_HASP_LED = 41,
|
||||
|
||||
LV_HASP_DDLIST = 50,
|
||||
LV_HASP_ROLLER = 51,
|
||||
|
||||
LV_HASP_IMAGE = 60,
|
||||
LV_HASP_IMGBTN = 61,
|
||||
LV_HASP_CANVAS = 62,
|
||||
|
||||
LV_HASP_TILEVIEW = 70,
|
||||
LV_HASP_TABVIEW = 71,
|
||||
LV_HASP_TAB = 72,
|
||||
|
||||
LV_HASP_CHART = 80,
|
||||
LV_HASP_CALENDER = 81,
|
||||
|
||||
LV_HASP_CONTAINER = 90,
|
||||
LV_HASP_OBJECT = 91,
|
||||
LV_HASP_PAGE = 92,
|
||||
LV_HASP_MSGBOX = 93,
|
||||
LV_HASP_WINDOW = 94,
|
||||
};
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
@ -93,17 +52,17 @@ enum lv_hasp_obj_type_t {
|
||||
void haspSetup();
|
||||
void haspLoop(void);
|
||||
|
||||
lv_obj_t * get_page_obj(uint8_t pageid);
|
||||
bool get_page_id(lv_obj_t * obj, uint8_t * pageid);
|
||||
|
||||
void haspSetPage(uint8_t id);
|
||||
uint8_t haspGetPage();
|
||||
void haspClearPage(uint16_t pageid);
|
||||
|
||||
String haspGetNodename();
|
||||
String haspGetVersion();
|
||||
void haspBackground(uint16_t pageid, uint16_t imageid);
|
||||
|
||||
void hasp_send_obj_attribute_str(lv_obj_t * obj, const char * attribute, const char * data);
|
||||
void hasp_send_obj_attribute_int(lv_obj_t * obj, const char * attribute, int32_t val);
|
||||
void hasp_send_obj_attribute_color(lv_obj_t * obj, const char * attribute, lv_color_t color);
|
||||
void hasp_process_attribute(uint8_t pageid, uint8_t objid, const char * attr, const char * payload);
|
||||
void hasp_set_group_objects(uint8_t groupid, uint8_t eventid, lv_obj_t * src_obj);
|
||||
|
||||
void haspNewObject(const JsonObject & config, uint8_t & saved_page_id);
|
||||
@ -116,12 +75,8 @@ void haspProgressVal(uint8_t val);
|
||||
bool haspGetConfig(const JsonObject & settings);
|
||||
bool haspSetConfig(const JsonObject & settings);
|
||||
|
||||
lv_obj_t * hasp_find_obj_from_id(lv_obj_t * parent, uint8_t objid);
|
||||
lv_font_t * hasp_get_font(uint8_t fontid);
|
||||
|
||||
void IRAM_ATTR btn_event_handler(lv_obj_t * obj, lv_event_t event);
|
||||
void IRAM_ATTR toggle_event_handler(lv_obj_t * obj, lv_event_t event);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "lv_conf.h"
|
||||
|
||||
#include "hasp.h"
|
||||
#include "hasp_object.h"
|
||||
#include "hasp_dispatch.h"
|
||||
#include "hasp_attribute.h"
|
||||
|
||||
@ -12,6 +13,9 @@ LV_FONT_DECLARE(unscii_8_icon);
|
||||
extern lv_font_t * haspFonts[8];
|
||||
|
||||
static inline bool only_digits(const char * s);
|
||||
static inline void hasp_out_int(lv_obj_t * obj, const char * attr, uint32_t val);
|
||||
static inline void hasp_out_str(lv_obj_t * obj, const char * attr, const char * data);
|
||||
static inline void hasp_out_color(lv_obj_t * obj, const char * attr, lv_color_t color);
|
||||
|
||||
/* 16-bit hashing function http://www.cse.yorku.ca/~oz/hash.html */
|
||||
/* all possible attributes are hashed and checked if they are unique */
|
||||
@ -614,6 +618,86 @@ static void hasp_process_gauge_attribute(lv_obj_t * obj, const char * attr_p, ui
|
||||
Log.warning(TAG_ATTR, F("Unknown property %s"), attr_p);
|
||||
}
|
||||
|
||||
static void hasp_process_btnmatrix_attribute(lv_obj_t * obj, const char * attr_p, uint16_t attr_hash,
|
||||
const char * payload, bool update)
|
||||
{
|
||||
char * attr = (char *)attr_p;
|
||||
if(*attr == '.') attr++; // strip leading '.'
|
||||
|
||||
switch(attr_hash) {
|
||||
case ATTR_MAP: {
|
||||
const char ** map_p = lv_btnmatrix_get_map_array(obj);
|
||||
if(update) {
|
||||
// Free previous map
|
||||
// lv_mem_free(*map_p);
|
||||
|
||||
// if(map_p != lv_btnmatrix_def_map) {
|
||||
// }
|
||||
|
||||
// Create new map
|
||||
|
||||
// Reserve memory for JsonDocument
|
||||
size_t maxsize = (128u * ((strlen(payload) / 128) + 1)) + 256;
|
||||
DynamicJsonDocument map_doc(maxsize);
|
||||
DeserializationError jsonError = deserializeJson(map_doc, payload);
|
||||
|
||||
if(jsonError) { // Couldn't parse incoming JSON payload
|
||||
return Log.warning(TAG_ATTR, F("JSON: Failed to parse incoming button map with error: %s"),
|
||||
jsonError.c_str());
|
||||
}
|
||||
|
||||
JsonArray arr = map_doc.as<JsonArray>(); // Parse payload
|
||||
|
||||
size_t tot_len = sizeof(char *) * (arr.size() + 1);
|
||||
const char ** map_arr = (const char **)lv_mem_alloc(tot_len);
|
||||
if(map_arr == NULL) {
|
||||
return Log.error(TAG_ATTR, F("Out of memory while creating button map"));
|
||||
}
|
||||
memset(map_arr, 0, tot_len);
|
||||
|
||||
// Create buffer
|
||||
tot_len = 0;
|
||||
size_t pos = 0;
|
||||
for(JsonVariant btn : arr) {
|
||||
tot_len += btn.as<String>().length() + 1;
|
||||
}
|
||||
tot_len++; // trailing '\0'
|
||||
Log.verbose(TAG_ATTR, F("Array Size = %d, Map Length = %d"), arr.size(), tot_len);
|
||||
|
||||
char * buffer = (char *)lv_mem_alloc(tot_len);
|
||||
if(map_arr == NULL) {
|
||||
lv_mem_free(map_arr);
|
||||
return Log.error(TAG_ATTR, F("Out of memory while creating button map"));
|
||||
}
|
||||
memset(buffer, 0, tot_len); // Important, last index needs to be 0
|
||||
|
||||
// Fill buffer
|
||||
size_t index = 0;
|
||||
for(JsonVariant btn : arr) {
|
||||
size_t len = btn.as<String>().length() + 1;
|
||||
Log.verbose(TAG_ATTR, F(" * Adding button: %s (%d bytes)"), btn.as<String>().c_str(), len);
|
||||
memccpy(buffer + pos, btn.as<String>().c_str(), 0, len); // Copy the labels into the buffer
|
||||
map_arr[index++] = buffer + pos; // save pointer to start of the label
|
||||
pos += len;
|
||||
}
|
||||
map_arr[index] = buffer + pos; // save pointer to the last \0 byte
|
||||
|
||||
lv_btnmatrix_set_map(obj, map_arr);
|
||||
|
||||
// TO DO : free & destroy previous buttonmap!
|
||||
|
||||
} else {
|
||||
hasp_out_str(obj, attr, *map_p);
|
||||
}
|
||||
return;
|
||||
} // ATTR_MAP
|
||||
}
|
||||
|
||||
Log.warning(TAG_ATTR, F("Unknown property %s"), attr_p);
|
||||
}
|
||||
|
||||
// ##################### Common Attributes ########################################################
|
||||
|
||||
// OK
|
||||
static void hasp_process_obj_attribute_txt(lv_obj_t * obj, const char * attr, const char * payload, bool update)
|
||||
{
|
||||
@ -800,10 +884,12 @@ static void hasp_process_obj_attribute_range(lv_obj_t * obj, const char * attr,
|
||||
return update ? lv_chart_set_range(obj, set_min ? val : min, set_max ? val : max)
|
||||
: hasp_out_int(obj, attr, set_min ? min : max);
|
||||
}
|
||||
|
||||
|
||||
Log.warning(TAG_ATTR, F("Unknown property %s"), attr);
|
||||
}
|
||||
|
||||
// ##################### Default Attributes ########################################################
|
||||
|
||||
/**
|
||||
* Change or Retrieve the value of the attribute of an object
|
||||
* @param obj lv_obj_t*: the object to get/set the attribute
|
||||
@ -902,6 +988,18 @@ void hasp_process_obj_attribute(lv_obj_t * obj, const char * attr_p, const char
|
||||
return update ? lv_roller_set_visible_row_count(obj, (uint8_t)val)
|
||||
: hasp_out_int(obj, attr, lv_roller_get_visible_row_count(obj));
|
||||
}
|
||||
|
||||
if(check_obj_type(obj, LV_HASP_TABLE)) {
|
||||
return update ? lv_table_set_row_cnt(obj, (uint8_t)val)
|
||||
: hasp_out_int(obj, attr, lv_table_get_row_cnt(obj));
|
||||
}
|
||||
break;
|
||||
|
||||
case ATTR_COLS:
|
||||
if(check_obj_type(obj, LV_HASP_TABLE)) {
|
||||
return update ? lv_table_set_col_cnt(obj, (uint8_t)val)
|
||||
: hasp_out_int(obj, attr, lv_table_get_col_cnt(obj));
|
||||
}
|
||||
break;
|
||||
|
||||
// case ATTR_RECT:
|
||||
@ -980,6 +1078,10 @@ void hasp_process_obj_attribute(lv_obj_t * obj, const char * attr_p, const char
|
||||
case ATTR_DELETE:
|
||||
return lv_obj_del_async(obj);
|
||||
|
||||
case ATTR_MAP:
|
||||
if(check_obj_type(obj, LV_HASP_BTNMATRIX)) {
|
||||
return hasp_process_btnmatrix_attribute(obj, attr_p, attr_hash, payload, update);
|
||||
}
|
||||
// default:
|
||||
// hasp_local_style_attr(obj, attr, payload, update);
|
||||
}
|
||||
@ -1000,106 +1102,19 @@ static inline bool only_digits(const char * s)
|
||||
return strlen(s) == digits;
|
||||
}
|
||||
|
||||
void inline hasp_out_int(lv_obj_t * obj, const char * attr, uint32_t val)
|
||||
// ##################### Value Senders ########################################################
|
||||
|
||||
static inline void hasp_out_int(lv_obj_t * obj, const char * attr, uint32_t val)
|
||||
{
|
||||
hasp_send_obj_attribute_int(obj, attr, val);
|
||||
}
|
||||
|
||||
void inline hasp_out_str(lv_obj_t * obj, const char * attr, const char * data)
|
||||
static inline void hasp_out_str(lv_obj_t * obj, const char * attr, const char * data)
|
||||
{
|
||||
hasp_send_obj_attribute_str(obj, attr, data);
|
||||
}
|
||||
|
||||
void inline hasp_out_color(lv_obj_t * obj, const char * attr, lv_color_t color)
|
||||
static inline void hasp_out_color(lv_obj_t * obj, const char * attr, lv_color_t color)
|
||||
{
|
||||
hasp_send_obj_attribute_color(obj, attr, color);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an lvgl object typename corresponds to a given HASP object ID
|
||||
* @param lvobjtype a char* to a string
|
||||
* @param haspobjtype the HASP object ID to check against
|
||||
* @return true or false wether the types match
|
||||
* @note
|
||||
*/
|
||||
bool check_obj_type(const char * lvobjtype, lv_hasp_obj_type_t haspobjtype)
|
||||
{
|
||||
lvobjtype += 3; // skip "lv_"
|
||||
|
||||
switch(haspobjtype) {
|
||||
case LV_HASP_BTNMATRIX:
|
||||
return (strcmp_P(lvobjtype, PSTR("btnmatrix")) == 0);
|
||||
case LV_HASP_TABLE:
|
||||
return (strcmp_P(lvobjtype, PSTR("table")) == 0);
|
||||
case LV_HASP_BUTTON:
|
||||
return (strcmp_P(lvobjtype, PSTR("btn")) == 0);
|
||||
case LV_HASP_LABEL:
|
||||
return (strcmp_P(lvobjtype, PSTR("label")) == 0);
|
||||
case LV_HASP_CHECKBOX:
|
||||
return (strcmp_P(lvobjtype, PSTR("checkbox")) == 0); // || (strcmp_P(lvobjtype, PSTR("lv_cb")) == 0);
|
||||
case LV_HASP_DDLIST:
|
||||
return (strcmp_P(lvobjtype, PSTR("dropdown")) == 0); // || (strcmp_P(lvobjtype, PSTR("lv_ddlist")) == 0);
|
||||
case LV_HASP_CPICKER:
|
||||
return (strcmp_P(lvobjtype, PSTR("cpicker")) == 0);
|
||||
case LV_HASP_PRELOADER:
|
||||
return (strcmp_P(lvobjtype, PSTR("spinner")) == 0); // || (strcmp_P(lvobjtype, PSTR("lv_preload")) == 0);
|
||||
case LV_HASP_SLIDER:
|
||||
return (strcmp_P(lvobjtype, PSTR("slider")) == 0);
|
||||
case LV_HASP_GAUGE:
|
||||
return (strcmp_P(lvobjtype, PSTR("gauge")) == 0);
|
||||
case LV_HASP_ARC:
|
||||
return (strcmp_P(lvobjtype, PSTR("arc")) == 0);
|
||||
case LV_HASP_BAR:
|
||||
return (strcmp_P(lvobjtype, PSTR("bar")) == 0);
|
||||
case LV_HASP_LMETER:
|
||||
return (strcmp_P(lvobjtype, PSTR("linemeter")) == 0); // || (strcmp_P(lvobjtype, PSTR("lv_lmeter")) == 0)
|
||||
case LV_HASP_ROLLER:
|
||||
return (strcmp_P(lvobjtype, PSTR("roller")) == 0);
|
||||
case LV_HASP_SWITCH:
|
||||
return (strcmp_P(lvobjtype, PSTR("switch")) == 0); // || (strcmp_P(lvobjtype, PSTR("lv_sw")) == 0)
|
||||
case LV_HASP_LED:
|
||||
return (strcmp_P(lvobjtype, PSTR("led")) == 0);
|
||||
case LV_HASP_IMAGE:
|
||||
return (strcmp_P(lvobjtype, PSTR("img")) == 0);
|
||||
case LV_HASP_IMGBTN:
|
||||
return (strcmp_P(lvobjtype, PSTR("imgbtn")) == 0);
|
||||
case LV_HASP_CONTAINER:
|
||||
return (strcmp_P(lvobjtype, PSTR("container")) == 0); // || (strcmp_P(lvobjtype, PSTR("lv_cont")) == 0)
|
||||
case LV_HASP_OBJECT:
|
||||
return (strcmp_P(lvobjtype, PSTR("page")) == 0); // || (strcmp_P(lvobjtype, PSTR("lv_cont")) == 0)
|
||||
case LV_HASP_PAGE:
|
||||
return (strcmp_P(lvobjtype, PSTR("obj")) == 0); // || (strcmp_P(lvobjtype, PSTR("lv_cont")) == 0)
|
||||
case LV_HASP_TABVIEW:
|
||||
return (strcmp_P(lvobjtype, PSTR("tabview")) == 0);
|
||||
case LV_HASP_TILEVIEW:
|
||||
return (strcmp_P(lvobjtype, PSTR("tileview")) == 0);
|
||||
case LV_HASP_CHART:
|
||||
return (strcmp_P(lvobjtype, PSTR("chart")) == 0);
|
||||
case LV_HASP_CANVAS:
|
||||
return (strcmp_P(lvobjtype, PSTR("canvas")) == 0);
|
||||
case LV_HASP_CALENDER:
|
||||
return (strcmp_P(lvobjtype, PSTR("calender")) == 0);
|
||||
case LV_HASP_MSGBOX:
|
||||
return (strcmp_P(lvobjtype, PSTR("msgbox")) == 0);
|
||||
case LV_HASP_WINDOW:
|
||||
return (strcmp_P(lvobjtype, PSTR("window")) == 0);
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an lvgl objecttype name corresponds to a given HASP object ID
|
||||
* @param obj an lv_obj_t* of the object to check its type
|
||||
* @param haspobjtype the HASP object ID to check against
|
||||
* @return true or false wether the types match
|
||||
* @note
|
||||
*/
|
||||
bool check_obj_type(lv_obj_t * obj, lv_hasp_obj_type_t haspobjtype)
|
||||
{
|
||||
lv_obj_type_t list;
|
||||
lv_obj_get_type(obj, &list);
|
||||
const char * objtype = list.type[0];
|
||||
return check_obj_type(objtype, haspobjtype);
|
||||
}
|
@ -18,13 +18,6 @@ void hasp_process_obj_attribute(lv_obj_t * obj, const char * attr_p, const char
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
void hasp_out_int(lv_obj_t * obj, const char * attr, uint32_t val);
|
||||
void hasp_out_str(lv_obj_t * obj, const char * attr, const char * data);
|
||||
void hasp_out_color(lv_obj_t * obj, const char * attr, lv_color_t color);
|
||||
|
||||
bool check_obj_type(const char * lvobjtype, lv_hasp_obj_type_t haspobjtype);
|
||||
bool check_obj_type(lv_obj_t * obj, lv_hasp_obj_type_t haspobjtype);
|
||||
|
||||
#define _HASP_ATTRIBUTE(prop_name, func_name, value_type) \
|
||||
static inline void attribute_##func_name(lv_obj_t * obj, uint8_t part, lv_state_t state, bool update, \
|
||||
const char * attr, value_type val) \
|
||||
@ -34,7 +27,7 @@ bool check_obj_type(lv_obj_t * obj, lv_hasp_obj_type_t haspobjtype);
|
||||
} else { \
|
||||
value_type temp = lv_obj_get_style_##func_name(obj, part); \
|
||||
/*lv_obj_get_style_##func_name(obj, part, state, &temp);*/ \
|
||||
return hasp_out_int(obj, attr, temp); \
|
||||
return hasp_send_obj_attribute_int(obj, attr, temp); \
|
||||
} \
|
||||
}
|
||||
|
||||
@ -253,6 +246,7 @@ _HASP_ATTRIBUTE(SCALE_END_LINE_WIDTH, scale_end_line_width, lv_style_int_t)
|
||||
#define ATTR_MODE 45891
|
||||
// #define ATTR_RECT 11204
|
||||
#define ATTR_ROWS 52153
|
||||
#define ATTR_COLS 36307
|
||||
#define ATTR_MIN 46130
|
||||
#define ATTR_MAX 45636
|
||||
#define ATTR_VAL 15809
|
||||
@ -267,4 +261,7 @@ _HASP_ATTRIBUTE(SCALE_END_LINE_WIDTH, scale_end_line_width, lv_style_int_t)
|
||||
#define ATTR_LABEL_COUNT 20356
|
||||
#define ATTR_LINE_COUNT 57860
|
||||
#define ATTR_FORMAT 38871
|
||||
|
||||
// Buttonmatric
|
||||
#define ATTR_MAP 45628
|
||||
#endif
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "hasp_dispatch.h"
|
||||
#include "hasp_config.h"
|
||||
#include "hasp_debug.h"
|
||||
#include "hasp_object.h"
|
||||
#include "hasp_gui.h"
|
||||
#include "hasp_oobe.h"
|
||||
#include "hasp_hal.h"
|
||||
@ -109,7 +110,7 @@ void dispatchParseJsonl(Stream & stream)
|
||||
while(deserializeJson(jsonl, stream) == DeserializationError::Ok) {
|
||||
// serializeJson(jsonl, Serial);
|
||||
// Serial.println();
|
||||
haspNewObject(jsonl.as<JsonObject>(), savedPage);
|
||||
hasp_new_object(jsonl.as<JsonObject>(), savedPage);
|
||||
}
|
||||
}
|
||||
|
||||
|
655
src/hasp_object.cpp
Normal file
655
src/hasp_object.cpp
Normal file
@ -0,0 +1,655 @@
|
||||
/* ********************************************************************************************
|
||||
*
|
||||
* HASP Object Handlers
|
||||
* - Object Finders : Convert from object pointers to and from p[x].b[y] IDs
|
||||
* - Value Dispatchers : Forward output data to the dispatcher
|
||||
* - Value Senders : Convert values and events into topic/payload before forwarding
|
||||
* - Event Handlers : Callbacks for object event processing
|
||||
* - Attribute processor : Decide if an attribute needs updating or querying and forward
|
||||
* - Object creator : Creates an object from a line of jsonl
|
||||
*
|
||||
******************************************************************************************** */
|
||||
|
||||
#include "ArduinoLog.h"
|
||||
|
||||
#include "hasp.h"
|
||||
#include "hasp_object.h"
|
||||
#include "hasp_dispatch.h"
|
||||
#include "hasp_attribute.h"
|
||||
|
||||
// ##################### Object Finders ########################################################
|
||||
|
||||
lv_obj_t * hasp_find_obj_from_id(lv_obj_t * parent, uint8_t objid)
|
||||
{
|
||||
if(objid == 0 || parent == nullptr) return parent;
|
||||
|
||||
lv_obj_t * child;
|
||||
child = lv_obj_get_child(parent, NULL);
|
||||
while(child) {
|
||||
/* child found, return it */
|
||||
if(child->user_data && (lv_obj_user_data_t)objid == child->user_data) return child;
|
||||
|
||||
/* check grandchildren */
|
||||
lv_obj_t * grandchild = hasp_find_obj_from_id(child, objid);
|
||||
if(grandchild) return grandchild; /* grandchild found, return it */
|
||||
|
||||
/* check tabs */
|
||||
if(check_obj_type(child, LV_HASP_TABVIEW)) {
|
||||
uint16_t tabcount = lv_tabview_get_tab_count(child);
|
||||
for(uint16_t i = 0; i < tabcount; i++) {
|
||||
lv_obj_t * tab = lv_tabview_get_tab(child, i);
|
||||
Log.verbose(TAG_HASP, "Found tab %i", i);
|
||||
if(tab->user_data && (lv_obj_user_data_t)objid == tab->user_data) return tab; /* tab found, return it */
|
||||
|
||||
/* check grandchildren */
|
||||
grandchild = hasp_find_obj_from_id(tab, objid);
|
||||
if(grandchild) return grandchild; /* grandchild found, return it */
|
||||
}
|
||||
}
|
||||
|
||||
/* try next sibling */
|
||||
child = lv_obj_get_child(parent, child);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lv_obj_t * hasp_find_obj_from_id(uint8_t pageid, uint8_t objid)
|
||||
{
|
||||
return hasp_find_obj_from_id(get_page_obj(pageid), objid);
|
||||
}
|
||||
|
||||
bool hasp_find_id_from_obj(lv_obj_t * obj, uint8_t * pageid, lv_obj_user_data_t * objid)
|
||||
{
|
||||
if(!get_page_id(obj, pageid)) return false;
|
||||
if(!(obj->user_data > 0)) return false;
|
||||
memcpy(objid, &obj->user_data, sizeof(lv_obj_user_data_t));
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an lvgl object typename corresponds to a given HASP object ID
|
||||
* @param lvobjtype a char* to a string
|
||||
* @param haspobjtype the HASP object ID to check against
|
||||
* @return true or false wether the types match
|
||||
* @note
|
||||
*/
|
||||
bool check_obj_type(const char * lvobjtype, lv_hasp_obj_type_t haspobjtype)
|
||||
{
|
||||
lvobjtype += 3; // skip "lv_"
|
||||
|
||||
switch(haspobjtype) {
|
||||
case LV_HASP_BTNMATRIX:
|
||||
return (strcmp_P(lvobjtype, PSTR("btnmatrix")) == 0);
|
||||
case LV_HASP_TABLE:
|
||||
return (strcmp_P(lvobjtype, PSTR("table")) == 0);
|
||||
case LV_HASP_BUTTON:
|
||||
return (strcmp_P(lvobjtype, PSTR("btn")) == 0);
|
||||
case LV_HASP_LABEL:
|
||||
return (strcmp_P(lvobjtype, PSTR("label")) == 0);
|
||||
case LV_HASP_CHECKBOX:
|
||||
return (strcmp_P(lvobjtype, PSTR("checkbox")) == 0); // || (strcmp_P(lvobjtype, PSTR("lv_cb")) == 0);
|
||||
case LV_HASP_DDLIST:
|
||||
return (strcmp_P(lvobjtype, PSTR("dropdown")) == 0); // || (strcmp_P(lvobjtype, PSTR("lv_ddlist")) == 0);
|
||||
case LV_HASP_CPICKER:
|
||||
return (strcmp_P(lvobjtype, PSTR("cpicker")) == 0);
|
||||
case LV_HASP_PRELOADER:
|
||||
return (strcmp_P(lvobjtype, PSTR("spinner")) == 0); // || (strcmp_P(lvobjtype, PSTR("lv_preload")) == 0);
|
||||
case LV_HASP_SLIDER:
|
||||
return (strcmp_P(lvobjtype, PSTR("slider")) == 0);
|
||||
case LV_HASP_GAUGE:
|
||||
return (strcmp_P(lvobjtype, PSTR("gauge")) == 0);
|
||||
case LV_HASP_ARC:
|
||||
return (strcmp_P(lvobjtype, PSTR("arc")) == 0);
|
||||
case LV_HASP_BAR:
|
||||
return (strcmp_P(lvobjtype, PSTR("bar")) == 0);
|
||||
case LV_HASP_LMETER:
|
||||
return (strcmp_P(lvobjtype, PSTR("linemeter")) == 0); // || (strcmp_P(lvobjtype, PSTR("lv_lmeter")) == 0)
|
||||
case LV_HASP_ROLLER:
|
||||
return (strcmp_P(lvobjtype, PSTR("roller")) == 0);
|
||||
case LV_HASP_SWITCH:
|
||||
return (strcmp_P(lvobjtype, PSTR("switch")) == 0); // || (strcmp_P(lvobjtype, PSTR("lv_sw")) == 0)
|
||||
case LV_HASP_LED:
|
||||
return (strcmp_P(lvobjtype, PSTR("led")) == 0);
|
||||
case LV_HASP_IMAGE:
|
||||
return (strcmp_P(lvobjtype, PSTR("img")) == 0);
|
||||
case LV_HASP_IMGBTN:
|
||||
return (strcmp_P(lvobjtype, PSTR("imgbtn")) == 0);
|
||||
case LV_HASP_CONTAINER:
|
||||
return (strcmp_P(lvobjtype, PSTR("container")) == 0); // || (strcmp_P(lvobjtype, PSTR("lv_cont")) == 0)
|
||||
case LV_HASP_OBJECT:
|
||||
return (strcmp_P(lvobjtype, PSTR("page")) == 0); // || (strcmp_P(lvobjtype, PSTR("lv_cont")) == 0)
|
||||
case LV_HASP_PAGE:
|
||||
return (strcmp_P(lvobjtype, PSTR("obj")) == 0); // || (strcmp_P(lvobjtype, PSTR("lv_cont")) == 0)
|
||||
case LV_HASP_TABVIEW:
|
||||
return (strcmp_P(lvobjtype, PSTR("tabview")) == 0);
|
||||
case LV_HASP_TILEVIEW:
|
||||
return (strcmp_P(lvobjtype, PSTR("tileview")) == 0);
|
||||
case LV_HASP_CHART:
|
||||
return (strcmp_P(lvobjtype, PSTR("chart")) == 0);
|
||||
case LV_HASP_CANVAS:
|
||||
return (strcmp_P(lvobjtype, PSTR("canvas")) == 0);
|
||||
case LV_HASP_CALENDER:
|
||||
return (strcmp_P(lvobjtype, PSTR("calender")) == 0);
|
||||
case LV_HASP_MSGBOX:
|
||||
return (strcmp_P(lvobjtype, PSTR("msgbox")) == 0);
|
||||
case LV_HASP_WINDOW:
|
||||
return (strcmp_P(lvobjtype, PSTR("window")) == 0);
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if an lvgl objecttype name corresponds to a given HASP object ID
|
||||
* @param obj an lv_obj_t* of the object to check its type
|
||||
* @param haspobjtype the HASP object ID to check against
|
||||
* @return true or false wether the types match
|
||||
* @note
|
||||
*/
|
||||
bool check_obj_type(lv_obj_t * obj, lv_hasp_obj_type_t haspobjtype)
|
||||
{
|
||||
lv_obj_type_t list;
|
||||
lv_obj_get_type(obj, &list);
|
||||
const char * objtype = list.type[0];
|
||||
return check_obj_type(objtype, haspobjtype);
|
||||
}
|
||||
|
||||
// ##################### Value Dispatchers ########################################################
|
||||
|
||||
void hasp_send_obj_attribute_str(lv_obj_t * obj, const char * attribute, const char * data)
|
||||
{
|
||||
uint8_t pageid;
|
||||
uint8_t objid;
|
||||
|
||||
if(hasp_find_id_from_obj(obj, &pageid, &objid)) {
|
||||
dispatch_send_obj_attribute_str(pageid, objid, attribute, data);
|
||||
}
|
||||
}
|
||||
|
||||
void hasp_send_obj_attribute_int(lv_obj_t * obj, const char * attribute, int32_t val)
|
||||
{
|
||||
char data[64];
|
||||
itoa(val, data, 10);
|
||||
hasp_send_obj_attribute_str(obj, attribute, data);
|
||||
}
|
||||
|
||||
void hasp_send_obj_attribute_color(lv_obj_t * obj, const char * attribute, lv_color_t color)
|
||||
{
|
||||
char buffer[128];
|
||||
lv_color32_t c32;
|
||||
c32.full = lv_color_to32(color);
|
||||
snprintf(buffer, sizeof(buffer), PSTR("#%02x%02x%02x"), c32.ch.red, c32.ch.green, c32.ch.blue);
|
||||
hasp_send_obj_attribute_str(obj, attribute, buffer);
|
||||
}
|
||||
|
||||
// ##################### Value Senders ########################################################
|
||||
|
||||
static void hasp_send_obj_attribute_P(lv_obj_t * obj, const char * attr, const char * data)
|
||||
{
|
||||
char * buffer;
|
||||
buffer = (char *)malloc(strlen_P(attr) + 1);
|
||||
strcpy_P(buffer, attr);
|
||||
hasp_send_obj_attribute_str(obj, buffer, data);
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
static inline void hasp_send_obj_attribute_val(lv_obj_t * obj, int32_t val)
|
||||
{
|
||||
char data[32];
|
||||
itoa(val, data, DEC);
|
||||
hasp_send_obj_attribute_P(obj, PSTR("val"), data);
|
||||
}
|
||||
|
||||
static inline void hasp_send_obj_attribute_event(lv_obj_t * obj, const char * event)
|
||||
{
|
||||
hasp_send_obj_attribute_P(obj, PSTR("event"), event);
|
||||
}
|
||||
|
||||
static inline void hasp_send_obj_attribute_txt(lv_obj_t * obj, const char * txt)
|
||||
{
|
||||
hasp_send_obj_attribute_P(obj, PSTR("txt"), txt);
|
||||
}
|
||||
|
||||
// ##################### Event Handlers ########################################################
|
||||
|
||||
/**
|
||||
* Called when a button-style object is clicked
|
||||
* @param obj pointer to a button object
|
||||
* @param event type of event that occured
|
||||
*/
|
||||
void IRAM_ATTR btn_event_handler(lv_obj_t * obj, lv_event_t event)
|
||||
{
|
||||
uint8_t eventid;
|
||||
char buffer[64];
|
||||
|
||||
switch(event) {
|
||||
case LV_EVENT_PRESSED:
|
||||
eventid = HASP_EVENT_DOWN;
|
||||
memcpy_P(buffer, PSTR("DOWN"), sizeof(buffer));
|
||||
break;
|
||||
case LV_EVENT_CLICKED:
|
||||
// UP = the same object was release then was pressed and press was not lost!
|
||||
eventid = HASP_EVENT_UP;
|
||||
memcpy_P(buffer, PSTR("UP"), sizeof(buffer));
|
||||
break;
|
||||
case LV_EVENT_SHORT_CLICKED:
|
||||
eventid = HASP_EVENT_SHORT;
|
||||
memcpy_P(buffer, PSTR("SHORT"), sizeof(buffer));
|
||||
break;
|
||||
case LV_EVENT_LONG_PRESSED:
|
||||
eventid = HASP_EVENT_LONG;
|
||||
memcpy_P(buffer, PSTR("LONG"), sizeof(buffer));
|
||||
break;
|
||||
case LV_EVENT_LONG_PRESSED_REPEAT:
|
||||
eventid = HASP_EVENT_HOLD;
|
||||
memcpy_P(buffer, PSTR("HOLD"), sizeof(buffer));
|
||||
break;
|
||||
case LV_EVENT_PRESS_LOST:
|
||||
eventid = HASP_EVENT_LOST;
|
||||
memcpy_P(buffer, PSTR("LOST"), sizeof(buffer));
|
||||
break;
|
||||
case LV_EVENT_PRESSING:
|
||||
case LV_EVENT_FOCUSED:
|
||||
case LV_EVENT_DEFOCUSED:
|
||||
case LV_EVENT_RELEASED:
|
||||
return;
|
||||
|
||||
case LV_EVENT_VALUE_CHANGED:
|
||||
Log.warning(TAG_HASP, F("Value changed Event %d occured"), event);
|
||||
return;
|
||||
|
||||
case LV_EVENT_DELETE:
|
||||
Log.verbose(TAG_HASP, F("Object deleted Event %d occured"), event);
|
||||
// TODO:free and destroy persistent memory allocated for certain objects
|
||||
return;
|
||||
default:
|
||||
Log.warning(TAG_HASP, F("Unknown Event %d occured"), event);
|
||||
return;
|
||||
}
|
||||
|
||||
if(obj == lv_disp_get_layer_sys(NULL)) {
|
||||
#if HASP_USE_MQTT > 0
|
||||
mqtt_send_state(F("wakeuptouch"), buffer);
|
||||
#endif
|
||||
} else {
|
||||
// hasp_send_obj_attribute_event(obj, buffer);
|
||||
dispatch_send_object_event(haspGetPage(), (uint8_t)obj->user_data, eventid);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a button matrix object is clicked
|
||||
* @param obj pointer to a button matrix
|
||||
* @param event type of event that occured
|
||||
*/
|
||||
static void btnmap_event_handler(lv_obj_t * obj, lv_event_t event)
|
||||
{
|
||||
if(event == LV_EVENT_VALUE_CHANGED) hasp_send_obj_attribute_val(obj, lv_btnmatrix_get_active_btn(obj));
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a table object is clicked
|
||||
* @param obj pointer to a table
|
||||
* @param event type of event that occured
|
||||
*/
|
||||
static void table_event_handler(lv_obj_t * obj, lv_event_t event)
|
||||
{
|
||||
if(event == LV_EVENT_VALUE_CHANGED) {
|
||||
uint16_t row;
|
||||
uint16_t col;
|
||||
if(lv_table_get_pressed_cell(obj, &row, &col) == LV_RES_OK) {
|
||||
hasp_send_obj_attribute_val(obj, row);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a toggle button is clicked
|
||||
* @param obj pointer to a button
|
||||
* @param event type of event that occured
|
||||
*/
|
||||
void IRAM_ATTR toggle_event_handler(lv_obj_t * obj, lv_event_t event)
|
||||
{
|
||||
bool toggled =
|
||||
lv_btn_get_state(obj) == LV_BTN_STATE_CHECKED_PRESSED || lv_btn_get_state(obj) == LV_BTN_STATE_CHECKED_RELEASED;
|
||||
if(event == LV_EVENT_VALUE_CHANGED) hasp_send_obj_attribute_val(obj, toggled);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a switch is toggled
|
||||
* @param obj pointer to a switch object
|
||||
* @param event type of event that occured
|
||||
*/
|
||||
static void switch_event_handler(lv_obj_t * obj, lv_event_t event)
|
||||
{
|
||||
if(event == LV_EVENT_VALUE_CHANGED) hasp_send_obj_attribute_val(obj, lv_switch_get_state(obj));
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a checkboxed is clicked
|
||||
* @param obj pointer to a checkbox
|
||||
* @param event type of event that occured
|
||||
*/
|
||||
static void checkbox_event_handler(lv_obj_t * obj, lv_event_t event)
|
||||
{
|
||||
if(event == LV_EVENT_VALUE_CHANGED) hasp_send_obj_attribute_val(obj, lv_checkbox_is_checked(obj));
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a dropdown list is clicked
|
||||
* @param obj pointer to a dropdown list
|
||||
* @param event type of event that occured
|
||||
*/
|
||||
static void ddlist_event_handler(lv_obj_t * obj, lv_event_t event)
|
||||
{
|
||||
if(event == LV_EVENT_VALUE_CHANGED) {
|
||||
hasp_send_obj_attribute_val(obj, lv_dropdown_get_selected(obj));
|
||||
char buffer[128];
|
||||
lv_dropdown_get_selected_str(obj, buffer, sizeof(buffer));
|
||||
hasp_send_obj_attribute_txt(obj, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a slider is clicked
|
||||
* @param obj pointer to a slider
|
||||
* @param event type of event that occured
|
||||
*/
|
||||
static void slider_event_handler(lv_obj_t * obj, lv_event_t event)
|
||||
{
|
||||
if(event == LV_EVENT_VALUE_CHANGED) hasp_send_obj_attribute_val(obj, lv_slider_get_value(obj));
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a color picker is clicked
|
||||
* @param obj pointer to a color picker
|
||||
* @param event type of event that occured
|
||||
*/
|
||||
static void cpicker_event_handler(lv_obj_t * obj, lv_event_t event)
|
||||
{
|
||||
if(event == LV_EVENT_VALUE_CHANGED)
|
||||
hasp_send_obj_attribute_color(obj, "color", lv_cpicker_get_color(obj)); // Literial string
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a roller object is clicked
|
||||
* @param obj pointer to a roller object
|
||||
* @param event type of event that occured
|
||||
*/
|
||||
static void roller_event_handler(lv_obj_t * obj, lv_event_t event)
|
||||
{
|
||||
if(event == LV_EVENT_VALUE_CHANGED) {
|
||||
hasp_send_obj_attribute_val(obj, lv_roller_get_selected(obj));
|
||||
char buffer[128];
|
||||
lv_roller_get_selected_str(obj, buffer, sizeof(buffer));
|
||||
hasp_send_obj_attribute_txt(obj, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Used in the dispatcher & hasp_new_object
|
||||
void hasp_process_attribute(uint8_t pageid, uint8_t objid, const char * attr, const char * payload)
|
||||
{
|
||||
if(lv_obj_t * obj = hasp_find_obj_from_id(pageid, objid)) {
|
||||
hasp_process_obj_attribute(obj, attr, payload, strlen(payload) > 0);
|
||||
} else {
|
||||
Log.warning(TAG_HASP, F("Unknown object p[%d].b[%d]"), pageid, objid);
|
||||
}
|
||||
}
|
||||
|
||||
// ##################### Obhject Creator ########################################################
|
||||
|
||||
/**
|
||||
* Create a new object according to the json config
|
||||
* @param config Json representation for this object
|
||||
* @param saved_page_id the pageid to use when no pageid is specified in the Json, updated when it is specified so
|
||||
* following objects in the file can share the pageid
|
||||
*/
|
||||
void hasp_new_object(const JsonObject & config, uint8_t & saved_page_id)
|
||||
{
|
||||
/* Validate page */
|
||||
uint8_t pageid = config[F("page")].isNull() ? haspGetPage() : config[F("page")].as<uint8_t>();
|
||||
|
||||
/* Page selection */
|
||||
lv_obj_t * page = get_page_obj(pageid);
|
||||
if(!page) {
|
||||
return Log.warning(TAG_HASP, F("Page ID %u not defined"), pageid);
|
||||
} else {
|
||||
saved_page_id = pageid; /* save the current pageid */
|
||||
}
|
||||
|
||||
/* Validate type */
|
||||
if(config[F("objid")].isNull()) return; // comments
|
||||
|
||||
lv_obj_t * parent_obj = page;
|
||||
if(!config[F("parentid")].isNull()) {
|
||||
uint8_t parentid = config[F("parentid")].as<uint8_t>();
|
||||
parent_obj = hasp_find_obj_from_id(page, parentid);
|
||||
if(!parent_obj) {
|
||||
return Log.warning(TAG_HASP, F("Parent ID p[%u].b[%u] not found, skipping..."), pageid, parentid);
|
||||
// parent_obj = page; // don't create on the page instead ??
|
||||
} else {
|
||||
Log.verbose(TAG_HASP, F("Parent ID p[%u].b[%u] found"), pageid, parentid);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t objid = config[F("objid")].as<uint8_t>();
|
||||
uint8_t id = config[F("id")].as<uint8_t>();
|
||||
|
||||
/* Define Objects*/
|
||||
lv_obj_t * obj = hasp_find_obj_from_id(parent_obj, id);
|
||||
if(obj) {
|
||||
return Log.warning(TAG_HASP, F("Object ID %u already exists!"), id);
|
||||
}
|
||||
|
||||
switch(objid) {
|
||||
/* ----- Basic Objects ------ */
|
||||
case LV_HASP_BTNMATRIX:
|
||||
obj = lv_btnmatrix_create(parent_obj, NULL);
|
||||
lv_obj_set_event_cb(obj, btnmap_event_handler);
|
||||
break;
|
||||
case LV_HASP_TABLE:
|
||||
obj = lv_table_create(parent_obj, NULL);
|
||||
lv_obj_set_event_cb(obj, table_event_handler);
|
||||
break;
|
||||
|
||||
case LV_HASP_BUTTON:
|
||||
obj = lv_btn_create(parent_obj, NULL);
|
||||
lv_label_create(obj, NULL);
|
||||
lv_obj_set_event_cb(obj, btn_event_handler);
|
||||
break;
|
||||
|
||||
case LV_HASP_CHECKBOX:
|
||||
obj = lv_checkbox_create(parent_obj, NULL);
|
||||
lv_obj_set_event_cb(obj, checkbox_event_handler);
|
||||
break;
|
||||
|
||||
case LV_HASP_LABEL: {
|
||||
obj = lv_label_create(parent_obj, NULL);
|
||||
/* click area padding */
|
||||
uint8_t padh = config[F("padh")].as<uint8_t>();
|
||||
uint8_t padv = config[F("padv")].as<uint8_t>();
|
||||
/* text align */
|
||||
if(padh > 0 || padv > 0) {
|
||||
lv_obj_set_ext_click_area(obj, padh, padh, padv, padv);
|
||||
}
|
||||
if(!config[F("align")].isNull()) {
|
||||
lv_label_set_align(obj, LV_LABEL_ALIGN_CENTER);
|
||||
}
|
||||
lv_obj_set_event_cb(obj, btn_event_handler);
|
||||
break;
|
||||
}
|
||||
case LV_HASP_IMAGE: {
|
||||
obj = lv_img_create(parent_obj, NULL);
|
||||
lv_obj_set_event_cb(obj, btn_event_handler);
|
||||
break;
|
||||
}
|
||||
case LV_HASP_ARC: {
|
||||
obj = lv_arc_create(parent_obj, NULL);
|
||||
lv_obj_set_event_cb(obj, btn_event_handler);
|
||||
break;
|
||||
}
|
||||
case LV_HASP_CONTAINER: {
|
||||
obj = lv_cont_create(parent_obj, NULL);
|
||||
lv_obj_set_event_cb(obj, btn_event_handler);
|
||||
break;
|
||||
}
|
||||
case LV_HASP_OBJECT: {
|
||||
obj = lv_obj_create(parent_obj, NULL);
|
||||
lv_obj_set_event_cb(obj, btn_event_handler);
|
||||
break;
|
||||
}
|
||||
case LV_HASP_PAGE: {
|
||||
obj = lv_page_create(parent_obj, NULL);
|
||||
// No event handler for pages
|
||||
break;
|
||||
}
|
||||
case LV_HASP_TABVIEW: {
|
||||
obj = lv_tabview_create(parent_obj, NULL);
|
||||
// No event handler for tabs
|
||||
lv_obj_t * tab;
|
||||
tab = lv_tabview_add_tab(obj, "tab 1");
|
||||
lv_obj_set_user_data(tab, id + 1);
|
||||
tab = lv_tabview_add_tab(obj, "tab 2");
|
||||
lv_obj_set_user_data(tab, id + 2);
|
||||
tab = lv_tabview_add_tab(obj, "tab 3");
|
||||
lv_obj_set_user_data(tab, id + 3);
|
||||
break;
|
||||
}
|
||||
case LV_HASP_TILEVIEW: {
|
||||
obj = lv_tileview_create(parent_obj, NULL);
|
||||
// No event handler for tileviews
|
||||
break;
|
||||
}
|
||||
|
||||
/* ----- Color Objects ------ */
|
||||
case LV_HASP_CPICKER: {
|
||||
obj = lv_cpicker_create(parent_obj, NULL);
|
||||
lv_obj_set_event_cb(obj, cpicker_event_handler);
|
||||
break;
|
||||
}
|
||||
|
||||
#if LV_USE_PRELOAD != 0
|
||||
case LV_HASP_PRELOADER: {
|
||||
obj = lv_spinner_create(parent_obj, NULL);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
/* ----- Range Objects ------ */
|
||||
case LV_HASP_SLIDER: {
|
||||
obj = lv_slider_create(parent_obj, NULL);
|
||||
lv_slider_set_range(obj, 0, 100);
|
||||
lv_obj_set_event_cb(obj, slider_event_handler);
|
||||
// bool knobin = config[F("knobin")].as<bool>() | true;
|
||||
// lv_slider_set_knob_in(obj, knobin);
|
||||
break;
|
||||
}
|
||||
case LV_HASP_GAUGE: {
|
||||
obj = lv_gauge_create(parent_obj, NULL);
|
||||
lv_gauge_set_range(obj, 0, 100);
|
||||
lv_obj_set_event_cb(obj, btn_event_handler);
|
||||
break;
|
||||
}
|
||||
case LV_HASP_BAR: {
|
||||
obj = lv_bar_create(parent_obj, NULL);
|
||||
lv_bar_set_range(obj, 0, 100);
|
||||
lv_obj_set_event_cb(obj, btn_event_handler);
|
||||
break;
|
||||
}
|
||||
case LV_HASP_LMETER: {
|
||||
obj = lv_linemeter_create(parent_obj, NULL);
|
||||
lv_linemeter_set_range(obj, 0, 100);
|
||||
lv_obj_set_event_cb(obj, btn_event_handler);
|
||||
break;
|
||||
}
|
||||
case LV_HASP_CHART: {
|
||||
obj = lv_chart_create(parent_obj, NULL);
|
||||
lv_chart_set_range(obj, 0, 100);
|
||||
lv_obj_set_event_cb(obj, btn_event_handler);
|
||||
|
||||
lv_chart_add_series(obj, LV_COLOR_RED);
|
||||
lv_chart_add_series(obj, LV_COLOR_GREEN);
|
||||
lv_chart_add_series(obj, LV_COLOR_BLUE);
|
||||
|
||||
lv_chart_series_t * ser = lv_chart_get_series(obj, 2);
|
||||
lv_chart_set_next(obj, ser, 10);
|
||||
lv_chart_set_next(obj, ser, 20);
|
||||
lv_chart_set_next(obj, ser, 30);
|
||||
lv_chart_set_next(obj, ser, 40);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/* ----- On/Off Objects ------ */
|
||||
case LV_HASP_SWITCH: {
|
||||
obj = lv_switch_create(parent_obj, NULL);
|
||||
lv_obj_set_event_cb(obj, switch_event_handler);
|
||||
break;
|
||||
}
|
||||
case LV_HASP_LED: {
|
||||
obj = lv_led_create(parent_obj, NULL);
|
||||
lv_obj_set_event_cb(obj, btn_event_handler);
|
||||
break;
|
||||
}
|
||||
/* ----- List Object ------- */
|
||||
case LV_HASP_DDLIST: {
|
||||
obj = lv_dropdown_create(parent_obj, NULL);
|
||||
lv_dropdown_set_draw_arrow(obj, true);
|
||||
// lv_dropdown_set_anim_time(obj, 200);
|
||||
lv_obj_set_top(obj, true);
|
||||
// lv_obj_align(obj, NULL, LV_ALIGN_IN_TOP_MID, 0, 20);
|
||||
lv_obj_set_event_cb(obj, ddlist_event_handler);
|
||||
break;
|
||||
}
|
||||
case LV_HASP_ROLLER: {
|
||||
obj = lv_roller_create(parent_obj, NULL);
|
||||
// lv_obj_align(obj, NULL, LV_ALIGN_IN_TOP_MID, 0, 20);
|
||||
lv_obj_set_event_cb(obj, roller_event_handler);
|
||||
break;
|
||||
}
|
||||
|
||||
/* ----- Other Object ------ */
|
||||
// default:
|
||||
// return Log.warning(TAG_HASP, F("Unsupported Object ID %u"), objid);
|
||||
}
|
||||
|
||||
/* No object was actually created */
|
||||
if(!obj) {
|
||||
return Log.warning(TAG_HASP, F("Object ID %u is NULL, skipping..."), id);
|
||||
}
|
||||
|
||||
/* id tag the object */
|
||||
lv_obj_set_user_data(obj, id);
|
||||
|
||||
/* do not process these attributes */
|
||||
config.remove(F("page"));
|
||||
config.remove(F("id"));
|
||||
config.remove(F("objid"));
|
||||
config.remove(F("parentid"));
|
||||
String v;
|
||||
|
||||
for(JsonPair keyValue : config) {
|
||||
v = keyValue.value().as<String>();
|
||||
hasp_process_obj_attribute(obj, keyValue.key().c_str(), v.c_str(), true);
|
||||
// Log.verbose(TAG_HASP,F(" * %s => %s"), keyValue.key().c_str(), v.c_str());
|
||||
}
|
||||
|
||||
/** testing start **/
|
||||
lv_obj_user_data_t temp;
|
||||
if(!hasp_find_id_from_obj(obj, &pageid, &temp)) {
|
||||
return Log.error(TAG_HASP, F("Lost track of the created object, not found!"));
|
||||
}
|
||||
|
||||
/** verbose reporting **/
|
||||
lv_obj_type_t list;
|
||||
lv_obj_get_type(obj, &list);
|
||||
Log.verbose(TAG_HASP, F(" * p[%u].b[%u] = %s"), pageid, temp, list.type[0]);
|
||||
|
||||
/* test double-check */
|
||||
lv_obj_t * test = hasp_find_obj_from_id(pageid, (uint8_t)temp);
|
||||
if(test != obj) {
|
||||
return Log.error(TAG_HASP, F("Objects DO NOT match!"));
|
||||
}
|
||||
}
|
64
src/hasp_object.h
Normal file
64
src/hasp_object.h
Normal file
@ -0,0 +1,64 @@
|
||||
#ifndef HASP_OBJECT_H
|
||||
#define HASP_OBJECT_H
|
||||
|
||||
#include <ArduinoJson.h>
|
||||
#include "lvgl.h"
|
||||
|
||||
enum lv_hasp_obj_type_t {
|
||||
LV_HASP_BTNMATRIX = 1,
|
||||
LV_HASP_TABLE = 2,
|
||||
|
||||
LV_HASP_BUTTON = 10,
|
||||
LV_HASP_CHECKBOX = 11,
|
||||
LV_HASP_LABEL = 12,
|
||||
|
||||
LV_HASP_CPICKER = 20,
|
||||
LV_HASP_PRELOADER = 21,
|
||||
LV_HASP_ARC = 22,
|
||||
|
||||
LV_HASP_SLIDER = 30,
|
||||
LV_HASP_GAUGE = 31,
|
||||
LV_HASP_BAR = 32,
|
||||
LV_HASP_LMETER = 33,
|
||||
|
||||
LV_HASP_SWITCH = 40,
|
||||
LV_HASP_LED = 41,
|
||||
|
||||
LV_HASP_DDLIST = 50,
|
||||
LV_HASP_ROLLER = 51,
|
||||
|
||||
LV_HASP_IMAGE = 60,
|
||||
LV_HASP_IMGBTN = 61,
|
||||
LV_HASP_CANVAS = 62,
|
||||
|
||||
LV_HASP_TILEVIEW = 70,
|
||||
LV_HASP_TABVIEW = 71,
|
||||
LV_HASP_TAB = 72,
|
||||
|
||||
LV_HASP_CHART = 80,
|
||||
LV_HASP_CALENDER = 81,
|
||||
|
||||
LV_HASP_CONTAINER = 90,
|
||||
LV_HASP_OBJECT = 91,
|
||||
LV_HASP_PAGE = 92,
|
||||
LV_HASP_MSGBOX = 93,
|
||||
LV_HASP_WINDOW = 94,
|
||||
};
|
||||
|
||||
void hasp_new_object(const JsonObject & config, uint8_t & saved_page_id);
|
||||
|
||||
lv_obj_t * hasp_find_obj_from_id(lv_obj_t * parent, uint8_t objid);
|
||||
lv_obj_t * hasp_find_obj_from_id(uint8_t pageid, uint8_t objid);
|
||||
bool hasp_find_id_from_obj(lv_obj_t * obj, uint8_t * pageid, lv_obj_user_data_t * objid);
|
||||
bool check_obj_type(const char * lvobjtype, lv_hasp_obj_type_t haspobjtype);
|
||||
bool check_obj_type(lv_obj_t * obj, lv_hasp_obj_type_t haspobjtype);
|
||||
|
||||
void hasp_send_obj_attribute_str(lv_obj_t * obj, const char * attribute, const char * data);
|
||||
void hasp_send_obj_attribute_int(lv_obj_t * obj, const char * attribute, int32_t val);
|
||||
void hasp_send_obj_attribute_color(lv_obj_t * obj, const char * attribute, lv_color_t color);
|
||||
void hasp_process_attribute(uint8_t pageid, uint8_t objid, const char * attr, const char * payload);
|
||||
|
||||
void IRAM_ATTR btn_event_handler(lv_obj_t * obj, lv_event_t event);
|
||||
void IRAM_ATTR toggle_event_handler(lv_obj_t * obj, lv_event_t event);
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user