mirror of
https://github.com/lvgl/lvgl.git
synced 2025-01-28 07:03:00 +08:00
rotary: minor fixes on dragging
This commit is contained in:
parent
3af55796d9
commit
3aa35a77cb
@ -232,19 +232,29 @@ int64_t _lv_pow(int64_t base, int8_t exp)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the mapped of a number given an imput and output range
|
||||
* Get the mapped of a number given an input and output range
|
||||
* @param x integer which mapped value should be calculated
|
||||
* @param min_in min input range
|
||||
* @param max_in max input range
|
||||
* @param in min output range
|
||||
* @param out max output range
|
||||
* @param min_out max output range
|
||||
* @param max_out max output range
|
||||
* @return the mapped number
|
||||
*/
|
||||
LV_ATTRIBUTE_FAST_MEM int16_t _lv_map(int16_t x, int16_t min_in, int16_t max_in, int16_t min, int16_t max)
|
||||
int16_t _lv_map(int32_t x, int32_t min_in, int32_t max_in, int32_t min_out, int32_t max_out)
|
||||
{
|
||||
int32_t slope = ((int32_t)(max - min) * 10000) / (int32_t)(max_in - min_in); /** times 10000 to avoid rounding errors*/
|
||||
int32_t bias = (int32_t)(min * 10000) - slope * min_in;
|
||||
|
||||
return (bias + slope * x) / 10000;
|
||||
if(x <= min_in) return min_out;
|
||||
if(x >= max_in) return max_out;
|
||||
|
||||
/* The equation should be:
|
||||
* ((x - min_in) / delta in) * delta_out + min_out
|
||||
* To avoid rounding error reorder the operations:
|
||||
* (((x - min_in) * delta_out) / delta in) + min_out
|
||||
*/
|
||||
|
||||
int32_t delta_in = max_in - min_in;
|
||||
int32_t delta_out = max_out - min_out;
|
||||
|
||||
return ((x - min_in) * delta_out) / delta_in + min_out;
|
||||
}
|
||||
|
||||
/**********************
|
||||
|
@ -113,14 +113,15 @@ LV_ATTRIBUTE_FAST_MEM void _lv_sqrt(uint32_t x, lv_sqrt_res_t * q, uint32_t mask
|
||||
int64_t _lv_pow(int64_t base, int8_t exp);
|
||||
|
||||
/**
|
||||
* Get the mapped of a number given an imput and output range
|
||||
* Get the mapped of a number given an input and output range
|
||||
* @param x integer which mapped value should be calculated
|
||||
* @param min_in min input range
|
||||
* @param max_in max input range
|
||||
* @param in min output range
|
||||
* @param out max output range
|
||||
* @param min_out max output range
|
||||
* @param max_out max output range
|
||||
* @return the mapped number
|
||||
*/
|
||||
LV_ATTRIBUTE_FAST_MEM int16_t _lv_map(int16_t x, int16_t min_in, int16_t max_in, int16_t min, int16_t max);
|
||||
int16_t _lv_map(int32_t x, int32_t min_in, int32_t max_in, int32_t min, int32_t max);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
|
@ -207,8 +207,8 @@ bool lv_rotary_set_value(lv_obj_t * rotary, int16_t value, lv_anim_enable_t anim
|
||||
case LV_ROTARY_TYPE_REVERSE:
|
||||
lv_arc_set_start_angle(
|
||||
rotary,
|
||||
_lv_map(ext->cur_value, ext->max_value, ext->min_value,
|
||||
bg_end, ext->arc.bg_angle_start)
|
||||
_lv_map(ext->cur_value, ext->min_value, ext->max_value,
|
||||
ext->arc.bg_angle_start, bg_end)
|
||||
);
|
||||
break;
|
||||
default: /** LV_ROTARY_TYPE_NORMAL*/
|
||||
@ -403,51 +403,48 @@ static lv_res_t lv_rotary_signal(lv_obj_t * rotary, lv_signal_t sign, void * par
|
||||
|
||||
lv_rotary_ext_t * ext = lv_obj_get_ext_attr(rotary);
|
||||
|
||||
if(sign == LV_SIGNAL_PRESSED) {
|
||||
lv_indev_get_point(lv_indev_get_act(), &ext->last_press_point);
|
||||
ext->dragging = true;
|
||||
}
|
||||
else if(sign == LV_SIGNAL_PRESSING) {
|
||||
if(sign == LV_SIGNAL_PRESSING) {
|
||||
lv_indev_t * indev = lv_indev_get_act();
|
||||
if(indev == NULL) return res;
|
||||
|
||||
/*Handle only pointers here*/
|
||||
lv_indev_type_t indev_type = lv_indev_get_type(indev);
|
||||
if(indev_type != LV_INDEV_TYPE_POINTER) return res;
|
||||
|
||||
lv_point_t p;
|
||||
if(indev_type == LV_INDEV_TYPE_ENCODER || indev_type == LV_INDEV_TYPE_KEYPAD) {
|
||||
p.x = rotary->coords.x1 + lv_obj_get_width(rotary) / 2;
|
||||
p.y = rotary->coords.y1 + lv_obj_get_height(rotary) / 2;
|
||||
}
|
||||
else {
|
||||
lv_indev_get_point(indev, &p);
|
||||
lv_indev_get_point(indev, &p);
|
||||
|
||||
/*Make point relative to the rotary's center*/
|
||||
lv_coord_t w_half = lv_obj_get_width(rotary) / 2;
|
||||
p.x -= rotary->coords.x1 + w_half;
|
||||
p.y -= rotary->coords.y1 + w_half;
|
||||
|
||||
/*Enter dragging mode if pressed out of the knob*/
|
||||
if(ext->dragging == false) {
|
||||
lv_coord_t r_in = lv_area_get_width(&ext->knob_area) / 2;
|
||||
|
||||
if(p.x * p.x + p.y * p.y > r_in * r_in) {
|
||||
ext->dragging = true;
|
||||
}
|
||||
}
|
||||
|
||||
ext->last_press_point.x = p.x;
|
||||
ext->last_press_point.y = p.y;
|
||||
/*It must be in "dragging" mode to turn the arc*/
|
||||
if(ext->dragging == false) return res;
|
||||
|
||||
/*Make point 0 relative to the rotary*/
|
||||
p.x -= rotary->coords.x1;
|
||||
p.y -= rotary->coords.y1;
|
||||
|
||||
/*Ignore pressing in the inner area*/
|
||||
/*Calculate the angle of the pressed point*/
|
||||
int16_t angle;
|
||||
lv_coord_t r_in = lv_area_get_width(&ext->knob_area) / 2;
|
||||
|
||||
p.x -= r_in;
|
||||
p.y -= r_in;
|
||||
if(p.x * p.x + p.y * p.y < r_in * r_in) {
|
||||
return res; /*Set the angle only if pressed on the ring*/
|
||||
}
|
||||
|
||||
int16_t bg_zero, bg_end = ext->arc.bg_angle_end;
|
||||
int16_t bg_end = ext->arc.bg_angle_end;
|
||||
if (ext->arc.bg_angle_end < ext->arc.bg_angle_start) {
|
||||
bg_end = ext->arc.bg_angle_end + 360;
|
||||
}
|
||||
bg_zero = (((ext->arc.bg_angle_start + bg_end) / 2) + 180) % 360;
|
||||
|
||||
angle = (_lv_atan2(p.x, p.y) + bg_zero) % 360;
|
||||
if (bg_end > 360 && angle < ext->arc.bg_angle_start) angle += 360;
|
||||
angle = 360 - _lv_atan2(p.x, p.y) + 90; /*Some transformation is required*/
|
||||
if(angle < ext->arc.bg_angle_start) angle = ext->arc.bg_angle_start;
|
||||
if(angle > bg_end) angle = bg_end;
|
||||
|
||||
int16_t new_value = _lv_map(angle, ext->arc.bg_angle_start, bg_end, ext->max_value, ext->min_value);
|
||||
int16_t new_value = _lv_map(angle, ext->arc.bg_angle_start, bg_end, ext->min_value, ext->max_value);
|
||||
|
||||
/*Set the new value if it's larger than the threshold*/
|
||||
if (LV_MATH_ABS(ext->cur_value - new_value) < ext->threshold) {
|
||||
if (lv_rotary_set_value(rotary, new_value, LV_ANIM_OFF)) {
|
||||
res = lv_event_send(rotary, LV_EVENT_VALUE_CHANGED, NULL);
|
||||
|
@ -72,10 +72,7 @@ typedef struct {
|
||||
int16_t max_value; /*Maximum value of the rotary*/
|
||||
int16_t sensitivity; /*Control signal increment multiplier of the rotary*/
|
||||
int16_t threshold; /*Drag increment threshold of the rotary*/
|
||||
lv_point_t last_press_point; /*Last press point of the rotary*/
|
||||
uint16_t last_press_angle; /*Last press angle of the rotary*/
|
||||
uint16_t dragging :1;
|
||||
|
||||
} lv_rotary_ext_t;
|
||||
|
||||
/** Built-in styles of rotary*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user