1
0
mirror of https://github.com/lvgl/lvgl.git synced 2025-01-28 07:03:00 +08:00

feat(arc) add support to LV_OBJ_FLAG_ADV_HITTEST

This commit is contained in:
Gabor Kiss-Vamosi 2021-10-19 12:52:27 +02:00
parent c61c371ee9
commit dfa4f5cff5
2 changed files with 42 additions and 1 deletions

View File

@ -58,6 +58,13 @@ lv_obj_remove_style(arc, NULL, LV_PART_KNOB);
lv_obj_clear_flag(arc, LV_OBJ_FLAG_CLICKABLE);
```
### Advanced hit test
If the `LV_OBJ_FLAG_ADV_HITTEST` flag is enabled the arc can be clicked through in the middle. Clicks are recognized only on the ring of the background arc. `lv_obj_set_ext_click_size()` makes the sensitive area larger inside and outside with the given number of pixels.
## Events
- `LV_EVENT_VALUE_CHANGED` sent when the arc is pressed/dragged to set a new value.
- `LV_EVENT_DRAW_PART_BEGIN` and `LV_EVENT_DRAW_PART_END` are sent with the following types:

View File

@ -379,7 +379,16 @@ static void lv_arc_event(const lv_obj_class_t * class_p, lv_event_t * e)
if(arc->dragging == false) {
lv_coord_t indic_width = lv_obj_get_style_arc_width(obj, LV_PART_INDICATOR);
r -= indic_width;
r -= r / 2; /*Add some more sensitive area*/
/*Add some more sensitive area if there is no advanced git testing.
* (Advanced hit testing is more precise)*/
if(lv_obj_has_flag(obj, LV_OBJ_FLAG_ADV_HITTEST)) {
r -= indic_width;
} else {
r -= LV_MAX(r / 4, indic_width);
}
if(r < 1) r = 1;
if(p.x * p.x + p.y * p.y > r * r) {
arc->dragging = true;
arc->last_tick = lv_tick_get(); /*Capture timestamp at dragging start*/
@ -488,6 +497,31 @@ static void lv_arc_event(const lv_obj_class_t * class_p, lv_event_t * e)
if(res != LV_RES_OK) return;
}
}
else if(code == LV_EVENT_HIT_TEST) {
lv_hit_test_info_t * info = lv_event_get_param(e);;
lv_point_t p;
lv_coord_t r;
get_center(obj, &p, &r);
lv_coord_t ext_click_area = 0;
if(obj->spec_attr) ext_click_area = obj->spec_attr->ext_click_pad;
lv_coord_t w = lv_obj_get_style_arc_width(obj, LV_PART_MAIN);
r -= w + ext_click_area;
lv_area_t a;
/*Invalid if clicked inside*/
lv_area_set(&a, p.x - r, p.y - r, p.x + r, p.y + r);
if(_lv_area_is_point_on(&a, info->point, LV_RADIUS_CIRCLE)) {
info->res = false;
return;
}
/*Valid if no clicked outside*/
lv_area_increase(&a, w + ext_click_area * 2, w + ext_click_area * 2);
info->res = _lv_area_is_point_on(&a, info->point, LV_RADIUS_CIRCLE);
}
else if(code == LV_EVENT_REFR_EXT_DRAW_SIZE) {
lv_coord_t bg_left = lv_obj_get_style_pad_left(obj, LV_PART_MAIN);
lv_coord_t bg_right = lv_obj_get_style_pad_right(obj, LV_PART_MAIN);