indev.c: indev_obj_focused initial commit to correctly reset indev query when a callback changed the currently focused object and deletes the old one. Only tested on keypad indev, other indev types may need a similar fix re-using the indev_obj_focused variable

This commit is contained in:
Brian Pugh
2019-05-19 10:56:34 -07:00
parent f28efdd9f3
commit 7bbe91512a
3 changed files with 128 additions and 111 deletions

View File

@@ -47,10 +47,23 @@ static void indev_drag_throw(lv_indev_proc_t * proc);
* STATIC VARIABLES * STATIC VARIABLES
**********************/ **********************/
static lv_indev_t * indev_act; static lv_indev_t * indev_act;
#if LV_USE_GROUP
static lv_obj_t * indev_obj_focused = NULL;
#endif
/********************** /**********************
* MACROS * MACROS
**********************/ **********************/
/* Return if the lv_indev_proc_t proc reset_query is true, indicating that the object may have been deleted*/
#if LV_USE_GROUP
#define CHECK_INDEV_RESET(proc) \
if((proc).reset_query) { \
indev_obj_focused = NULL; \
return; \
} while(0)
#else
#define CHECK_INDEV_RESET(proc) if((proc).reset_query) return; while(0)
#endif
/********************** /**********************
* GLOBAL FUNCTIONS * GLOBAL FUNCTIONS
@@ -310,6 +323,14 @@ lv_task_t * lv_indev_get_read_task(lv_disp_t * indev)
return indev->refr_task; return indev->refr_task;
} }
lv_obj_t * lv_indev_get_obj_focused() {
#if LV_USE_GROUP
return indev_obj_focused;
#else
return NULL;
#endif
}
/********************** /**********************
* STATIC FUNCTIONS * STATIC FUNCTIONS
**********************/ **********************/
@@ -360,8 +381,8 @@ static void indev_keypad_proc(lv_indev_t * i, lv_indev_data_t * data)
lv_group_t * g = i->group; lv_group_t * g = i->group;
if(g == NULL) return; if(g == NULL) return;
lv_obj_t * focused = lv_group_get_focused(g); indev_obj_focused = lv_group_get_focused(g);
if(focused == NULL) return; if(indev_obj_focused == NULL) return;
/*Save the last key to compare it with the current latter on RELEASE*/ /*Save the last key to compare it with the current latter on RELEASE*/
uint32_t prev_key = i->proc.types.keypad.last_key; uint32_t prev_key = i->proc.types.keypad.last_key;
@@ -385,30 +406,30 @@ static void indev_keypad_proc(lv_indev_t * i, lv_indev_data_t * data)
/*Send the ENTER as a normal KEY*/ /*Send the ENTER as a normal KEY*/
lv_group_send_data(g, LV_KEY_ENTER); lv_group_send_data(g, LV_KEY_ENTER);
focused->signal_cb(focused, LV_SIGNAL_PRESSED, NULL); indev_obj_focused->signal_cb(indev_obj_focused, LV_SIGNAL_PRESSED, NULL);
if(i->proc.reset_query) return; /*The object might be deleted*/ CHECK_INDEV_RESET(i->proc);
lv_event_send(focused, LV_EVENT_PRESSED, NULL); lv_event_send(indev_obj_focused, LV_EVENT_PRESSED, NULL);
if(i->proc.reset_query) return; /*The object might be deleted*/ CHECK_INDEV_RESET(i->proc);
} else if(data->key == LV_KEY_ESC) { } else if(data->key == LV_KEY_ESC) {
/*Send the ESC as a normal KEY*/ /*Send the ESC as a normal KEY*/
lv_group_send_data(g, LV_KEY_ESC); lv_group_send_data(g, LV_KEY_ESC);
lv_event_send(focused, LV_EVENT_CANCEL, NULL); lv_event_send(indev_obj_focused, LV_EVENT_CANCEL, NULL);
if(i->proc.reset_query) return; /*The object might be deleted*/ CHECK_INDEV_RESET(i->proc);
} }
/*Move the focus on NEXT*/ /*Move the focus on NEXT*/
else if(data->key == LV_KEY_NEXT) { else if(data->key == LV_KEY_NEXT) {
lv_group_set_editing(g, lv_group_set_editing(g,
false); /*Editing is not used by KEYPAD is be sure it is disabled*/ false); /*Editing is not used by KEYPAD is be sure it is disabled*/
lv_group_focus_next(g); lv_group_focus_next(g);
if(i->proc.reset_query) return; /*The object might be deleted*/ CHECK_INDEV_RESET(i->proc);
} }
/*Move the focus on PREV*/ /*Move the focus on PREV*/
else if(data->key == LV_KEY_PREV) { else if(data->key == LV_KEY_PREV) {
lv_group_set_editing(g, lv_group_set_editing(g,
false); /*Editing is not used by KEYPAD is be sure it is disabled*/ false); /*Editing is not used by KEYPAD is be sure it is disabled*/
lv_group_focus_prev(g); lv_group_focus_prev(g);
if(i->proc.reset_query) return; /*The object might be deleted*/ CHECK_INDEV_RESET(i->proc);
} }
/*Just send other keys to the object (e.g. 'A' or `LV_GROUP_KEY_RIGHT`)*/ /*Just send other keys to the object (e.g. 'A' or `LV_GROUP_KEY_RIGHT`)*/
else { else {
@@ -423,10 +444,10 @@ static void indev_keypad_proc(lv_indev_t * i, lv_indev_data_t * data)
i->proc.long_pr_sent = 1; i->proc.long_pr_sent = 1;
if(data->key == LV_KEY_ENTER) { if(data->key == LV_KEY_ENTER) {
i->proc.longpr_rep_timestamp = lv_tick_get(); i->proc.longpr_rep_timestamp = lv_tick_get();
focused->signal_cb(focused, LV_SIGNAL_LONG_PRESS, NULL); indev_obj_focused->signal_cb(indev_obj_focused, LV_SIGNAL_LONG_PRESS, NULL);
if(i->proc.reset_query) return; /*The object might be deleted*/ CHECK_INDEV_RESET(i->proc);
lv_event_send(focused, LV_EVENT_LONG_PRESSED, NULL); lv_event_send(indev_obj_focused, LV_EVENT_LONG_PRESSED, NULL);
if(i->proc.reset_query) return; /*The object might be deleted*/ CHECK_INDEV_RESET(i->proc);
} }
} }
/*Long press repeated time has elapsed?*/ /*Long press repeated time has elapsed?*/
@@ -437,29 +458,29 @@ static void indev_keypad_proc(lv_indev_t * i, lv_indev_data_t * data)
/*Send LONG_PRESS_REP on ENTER*/ /*Send LONG_PRESS_REP on ENTER*/
if(data->key == LV_KEY_ENTER) { if(data->key == LV_KEY_ENTER) {
focused->signal_cb(focused, LV_SIGNAL_LONG_PRESS_REP, NULL); indev_obj_focused->signal_cb(indev_obj_focused, LV_SIGNAL_LONG_PRESS_REP, NULL);
if(i->proc.reset_query) return; /*The object might be deleted*/ CHECK_INDEV_RESET(i->proc);
lv_event_send(focused, LV_EVENT_LONG_PRESSED_REPEAT, NULL); lv_event_send(indev_obj_focused, LV_EVENT_LONG_PRESSED_REPEAT, NULL);
if(i->proc.reset_query) return; /*The object might be deleted*/ CHECK_INDEV_RESET(i->proc);
} }
/*Move the focus on NEXT again*/ /*Move the focus on NEXT again*/
else if(data->key == LV_KEY_NEXT) { else if(data->key == LV_KEY_NEXT) {
lv_group_set_editing( lv_group_set_editing(
g, false); /*Editing is not used by KEYPAD is be sure it is disabled*/ g, false); /*Editing is not used by KEYPAD is be sure it is disabled*/
lv_group_focus_next(g); lv_group_focus_next(g);
if(i->proc.reset_query) return; /*The object might be deleted*/ CHECK_INDEV_RESET(i->proc);
} }
/*Move the focus on PREV again*/ /*Move the focus on PREV again*/
else if(data->key == LV_KEY_PREV) { else if(data->key == LV_KEY_PREV) {
lv_group_set_editing( lv_group_set_editing(
g, false); /*Editing is not used by KEYPAD is be sure it is disabled*/ g, false); /*Editing is not used by KEYPAD is be sure it is disabled*/
lv_group_focus_prev(g); lv_group_focus_prev(g);
if(i->proc.reset_query) return; /*The object might be deleted*/ CHECK_INDEV_RESET(i->proc);
} }
/*Just send other keys again to the object (e.g. 'A' or `LV_GORUP_KEY_RIGHT)*/ /*Just send other keys again to the object (e.g. 'A' or `LV_GORUP_KEY_RIGHT)*/
else { else {
lv_group_send_data(g, data->key); lv_group_send_data(g, data->key);
if(i->proc.reset_query) return; /*The object might be deleted*/ CHECK_INDEV_RESET(i->proc);
} }
} }
} }
@@ -469,23 +490,24 @@ static void indev_keypad_proc(lv_indev_t * i, lv_indev_data_t * data)
data->key = prev_key; data->key = prev_key;
if(data->key == LV_KEY_ENTER) { if(data->key == LV_KEY_ENTER) {
focused->signal_cb(focused, LV_SIGNAL_RELEASED, NULL); indev_obj_focused->signal_cb(indev_obj_focused, LV_SIGNAL_RELEASED, NULL);
if(i->proc.reset_query) return; /*The object might be deleted*/ CHECK_INDEV_RESET(i->proc);
if(i->proc.long_pr_sent == 0) { if(i->proc.long_pr_sent == 0) {
lv_event_send(focused, LV_EVENT_SHORT_CLICKED, NULL); lv_event_send(indev_obj_focused, LV_EVENT_SHORT_CLICKED, NULL);
if(i->proc.reset_query) return; /*The object might be deleted*/ CHECK_INDEV_RESET(i->proc);
} }
lv_event_send(focused, LV_EVENT_CLICKED, NULL); lv_event_send(indev_obj_focused, LV_EVENT_CLICKED, NULL);
if(i->proc.reset_query) return; /*The object might be deleted*/ CHECK_INDEV_RESET(i->proc);
lv_event_send(focused, LV_EVENT_RELEASED, NULL); lv_event_send(indev_obj_focused, LV_EVENT_RELEASED, NULL);
if(i->proc.reset_query) return; /*The object might be deleted*/ CHECK_INDEV_RESET(i->proc);
} }
i->proc.pr_timestamp = 0; i->proc.pr_timestamp = 0;
i->proc.long_pr_sent = 0; i->proc.long_pr_sent = 0;
} }
indev_obj_focused = NULL;
#else #else
(void)data; /*Unused*/ (void)data; /*Unused*/
(void)i; /*Unused*/ (void)i; /*Unused*/
@@ -519,10 +541,8 @@ static void indev_encoder_proc(lv_indev_t * i, lv_indev_data_t * data)
lv_group_t * g = i->group; lv_group_t * g = i->group;
if(g == NULL) return; if(g == NULL) return;
lv_obj_t * focused = lv_group_get_focused(g); indev_obj_focused = lv_group_get_focused(g);
if(focused == NULL) return; if(indev_obj_focused == NULL) return;
/*Process the steps first. They are valid only with released button*/ /*Process the steps first. They are valid only with released button*/
if(data->state == LV_INDEV_STATE_REL) { if(data->state == LV_INDEV_STATE_REL) {
@@ -547,21 +567,21 @@ static void indev_encoder_proc(lv_indev_t * i, lv_indev_data_t * data)
} }
/*Refresh the focused object. It might change due to lv_group_focus_prev/next*/ /*Refresh the focused object. It might change due to lv_group_focus_prev/next*/
focused = lv_group_get_focused(g); indev_obj_focused = lv_group_get_focused(g);
if(focused == NULL) return; if(indev_obj_focused == NULL) return;
/*Button press happened*/ /*Button press happened*/
if(data->state == LV_INDEV_STATE_PR && last_state == LV_INDEV_STATE_REL) { if(data->state == LV_INDEV_STATE_PR && last_state == LV_INDEV_STATE_REL) {
bool editable = false; bool editable = false;
focused->signal_cb(focused, LV_SIGNAL_GET_EDITABLE, &editable); indev_obj_focused->signal_cb(indev_obj_focused, LV_SIGNAL_GET_EDITABLE, &editable);
i->proc.pr_timestamp = lv_tick_get(); i->proc.pr_timestamp = lv_tick_get();
if(lv_group_get_editing(g) == true || editable == false) { if(lv_group_get_editing(g) == true || editable == false) {
focused->signal_cb(focused, LV_SIGNAL_PRESSED, NULL); indev_obj_focused->signal_cb(indev_obj_focused, LV_SIGNAL_PRESSED, NULL);
if(i->proc.reset_query) return; /*The object might be deleted*/ CHECK_INDEV_RESET(i->proc);
lv_event_send(focused, LV_EVENT_PRESSED, NULL); lv_event_send(indev_obj_focused, LV_EVENT_PRESSED, NULL);
if(i->proc.reset_query) return; /*The object might be deleted*/ CHECK_INDEV_RESET(i->proc);
} }
} }
/*Pressing*/ /*Pressing*/
@@ -570,7 +590,7 @@ static void indev_encoder_proc(lv_indev_t * i, lv_indev_data_t * data)
if(i->proc.long_pr_sent == 0 && if(i->proc.long_pr_sent == 0 &&
lv_tick_elaps(i->proc.pr_timestamp) > i->driver.long_press_time) { lv_tick_elaps(i->proc.pr_timestamp) > i->driver.long_press_time) {
bool editable = false; bool editable = false;
focused->signal_cb(focused, LV_SIGNAL_GET_EDITABLE, &editable); indev_obj_focused->signal_cb(indev_obj_focused, LV_SIGNAL_GET_EDITABLE, &editable);
/*On enter long press toggle edit mode.*/ /*On enter long press toggle edit mode.*/
if(editable) { if(editable) {
@@ -583,10 +603,10 @@ static void indev_encoder_proc(lv_indev_t * i, lv_indev_data_t * data)
} }
/*If not editable then just send a long press signal*/ /*If not editable then just send a long press signal*/
else { else {
focused->signal_cb(focused, LV_SIGNAL_LONG_PRESS, NULL); indev_obj_focused->signal_cb(indev_obj_focused, LV_SIGNAL_LONG_PRESS, NULL);
if(i->proc.reset_query) return; /*The object might be deleted*/ CHECK_INDEV_RESET(i->proc);
lv_event_send(focused, LV_EVENT_LONG_PRESSED, NULL); lv_event_send(indev_obj_focused, LV_EVENT_LONG_PRESSED, NULL);
if(i->proc.reset_query) return; /*The object might be deleted*/ CHECK_INDEV_RESET(i->proc);
} }
i->proc.long_pr_sent = 1; i->proc.long_pr_sent = 1;
} }
@@ -596,37 +616,37 @@ static void indev_encoder_proc(lv_indev_t * i, lv_indev_data_t * data)
last_state == LV_INDEV_STATE_PR) { last_state == LV_INDEV_STATE_PR) {
bool editable = false; bool editable = false;
focused->signal_cb(focused, LV_SIGNAL_GET_EDITABLE, &editable); indev_obj_focused->signal_cb(indev_obj_focused, LV_SIGNAL_GET_EDITABLE, &editable);
/*The button was released on a non-editable object. Just send enter*/ /*The button was released on a non-editable object. Just send enter*/
if(editable == false) { if(editable == false) {
focused->signal_cb(focused, LV_SIGNAL_RELEASED, NULL); indev_obj_focused->signal_cb(indev_obj_focused, LV_SIGNAL_RELEASED, NULL);
if(i->proc.reset_query) return; /*The object might be deleted*/ CHECK_INDEV_RESET(i->proc);
if(i->proc.long_pr_sent == 0) lv_event_send(focused, LV_EVENT_SHORT_CLICKED, NULL); if(i->proc.long_pr_sent == 0) lv_event_send(indev_obj_focused, LV_EVENT_SHORT_CLICKED, NULL);
if(i->proc.reset_query) return; /*The object might be deleted*/ CHECK_INDEV_RESET(i->proc);
lv_event_send(focused, LV_EVENT_CLICKED, NULL); lv_event_send(indev_obj_focused, LV_EVENT_CLICKED, NULL);
if(i->proc.reset_query) return; /*The object might be deleted*/ CHECK_INDEV_RESET(i->proc);
lv_event_send(focused, LV_EVENT_RELEASED, NULL); lv_event_send(indev_obj_focused, LV_EVENT_RELEASED, NULL);
if(i->proc.reset_query) return; /*The object might be deleted*/ CHECK_INDEV_RESET(i->proc);
} }
/*An object is being edited and the button is released. */ /*An object is being edited and the button is released. */
else if(g->editing) { else if(g->editing) {
/*Ignore long pressed enter release because it comes from mode switch*/ /*Ignore long pressed enter release because it comes from mode switch*/
if(!i->proc.long_pr_sent || lv_ll_is_empty(&g->obj_ll)) { if(!i->proc.long_pr_sent || lv_ll_is_empty(&g->obj_ll)) {
focused->signal_cb(focused, LV_SIGNAL_RELEASED, NULL); indev_obj_focused->signal_cb(indev_obj_focused, LV_SIGNAL_RELEASED, NULL);
if(i->proc.reset_query) return; /*The object might be deleted*/ CHECK_INDEV_RESET(i->proc);
lv_event_send(focused, LV_EVENT_SHORT_CLICKED, NULL); lv_event_send(indev_obj_focused, LV_EVENT_SHORT_CLICKED, NULL);
if(i->proc.reset_query) return; /*The object might be deleted*/ CHECK_INDEV_RESET(i->proc);
lv_event_send(focused, LV_EVENT_CLICKED, NULL); lv_event_send(indev_obj_focused, LV_EVENT_CLICKED, NULL);
if(i->proc.reset_query) return; /*The object might be deleted*/ CHECK_INDEV_RESET(i->proc);
lv_event_send(focused, LV_EVENT_RELEASED, NULL); lv_event_send(indev_obj_focused, LV_EVENT_RELEASED, NULL);
if(i->proc.reset_query) return; /*The object might be deleted*/ CHECK_INDEV_RESET(i->proc);
lv_group_send_data(g, LV_KEY_ENTER); lv_group_send_data(g, LV_KEY_ENTER);
} }
@@ -640,7 +660,7 @@ static void indev_encoder_proc(lv_indev_t * i, lv_indev_data_t * data)
i->proc.pr_timestamp = 0; i->proc.pr_timestamp = 0;
i->proc.long_pr_sent = 0; i->proc.long_pr_sent = 0;
} }
indev_obj_focused = NULL;
#else #else
(void)data; /*Unused*/ (void)data; /*Unused*/
(void)i; /*Unused*/ (void)i; /*Unused*/
@@ -713,9 +733,9 @@ static void indev_proc_press(lv_indev_proc_t * proc)
if(proc->types.pointer.act_obj != NULL) { if(proc->types.pointer.act_obj != NULL) {
proc->types.pointer.act_obj->signal_cb(proc->types.pointer.act_obj, proc->types.pointer.act_obj->signal_cb(proc->types.pointer.act_obj,
LV_SIGNAL_PRESS_LOST, indev_act); LV_SIGNAL_PRESS_LOST, indev_act);
if(proc->reset_query) return; /*The object might be deleted*/ CHECK_INDEV_RESET(*proc);
lv_event_send(proc->types.pointer.act_obj, LV_EVENT_PRESS_LOST, NULL); lv_event_send(proc->types.pointer.act_obj, LV_EVENT_PRESS_LOST, NULL);
if(proc->reset_query) return; /*The object might be deleted*/ CHECK_INDEV_RESET(*proc);
} }
proc->types.pointer.act_obj = pr_obj; /*Save the pressed object*/ proc->types.pointer.act_obj = pr_obj; /*Save the pressed object*/
@@ -750,9 +770,9 @@ static void indev_proc_press(lv_indev_proc_t * proc)
/*Send a signal about the press*/ /*Send a signal about the press*/
proc->types.pointer.act_obj->signal_cb(proc->types.pointer.act_obj, LV_SIGNAL_PRESSED, proc->types.pointer.act_obj->signal_cb(proc->types.pointer.act_obj, LV_SIGNAL_PRESSED,
indev_act); indev_act);
if(proc->reset_query) return; /*The object might be deleted*/ CHECK_INDEV_RESET(*proc);
lv_event_send(proc->types.pointer.act_obj, LV_EVENT_PRESSED, NULL); lv_event_send(proc->types.pointer.act_obj, LV_EVENT_PRESSED, NULL);
if(proc->reset_query) return; /*The object might be deleted*/ CHECK_INDEV_RESET(*proc);
} }
} }
@@ -778,23 +798,23 @@ static void indev_proc_press(lv_indev_proc_t * proc)
/*If there is active object and it can be dragged run the drag*/ /*If there is active object and it can be dragged run the drag*/
if(proc->types.pointer.act_obj != NULL) { if(proc->types.pointer.act_obj != NULL) {
proc->types.pointer.act_obj->signal_cb(proc->types.pointer.act_obj, LV_SIGNAL_PRESSING, proc->types.pointer.act_obj->signal_cb(proc->types.pointer.act_obj,
indev_act); LV_SIGNAL_PRESSING, indev_act);
if(proc->reset_query) return; /*The object might be deleted*/ CHECK_INDEV_RESET(*proc);
lv_event_send(proc->types.pointer.act_obj, LV_EVENT_PRESSING, NULL); lv_event_send(proc->types.pointer.act_obj, LV_EVENT_PRESSING, NULL);
if(proc->reset_query) return; /*The object might be deleted*/ CHECK_INDEV_RESET(*proc);
indev_drag(proc); indev_drag(proc);
if(proc->reset_query != 0) return; CHECK_INDEV_RESET(*proc);
/*If there is no drag then check for long press time*/ /*If there is no drag then check for long press time*/
if(proc->types.pointer.drag_in_prog == 0 && proc->long_pr_sent == 0) { if(proc->types.pointer.drag_in_prog == 0 && proc->long_pr_sent == 0) {
/*Send a signal about the long press if enough time elapsed*/ /*Send a signal about the long press if enough time elapsed*/
if(lv_tick_elaps(proc->pr_timestamp) > indev_act->driver.long_press_time) { if(lv_tick_elaps(proc->pr_timestamp) > indev_act->driver.long_press_time) {
pr_obj->signal_cb(pr_obj, LV_SIGNAL_LONG_PRESS, indev_act); pr_obj->signal_cb(pr_obj, LV_SIGNAL_LONG_PRESS, indev_act);
if(proc->reset_query) return; /*The object might be deleted*/ CHECK_INDEV_RESET(*proc);
lv_event_send(pr_obj, LV_EVENT_LONG_PRESSED, NULL); lv_event_send(pr_obj, LV_EVENT_LONG_PRESSED, NULL);
if(proc->reset_query) return; /*The object might be deleted*/ CHECK_INDEV_RESET(*proc);
/*Mark the signal sending to do not send it again*/ /*Mark the signal sending to do not send it again*/
proc->long_pr_sent = 1; proc->long_pr_sent = 1;
@@ -808,9 +828,9 @@ static void indev_proc_press(lv_indev_proc_t * proc)
/*Send a signal about the long press repeate if enough time elapsed*/ /*Send a signal about the long press repeate if enough time elapsed*/
if(lv_tick_elaps(proc->longpr_rep_timestamp) > indev_act->driver.long_press_rep_time) { if(lv_tick_elaps(proc->longpr_rep_timestamp) > indev_act->driver.long_press_rep_time) {
pr_obj->signal_cb(pr_obj, LV_SIGNAL_LONG_PRESS_REP, indev_act); pr_obj->signal_cb(pr_obj, LV_SIGNAL_LONG_PRESS_REP, indev_act);
if(proc->reset_query) return; /*The object might be deleted*/ CHECK_INDEV_RESET(*proc);
lv_event_send(pr_obj, LV_EVENT_LONG_PRESSED_REPEAT, NULL); lv_event_send(pr_obj, LV_EVENT_LONG_PRESSED_REPEAT, NULL);
if(proc->reset_query) return; /*The object might be deleted*/ CHECK_INDEV_RESET(*proc);
proc->longpr_rep_timestamp = lv_tick_get(); proc->longpr_rep_timestamp = lv_tick_get();
} }
} }
@@ -840,41 +860,41 @@ static void indev_proc_release(lv_indev_proc_t * proc)
if(lv_obj_is_protected(proc->types.pointer.act_obj, LV_PROTECT_PRESS_LOST)) { if(lv_obj_is_protected(proc->types.pointer.act_obj, LV_PROTECT_PRESS_LOST)) {
proc->types.pointer.act_obj->signal_cb(proc->types.pointer.act_obj, LV_SIGNAL_RELEASED, proc->types.pointer.act_obj->signal_cb(proc->types.pointer.act_obj, LV_SIGNAL_RELEASED,
indev_act); indev_act);
if(proc->reset_query) return; /*The object might be deleted*/ CHECK_INDEV_RESET(*proc);
if(proc->types.pointer.drag_in_prog == 0) { if(proc->types.pointer.drag_in_prog == 0) {
if(proc->long_pr_sent == 0) { if(proc->long_pr_sent == 0) {
lv_event_send(proc->types.pointer.act_obj, LV_EVENT_SHORT_CLICKED, NULL); lv_event_send(proc->types.pointer.act_obj, LV_EVENT_SHORT_CLICKED, NULL);
if(proc->reset_query) return; /*The object might be deleted*/ CHECK_INDEV_RESET(*proc);
} }
lv_event_send(proc->types.pointer.act_obj, LV_EVENT_CLICKED, NULL); lv_event_send(proc->types.pointer.act_obj, LV_EVENT_CLICKED, NULL);
if(proc->reset_query) return; /*The object might be deleted*/ CHECK_INDEV_RESET(*proc);
} }
lv_event_send(proc->types.pointer.act_obj, LV_EVENT_RELEASED, NULL); lv_event_send(proc->types.pointer.act_obj, LV_EVENT_RELEASED, NULL);
if(proc->reset_query) return; /*The object might be deleted*/ CHECK_INDEV_RESET(*proc);
} }
/* The simple case: `act_obj` was not protected against press lost. /* The simple case: `act_obj` was not protected against press lost.
* If it is already not pressed then was `indev_proc_press` would set `act_obj = NULL`*/ * If it is already not pressed then was `indev_proc_press` would set `act_obj = NULL`*/
else { else {
proc->types.pointer.act_obj->signal_cb(proc->types.pointer.act_obj, LV_SIGNAL_RELEASED, proc->types.pointer.act_obj->signal_cb(proc->types.pointer.act_obj, LV_SIGNAL_RELEASED,
indev_act); indev_act);
if(proc->reset_query) return; /*The object might be deleted*/ CHECK_INDEV_RESET(*proc);
if(proc->long_pr_sent == 0 && proc->types.pointer.drag_in_prog == 0) { if(proc->long_pr_sent == 0 && proc->types.pointer.drag_in_prog == 0) {
lv_event_send(proc->types.pointer.act_obj, LV_EVENT_SHORT_CLICKED, NULL); lv_event_send(proc->types.pointer.act_obj, LV_EVENT_SHORT_CLICKED, NULL);
if(proc->reset_query) return; /*The object might be deleted*/ CHECK_INDEV_RESET(*proc);
} }
lv_event_send(proc->types.pointer.act_obj, LV_EVENT_CLICKED, NULL); lv_event_send(proc->types.pointer.act_obj, LV_EVENT_CLICKED, NULL);
if(proc->reset_query) return; /*The object might be deleted*/ CHECK_INDEV_RESET(*proc);
lv_event_send(proc->types.pointer.act_obj, LV_EVENT_RELEASED, NULL); lv_event_send(proc->types.pointer.act_obj, LV_EVENT_RELEASED, NULL);
if(proc->reset_query) return; /*The object might be deleted*/ CHECK_INDEV_RESET(*proc);
} }
if(proc->reset_query != 0) return; CHECK_INDEV_RESET(*proc);
/*Handle click focus*/ /*Handle click focus*/
#if LV_USE_GROUP #if LV_USE_GROUP
@@ -912,16 +932,15 @@ static void indev_proc_release(lv_indev_proc_t * proc)
* a focus/defucus signal because of `click focus`*/ * a focus/defucus signal because of `click focus`*/
if(proc->types.pointer.last_pressed != proc->types.pointer.act_obj) { if(proc->types.pointer.last_pressed != proc->types.pointer.act_obj) {
lv_event_send(proc->types.pointer.last_pressed, LV_EVENT_DEFOCUSED, NULL); lv_event_send(proc->types.pointer.last_pressed, LV_EVENT_DEFOCUSED, NULL);
if(proc->reset_query) CHECK_INDEV_RESET(*proc);
return; /*Not so strict as it's only the previous object and indev not uses it.*/
lv_event_send(proc->types.pointer.act_obj, LV_EVENT_FOCUSED, NULL); lv_event_send(proc->types.pointer.act_obj, LV_EVENT_FOCUSED, NULL);
if(proc->reset_query) return; /*The object might be deleted*/ CHECK_INDEV_RESET(*proc);
proc->types.pointer.last_pressed = proc->types.pointer.act_obj; proc->types.pointer.last_pressed = proc->types.pointer.act_obj;
} }
if(proc->reset_query != 0) return; CHECK_INDEV_RESET(*proc);
proc->types.pointer.act_obj = NULL; proc->types.pointer.act_obj = NULL;
proc->pr_timestamp = 0; proc->pr_timestamp = 0;
proc->longpr_rep_timestamp = 0; proc->longpr_rep_timestamp = 0;
@@ -931,7 +950,7 @@ static void indev_proc_release(lv_indev_proc_t * proc)
* In case of reset query ignore the remaining parts.*/ * In case of reset query ignore the remaining parts.*/
if(proc->types.pointer.last_obj != NULL && proc->reset_query == 0) { if(proc->types.pointer.last_obj != NULL && proc->reset_query == 0) {
indev_drag_throw(proc); indev_drag_throw(proc);
if(proc->reset_query != 0) return; CHECK_INDEV_RESET(*proc);
} }
} }
@@ -1094,9 +1113,9 @@ static void indev_drag(lv_indev_proc_t * state)
/*Send the drag begin signal on first move*/ /*Send the drag begin signal on first move*/
if(state->types.pointer.drag_in_prog == 0) { if(state->types.pointer.drag_in_prog == 0) {
drag_obj->signal_cb(drag_obj, LV_SIGNAL_DRAG_BEGIN, indev_act); drag_obj->signal_cb(drag_obj, LV_SIGNAL_DRAG_BEGIN, indev_act);
if(state->reset_query != 0) return; CHECK_INDEV_RESET(*state);
lv_event_send(drag_obj, LV_EVENT_DRAG_BEGIN, NULL); lv_event_send(drag_obj, LV_EVENT_DRAG_BEGIN, NULL);
if(state->reset_query) return; /*The object might be deleted*/ CHECK_INDEV_RESET(*state);
} }
state->types.pointer.drag_in_prog = 1; state->types.pointer.drag_in_prog = 1;
@@ -1143,7 +1162,7 @@ static void indev_drag_throw(lv_indev_proc_t * proc)
proc->types.pointer.drag_in_prog = 0; proc->types.pointer.drag_in_prog = 0;
drag_obj->signal_cb(drag_obj, LV_SIGNAL_DRAG_END, indev_act); drag_obj->signal_cb(drag_obj, LV_SIGNAL_DRAG_END, indev_act);
lv_event_send(drag_obj, LV_EVENT_DRAG_END, NULL); lv_event_send(drag_obj, LV_EVENT_DRAG_END, NULL);
if(proc->reset_query) return; /*The object might be deleted*/ CHECK_INDEV_RESET(*proc);
lv_event_send(drag_obj, LV_EVENT_DRAG_END, NULL); lv_event_send(drag_obj, LV_EVENT_DRAG_END, NULL);
return; return;
@@ -1183,9 +1202,9 @@ static void indev_drag_throw(lv_indev_proc_t * proc)
proc->types.pointer.drag_throw_vect.x = 0; proc->types.pointer.drag_throw_vect.x = 0;
proc->types.pointer.drag_throw_vect.y = 0; proc->types.pointer.drag_throw_vect.y = 0;
drag_obj->signal_cb(drag_obj, LV_SIGNAL_DRAG_END, indev_act); drag_obj->signal_cb(drag_obj, LV_SIGNAL_DRAG_END, indev_act);
if(proc->reset_query) return; /*The object might be deleted*/ CHECK_INDEV_RESET(*proc);
lv_event_send(drag_obj, LV_EVENT_DRAG_END, NULL); lv_event_send(drag_obj, LV_EVENT_DRAG_END, NULL);
if(proc->reset_query) return; /*The object might be deleted*/ CHECK_INDEV_RESET(*proc);
} }
} }
/*If the types.pointer.vectors become 0 -> types.pointer.drag_in_prog = 0 and send a drag end /*If the types.pointer.vectors become 0 -> types.pointer.drag_in_prog = 0 and send a drag end
@@ -1193,8 +1212,8 @@ static void indev_drag_throw(lv_indev_proc_t * proc)
else { else {
proc->types.pointer.drag_in_prog = 0; proc->types.pointer.drag_in_prog = 0;
drag_obj->signal_cb(drag_obj, LV_SIGNAL_DRAG_END, indev_act); drag_obj->signal_cb(drag_obj, LV_SIGNAL_DRAG_END, indev_act);
if(proc->reset_query) return; /*The object might be deleted*/ CHECK_INDEV_RESET(*proc);
lv_event_send(drag_obj, LV_EVENT_DRAG_END, NULL); lv_event_send(drag_obj, LV_EVENT_DRAG_END, NULL);
if(proc->reset_query) return; /*The object might be deleted*/ CHECK_INDEV_RESET(*proc);
} }
} }

View File

@@ -141,6 +141,13 @@ void lv_indev_wait_release(lv_indev_t * indev);
*/ */
lv_task_t * lv_indev_get_read_task(lv_disp_t * indev); lv_task_t * lv_indev_get_read_task(lv_disp_t * indev);
/**
* Gets a pointer to the currently handled object.
* NULL if no object is currently being handled or if groups aren't used.
* @return pointer to currently focused object
*/
lv_obj_t * lv_indev_get_obj_focused();
/********************** /**********************
* MACROS * MACROS
**********************/ **********************/

View File

@@ -378,13 +378,8 @@ lv_res_t lv_obj_del(lv_obj_t * obj)
/*Delete from the group*/ /*Delete from the group*/
#if LV_USE_GROUP #if LV_USE_GROUP
bool was_focused = false;
lv_group_t * group = lv_obj_get_group(obj); lv_group_t * group = lv_obj_get_group(obj);
if(group) lv_group_remove_obj(obj);
if(group) {
if(lv_group_get_focused(group) == obj) was_focused = true;
lv_group_remove_obj(obj);
}
#endif #endif
/*Remove the animations from this object*/ /*Remove the animations from this object*/
@@ -432,7 +427,7 @@ lv_res_t lv_obj_del(lv_obj_t * obj)
} }
#if LV_USE_GROUP #if LV_USE_GROUP
if(indev->group == group && was_focused) { if(indev->group == group && obj == lv_indev_get_obj_focused() ) {
lv_indev_reset(indev); lv_indev_reset(indev);
} }
#endif #endif
@@ -2197,15 +2192,11 @@ static void delete_children(lv_obj_t * obj)
* the object still has access to all children during the * the object still has access to all children during the
* LV_SIGNAL_DEFOCUS call*/ * LV_SIGNAL_DEFOCUS call*/
#if LV_USE_GROUP #if LV_USE_GROUP
bool was_focused = false;
lv_group_t * group = lv_obj_get_group(obj); lv_group_t * group = lv_obj_get_group(obj);
if(group) lv_group_remove_obj(obj);
if(group) {
if(lv_group_get_focused(obj->group_p) == obj) was_focused = true;
lv_group_remove_obj(obj);
}
#endif #endif
while(i != NULL) { while(i != NULL) {
/*Get the next object before delete this*/ /*Get the next object before delete this*/
i_next = lv_ll_get_next(&(obj->child_ll), i); i_next = lv_ll_get_next(&(obj->child_ll), i);
@@ -2239,7 +2230,7 @@ static void delete_children(lv_obj_t * obj)
indev->proc.types.pointer.last_pressed = NULL; indev->proc.types.pointer.last_pressed = NULL;
} }
#if LV_USE_GROUP #if LV_USE_GROUP
if(indev->group == group && was_focused) { if(indev->group == group && obj == lv_indev_get_obj_focused() ) {
lv_indev_reset(indev); lv_indev_reset(indev);
} }
#endif #endif