diff --git a/src/hasp/hasp_event.cpp b/src/hasp/hasp_event.cpp index 71393506..d84796fd 100644 --- a/src/hasp/hasp_event.cpp +++ b/src/hasp/hasp_event.cpp @@ -15,15 +15,76 @@ static lv_style_int_t last_value_sent; static lv_color_t last_color_sent; +/** + * Clean-up allocated memory before an object is deleted + * @param obj pointer to an object to clean-up + */ +static void event_delete_object(lv_obj_t* obj) +{ + switch(obj->user_data.objid) { + case LV_HASP_LINE: + line_clear_points(obj); + break; + + case LV_HASP_BTNMATRIX: + my_btnmatrix_map_clear(obj); + _LV_WIN_PART_REAL_LAST; + _LV_WIN_PART_VIRTUAL_LAST; + break; + + case LV_HASP_GAUGE: + break; + } + + // TODO: delete value_str data for ALL parts + my_obj_set_value_str_txt(obj, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, NULL); +} + /* ============================== Event Senders ============================ */ /* Takes and lv_obj and finds the pageid and objid Then sends the data out on the state/pxby topic */ +/** + * Get the hasp eventid for LV_EVENT_PRESSED, LV_EVENT_VALUE_CHANGED, LV_EVENT_LONG_PRESSED_REPEAT and + * LV_EVENT_RELEASED Also updates the sleep state and handles LV_EVENT_DELETE events + * @param obj pointer to a color picker + * @param event type of event that occured + * @param eventid returns the hasp eventid + */ +static bool translate_event(lv_obj_t* obj, lv_event_t event, uint8_t& eventid) +{ + switch(event) { + case LV_EVENT_DELETE: + LOG_VERBOSE(TAG_EVENT, F(D_OBJECT_DELETED)); + event_delete_object(obj); + break; + + case LV_EVENT_PRESSED: + hasp_update_sleep_state(); // wakeup on press down? + eventid = HASP_EVENT_DOWN; + return true; + + case LV_EVENT_LONG_PRESSED_REPEAT: + eventid = HASP_EVENT_CHANGED; + return true; + + case LV_EVENT_RELEASED: + eventid = HASP_EVENT_UP; + return true; + + case LV_EVENT_VALUE_CHANGED: + eventid = HASP_EVENT_CHANGED; + return true; + } + + return false; // event not translated +} + // ##################### Value Senders ######################################################## -void event_obj_data(lv_obj_t* obj, const char* data) +void event_send_object_data(lv_obj_t* obj, const char* data) { uint8_t pageid; uint8_t objid; @@ -39,17 +100,6 @@ void event_obj_data(lv_obj_t* obj, const char* data) void event_dispatch(lv_obj_t* obj, uint8_t eventid, const char* data) {} -// Send out the event that occured -void event_object_generic_event(lv_obj_t* obj, uint8_t eventid) -{ - char data[40]; - char eventname[8]; - - Parser::get_event_name(eventid, eventname, sizeof(eventname)); - snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\"}"), eventname); - event_obj_data(obj, data); -} - // Send out the on/off event, with the val void event_object_val_event(lv_obj_t* obj, uint8_t eventid, int16_t val) { @@ -57,31 +107,21 @@ void event_object_val_event(lv_obj_t* obj, uint8_t eventid, int16_t val) char eventname[8]; Parser::get_event_name(eventid, eventname, sizeof(eventname)); - snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\",\"val\":%d}"), eventname, val); - event_obj_data(obj, data); + snprintf_P(data, sizeof(data), PSTR("{\"obj\":\"%s\",\"event\":\"%s\",\"val\":%d}"), get_obj_type_name(obj), + eventname, val); + event_send_object_data(obj, data); } // Send out the changed event, with the val and text -void event_object_selection_changed(lv_obj_t* obj, int16_t val, const char* text) +void event_object_selection_changed(lv_obj_t* obj, uint8_t eventid, int16_t val, const char* text) { char data[200]; - - snprintf_P(data, sizeof(data), PSTR("{\"event\":\"changed\",\"val\":%d,\"text\":\"%s\"}"), val, text); - event_obj_data(obj, data); -} - -// Send out the changed event, with the color -void event_object_color_event(lv_obj_t* obj, uint8_t eventid, lv_color_t color) -{ - char data[80]; char eventname[8]; - lv_color32_t c32; - c32.full = lv_color_to32(color); Parser::get_event_name(eventid, eventname, sizeof(eventname)); - snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\",\"color\":\"#%02x%02x%02x\",\"r\":%d,\"g\":%d,\"b\":%d}"), - eventname, c32.ch.red, c32.ch.green, c32.ch.blue, c32.ch.red, c32.ch.green, c32.ch.blue); - event_obj_data(obj, data); + snprintf_P(data, sizeof(data), PSTR("{\"obj\":\"%s\",\"event\":\"%s\",\"val\":%d,\"text\":\"%s\"}"), + get_obj_type_name(obj), eventname, val, text); + event_send_object_data(obj, data); } // ##################### Event Handlers ######################################################## @@ -103,27 +143,6 @@ void event_gpio_input(uint8_t pin, uint8_t group, uint8_t eventid) } #endif -void event_delete_object(lv_obj_t* obj) -{ - switch(obj->user_data.objid) { - case LV_HASP_LINE: - line_clear_points(obj); - break; - - case LV_HASP_BTNMATRIX: - my_btnmatrix_map_clear(obj); - _LV_WIN_PART_REAL_LAST; - _LV_WIN_PART_VIRTUAL_LAST; - break; - - case LV_HASP_GAUGE: - break; - } - - // TODO: delete value_str data for ALL parts - my_obj_set_value_str_txt(obj, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, NULL); -} - void log_event(const char* name, lv_event_t event) { return; @@ -258,12 +277,6 @@ void generic_event_handler(lv_obj_t* obj, lv_event_t event) last_value_sent = HASP_EVENT_LOST; break; - case LV_EVENT_PRESSING: - case LV_EVENT_FOCUSED: - case LV_EVENT_DEFOCUSED: - case LV_EVENT_GESTURE: - return; // Don't care about these - case LV_EVENT_RELEASED: if(last_value_sent == HASP_EVENT_UP) return; last_value_sent = HASP_EVENT_RELEASE; @@ -274,6 +287,12 @@ void generic_event_handler(lv_obj_t* obj, lv_event_t event) event_delete_object(obj); // free and destroy persistent memory allocated for certain objects return; + case LV_EVENT_PRESSING: + case LV_EVENT_FOCUSED: + case LV_EVENT_DEFOCUSED: + case LV_EVENT_GESTURE: + return; // Don't care about these + case LV_EVENT_VALUE_CHANGED: // Should not occur in this event handler default: LOG_WARNING(TAG_EVENT, F(D_OBJECT_EVENT_UNKNOWN), event); @@ -302,7 +321,11 @@ void generic_event_handler(lv_obj_t* obj, lv_event_t event) dispatch_output_current_page(); } } else { - event_object_generic_event(obj, last_value_sent); // send normal object event + char data[40]; + char eventname[8]; + Parser::get_event_name(last_value_sent, eventname, sizeof(eventname)); + snprintf_P(data, sizeof(data), PSTR("{\"event\":\"%s\"}"), eventname); + event_send_object_data(obj, data); } dispatch_normalized_group_value(obj->user_data.groupid, obj, Parser::get_event_state(last_value_sent), HASP_EVENT_OFF, HASP_EVENT_ON); @@ -317,39 +340,31 @@ void toggle_event_handler(lv_obj_t* obj, lv_event_t event) { log_event("toggle", event); - switch(event) { - case LV_EVENT_PRESSED: - hasp_update_sleep_state(); // wakeup? - case LV_EVENT_RELEASED: + uint8_t hasp_event_id; + if(!translate_event(obj, event, hasp_event_id)) return; + if(hasp_event_id != HASP_EVENT_DOWN && hasp_event_id != HASP_EVENT_UP) return; // only up or down wanted - switch(obj->user_data.objid) { - case LV_HASP_SWITCH: - last_value_sent = lv_switch_get_state(obj); - break; - - case LV_HASP_CHECKBOX: - last_value_sent = lv_checkbox_is_checked(obj); - break; - - case LV_HASP_BUTTON: { - last_value_sent = lv_obj_get_state(obj, LV_BTN_PART_MAIN) & LV_STATE_CHECKED; - break; - } - - default: - return; - } - - event_object_val_event(obj, event == LV_EVENT_PRESSED ? HASP_EVENT_DOWN : HASP_EVENT_UP, last_value_sent); - dispatch_normalized_group_value(obj->user_data.groupid, obj, last_value_sent, HASP_EVENT_OFF, - HASP_EVENT_ON); + /* Get the new value */ + switch(obj->user_data.objid) { + case LV_HASP_SWITCH: + last_value_sent = lv_switch_get_state(obj); break; - case LV_EVENT_DELETE: - LOG_VERBOSE(TAG_EVENT, F(D_OBJECT_DELETED)); - event_delete_object(obj); + case LV_HASP_CHECKBOX: + last_value_sent = lv_checkbox_is_checked(obj); break; + + case LV_HASP_BUTTON: { + last_value_sent = lv_obj_get_state(obj, LV_BTN_PART_MAIN) & LV_STATE_CHECKED; + break; + } + + default: + return; // invalid object } + + event_object_val_event(obj, hasp_event_id, last_value_sent); + dispatch_normalized_group_value(obj->user_data.groupid, obj, last_value_sent, HASP_EVENT_OFF, HASP_EVENT_ON); } /** @@ -361,61 +376,92 @@ void selector_event_handler(lv_obj_t* obj, lv_event_t event) { log_event("selector", event); - if(event == LV_EVENT_VALUE_CHANGED) { - char buffer[128]; - char property[36]; - uint16_t val = 0; - uint16_t max = 0; - hasp_update_sleep_state(); // wakeup? + uint8_t hasp_event_id; + if(!translate_event(obj, event, hasp_event_id)) return; // Use LV_EVENT_VALUE_CHANGED - switch(obj->user_data.objid) { - case LV_HASP_DROPDOWN: - val = lv_dropdown_get_selected(obj); - max = lv_dropdown_get_option_cnt(obj) - 1; - lv_dropdown_get_selected_str(obj, buffer, sizeof(buffer)); - break; + /* Get the new value */ + char buffer[128]; + char property[36]; + uint16_t val = 0; + uint16_t max = 0; - case LV_HASP_ROLLER: - val = lv_roller_get_selected(obj); - max = lv_roller_get_option_cnt(obj) - 1; - lv_roller_get_selected_str(obj, buffer, sizeof(buffer)); - break; + /* Get the text, val and max properties */ + switch(obj->user_data.objid) { + case LV_HASP_DROPDOWN: + val = lv_dropdown_get_selected(obj); + max = lv_dropdown_get_option_cnt(obj) - 1; + lv_dropdown_get_selected_str(obj, buffer, sizeof(buffer)); + break; - case LV_HASP_BTNMATRIX: { - val = lv_btnmatrix_get_active_btn(obj); - const char* txt = lv_btnmatrix_get_btn_text(obj, val); - strncpy(buffer, txt, sizeof(buffer)); - break; - } + case LV_HASP_ROLLER: + val = lv_roller_get_selected(obj); + max = lv_roller_get_option_cnt(obj) - 1; + lv_roller_get_selected_str(obj, buffer, sizeof(buffer)); + break; - case LV_HASP_TABLE: { - uint16_t row; - uint16_t col; - if(lv_table_get_pressed_cell(obj, &row, &col) != LV_RES_OK) return; // outside any cell + case LV_HASP_TABLE: { + uint16_t row; + uint16_t col; + if(lv_table_get_pressed_cell(obj, &row, &col) != LV_RES_OK) return; // outside any cell - const char* txt = lv_table_get_cell_value(obj, row, col); - strncpy(buffer, txt, sizeof(buffer)); + const char* txt = lv_table_get_cell_value(obj, row, col); + strncpy(buffer, txt, sizeof(buffer)); - snprintf_P(property, sizeof(property), PSTR("row\":%d,\"col\":%d,\"text"), row, col); - attr_out_str(obj, property, buffer); - return; - } - - default: - return; + snprintf_P(property, sizeof(property), PSTR("row\":%d,\"col\":%d,\"text"), row, col); + attr_out_str(obj, property, buffer); + return; // done sending } - // set the property - // snprintf_P(property, sizeof(property), PSTR("val\":%d,\"text"), val); - // attr_out_str(obj, property, buffer); - - event_object_selection_changed(obj, val, buffer); - if(max > 0) dispatch_normalized_group_value(obj->user_data.groupid, obj, val, 0, max); - - } else if(event == LV_EVENT_DELETE) { - LOG_VERBOSE(TAG_EVENT, F(D_OBJECT_DELETED)); - event_delete_object(obj); + default: + return; // Invalid selector type } + + if((event == LV_EVENT_LONG_PRESSED_REPEAT && last_value_sent != val) || event != LV_EVENT_LONG_PRESSED_REPEAT) { + last_value_sent = val; + event_object_selection_changed(obj, hasp_event_id, val, buffer); + // if(max > 0) dispatch_normalized_group_value(obj->user_data.groupid, obj, val, 0, max); + } + + // set the property + // snprintf_P(property, sizeof(property), PSTR("val\":%d,\"text"), val); + // attr_out_str(obj, property, buffer); +} + +/** + * Called when a btnmatrix value has changed + * @param obj pointer to a dropdown list or roller + * @param event type of event that occured + */ +void btnmatrix_event_handler(lv_obj_t* obj, lv_event_t event) +{ + log_event("btnmatrix", event); + + uint8_t hasp_event_id; + if(!translate_event(obj, event, hasp_event_id)) return; // Use LV_EVENT_VALUE_CHANGED + + /* Get the new value */ + char buffer[128]; + char property[36]; + uint16_t val = 0; + uint16_t max = 0; + + val = lv_btnmatrix_get_active_btn(obj); + if(val != LV_BTNMATRIX_BTN_NONE) { + const char* txt = lv_btnmatrix_get_btn_text(obj, val); + strncpy(buffer, txt, sizeof(buffer)); + } else { + buffer[0] = 0; // empty string + } + + if((event == LV_EVENT_LONG_PRESSED_REPEAT && last_value_sent != val) || event != LV_EVENT_LONG_PRESSED_REPEAT) { + last_value_sent = val; + event_object_selection_changed(obj, hasp_event_id, val, buffer); + // if(max > 0) dispatch_normalized_group_value(obj->user_data.groupid, obj, val, 0, max); + } + + // set the property + // snprintf_P(property, sizeof(property), PSTR("val\":%d,\"text"), val); + // attr_out_str(obj, property, buffer); } /** @@ -427,54 +473,32 @@ void slider_event_handler(lv_obj_t* obj, lv_event_t event) { log_event("slider", event); - uint16_t evt; - switch(event) { + uint8_t hasp_event_id; + if(!translate_event(obj, event, hasp_event_id) || event == LV_EVENT_VALUE_CHANGED) return; - case LV_EVENT_PRESSED: - hasp_update_sleep_state(); // wakeup on press down? - evt = HASP_EVENT_DOWN; - case LV_EVENT_LONG_PRESSED_REPEAT: - if(event == LV_EVENT_LONG_PRESSED_REPEAT) evt = HASP_EVENT_CHANGED; - case LV_EVENT_RELEASED: { - if(event == LV_EVENT_RELEASED) evt = HASP_EVENT_UP; + /* Get the new value */ + int16_t val; + int16_t min; + int16_t max; - // case LV_EVENT_PRESSED || LV_EVENT_LONG_PRESSED_REPEAT || LV_EVENT_RELEASED - int16_t val; - int16_t min; - int16_t max; + if(obj->user_data.objid == LV_HASP_SLIDER) { + val = lv_slider_get_value(obj); + min = lv_slider_get_min_value(obj); + max = lv_slider_get_max_value(obj); - if(obj->user_data.objid == LV_HASP_SLIDER) { - val = lv_slider_get_value(obj); - min = lv_slider_get_min_value(obj); - max = lv_slider_get_max_value(obj); - } else if(obj->user_data.objid == LV_HASP_ARC) { - val = lv_arc_get_value(obj); - min = lv_arc_get_min_value(obj); - max = lv_arc_get_max_value(obj); - } else { - return; - } + } else if(obj->user_data.objid == LV_HASP_ARC) { + val = lv_arc_get_value(obj); + min = lv_arc_get_min_value(obj); + max = lv_arc_get_max_value(obj); - if((event == LV_EVENT_LONG_PRESSED_REPEAT && last_value_sent != val) || - event != LV_EVENT_LONG_PRESSED_REPEAT) { - last_value_sent = val; - event_object_val_event(obj, evt, val); - dispatch_normalized_group_value(obj->user_data.groupid, obj, val, min, max); - } - break; - } + } else { + return; // not a slider + } - case LV_EVENT_VALUE_CHANGED: - break; - - case LV_EVENT_DELETE: - LOG_VERBOSE(TAG_EVENT, F(D_OBJECT_DELETED)); - event_delete_object(obj); - break; - - default: - // LOG_VERBOSE(TAG_EVENT, F("Event ID: %d"), event); - ; + if((event == LV_EVENT_LONG_PRESSED_REPEAT && last_value_sent != val) || event != LV_EVENT_LONG_PRESSED_REPEAT) { + last_value_sent = val; + event_object_val_event(obj, hasp_event_id, val); + dispatch_normalized_group_value(obj->user_data.groupid, obj, val, min, max); } } @@ -485,41 +509,31 @@ void slider_event_handler(lv_obj_t* obj, lv_event_t event) */ void cpicker_event_handler(lv_obj_t* obj, lv_event_t event) { - char color[6]; - snprintf_P(color, sizeof(color), PSTR("color")); log_event("cpicker", event); - uint16_t evt; - switch(event) { + uint8_t hasp_event_id; + if(!translate_event(obj, event, hasp_event_id) || event == LV_EVENT_LONG_PRESSED_REPEAT) return; - case LV_EVENT_PRESSED: - hasp_update_sleep_state(); // wakeup on press down? - evt = HASP_EVENT_DOWN; - case LV_EVENT_LONG_PRESSED_REPEAT: - if(event == LV_EVENT_LONG_PRESSED_REPEAT) evt = HASP_EVENT_CHANGED; - case LV_EVENT_RELEASED: { - if(event == LV_EVENT_RELEASED) evt = HASP_EVENT_UP; - lv_color_t color = lv_cpicker_get_color(obj); + /* Get the new value */ + lv_color_t color = lv_cpicker_get_color(obj); - if((event == LV_EVENT_LONG_PRESSED_REPEAT && last_color_sent.full != color.full) || - event != LV_EVENT_LONG_PRESSED_REPEAT) { - last_color_sent = color; - event_object_color_event(obj, evt, color); - // dispatch_normalized_group_value(obj->user_data.groupid, obj, val, min, max); - } - break; - } + if((event == LV_EVENT_LONG_PRESSED_REPEAT && last_color_sent.full != color.full) || + event != LV_EVENT_LONG_PRESSED_REPEAT) { - case LV_EVENT_VALUE_CHANGED: - break; + char data[100]; + char eventname[8]; + Parser::get_event_name(hasp_event_id, eventname, sizeof(eventname)); - case LV_EVENT_DELETE: - LOG_VERBOSE(TAG_EVENT, F(D_OBJECT_DELETED)); - event_delete_object(obj); - break; + lv_color32_t c32; + c32.full = lv_color_to32(color); + last_color_sent = color; - default: - // LOG_VERBOSE(TAG_EVENT, F("Event ID: %d"), event); - ; + snprintf_P( + data, sizeof(data), + PSTR("{\"obj\":\"cpicker\",\"event\":\"%s\",\"color\":\"#%02x%02x%02x\",\"r\":%d,\"g\":%d,\"b\":%d}"), + eventname, c32.ch.red, c32.ch.green, c32.ch.blue, c32.ch.red, c32.ch.green, c32.ch.blue); + event_send_object_data(obj, data); + + // dispatch_normalized_group_value(obj->user_data.groupid, obj, val, min, max); } } \ No newline at end of file diff --git a/src/hasp/hasp_event.h b/src/hasp/hasp_event.h index d1770bbd..835be476 100644 --- a/src/hasp/hasp_event.h +++ b/src/hasp/hasp_event.h @@ -17,6 +17,7 @@ void generic_event_handler(lv_obj_t* obj, lv_event_t event); void toggle_event_handler(lv_obj_t* obj, lv_event_t event); void slider_event_handler(lv_obj_t* obj, lv_event_t event); void selector_event_handler(lv_obj_t* obj, lv_event_t event); +void btnmatrix_event_handler(lv_obj_t* obj, lv_event_t event); void cpicker_event_handler(lv_obj_t* obj, lv_event_t event); #if HASP_USE_GPIO > 0