mirror of
https://github.com/lvgl/lvgl.git
synced 2025-01-21 06:53:01 +08:00
fix(btnmatrix) improve focusing if used in groups
This commit is contained in:
parent
3c39c39c9d
commit
e1e45b1de3
@ -83,7 +83,7 @@ lv_res_t lv_event_send(lv_obj_t * obj, lv_event_code_t event_code, void * param)
|
|||||||
lv_res_t lv_obj_event_base(const lv_obj_class_t * class_p, lv_event_t * e)
|
lv_res_t lv_obj_event_base(const lv_obj_class_t * class_p, lv_event_t * e)
|
||||||
{
|
{
|
||||||
const lv_obj_class_t * base;
|
const lv_obj_class_t * base;
|
||||||
if(class_p == NULL) base = e->target->class_p;
|
if(class_p == NULL) base = e->current_target->class_p;
|
||||||
else base = class_p->base_class;
|
else base = class_p->base_class;
|
||||||
|
|
||||||
/*Find a base in which Call the ancestor's event handler_cb is set*/
|
/*Find a base in which Call the ancestor's event handler_cb is set*/
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include "lv_group.h"
|
#include "lv_group.h"
|
||||||
#include "../misc/lv_gc.h"
|
#include "../misc/lv_gc.h"
|
||||||
#include "../core/lv_obj.h"
|
#include "../core/lv_obj.h"
|
||||||
|
#include "../core/lv_indev.h"
|
||||||
|
|
||||||
/*********************
|
/*********************
|
||||||
* DEFINES
|
* DEFINES
|
||||||
@ -26,6 +27,7 @@
|
|||||||
static void focus_next_core(lv_group_t * group, void * (*begin)(const lv_ll_t *),
|
static void focus_next_core(lv_group_t * group, void * (*begin)(const lv_ll_t *),
|
||||||
void * (*move)(const lv_ll_t *, const void *));
|
void * (*move)(const lv_ll_t *, const void *));
|
||||||
static void lv_group_refocus(lv_group_t * g);
|
static void lv_group_refocus(lv_group_t * g);
|
||||||
|
static lv_indev_t * get_indev(const lv_group_t * g);
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
* STATIC VARIABLES
|
* STATIC VARIABLES
|
||||||
@ -70,7 +72,7 @@ void lv_group_del(lv_group_t * group)
|
|||||||
{
|
{
|
||||||
/*Defocus the currently focused object*/
|
/*Defocus the currently focused object*/
|
||||||
if(group->obj_focus != NULL) {
|
if(group->obj_focus != NULL) {
|
||||||
lv_event_send(*group->obj_focus, LV_EVENT_DEFOCUSED, NULL);
|
lv_event_send(*group->obj_focus, LV_EVENT_DEFOCUSED, get_indev(group));
|
||||||
lv_obj_invalidate(*group->obj_focus);
|
lv_obj_invalidate(*group->obj_focus);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,7 +152,7 @@ void lv_group_remove_obj(lv_obj_t * obj)
|
|||||||
|
|
||||||
/*If this is the only object in the group then focus to nothing.*/
|
/*If this is the only object in the group then focus to nothing.*/
|
||||||
if(_lv_ll_get_head(&g->obj_ll) == g->obj_focus && _lv_ll_get_tail(&g->obj_ll) == g->obj_focus) {
|
if(_lv_ll_get_head(&g->obj_ll) == g->obj_focus && _lv_ll_get_tail(&g->obj_ll) == g->obj_focus) {
|
||||||
lv_event_send(*g->obj_focus, LV_EVENT_DEFOCUSED, NULL);
|
lv_event_send(*g->obj_focus, LV_EVENT_DEFOCUSED, get_indev(g));
|
||||||
}
|
}
|
||||||
/*If there more objects in the group then focus to the next/prev object*/
|
/*If there more objects in the group then focus to the next/prev object*/
|
||||||
else {
|
else {
|
||||||
@ -182,7 +184,7 @@ void lv_group_remove_all_objs(lv_group_t * group)
|
|||||||
{
|
{
|
||||||
/*Defocus the currently focused object*/
|
/*Defocus the currently focused object*/
|
||||||
if(group->obj_focus != NULL) {
|
if(group->obj_focus != NULL) {
|
||||||
lv_event_send(*group->obj_focus, LV_EVENT_DEFOCUSED, NULL);
|
lv_event_send(*group->obj_focus, LV_EVENT_DEFOCUSED, get_indev(group));
|
||||||
lv_obj_invalidate(*group->obj_focus);
|
lv_obj_invalidate(*group->obj_focus);
|
||||||
group->obj_focus = NULL;
|
group->obj_focus = NULL;
|
||||||
}
|
}
|
||||||
@ -213,7 +215,7 @@ void lv_group_focus_obj(lv_obj_t * obj)
|
|||||||
_LV_LL_READ(&g->obj_ll, i) {
|
_LV_LL_READ(&g->obj_ll, i) {
|
||||||
if(*i == obj) {
|
if(*i == obj) {
|
||||||
if(g->obj_focus != NULL) {
|
if(g->obj_focus != NULL) {
|
||||||
lv_res_t res = lv_event_send(*g->obj_focus, LV_EVENT_DEFOCUSED, NULL);
|
lv_res_t res = lv_event_send(*g->obj_focus, LV_EVENT_DEFOCUSED, get_indev(g));
|
||||||
if(res != LV_RES_OK) return;
|
if(res != LV_RES_OK) return;
|
||||||
lv_obj_invalidate(*g->obj_focus);
|
lv_obj_invalidate(*g->obj_focus);
|
||||||
}
|
}
|
||||||
@ -222,7 +224,7 @@ void lv_group_focus_obj(lv_obj_t * obj)
|
|||||||
|
|
||||||
if(g->obj_focus != NULL) {
|
if(g->obj_focus != NULL) {
|
||||||
if(g->focus_cb) g->focus_cb(g);
|
if(g->focus_cb) g->focus_cb(g);
|
||||||
lv_res_t res = lv_event_send(*g->obj_focus, LV_EVENT_FOCUSED, NULL);
|
lv_res_t res = lv_event_send(*g->obj_focus, LV_EVENT_FOCUSED, get_indev(g));
|
||||||
if(res != LV_RES_OK) return;
|
if(res != LV_RES_OK) return;
|
||||||
lv_obj_invalidate(*g->obj_focus);
|
lv_obj_invalidate(*g->obj_focus);
|
||||||
}
|
}
|
||||||
@ -243,10 +245,8 @@ void lv_group_focus_prev(lv_group_t * group)
|
|||||||
|
|
||||||
void lv_group_focus_freeze(lv_group_t * group, bool en)
|
void lv_group_focus_freeze(lv_group_t * group, bool en)
|
||||||
{
|
{
|
||||||
if(en == false)
|
if(en == false) group->frozen = 0;
|
||||||
group->frozen = 0;
|
else group->frozen = 1;
|
||||||
else
|
|
||||||
group->frozen = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lv_res_t lv_group_send_data(lv_group_t * group, uint32_t c)
|
lv_res_t lv_group_send_data(lv_group_t * group, uint32_t c)
|
||||||
@ -278,7 +278,7 @@ void lv_group_set_editing(lv_group_t * group, bool edit)
|
|||||||
lv_obj_t * focused = lv_group_get_focused(group);
|
lv_obj_t * focused = lv_group_get_focused(group);
|
||||||
|
|
||||||
if(focused) {
|
if(focused) {
|
||||||
lv_res_t res = lv_event_send(*group->obj_focus, LV_EVENT_FOCUSED, NULL);
|
lv_res_t res = lv_event_send(*group->obj_focus, LV_EVENT_FOCUSED, get_indev(group));
|
||||||
if(res != LV_RES_OK) return;
|
if(res != LV_RES_OK) return;
|
||||||
|
|
||||||
lv_obj_invalidate(focused);
|
lv_obj_invalidate(focused);
|
||||||
@ -387,14 +387,14 @@ static void focus_next_core(lv_group_t * group, void * (*begin)(const lv_ll_t *)
|
|||||||
if(obj_next == group->obj_focus) return; /*There's only one visible object and it's already focused*/
|
if(obj_next == group->obj_focus) return; /*There's only one visible object and it's already focused*/
|
||||||
|
|
||||||
if(group->obj_focus) {
|
if(group->obj_focus) {
|
||||||
lv_res_t res = lv_event_send(*group->obj_focus, LV_EVENT_DEFOCUSED, NULL);
|
lv_res_t res = lv_event_send(*group->obj_focus, LV_EVENT_DEFOCUSED, get_indev(group));
|
||||||
if(res != LV_RES_OK) return;
|
if(res != LV_RES_OK) return;
|
||||||
lv_obj_invalidate(*group->obj_focus);
|
lv_obj_invalidate(*group->obj_focus);
|
||||||
}
|
}
|
||||||
|
|
||||||
group->obj_focus = obj_next;
|
group->obj_focus = obj_next;
|
||||||
|
|
||||||
lv_res_t res = lv_event_send(*group->obj_focus, LV_EVENT_FOCUSED, NULL);
|
lv_res_t res = lv_event_send(*group->obj_focus, LV_EVENT_FOCUSED, get_indev(group));
|
||||||
if(res != LV_RES_OK) return;
|
if(res != LV_RES_OK) return;
|
||||||
|
|
||||||
lv_obj_invalidate(*group->obj_focus);
|
lv_obj_invalidate(*group->obj_focus);
|
||||||
@ -402,3 +402,33 @@ static void focus_next_core(lv_group_t * group, void * (*begin)(const lv_ll_t *)
|
|||||||
if(group->focus_cb) group->focus_cb(group);
|
if(group->focus_cb) group->focus_cb(group);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find an indev preferably with KEYPAD or ENCOEDR type that uses the given group.
|
||||||
|
* In other words, find an indev, that is related to the given group.
|
||||||
|
* In the worst case simply return the latest indev
|
||||||
|
* @param g a group the find in the indevs
|
||||||
|
* @return the suggested indev
|
||||||
|
*/
|
||||||
|
static lv_indev_t * get_indev(const lv_group_t * g)
|
||||||
|
{
|
||||||
|
lv_indev_t * indev_encoder = NULL;
|
||||||
|
lv_indev_t * indev_group = NULL;
|
||||||
|
lv_indev_t * indev = lv_indev_get_next(NULL);
|
||||||
|
while(indev) {
|
||||||
|
lv_indev_type_t indev_type = lv_indev_get_type(indev);
|
||||||
|
if(indev->group == g) {
|
||||||
|
/*Prefer KEYPAD*/
|
||||||
|
if(indev_type == LV_INDEV_TYPE_KEYPAD) return indev;
|
||||||
|
if(indev_type == LV_INDEV_TYPE_ENCODER) indev_encoder = indev;
|
||||||
|
indev_group = indev;
|
||||||
|
}
|
||||||
|
indev = lv_indev_get_next(indev);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(indev_encoder) return indev_encoder;
|
||||||
|
if(indev_group) return indev_group;
|
||||||
|
|
||||||
|
/*In lack of a better option use the first input device. (It can be NULL if there is no input device)*/
|
||||||
|
return lv_indev_get_next(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -662,7 +662,9 @@ static void lv_obj_event(const lv_obj_class_t * class_p, lv_event_t * e)
|
|||||||
bool editing = false;
|
bool editing = false;
|
||||||
editing = lv_group_get_editing(lv_obj_get_group(obj));
|
editing = lv_group_get_editing(lv_obj_get_group(obj));
|
||||||
lv_state_t state = LV_STATE_FOCUSED;
|
lv_state_t state = LV_STATE_FOCUSED;
|
||||||
lv_indev_type_t indev_type = lv_indev_get_type(lv_indev_get_act());
|
|
||||||
|
lv_indev_t * indev = lv_event_get_param(e);
|
||||||
|
lv_indev_type_t indev_type = lv_indev_get_type(indev);
|
||||||
if(indev_type == LV_INDEV_TYPE_KEYPAD || indev_type == LV_INDEV_TYPE_ENCODER) state |= LV_STATE_FOCUS_KEY;
|
if(indev_type == LV_INDEV_TYPE_KEYPAD || indev_type == LV_INDEV_TYPE_ENCODER) state |= LV_STATE_FOCUS_KEY;
|
||||||
if(editing) {
|
if(editing) {
|
||||||
state |= LV_STATE_EDITED;
|
state |= LV_STATE_EDITED;
|
||||||
|
@ -663,10 +663,12 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj)
|
|||||||
if(lv_obj_check_type(lv_obj_get_parent(obj), &lv_msgbox_class)) {
|
if(lv_obj_check_type(lv_obj_get_parent(obj), &lv_msgbox_class)) {
|
||||||
lv_obj_add_style(obj, &styles->msgbox_btns_bg, 0);
|
lv_obj_add_style(obj, &styles->msgbox_btns_bg, 0);
|
||||||
lv_obj_add_style(obj, &styles->pad_gap, 0);
|
lv_obj_add_style(obj, &styles->pad_gap, 0);
|
||||||
|
lv_obj_add_style(obj, &styles->pad_tiny, 0);
|
||||||
lv_obj_add_style(obj, &styles->btn, LV_PART_ITEMS);
|
lv_obj_add_style(obj, &styles->btn, LV_PART_ITEMS);
|
||||||
lv_obj_add_style(obj, &styles->pressed, LV_PART_ITEMS | LV_STATE_PRESSED);
|
lv_obj_add_style(obj, &styles->pressed, LV_PART_ITEMS | LV_STATE_PRESSED);
|
||||||
lv_obj_add_style(obj, &styles->bg_color_primary, LV_PART_ITEMS | LV_STATE_CHECKED);
|
lv_obj_add_style(obj, &styles->bg_color_primary, LV_PART_ITEMS | LV_STATE_CHECKED);
|
||||||
lv_obj_add_style(obj, &styles->outline_primary, LV_PART_ITEMS | LV_STATE_FOCUS_KEY);
|
lv_obj_add_style(obj, &styles->bg_color_primary_muted, LV_PART_ITEMS | LV_STATE_FOCUS_KEY);
|
||||||
|
lv_obj_add_style(obj, &styles->bg_color_secondary_muted, LV_PART_ITEMS | LV_STATE_EDITED);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -500,7 +500,7 @@ static void lv_btnmatrix_event(const lv_obj_class_t * class_p, lv_event_t * e)
|
|||||||
btnm->btn_id_sel = LV_BTNMATRIX_BTN_NONE;
|
btnm->btn_id_sel = LV_BTNMATRIX_BTN_NONE;
|
||||||
}
|
}
|
||||||
else if(code == LV_EVENT_FOCUSED) {
|
else if(code == LV_EVENT_FOCUSED) {
|
||||||
lv_indev_t * indev = lv_indev_get_act();
|
lv_indev_t * indev = lv_event_get_param(e);
|
||||||
lv_indev_type_t indev_type = lv_indev_get_type(indev);
|
lv_indev_type_t indev_type = lv_indev_get_type(indev);
|
||||||
|
|
||||||
/*If not focused by an input device assume the last input device*/
|
/*If not focused by an input device assume the last input device*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user