mirror of
https://github.com/HASwitchPlate/openHASP.git
synced 2025-07-28 21:56:35 +00:00
Allow any command in the swipe attribute (like action)
This commit is contained in:
parent
c296a5e568
commit
46e9e97132
@ -851,12 +851,12 @@ typedef void* lv_font_user_data_t;
|
||||
typedef struct {
|
||||
uint8_t id:8;
|
||||
uint8_t objid:6;
|
||||
uint8_t transitionid:4;
|
||||
uint8_t actionid:4;
|
||||
//uint8_t transitionid:4;
|
||||
//uint8_t actionid:4;
|
||||
uint8_t groupid:4;
|
||||
uint8_t swipeid:4;
|
||||
void* tag;
|
||||
char* action;
|
||||
// uint8_t swipeid:4;
|
||||
void* ext;
|
||||
// char* action;
|
||||
} lv_obj_user_data_t;
|
||||
|
||||
/*1: enable `lv_obj_realaign()` based on `lv_obj_align()` parameters*/
|
||||
|
@ -1637,6 +1637,18 @@ static hasp_attribute_type_t attribute_common_tag(lv_obj_t* obj, uint16_t attr_h
|
||||
}
|
||||
break; // attribute_found
|
||||
|
||||
case ATTR_SWIPE:
|
||||
if(update) {
|
||||
my_obj_set_swipe(obj, payload);
|
||||
} else {
|
||||
if(my_obj_get_swipe(obj)) {
|
||||
*text = (char*)my_obj_get_swipe(obj);
|
||||
} else {
|
||||
strcpy_P(*text, "null"); // TODO : Literal String
|
||||
}
|
||||
}
|
||||
break; // attribute_found
|
||||
|
||||
default:
|
||||
return HASP_ATTR_TYPE_NOT_FOUND;
|
||||
}
|
||||
@ -2324,12 +2336,12 @@ static hasp_attribute_type_t attribute_common_int(lv_obj_t* obj, uint16_t attr_h
|
||||
val = obj->user_data.groupid;
|
||||
break; // attribute_found
|
||||
|
||||
case ATTR_TRANSITION:
|
||||
if(update)
|
||||
obj->user_data.transitionid = (uint8_t)val;
|
||||
else
|
||||
val = obj->user_data.transitionid;
|
||||
break; // attribute_found
|
||||
// case ATTR_TRANSITION:
|
||||
// if(update)
|
||||
// obj->user_data.transitionid = (uint8_t)val;
|
||||
// else
|
||||
// val = obj->user_data.transitionid;
|
||||
// break; // attribute_found
|
||||
|
||||
case ATTR_OBJID:
|
||||
if(update && val != obj->user_data.objid) return HASP_ATTR_TYPE_INT_READONLY;
|
||||
@ -2450,12 +2462,12 @@ static hasp_attribute_type_t attribute_common_bool(lv_obj_t* obj, uint16_t attr_
|
||||
val = !(lv_obj_get_state(obj, LV_BTN_PART_MAIN) & LV_STATE_DISABLED);
|
||||
break; // attribute_found
|
||||
|
||||
case ATTR_SWIPE:
|
||||
if(update)
|
||||
obj->user_data.swipeid = (!!val) % 16;
|
||||
else
|
||||
val = obj->user_data.swipeid;
|
||||
break; // attribute_found
|
||||
// case ATTR_SWIPE:
|
||||
// if(update)
|
||||
// obj->user_data.swipeid = (!!val) % 16;
|
||||
// else
|
||||
// val = obj->user_data.swipeid;
|
||||
// break; // attribute_found
|
||||
|
||||
case ATTR_TOGGLE:
|
||||
switch(obj_get_type(obj)) {
|
||||
@ -2594,7 +2606,7 @@ void hasp_process_obj_attribute(lv_obj_t* obj, const char* attribute, const char
|
||||
switch(attr_hash) {
|
||||
case ATTR_GROUPID:
|
||||
case ATTR_ID:
|
||||
case ATTR_TRANSITION:
|
||||
// case ATTR_TRANSITION:
|
||||
case ATTR_OBJID:
|
||||
case ATTR_X:
|
||||
case ATTR_Y:
|
||||
@ -2611,7 +2623,7 @@ void hasp_process_obj_attribute(lv_obj_t* obj, const char* attribute, const char
|
||||
case ATTR_HIDDEN:
|
||||
case ATTR_TOGGLE:
|
||||
case ATTR_CLICK:
|
||||
case ATTR_SWIPE:
|
||||
// case ATTR_SWIPE:
|
||||
case ATTR_ENABLED:
|
||||
val = Parser::is_true(payload);
|
||||
ret = attribute_common_bool(obj, attr_hash, val, update);
|
||||
@ -2644,6 +2656,7 @@ void hasp_process_obj_attribute(lv_obj_t* obj, const char* attribute, const char
|
||||
break;
|
||||
case ATTR_TAG:
|
||||
case ATTR_ACTION:
|
||||
case ATTR_SWIPE:
|
||||
ret = attribute_common_tag(obj, attr_hash, payload, &text, update);
|
||||
break;
|
||||
case ATTR_JSONL:
|
||||
|
@ -17,7 +17,10 @@ lv_chart_series_t* my_chart_get_series(lv_obj_t* chart, uint8_t ser_num);
|
||||
void my_obj_set_value_str_text(lv_obj_t* obj, uint8_t part, lv_state_t state, const char* text);
|
||||
void my_obj_set_tag(lv_obj_t* obj, const char* tag);
|
||||
void my_obj_set_action(lv_obj_t* obj, const char* tag);
|
||||
void my_obj_set_swipe(lv_obj_t* obj, const char* tag);
|
||||
const char* my_obj_get_tag(lv_obj_t* obj);
|
||||
const char* my_obj_get_action(lv_obj_t* obj);
|
||||
const char* my_obj_get_swipe(lv_obj_t* obj);
|
||||
void my_btnmatrix_map_clear(lv_obj_t* obj);
|
||||
void my_msgbox_map_clear(lv_obj_t* obj);
|
||||
void my_line_clear_points(lv_obj_t* obj);
|
||||
|
@ -58,8 +58,67 @@ void my_obj_set_template(lv_obj_t* obj, const char* text)
|
||||
LOG_WARNING(TAG_ATTR, "Failed to allocate memory!");
|
||||
}
|
||||
|
||||
static hasp_ext_user_data_t* my_create_ext_tag(lv_obj_t* obj)
|
||||
{
|
||||
void* ext = hasp_calloc(1, sizeof(hasp_ext_user_data_t));
|
||||
obj->user_data.ext = ext;
|
||||
return (hasp_ext_user_data_t*)ext;
|
||||
}
|
||||
|
||||
void my_obj_set_tag(lv_obj_t* obj, const char* payload)
|
||||
{
|
||||
hasp_ext_user_data_t* ext = (hasp_ext_user_data_t*)obj->user_data.ext;
|
||||
|
||||
// extended tag exists, free old tag
|
||||
if(ext && ext->tag) {
|
||||
hasp_free(ext->tag);
|
||||
ext->tag = NULL;
|
||||
}
|
||||
|
||||
// new tag is blank
|
||||
if(payload == NULL || payload[0] == '\0') {
|
||||
// my_prune_ext_tag(obj); // delete extended data if all extended properties are NULL
|
||||
return;
|
||||
}
|
||||
|
||||
// create new extended tags
|
||||
if(!ext) {
|
||||
ext = my_create_ext_tag(obj);
|
||||
}
|
||||
|
||||
// create new tag
|
||||
if(ext) {
|
||||
StaticJsonDocument<512> doc;
|
||||
size_t len = payload ? strlen(payload) : 0;
|
||||
|
||||
// check if it is a proper JSON object
|
||||
DeserializationError error = deserializeJson(doc, payload, len);
|
||||
if(error != DeserializationError::Ok) doc.set(payload); // use tag as-is
|
||||
|
||||
const size_t size = measureJson(doc) + 1;
|
||||
if(char* str = (char*)hasp_malloc(size)) {
|
||||
len = serializeJson(doc, str, size); // tidy-up the json object
|
||||
ext->tag = str;
|
||||
LOG_VERBOSE(TAG_ATTR, "new json: %s", str);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// ext or str was NULL
|
||||
LOG_WARNING(TAG_ATTR, D_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
// the tag data is stored as SERIALIZED JSON data
|
||||
void my_obj_set_tag(lv_obj_t* obj, const char* tag)
|
||||
const char* my_obj_get_tag(lv_obj_t* obj)
|
||||
{
|
||||
hasp_ext_user_data_t* ext = (hasp_ext_user_data_t*)obj->user_data.ext;
|
||||
if(!ext) return NULL;
|
||||
return ext->tag;
|
||||
}
|
||||
|
||||
/*
|
||||
// the tag data is stored as SERIALIZED JSON data
|
||||
void my_obj_set_tag2(lv_obj_t* obj, const char* tag)
|
||||
{
|
||||
size_t len = tag ? strlen(tag) : 0;
|
||||
|
||||
@ -90,45 +149,115 @@ void my_obj_set_tag(lv_obj_t* obj, const char* tag)
|
||||
}
|
||||
|
||||
// the tag data is stored as SERIALIZED JSON data
|
||||
const char* my_obj_get_tag(lv_obj_t* obj)
|
||||
const char* my_obj_get_tag2(lv_obj_t* obj)
|
||||
{
|
||||
return (char*)obj->user_data.tag;
|
||||
}
|
||||
*/
|
||||
|
||||
// the action data is stored as SERIALIZED JSON data
|
||||
void my_obj_set_action(lv_obj_t* obj, const char* action)
|
||||
void my_obj_set_action(lv_obj_t* obj, const char* payload)
|
||||
{
|
||||
// release old action
|
||||
if(obj->user_data.action) {
|
||||
hasp_free(obj->user_data.action);
|
||||
obj->user_data.action = NULL;
|
||||
hasp_ext_user_data_t* ext = (hasp_ext_user_data_t*)obj->user_data.ext;
|
||||
|
||||
// extended tag exists, free old tag
|
||||
if(ext && ext->action) {
|
||||
hasp_free(ext->action);
|
||||
ext->action = NULL;
|
||||
}
|
||||
|
||||
// new action is blank
|
||||
if(action == NULL || action[0] == '\0') return;
|
||||
// new tag is blank
|
||||
if(payload == NULL || payload[0] == '\0') {
|
||||
// my_prune_ext_tag(obj); // delete extended data if all extended properties are NULL
|
||||
return;
|
||||
}
|
||||
|
||||
// create new extended tags
|
||||
if(!ext) {
|
||||
ext = my_create_ext_tag(obj);
|
||||
}
|
||||
|
||||
// create new action
|
||||
{
|
||||
StaticJsonDocument<512> doc;
|
||||
// size_t len = action ? strlen(action) : 0;
|
||||
size_t len = payload ? strlen(payload) : 0;
|
||||
|
||||
// check if it is a proper JSON object
|
||||
DeserializationError error = deserializeJson(doc, action /*, len*/);
|
||||
if(error != DeserializationError::Ok) doc.set(action); // use tag as-is
|
||||
DeserializationError error = deserializeJson(doc, payload, len);
|
||||
if(error != DeserializationError::Ok) doc.set(payload); // use tag as-is
|
||||
|
||||
const size_t size = measureJson(doc) + 1;
|
||||
if(char* str = (char*)hasp_malloc(size)) {
|
||||
size_t len = serializeJson(doc, str, size); // tidy-up the json object
|
||||
obj->user_data.action = str;
|
||||
size_t len = serializeJson(doc, str, size); // tidy-up the json object
|
||||
ext->action = str;
|
||||
LOG_VERBOSE(TAG_ATTR, "new json: %s", str);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// ext or str was NULL
|
||||
LOG_WARNING(TAG_ATTR, D_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
// the tag data is stored as SERIALIZED JSON data
|
||||
const char* my_obj_get_action(lv_obj_t* obj)
|
||||
{
|
||||
return obj->user_data.action;
|
||||
hasp_ext_user_data_t* ext = (hasp_ext_user_data_t*)obj->user_data.ext;
|
||||
if(!ext) return NULL;
|
||||
return ext->action;
|
||||
}
|
||||
|
||||
|
||||
// the swipe data is stored as SERIALIZED JSON data
|
||||
void my_obj_set_swipe(lv_obj_t* obj, const char* payload)
|
||||
{
|
||||
hasp_ext_user_data_t* ext = (hasp_ext_user_data_t*)obj->user_data.ext;
|
||||
|
||||
// extended tag exists, free old tag
|
||||
if(ext && ext->swipe) {
|
||||
hasp_free(ext->swipe);
|
||||
ext->swipe = NULL;
|
||||
}
|
||||
|
||||
// new tag is blank
|
||||
if(payload == NULL || payload[0] == '\0') {
|
||||
// my_prune_ext_tag(obj); // delete extended data if all extended properties are NULL
|
||||
return;
|
||||
}
|
||||
|
||||
// create new extended tags
|
||||
if(!ext) {
|
||||
ext = my_create_ext_tag(obj);
|
||||
}
|
||||
|
||||
// create new action
|
||||
{
|
||||
StaticJsonDocument<512> doc;
|
||||
size_t len = payload ? strlen(payload) : 0;
|
||||
|
||||
// check if it is a proper JSON object
|
||||
DeserializationError error = deserializeJson(doc, payload, len);
|
||||
if(error != DeserializationError::Ok) doc.set(payload); // use tag as-is
|
||||
|
||||
const size_t size = measureJson(doc) + 1;
|
||||
if(char* str = (char*)hasp_malloc(size)) {
|
||||
size_t len = serializeJson(doc, str, size); // tidy-up the json object
|
||||
ext->swipe = str;
|
||||
LOG_VERBOSE(TAG_ATTR, "new json: %s", str);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// ext or str was NULL
|
||||
LOG_WARNING(TAG_ATTR, D_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
// the tag data is stored as SERIALIZED JSON data
|
||||
const char* my_obj_get_swipe(lv_obj_t* obj)
|
||||
{
|
||||
hasp_ext_user_data_t* ext = (hasp_ext_user_data_t*)obj->user_data.ext;
|
||||
if(!ext) return NULL;
|
||||
return ext->swipe;
|
||||
}
|
||||
|
||||
lv_label_align_t my_textarea_get_text_align(lv_obj_t* ta)
|
||||
|
@ -42,6 +42,25 @@ void event_reset_last_value_sent()
|
||||
last_value_sent = INT16_MIN;
|
||||
}
|
||||
|
||||
void script_event_handler(const char* eventname, const char* json)
|
||||
{
|
||||
StaticJsonDocument<256> doc;
|
||||
StaticJsonDocument<64> filter;
|
||||
|
||||
filter[eventname] = true;
|
||||
DeserializationError jsonError = deserializeJson(doc, json, DeserializationOption::Filter(filter));
|
||||
|
||||
if(!jsonError) {
|
||||
JsonVariant json = doc[eventname].as<JsonVariant>();
|
||||
uint8_t savedPage = haspPages.get();
|
||||
if(!dispatch_json_variant(json, savedPage, TAG_EVENT)) {
|
||||
LOG_WARNING(TAG_EVENT, F(D_DISPATCH_COMMAND_NOT_FOUND), eventname);
|
||||
}
|
||||
} else {
|
||||
dispatch_json_error(TAG_EVENT, jsonError);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean-up allocated memory before an object is deleted
|
||||
* @param obj pointer to an object to clean-up
|
||||
@ -87,6 +106,7 @@ void delete_event_handler(lv_obj_t* obj, lv_event_t event)
|
||||
}
|
||||
my_obj_set_tag(obj, (char*)NULL);
|
||||
my_obj_set_action(obj, (char*)NULL);
|
||||
my_obj_set_swipe(obj, (char*)NULL);
|
||||
}
|
||||
|
||||
/* ============================== Timer Event ============================ */
|
||||
@ -239,7 +259,7 @@ static void event_send_object_data(lv_obj_t* obj, const char* data)
|
||||
if(!data) return;
|
||||
object_dispatch_state(pageid, objid, data);
|
||||
} else {
|
||||
LOG_ERROR(TAG_MSGR, F(D_OBJECT_UNKNOWN));
|
||||
LOG_ERROR(TAG_EVENT, F(D_OBJECT_UNKNOWN));
|
||||
}
|
||||
}
|
||||
|
||||
@ -370,22 +390,22 @@ void first_touch_event_handler(lv_obj_t* obj, lv_event_t event)
|
||||
|
||||
void swipe_event_handler(lv_obj_t* obj, lv_event_t event)
|
||||
{
|
||||
if(!obj || obj->user_data.swipeid == 0) return;
|
||||
if(event != LV_EVENT_GESTURE || !obj || !obj->user_data.ext) return;
|
||||
|
||||
if(event == LV_EVENT_GESTURE) {
|
||||
if(const char* swipe = my_obj_get_swipe(obj)) {
|
||||
lv_gesture_dir_t dir = lv_indev_get_gesture_dir(lv_indev_get_act());
|
||||
switch(dir) {
|
||||
case LV_GESTURE_DIR_LEFT:
|
||||
haspPages.next(LV_SCR_LOAD_ANIM_NONE, 500, 0);
|
||||
script_event_handler("left", swipe);
|
||||
break;
|
||||
case LV_GESTURE_DIR_RIGHT:
|
||||
haspPages.prev(LV_SCR_LOAD_ANIM_NONE, 500, 0);
|
||||
script_event_handler("right", swipe);
|
||||
break;
|
||||
case LV_GESTURE_DIR_BOTTOM:
|
||||
haspPages.back(LV_SCR_LOAD_ANIM_NONE, 500, 0);
|
||||
script_event_handler("down", swipe);
|
||||
break;
|
||||
default:
|
||||
dispatch_current_page();
|
||||
script_event_handler("up", swipe);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -492,49 +512,10 @@ void generic_event_handler(lv_obj_t* obj, lv_event_t event)
|
||||
|
||||
if(last_value_sent == HASP_EVENT_LOST) return;
|
||||
|
||||
if(obj->user_data.action) {
|
||||
// if(last_value_sent == HASP_EVENT_UP || last_value_sent == HASP_EVENT_RELEASE) {
|
||||
// dispatch_text_line(obj->user_data.action, TAG_EVENT);
|
||||
|
||||
StaticJsonDocument<256> doc;
|
||||
StaticJsonDocument<64> filter;
|
||||
char eventname[8];
|
||||
|
||||
Parser::get_event_name(last_value_sent, eventname, sizeof(eventname));
|
||||
filter[eventname] = true;
|
||||
DeserializationError jsonError =
|
||||
deserializeJson(doc, (const char*)obj->user_data.action, DeserializationOption::Filter(filter));
|
||||
|
||||
if(!jsonError) {
|
||||
JsonVariant json = doc[eventname].as<JsonVariant>();
|
||||
uint8_t savedPage = haspPages.get();
|
||||
if(!dispatch_json_variant(json, savedPage, TAG_EVENT)) {
|
||||
LOG_WARNING(TAG_MSGR, F(D_DISPATCH_COMMAND_NOT_FOUND), eventname);
|
||||
// dispatch_simple_text_command(payload, source);
|
||||
}
|
||||
}
|
||||
// }
|
||||
|
||||
} else if(obj->user_data.actionid) {
|
||||
/* If an actionid is attached, perform that action on UP event only */
|
||||
if(last_value_sent == HASP_EVENT_UP || last_value_sent == HASP_EVENT_RELEASE) {
|
||||
lv_scr_load_anim_t transitionid = (lv_scr_load_anim_t)obj->user_data.transitionid;
|
||||
switch(obj->user_data.actionid) {
|
||||
case HASP_NUM_PAGE_PREV:
|
||||
haspPages.prev(transitionid, 500, 0);
|
||||
break;
|
||||
case HASP_NUM_PAGE_BACK:
|
||||
haspPages.back(transitionid, 500, 0);
|
||||
break;
|
||||
case HASP_NUM_PAGE_NEXT:
|
||||
haspPages.next(transitionid, 500, 0);
|
||||
break;
|
||||
default:
|
||||
haspPages.set(obj->user_data.actionid, transitionid, 500, 0);
|
||||
}
|
||||
dispatch_current_page();
|
||||
}
|
||||
|
||||
if(const char* action = my_obj_get_action(obj)) {
|
||||
char eventname[8];
|
||||
Parser::get_event_name(last_value_sent, eventname, sizeof(eventname));
|
||||
script_event_handler(eventname, action);
|
||||
} else {
|
||||
char data[512];
|
||||
{
|
||||
|
@ -14,6 +14,13 @@ const char FP_OBJID[] PROGMEM = "objid";
|
||||
const char FP_PARENTID[] PROGMEM = "parentid";
|
||||
const char FP_GROUPID[] PROGMEM = "groupid";
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char* action;
|
||||
char* swipe;
|
||||
char* tag;
|
||||
} hasp_ext_user_data_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
lv_obj_t* obj;
|
||||
|
Loading…
x
Reference in New Issue
Block a user