diff --git a/LVGL.Simulator/lvgl_mydemo/event/gl_dragable_event.c b/LVGL.Simulator/lvgl_mydemo/event/gl_dragable_event.c new file mode 100644 index 0000000..51c9d82 --- /dev/null +++ b/LVGL.Simulator/lvgl_mydemo/event/gl_dragable_event.c @@ -0,0 +1,102 @@ +/************************************************************************ + * FilePath : gl_dragable_event.c + * Author : GX.Duan + * Date : 2022-09-10 17:40:10 + * LastEditTime : 2022-09-10 17:41:17 + * LastEditors : ShallowGreen123 2608653986@qq.com + * Copyright (c): 2022 by GX.Duan, All Rights Reserved. + * Github : https://github.com/ShallowGreen123/lvgl_mydemo + ************************************************************************/ +#include "gl_dragable_event.h" + +static bool drag_flag = false; // if you has setten dragable and clicked event togather, use this flag to make sure not mix up them; +static int innerX = -1; +static int innerY = -1; +static void gl_obj_add_anim(lv_obj_t *obj, lv_anim_exec_xcb_t exec_cb, lv_anim_ready_cb_t rdy_cb, + uint16_t time, lv_coord_t start, lv_coord_t end, lv_anim_path_cb_t path_cb) { + lv_anim_t a; + + lv_anim_init(&a); + lv_anim_set_var(&a, obj); + lv_anim_set_exec_cb(&a, exec_cb); + if (rdy_cb != NULL) { + lv_anim_set_ready_cb(&a, rdy_cb); + } + lv_anim_set_time(&a, time); + + a.start_value = start; + a.end_value = end; + a.path_cb = path_cb; + a.playback_time = 0; + + lv_anim_start(&a); +} + +static void gl_drag_event_cb(lv_event_t *e) { + lv_obj_t *lvObj = lv_event_get_target(e); + lv_event_code_t code = lv_event_get_code(e); + + if (code == LV_EVENT_PRESSED) { + drag_flag = false; + lv_indev_t *indev = lv_indev_get_act(); + + if (lv_indev_get_type(indev) != LV_INDEV_TYPE_POINTER) return; + + lv_point_t p; + lv_indev_get_point(indev, &p); + innerX = p.x - lvObj->coords.x1; + innerY = p.y - lvObj->coords.y1; + } else if (code == LV_EVENT_PRESSING && innerY != -1 && innerX != -1) { + lv_point_t p; + lv_indev_t *indev = lv_indev_get_act(); + lv_coord_t tx, ty; + lv_coord_t w, h; + + if (lv_indev_get_type(indev) != LV_INDEV_TYPE_POINTER) { + return; + } + + lv_indev_get_point(indev, &p); + if (abs(p.x - lvObj->coords.x1 - innerX) + abs(p.y - lvObj->coords.y1 - innerY) > 3) { + drag_flag = true; + } + if (drag_flag) { + w = lv_obj_get_width(lvObj->parent) - lv_obj_get_width(lvObj); + h = lv_obj_get_height(lvObj->parent) - lv_obj_get_height(lvObj); + tx = p.x - innerX; + ty = p.y - innerY; + if (tx < 0) { + tx = 0; + } else if (tx >= w) { + tx = w - 1; + } + if (ty < 0) { + ty = 0; + } else if (ty >= h) { + ty = h - 1; + } + lv_obj_set_pos(lvObj, tx, ty); + } + } else if (code == LV_EVENT_RELEASED || code == LV_EVENT_PRESS_LOST) { + lv_coord_t cx = lvObj->coords.x1 + (lvObj->coords.x2 - lvObj->coords.x1) / 2; + lv_coord_t parent_cx = lvObj->parent->coords.x1 + (lvObj->parent->coords.x2 - lvObj->parent->coords.x1) / 2; + + if (cx < parent_cx) { + gl_obj_add_anim(lvObj, (lv_anim_exec_xcb_t)lv_obj_set_x, (lv_anim_ready_cb_t)e->user_data, 200, + lvObj->coords.x1, lvObj->parent->coords.x1, lv_anim_path_linear); + } else { + gl_obj_add_anim(lvObj, (lv_anim_exec_xcb_t)lv_obj_set_x, (lv_anim_ready_cb_t)e->user_data, 200, + lvObj->coords.x1, lvObj->parent->coords.x2 - lvObj->coords.x2 + lvObj->coords.x1, lv_anim_path_linear); + } + + innerX = -1; + innerY = -1; + } +} +bool gl_has_drag_flag(void) { + return drag_flag; +} + +void gl_clear_drag_flag(void) { + drag_flag = false; +} diff --git a/LVGL.Simulator/lvgl_mydemo/event/gl_dragable_event.h b/LVGL.Simulator/lvgl_mydemo/event/gl_dragable_event.h new file mode 100644 index 0000000..edc5c0b --- /dev/null +++ b/LVGL.Simulator/lvgl_mydemo/event/gl_dragable_event.h @@ -0,0 +1,30 @@ +/************************************************************************ + * FilePath : gl_dragable_event.h + * Author : GX.Duan + * Date : 2022-09-10 17:40:03 + * LastEditTime : 2022-09-10 17:40:52 + * LastEditors : ShallowGreen123 2608653986@qq.com + * Copyright (c): 2022 by GX.Duan, All Rights Reserved. + * Github : https://github.com/ShallowGreen123/lvgl_mydemo + ************************************************************************/ +/** + * @file gl_dragable_event.h + * + */ + +#ifndef GL_GRAGABLE_EVENT_H +#define GL_GRAGABLE_EVENT_H + +/********************* + * INCLUDES + *********************/ +#include "lvgl.h" + +/********************** + * GLOBAL PROTOTYPES + **********************/ +void gl_set_dragable(lv_obj_t *obj, lv_anim_ready_cb_t rdy_cb); +bool gl_has_drag_flag(void); +void gl_clear_drag_flag(void); + +#endif diff --git a/LVGL.Simulator/lvgl_mydemo/event/gl_velocity_tracker.c b/LVGL.Simulator/lvgl_mydemo/event/gl_velocity_tracker.c new file mode 100644 index 0000000..1dde6ca --- /dev/null +++ b/LVGL.Simulator/lvgl_mydemo/event/gl_velocity_tracker.c @@ -0,0 +1,209 @@ +/************************************************************************ + * FilePath : gl_velocity_tracker.c + * Author : GX.Duan + * Date : 2022-09-10 17:44:04 + * LastEditTime : 2022-09-10 17:46:29 + * LastEditors : ShallowGreen123 2608653986@qq.com + * Copyright (c): 2022 by GX.Duan, All Rights Reserved. + * Github : https://github.com/ShallowGreen123/lvgl_mydemo + ************************************************************************/ + +#define DEF_GL_VELOCITY_TRACKER_MODULE +#include "gl_velocity_tracker.h" +#include +#include "lvgl.h" + +static GL_VELOCITY_TRACKER_POINT_T Gl_VelocityTrackerPoints[DEF_GL_VELOCITY_TRACKER_POINTS_CNT]; + +// +static bool Gl_VelocityTrackerSolveX(GL_VELOCITY_TRACKER_POINT_T *points, uint32_t points_cnt, float *x_coeff) { + size_t count = points_cnt; + + // Solving y = a*x^2 + b*x + c + float sxi = 0, sxiyi = 0, syi = 0, sxi2 = 0, sxi3 = 0, sxi2yi = 0, sxi4 = 0; + float numerator; + float a, b, c; + float denominator; + float xi, yi, xi2, xi3, xi4, xiyi, xi2yi; + float Sxx, Sxy, Sxx2, Sx2y, Sx2x2; + size_t i; + + for (i = 0; i < count; i++) { + xi = (float)(points[i].Timestamp) * -0.001f; + yi = (float)(points[i].X); + xi2 = xi * xi; + xi3 = xi2 * xi; + xi4 = xi3 * xi; + xiyi = xi * yi; + xi2yi = xi2 * yi; + + sxi += xi; + sxi2 += xi2; + sxiyi += xiyi; + sxi2yi += xi2yi; + syi += yi; + sxi3 += xi3; + sxi4 += xi4; + } + Sxx = sxi2 - sxi * sxi / count; + Sxy = sxiyi - sxi * syi / count; + Sxx2 = sxi3 - sxi * sxi2 / count; + Sx2y = sxi2yi - sxi2 * syi / count; + Sx2x2 = sxi4 - sxi2 * sxi2 / count; + + denominator = Sxx * Sx2x2 - Sxx2 * Sxx2; + if (denominator == 0) { + return false; + } + // Compute a, b, c + numerator = Sx2y * Sxx - Sxy * Sxx2; + a = numerator / denominator; + numerator = Sxy * Sx2x2 - Sx2y * Sxx2; + b = numerator / denominator; + c = syi / count - b * sxi / count - a * sxi2 / count; + + *x_coeff = b; + return true; +} + +static bool Gl_VelocityTrackerSolveY(GL_VELOCITY_TRACKER_POINT_T *points, uint32_t points_cnt, float *y_coeff) { + size_t count = points_cnt; + + // Solving y = a*x^2 + b*x + c + float sxi = 0, sxiyi = 0, syi = 0, sxi2 = 0, sxi3 = 0, sxi2yi = 0, sxi4 = 0; + float numerator; + float a, b, c; + float denominator; + float xi, yi, xi2, xi3, xi4, xiyi, xi2yi; + float Sxx, Sxy, Sxx2, Sx2y, Sx2x2; + size_t i; + + for (i = 0; i < count; i++) { + xi = (float)(points[i].Timestamp) * -0.001f; + yi = (float)(points[i].Y); + xi2 = xi * xi; + xi3 = xi2 * xi; + xi4 = xi3 * xi; + xiyi = xi * yi; + xi2yi = xi2 * yi; + + sxi += xi; + sxi2 += xi2; + sxiyi += xiyi; + sxi2yi += xi2yi; + syi += yi; + sxi3 += xi3; + sxi4 += xi4; + } + Sxx = sxi2 - sxi * sxi / count; + Sxy = sxiyi - sxi * syi / count; + Sxx2 = sxi3 - sxi * sxi2 / count; + Sx2y = sxi2yi - sxi2 * syi / count; + Sx2x2 = sxi4 - sxi2 * sxi2 / count; + + denominator = Sxx * Sx2x2 - Sxx2 * Sxx2; + if (denominator == 0) { + LV_LOG_WARN("[VelocityTracker] Denominator zero\n"); + return false; + } + // Compute a, b, c + numerator = Sx2y * Sxx - Sxy * Sxx2; + a = numerator / denominator; + numerator = Sxy * Sx2x2 - Sx2y * Sxx2; + b = numerator / denominator; + c = syi / count - b * sxi / count - a * sxi2 / count; + + *y_coeff = b; + return true; +} + +bool Gl_VelocityTrackerSolve(GL_VELOCITY_TRACKER_HANDLE_T *handle, uint32_t timestamp, float *x_coeff, float *y_coeff) { + GL_VELOCITY_TRACKER_POINT_T *point; + uint32_t cnt; + uint32_t valid_cnt; + uint32_t time_diff; + uint32_t i; + int32_t last_x; + int32_t last_y; + + memset(Gl_VelocityTrackerPoints, 0, sizeof(Gl_VelocityTrackerPoints)); + + if (handle->Wp >= handle->Rp) { + cnt = handle->Wp - handle->Rp; + } else { + cnt = handle->Wp - handle->Rp + DEF_GL_VELOCITY_TRACKER_POINTS_CNT; + } + if (cnt < 4) { + LV_LOG_WARN("[VelocityTracker] Points not enough %u\n", cnt); + return false; + } + + valid_cnt = 0; + for (i = 0; i < cnt; i++) { + point = &handle->Points[(handle->Rp + i) % DEF_GL_VELOCITY_TRACKER_POINTS_CNT]; + time_diff = timestamp - point->Timestamp; + // LV_LOG_TRACE("[VelocityTracker] Point[%u] = (%u, %d, %d)\n", i, point->Timestamp, point->X, point->Y); + if (time_diff > DEF_GL_VELOCITY_TRACKER_HORIZON_MS) { + last_x = point->X; + last_y = point->Y; + continue; + } + if (i > 0) { + Gl_VelocityTrackerPoints[valid_cnt].Timestamp = time_diff; + Gl_VelocityTrackerPoints.X = point->X - last_x; + Gl_VelocityTrackerPoints[valid_cnt].Y = point->Y - last_y; + valid_cnt++; + } + last_x = point->X; + last_y = point->Y; + } + + if (valid_cnt < 3) { + LV_LOG_WARN("[VelocityTracker] Valid points not enough %u\n", valid_cnt); + return false; + } + if (Gl_VelocityTrackerSolveX(Gl_VelocityTrackerPoints, valid_cnt, x_coeff) + && Gl_VelocityTrackerSolveY(Gl_VelocityTrackerPoints, valid_cnt, y_coeff)) { + return true; + } + + return false; +} + +void Gl_VelocityTrackerInit(GL_VELOCITY_TRACKER_HANDLE_T *handle) { + Gl_VelocityTrackerReset(handle); +} + +void Gl_VelocityTrackerReset(GL_VELOCITY_TRACKER_HANDLE_T *handle) { + memset(handle, 0, sizeof(GL_VELOCITY_TRACKER_HANDLE_T)); +} + +void Gl_VelocityTrackerAddPoint(GL_VELOCITY_TRACKER_HANDLE_T *handle, uint32_t timestamp, int32_t x, int32_t y) { + GL_VELOCITY_TRACKER_POINT_T *point = &handle->Points[handle->Wp]; + + point->Timestamp = timestamp; + point->X = x; + point->Y = y; + handle->Wp = (handle->Wp + 1) % DEF_GL_VELOCITY_TRACKER_POINTS_CNT; + if (handle->Wp == handle->Rp) { + handle->Rp = (handle->Rp + 1) % DEF_GL_VELOCITY_TRACKER_POINTS_CNT; + } +} +bool Gl_VelocityTrackerCalc(GL_VELOCITY_TRACKER_HANDLE_T *handle, uint32_t timestamp) { + float x_coeff = 0.0f; + float y_coeff = 0.0f; + bool ret = Gl_VelocityTrackerSolve(handle, timestamp, &x_coeff, &y_coeff); + if (ret) { + handle->Vx = x_coeff; + handle->Vy = y_coeff; + } + return ret; +} + +float Gl_VelocityTrackerGetVx(GL_VELOCITY_TRACKER_HANDLE_T *handle) { + return handle->Vx; +} + +float Gl_VelocityTrackerGetVy(GL_VELOCITY_TRACKER_HANDLE_T *handle) { + return handle->Vy; +} diff --git a/LVGL.Simulator/lvgl_mydemo/event/gl_velocity_tracker.h b/LVGL.Simulator/lvgl_mydemo/event/gl_velocity_tracker.h new file mode 100644 index 0000000..49e19af --- /dev/null +++ b/LVGL.Simulator/lvgl_mydemo/event/gl_velocity_tracker.h @@ -0,0 +1,51 @@ +/************************************************************************ + * FilePath : gl_velocity_tracker.h + * Author : GX.Duan + * Date : 2022-09-10 17:44:10 + * LastEditTime : 2022-09-10 17:44:41 + * LastEditors : ShallowGreen123 2608653986@qq.com + * Copyright (c): 2022 by GX.Duan, All Rights Reserved. + * Github : https://github.com/ShallowGreen123/lvgl_mydemo + ************************************************************************/ +#ifndef __GL_VELOCITY_TRACKER_H__ +#define __GL_VELOCITY_TRACKER_H__ +/* +********************************************************************************************************* +* INCLUDE HEADER FILES +********************************************************************************************************* +*/ +#include +#include +#include +#ifdef DEF_GL_VELOCITY_TRACKER_MODULE +#define DEF_GL_VELOCITY_TRACKER_EXT +#else +#define DEF_GL_VELOCITY_TRACKER_EXT extern +#endif +/* +********************************************************************************************************* +* DEFAULT CONFIGURATION +********************************************************************************************************* +*/ +#define DEF_GL_VELOCITY_TRACKER_POINTS_CNT 20 +#define DEF_GL_VELOCITY_TRACKER_HORIZON_MS 100 +typedef struct gl_velocity_tracker_point_t { + uint32_t Timestamp; + int32_t X; + int32_t Y; +} GL_VELOCITY_TRACKER_POINT_T; + +typedef struct gl_velocity_tracker_handle_t { + GL_VELOCITY_TRACKER_POINT_T Points[DEF_GL_VELOCITY_TRACKER_POINTS_CNT]; + uint8_t Rp; + uint8_t Wp; + float Vx; // px/s + float Vy; // px/s +} GL_VELOCITY_TRACKER_HANDLE_T; +DEF_GL_VELOCITY_TRACKER_EXT void Gl_VelocityTrackerInit(GL_VELOCITY_TRACKER_HANDLE_T *handle); +DEF_GL_VELOCITY_TRACKER_EXT void Gl_VelocityTrackerReset(GL_VELOCITY_TRACKER_HANDLE_T *handle); +DEF_GL_VELOCITY_TRACKER_EXT void Gl_VelocityTrackerAddPoint(GL_VELOCITY_TRACKER_HANDLE_T *handle, uint32_t timestamp, int32_t x, int32_t y); +DEF_GL_VELOCITY_TRACKER_EXT bool Gl_VelocityTrackerCalc(GL_VELOCITY_TRACKER_HANDLE_T *handle, uint32_t timestamp); +DEF_GL_VELOCITY_TRACKER_EXT float Gl_VelocityTrackerGetVx(GL_VELOCITY_TRACKER_HANDLE_T *handle); +DEF_GL_VELOCITY_TRACKER_EXT float Gl_VelocityTrackerGetVy(GL_VELOCITY_TRACKER_HANDLE_T *handle); +#endif /* __GL_VELOCITY_TRACKER_H__ */ \ No newline at end of file