feat: Add events

This commit is contained in:
ShallowGreen123
2022-09-10 17:57:47 +08:00
parent 39517d62b2
commit e39d9e53b8
4 changed files with 392 additions and 0 deletions

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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 <string.h>
#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;
}

View File

@@ -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 <stdint.h>
#include <stdbool.h>
#include <math.h>
#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__ */