From f6d75e759c63136b8a9f5023642ddc5a8bb732ae Mon Sep 17 00:00:00 2001 From: Adam Martini Date: Sat, 20 Jun 2020 12:12:42 -0700 Subject: [PATCH] Add btn like signal handling for knob part. Add custom event to distuinguish from VALUE_CHANGED --- src/lv_core/lv_obj.h | 1 + src/lv_widgets/lv_rotary.c | 49 ++++++++++++++++++++++++++++++++++++++ src/lv_widgets/lv_rotary.h | 43 +++++++++++++++++++++++++++++++-- 3 files changed, 91 insertions(+), 2 deletions(-) diff --git a/src/lv_core/lv_obj.h b/src/lv_core/lv_obj.h index 88b71cb99..9d5edffb5 100644 --- a/src/lv_core/lv_obj.h +++ b/src/lv_core/lv_obj.h @@ -102,6 +102,7 @@ enum { LV_EVENT_APPLY, /**< "Ok", "Apply" or similar specific button has clicked*/ LV_EVENT_CANCEL, /**< "Close", "Cancel" or similar specific button has clicked*/ LV_EVENT_DELETE, /**< Object is being deleted */ + _LV_EVENT_LAST /** Number of events*/ }; typedef uint8_t lv_event_t; /**< Type of event being sent to the object. */ diff --git a/src/lv_widgets/lv_rotary.c b/src/lv_widgets/lv_rotary.c index 309b263dc..0fd4b5cc3 100644 --- a/src/lv_widgets/lv_rotary.c +++ b/src/lv_widgets/lv_rotary.c @@ -87,6 +87,7 @@ lv_obj_t * lv_rotary_create(lv_obj_t * par, const lv_obj_t * copy) ext->min_value = 0; ext->max_value = 0; ext->dragging = false; + ext->checkable = 0; lv_style_list_init(&ext->style_knob); /*The signal and design functions are not copied so set them here*/ @@ -108,6 +109,8 @@ lv_obj_t * lv_rotary_create(lv_obj_t * par, const lv_obj_t * copy) ext->min_value = copy_ext->min_value; ext->max_value = copy_ext->max_value; ext->dragging = copy_ext->dragging; + ext->sym = copy_ext->sym; + ext->checkable = copy_ext->checkable; lv_style_list_copy(&ext->style_knob, ©_ext->style_knob); lv_obj_refresh_style(rotary, LV_OBJ_PART_ALL); @@ -192,6 +195,20 @@ void lv_rotary_set_symmetric(lv_obj_t * rotary, bool en) lv_obj_invalidate(rotary); } +/** + * Enable the toggled states + * @param rotary pointer to a button object + * @param tgl true: enable toggled states, false: disable + */ +void lv_rotary_set_checkable(lv_obj_t * rotary, bool tgl) +{ + LV_ASSERT_OBJ(rotary, LV_OBJX_NAME); + + lv_rotary_ext_t * ext = (lv_rotary_ext_t *)lv_obj_get_ext_attr(rotary); + + ext->checkable = tgl != false ? 1 : 0; +} + /*===================== * Getter functions *====================*/ @@ -248,6 +265,20 @@ bool lv_rotary_is_dragged(const lv_obj_t * rotary) return ext->dragging; } +/** + * Get the toggle enable attribute of the rotary + * @param rotary pointer to a rotary object + * @return true: toggle enabled, false: disabled + */ +bool lv_rotary_get_checkable(const lv_obj_t * rotary) +{ + LV_ASSERT_OBJ(rotary, LV_OBJX_NAME); + + lv_rotary_ext_t * ext = (lv_rotary_ext_t *)lv_obj_get_ext_attr(rotary); + + return ext->checkable != 0 ? true : false; +} + /********************** * STATIC FUNCTIONS **********************/ @@ -305,6 +336,7 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par if(res != LV_RES_OK) return res; if(sign == LV_SIGNAL_GET_TYPE) return lv_obj_handle_get_type_signal(param, LV_OBJX_NAME); + bool tgl = lv_rotary_get_checkable(rotary); lv_rotary_ext_t * ext = lv_obj_get_ext_attr(rotary); lv_point_t p; @@ -320,6 +352,23 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par ext->dragging = false; ext->value_to_set = NULL; + /*If not dragged and it was not long press action then + *change state and run the action*/ + if(lv_indev_is_dragging(param) == false && tgl) { + uint32_t toggled = 0; + if(lv_obj_get_state(rotary, LV_ROTARY_PART_KNOB) & LV_STATE_CHECKED) { + lv_btn_set_state(rotary, LV_ROTARY_STATE_RELEASED); + toggled = 0; + } + else { + lv_btn_set_state(rotary, LV_ROTARY_STATE_CHECKED_RELEASED); + toggled = 1; + } + + res = lv_event_send(rotary, LV_EVENT_ROTARY_TOGGLED, &toggled); + if(res != LV_RES_OK) return res; + } + #if LV_USE_GROUP /*Leave edit mode if released. (No need to wait for LONG_PRESS) */ lv_group_t * g = lv_obj_get_group(rotary); diff --git a/src/lv_widgets/lv_rotary.h b/src/lv_widgets/lv_rotary.h index 5ddd1a485..f833902c8 100644 --- a/src/lv_widgets/lv_rotary.h +++ b/src/lv_widgets/lv_rotary.h @@ -69,6 +69,7 @@ typedef struct { int16_t * value_to_set; /*Start value of the rotary*/ uint16_t dragging :1; uint16_t sym :1; + uint8_t checkable :1; /* 1: Toggle enabled*/ } lv_rotary_ext_t; /** Built-in styles of rotary*/ @@ -79,6 +80,13 @@ enum { _LV_ROTARY_PART_VIRTUAL_LAST }; +/** Custom events of rotary*/ +enum { + LV_EVENT_ROTARY_TOGGLED = _LV_EVENT_LAST +}; +typedef uint8_t lv_rotary_event_t; + + /********************** * GLOBAL PROTOTYPES **********************/ @@ -184,16 +192,30 @@ static inline void lv_rotary_set_rotation(lv_obj_t * rotary, uint16_t rotation_a lv_arc_set_rotation(rotary, rotation_angle); } +/** + * Enable the toggled states + * @param rotary pointer to a rotary object + * @param tgl true: enable toggled states, false: disable + */ +void lv_rotary_set_checkable(lv_obj_t * rotary, bool tgl) + /** * Set the state of the rotary * @param rotary pointer to a rotary object * @param state the new state of the rotary (from lv_rotary_state_t enum) */ -static inline void lv_rotary_set_state(lv_obj_t * rotary, lv_rotary_state_t state) -{ +static inline void lv_rotary_set_state(lv_obj_t * rotary, lv_rotary_state_t state) { lv_btn_set_state(rotary, state); } +/** + * Toggle the state of the rotary (ON->OFF, OFF->ON) + * @param rotary pointer to a rotary object + */ +static inline void lv_rotary_toggle(lv_obj_t * rotary) { + lv_btn_toggle(rotary); +} + /*===================== * Getter functions *====================*/ @@ -273,6 +295,23 @@ static inline bool lv_rotary_get_symmetric(lv_obj_t * rotary) return ext->sym; } +/** + * Get the current state of the rotary + * @param rotary pointer to a rotary object + * @return the state of the rotary (from lv_rotary_state_t enum). + * If the rotary is in disabled state `LV_ROTARY_STATE_DISABLED` will be ORed to the other rotary states. + */ +static inline lv_btn_state_t lv_rotary_get_state(const lv_obj_t * rotary) { + return lv_btn_get_state(rotary); +} + +/** + * Get the toggle enable attribute of the rotary + * @param rotary pointer to a rotary object + * @return true: toggle enabled, false: disabled + */ +bool lv_rotary_get_checkable(const lv_obj_t * rotary) + /********************** * MACROS **********************/