From 400ca85c67d74a2807ff76571e2bc1c444e47f82 Mon Sep 17 00:00:00 2001 From: zlm <40327908+LanFengXiMenChuiXue@users.noreply.github.com> Date: Thu, 16 Jan 2020 19:24:08 -0500 Subject: [PATCH 1/2] Add a gesture event and fix an arc drawing bug (#1300) --- lv_conf_template.h | 7 ++++ src/lv_conf_internal.h | 16 +++++++++ src/lv_core/lv_indev.c | 73 +++++++++++++++++++++++++++++++++++++++ src/lv_core/lv_indev.h | 7 ++++ src/lv_core/lv_obj.c | 24 +++++++++++++ src/lv_core/lv_obj.h | 21 ++++++++++- src/lv_draw/lv_draw_arc.c | 8 ++--- src/lv_hal/lv_hal_indev.c | 12 ++++--- src/lv_hal/lv_hal_indev.h | 16 +++++++++ 9 files changed, 174 insertions(+), 10 deletions(-) diff --git a/lv_conf_template.h b/lv_conf_template.h index 67ed46809..87d7df2ff 100644 --- a/lv_conf_template.h +++ b/lv_conf_template.h @@ -122,6 +122,13 @@ typedef int16_t lv_coord_t; * Time between `LV_EVENT_LONG_PRESSED_REPEAT */ #define LV_INDEV_DEF_LONG_PRESS_REP_TIME 100 + +/* Gesture threshold in pixels */ +#define LV_INDEV_DEF_GESTURE_LIMIT 50 + +/* Gesture min velocity at release before swipe (pixels)*/ +#define LV_INDEV_DEF_GESTURE_MIN_VELOCITY 3 + /*================== * Feature usage *==================*/ diff --git a/src/lv_conf_internal.h b/src/lv_conf_internal.h index 7e134d932..c0a5dad81 100644 --- a/src/lv_conf_internal.h +++ b/src/lv_conf_internal.h @@ -182,6 +182,17 @@ #define LV_INDEV_DEF_LONG_PRESS_REP_TIME 100 #endif + +/* Gesture threshold in pixels */ +#ifndef LV_INDEV_DEF_GESTURE_LIMIT +#define LV_INDEV_DEF_GESTURE_LIMIT 50 +#endif + +/* Gesture min velocity at release before swipe (pixels)*/ +#ifndef LV_INDEV_DEF_GESTURE_MIN_VELOCITY +#define LV_INDEV_DEF_GESTURE_MIN_VELOCITY 3 +#endif + /*================== * Feature usage *==================*/ @@ -726,6 +737,11 @@ #define LV_USE_LMETER 1 #endif +/*Mask (dependencies: -)*/ +#ifndef LV_USE_OBJMASK +#define LV_USE_OBJMASK 0 +#endif + /*Message box (dependencies: lv_rect, lv_btnm, lv_label)*/ #ifndef LV_USE_MBOX #define LV_USE_MBOX 1 diff --git a/src/lv_core/lv_indev.c b/src/lv_core/lv_indev.c index 8bf050d5f..33415c84b 100644 --- a/src/lv_core/lv_indev.c +++ b/src/lv_core/lv_indev.c @@ -42,6 +42,7 @@ static void indev_proc_reset_query_handler(lv_indev_t * indev); static void indev_drag(lv_indev_proc_t * proc); static void indev_drag_throw(lv_indev_proc_t * proc); static lv_obj_t * get_dragged_obj(lv_obj_t * obj); +static void indev_gesture(lv_indev_proc_t * proc); static bool indev_reset_check(lv_indev_proc_t * proc); /********************** @@ -242,6 +243,16 @@ void lv_indev_get_point(const lv_indev_t * indev, lv_point_t * point) } } +/** +* Get the current gesture direct +* @param indev pointer to an input device +* @return current gesture direct +*///zlm +lv_gesture_dir_t lv_indev_get_gesture_dir(const lv_indev_t * indev) +{ + return indev->proc.types.pointer.gesture_dir; +} + /** * Get the last pressed key of an input device (for LV_INDEV_TYPE_KEYPAD) * @param indev pointer to an input device @@ -774,6 +785,9 @@ static void indev_proc_press(lv_indev_proc_t * proc) proc->types.pointer.drag_sum.x = 0; proc->types.pointer.drag_sum.y = 0; proc->types.pointer.drag_dir = LV_DRAG_DIR_NONE; + proc->types.pointer.gesture_sent = 0; + proc->types.pointer.gesture_sum.x = 0; + proc->types.pointer.gesture_sum.y = 0; proc->types.pointer.vect.x = 0; proc->types.pointer.vect.y = 0; @@ -829,6 +843,7 @@ static void indev_proc_press(lv_indev_proc_t * proc) if(indev_act->proc.wait_until_release) return; indev_drag(proc); + indev_gesture(proc); if(indev_reset_check(proc)) return; /*If there is no drag then check for long press time*/ @@ -1019,6 +1034,8 @@ static void indev_proc_reset_query_handler(lv_indev_t * indev) indev->proc.types.pointer.drag_dir = LV_DRAG_DIR_NONE; indev->proc.types.pointer.drag_throw_vect.x = 0; indev->proc.types.pointer.drag_throw_vect.y = 0; + indev->proc.types.pointer.gesture_sum.x = 0; + indev->proc.types.pointer.gesture_sum.y = 0; indev->proc.reset_query = 0; indev_obj_act = NULL; } @@ -1296,6 +1313,62 @@ static lv_obj_t * get_dragged_obj(lv_obj_t * obj) return drag_obj; } + +/** +* Handle the gesture of indev_proc_p->types.pointer.act_obj +* @param indev pointer to a input device state +*/ +static void indev_gesture(lv_indev_proc_t * proc) +{ + + if (proc->types.pointer.drag_in_prog) return; + if (proc->types.pointer.gesture_sent) return; + + lv_obj_t * gesture_obj = proc->types.pointer.act_obj; + + /*If gesture parent is active check recursively the drag_parent attribute*/ + while (lv_obj_get_gesture_parent(gesture_obj) != false && gesture_obj != NULL) { + gesture_obj = lv_obj_get_parent(gesture_obj); + } + + if (gesture_obj == NULL) return; + + if ((LV_MATH_ABS(proc->types.pointer.vect.x) < indev_act->driver.gesture_min_velocity) && + (LV_MATH_ABS(proc->types.pointer.vect.y) < indev_act->driver.gesture_min_velocity)) { + proc->types.pointer.gesture_sum.x = 0; + proc->types.pointer.gesture_sum.y = 0; + } + + /*Count the movement by gesture*/ + proc->types.pointer.gesture_sum.x += proc->types.pointer.vect.x; + proc->types.pointer.gesture_sum.y += proc->types.pointer.vect.y; + + if ((LV_MATH_ABS(proc->types.pointer.gesture_sum.x) > indev_act->driver.gesture_limit) || + (LV_MATH_ABS(proc->types.pointer.gesture_sum.y) > indev_act->driver.gesture_limit)){ + + proc->types.pointer.gesture_sent = 1; + + if (LV_MATH_ABS(proc->types.pointer.gesture_sum.x) > LV_MATH_ABS(proc->types.pointer.gesture_sum.y)){ + if (proc->types.pointer.gesture_sum.x > 0) + proc->types.pointer.gesture_dir = LV_GESTURE_DIR_RIGHT; + else + proc->types.pointer.gesture_dir = LV_GESTURE_DIR_LEFT; + } + else{ + if (proc->types.pointer.gesture_sum.y > 0) + proc->types.pointer.gesture_dir = LV_GESTURE_DIR_BOTTOM; + else + proc->types.pointer.gesture_dir = LV_GESTURE_DIR_TOP; + } + + gesture_obj->signal_cb(gesture_obj, LV_SIGNAL_GESTURE, indev_act); + if (indev_reset_check(proc)) return; + lv_event_send(gesture_obj, LV_EVENT_GESTURE, NULL); + if (indev_reset_check(proc)) return; + } +} + + /** * Checks if the reset_query flag has been set. If so, perform necessary global indev cleanup actions * @param proc pointer to an input device 'proc' diff --git a/src/lv_core/lv_indev.h b/src/lv_core/lv_indev.h index 21b8e844e..fca073901 100644 --- a/src/lv_core/lv_indev.h +++ b/src/lv_core/lv_indev.h @@ -104,6 +104,13 @@ void lv_indev_set_button_points(lv_indev_t * indev, const lv_point_t * points); */ void lv_indev_get_point(const lv_indev_t * indev, lv_point_t * point); +/** +* Get the current gesture direct +* @param indev pointer to an input device +* @return current gesture direct +*/ +lv_gesture_dir_t lv_indev_get_gesture_dir(const lv_indev_t * indev); + /** * Get the last pressed key of an input device (for LV_INDEV_TYPE_KEYPAD) * @param indev pointer to an input device diff --git a/src/lv_core/lv_obj.c b/src/lv_core/lv_obj.c index b6050dbee..aa297e32a 100644 --- a/src/lv_core/lv_obj.c +++ b/src/lv_core/lv_obj.c @@ -237,6 +237,7 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy) new_obj->base_dir = LV_BIDI_DIR_LTR; #endif + new_obj->gesture_parent = 0; new_obj->reserved = 0; new_obj->ext_attr = NULL; @@ -334,6 +335,7 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy) new_obj->opa_scale = LV_OPA_COVER; new_obj->opa_scale_en = 0; new_obj->parent_event = 0; + new_obj->gesture_parent = 1; new_obj->reserved = 0; new_obj->ext_attr = NULL; @@ -385,6 +387,7 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy) new_obj->opa_scale_en = copy->opa_scale_en; new_obj->protect = copy->protect; new_obj->opa_scale = copy->opa_scale; + new_obj->gesture_parent = copy->gesture_parent; new_obj->style_p = copy->style_p; @@ -1384,6 +1387,17 @@ void lv_obj_set_drag_parent(lv_obj_t * obj, bool en) obj->drag_parent = (en == true ? 1 : 0); } +/** +* Enable to use parent for gesture related operations. +* If trying to gesture the object the parent will be moved instead +* @param obj pointer to an object +* @param en true: enable the 'gesture parent' for the object +*/ +void lv_obj_set_gesture_parent(lv_obj_t * obj, bool en) +{ + obj->gesture_parent = (en == true ? 1 : 0); +} + /** * Propagate the events to the parent too * @param obj pointer to an object @@ -2171,6 +2185,16 @@ bool lv_obj_get_drag_parent(const lv_obj_t * obj) return obj->drag_parent == 0 ? false : true; } +/** +* Get the gesture parent attribute of an object +* @param obj pointer to an object +* @return true: gesture parent is enabled +*/ +bool lv_obj_get_gesture_parent(const lv_obj_t * obj) +{ + return obj->gesture_parent == 0 ? false : true; +} + /** * Get the drag parent attribute of an object * @param obj pointer to an object diff --git a/src/lv_core/lv_obj.h b/src/lv_core/lv_obj.h index d08ad62e5..49ca7de61 100644 --- a/src/lv_core/lv_obj.h +++ b/src/lv_core/lv_obj.h @@ -89,6 +89,7 @@ enum { LV_EVENT_DRAG_BEGIN, LV_EVENT_DRAG_END, LV_EVENT_DRAG_THROW_BEGIN, + LV_EVENT_GESTURE, /**< The object has been getture*/ LV_EVENT_KEY, LV_EVENT_FOCUSED, LV_EVENT_DEFOCUSED, @@ -133,6 +134,7 @@ enum { LV_SIGNAL_DRAG_BEGIN, LV_SIGNAL_DRAG_THROW_BEGIN, LV_SIGNAL_DRAG_END, + LV_SIGNAL_GESTURE, /**< The object has been getture*/ /*Group related*/ LV_SIGNAL_FOCUS, @@ -222,7 +224,8 @@ typedef struct _lv_obj_t lv_drag_dir_t drag_dir : 3; /**< Which directions the object can be dragged in */ lv_bidi_dir_t base_dir : 2; /**< Base direction of texts related to this object */ uint8_t adv_hittest : 1; /**< 1: Use advanced hit-testing (slower) */ - uint8_t reserved : 2; /**< Reserved for future use*/ + uint8_t gesture_parent : 1; /**< 1: Parent will be gesture instead*/ + uint8_t reserved : 1; /**< Reserved for future use*/ uint8_t protect; /**< Automatically happening actions can be prevented. 'OR'ed values from `lv_protect_t`*/ lv_opa_t opa_scale; /**< Scale down the opacity by this factor. Effects all children as well*/ @@ -529,6 +532,14 @@ void lv_obj_set_drag_throw(lv_obj_t * obj, bool en); */ void lv_obj_set_drag_parent(lv_obj_t * obj, bool en); +/** +* Enable to use parent for gesture related operations. +* If trying to gesture the object the parent will be moved instead +* @param obj pointer to an object +* @param en true: enable the 'gesture parent' for the object +*/ +void lv_obj_set_gesture_parent(lv_obj_t * obj, bool en); + /** * Propagate the events to the parent too * @param obj pointer to an object @@ -536,7 +547,9 @@ void lv_obj_set_drag_parent(lv_obj_t * obj, bool en); */ void lv_obj_set_parent_event(lv_obj_t * obj, bool en); + void lv_obj_set_base_dir(lv_obj_t * obj, lv_bidi_dir_t dir); + /** * Set the opa scale enable parameter (required to set opa_scale with `lv_obj_set_opa_scale()`) * @param obj pointer to an object @@ -883,6 +896,12 @@ bool lv_obj_get_drag_parent(const lv_obj_t * obj); */ bool lv_obj_get_parent_event(const lv_obj_t * obj); +/** +* Get the gesture parent attribute of an object +* @param obj pointer to an object +* @return true: gesture parent is enabled +*/ +bool lv_obj_get_gesture_parent(const lv_obj_t * obj); lv_bidi_dir_t lv_obj_get_base_dir(const lv_obj_t * obj); diff --git a/src/lv_draw/lv_draw_arc.c b/src/lv_draw/lv_draw_arc.c index fcb95d55d..2fe9e4fb4 100644 --- a/src/lv_draw/lv_draw_arc.c +++ b/src/lv_draw/lv_draw_arc.c @@ -107,8 +107,8 @@ static void get_rounded_area(int16_t angle, lv_coord_t radius, uint8_t tickness, const uint8_t ps = 8; const uint8_t pa = 127; - lv_coord_t thick_half = tickness / 2; - lv_coord_t thick_corr = tickness & 0x01 ? 0 : 1; + int32_t thick_half = tickness / 2; + uint8_t thick_corr = tickness & 0x01 ? 0 : 1; lv_coord_t rx_corr; lv_coord_t ry_corr; @@ -119,8 +119,8 @@ static void get_rounded_area(int16_t angle, lv_coord_t radius, uint8_t tickness, if(angle > 0 && angle < 180) ry_corr = 0; else ry_corr = 0; - lv_coord_t cir_x; - lv_coord_t cir_y; + int32_t cir_x; + int32_t cir_y; cir_x = ((radius - rx_corr - thick_half) * lv_trigo_sin(90 - angle)) >> (LV_TRIGO_SHIFT - ps); cir_y = ((radius - ry_corr - thick_half) * lv_trigo_sin(angle)) >> (LV_TRIGO_SHIFT - ps); diff --git a/src/lv_hal/lv_hal_indev.c b/src/lv_hal/lv_hal_indev.c index 35ff1b318..d08484859 100644 --- a/src/lv_hal/lv_hal_indev.c +++ b/src/lv_hal/lv_hal_indev.c @@ -53,11 +53,13 @@ void lv_indev_drv_init(lv_indev_drv_t * driver) { memset(driver, 0, sizeof(lv_indev_drv_t)); - driver->type = LV_INDEV_TYPE_NONE; - driver->drag_limit = LV_INDEV_DEF_DRAG_LIMIT; - driver->drag_throw = LV_INDEV_DEF_DRAG_THROW; - driver->long_press_time = LV_INDEV_DEF_LONG_PRESS_TIME; - driver->long_press_rep_time = LV_INDEV_DEF_LONG_PRESS_REP_TIME; + driver->type = LV_INDEV_TYPE_NONE; + driver->drag_limit = LV_INDEV_DEF_DRAG_LIMIT; + driver->drag_throw = LV_INDEV_DEF_DRAG_THROW; + driver->long_press_time = LV_INDEV_DEF_LONG_PRESS_TIME; + driver->long_press_rep_time = LV_INDEV_DEF_LONG_PRESS_REP_TIME; + driver->gesture_limit = LV_INDEV_DEF_GESTURE_LIMIT; + driver->gesture_min_velocity = LV_INDEV_DEF_GESTURE_MIN_VELOCITY; } /** diff --git a/src/lv_hal/lv_hal_indev.h b/src/lv_hal/lv_hal_indev.h index 38b9b5214..2a9c54bd2 100644 --- a/src/lv_hal/lv_hal_indev.h +++ b/src/lv_hal/lv_hal_indev.h @@ -61,6 +61,13 @@ enum { typedef uint8_t lv_drag_dir_t; +enum { + LV_GESTURE_DIR_TOP, /**< Gesture dir up. */ + LV_GESTURE_DIR_BOTTOM, /**< Gesture dir down. */ + LV_GESTURE_DIR_LEFT, /**< Gesture dir left. */ + LV_GESTURE_DIR_RIGHT, /**< Gesture dir right. */ +}; +typedef uint8_t lv_gesture_dir_t; /** Data structure passed to an input driver to fill */ typedef struct @@ -106,6 +113,12 @@ typedef struct _lv_indev_drv_t /**< Drag throw slow-down in [%]. Greater value means faster slow-down */ uint8_t drag_throw; + /**< At least this difference should between two points to evaluate as gesture */ + uint8_t gesture_min_velocity; + + /**< At least this difference should be to send a gesture */ + uint8_t gesture_limit; + /**< Long press time in milliseconds*/ uint16_t long_press_time; @@ -133,10 +146,13 @@ typedef struct _lv_indev_proc_t other post-release event)*/ struct _lv_obj_t * last_pressed; /*The lastly pressed object*/ + lv_gesture_dir_t gesture_dir; + lv_point_t gesture_sum; /*Count the gesture pixels to check LV_INDEV_DEF_GESTURE_LIMIT*/ /*Flags*/ uint8_t drag_limit_out : 1; uint8_t drag_in_prog : 1; lv_drag_dir_t drag_dir : 3; + uint8_t gesture_sent : 1; } pointer; struct { /*Keypad data*/ From 8d71d87242b2ef1308f28762c105f7c2859a5b7e Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Fri, 17 Jan 2020 13:30:48 +0100 Subject: [PATCH 2/2] anim: reinitialize 'last_task_run' when the first anim is added after suspend --- src/lv_misc/lv_anim.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/lv_misc/lv_anim.c b/src/lv_misc/lv_anim.c index c5cd53946..5ce7d82da 100644 --- a/src/lv_misc/lv_anim.c +++ b/src/lv_misc/lv_anim.c @@ -93,6 +93,11 @@ void lv_anim_create(lv_anim_t * a) /* Do not let two animations for the same 'var' with the same 'fp'*/ if(a->exec_cb != NULL) lv_anim_del(a->var, a->exec_cb); /*fp == NULL would delete all animations of var*/ + /*If the list is empty the anim task was suspended and it's last run measure is invalid*/ + if(lv_ll_is_empty(&LV_GC_ROOT(_lv_anim_ll))) { + last_task_run = lv_tick_get(); + } + /*Add the new animation to the animation linked list*/ lv_anim_t * new_anim = lv_ll_ins_head(&LV_GC_ROOT(_lv_anim_ll)); LV_ASSERT_MEM(new_anim);