From 5cce6daa4a2fb38fbe04ea7ea6198a271220963b Mon Sep 17 00:00:00 2001 From: Gabor Kiss-Vamosi Date: Tue, 21 Jul 2020 21:09:33 +0200 Subject: [PATCH] scroll: remove drag --- src/lv_core/lv_indev.c | 493 +++++++++++------------------------ src/lv_core/lv_indev.h | 20 +- src/lv_core/lv_obj.c | 120 ++------- src/lv_core/lv_obj.h | 119 +++------ src/lv_hal/lv_hal_indev.c | 4 +- src/lv_hal/lv_hal_indev.h | 24 +- src/lv_widgets/lv_btn.c | 2 +- src/lv_widgets/lv_cpicker.c | 4 +- src/lv_widgets/lv_dropdown.c | 6 +- src/lv_widgets/lv_list.c | 4 +- src/lv_widgets/lv_page.c | 2 +- src/lv_widgets/lv_roller.c | 2 +- src/lv_widgets/lv_tileview.c | 4 +- 13 files changed, 222 insertions(+), 582 deletions(-) diff --git a/src/lv_core/lv_indev.c b/src/lv_core/lv_indev.c index a415dc1ec..2be5474d9 100644 --- a/src/lv_core/lv_indev.c +++ b/src/lv_core/lv_indev.c @@ -40,9 +40,8 @@ static void indev_proc_press(lv_indev_proc_t * proc); static void indev_proc_release(lv_indev_proc_t * proc); static void indev_proc_reset_query_handler(lv_indev_t * indev); static void indev_click_focus(lv_indev_proc_t * proc); -static void indev_drag(lv_indev_proc_t * proc); -static void indev_drag_throw(lv_indev_proc_t * proc); -static lv_obj_t * get_dragged_obj(lv_obj_t * obj); +static void indev_scroll_handler(lv_indev_proc_t * proc); +static void indev_scroll_throw_handler(lv_indev_proc_t * proc); static void indev_gesture(lv_indev_proc_t * proc); static bool indev_reset_check(lv_indev_proc_t * proc); @@ -288,20 +287,21 @@ uint32_t lv_indev_get_key(const lv_indev_t * indev) } /** - * Check if there is dragging with an input device or not (for LV_INDEV_TYPE_POINTER and + * Check the current scroll direction of an input device (for LV_INDEV_TYPE_POINTER and * LV_INDEV_TYPE_BUTTON) * @param indev pointer to an input device - * @return true: drag is in progress + * @return LV_SCROLL_DIR_NONE: no scrolling now + * LV_SCROLL_DIR_HOR/VER */ -bool lv_indev_is_dragging(const lv_indev_t * indev) +lv_scroll_dir_t lv_indev_get_scroll_dir(const lv_indev_t * indev) { if(indev == NULL) return false; if(indev->driver.type != LV_INDEV_TYPE_POINTER && indev->driver.type != LV_INDEV_TYPE_BUTTON) return false; - return indev->proc.types.pointer.drag_in_prog == 0 ? false : true; + return indev->proc.types.pointer.scroll_dir; } /** - * Get the types.pointer.vector of dragging of an input device (for LV_INDEV_TYPE_POINTER and + * Get the movement vector of an input device (for LV_INDEV_TYPE_POINTER and * LV_INDEV_TYPE_BUTTON) * @param indev pointer to an input device * @param point pointer to a point to store the types.pointer.vector @@ -324,36 +324,6 @@ void lv_indev_get_vect(const lv_indev_t * indev, lv_point_t * point) } } -/** - * Manually finish dragging. - * `LV_SIGNAL_DRAG_END` and `LV_EVENT_DRAG_END` will be sent. - * @param indev pointer to an input device - * @return `LV_RES_INV` if the object being dragged was deleted. Else `LV_RES_OK`. - */ -lv_res_t lv_indev_finish_drag(lv_indev_t * indev) -{ - if(indev == NULL) return LV_RES_OK; - if(indev->driver.type != LV_INDEV_TYPE_POINTER) return LV_RES_OK; - if(indev->proc.types.pointer.drag_in_prog == 0) return LV_RES_OK; - - indev->proc.types.pointer.drag_in_prog = 0; - indev->proc.types.pointer.drag_throw_vect.x = 0; - indev->proc.types.pointer.drag_throw_vect.y = 0; - - lv_obj_t * drag_obj; - drag_obj = get_dragged_obj(indev->proc.types.pointer.act_obj); - if(drag_obj == NULL) return LV_RES_OK; - - lv_res_t res; - res = drag_obj->signal_cb(drag_obj, LV_SIGNAL_DRAG_END, NULL); - if(res != LV_RES_OK) return res; - - res = lv_event_send(drag_obj, LV_EVENT_DRAG_END, NULL); - if(res != LV_RES_OK) return res; - - return res; -} - /** * Do nothing until the next release * @param indev pointer to an input device @@ -846,8 +816,8 @@ static void indev_proc_press(lv_indev_proc_t * proc) &proc->types.pointer.act_point); new_obj_searched = true; } - /*If there is last object but it is not dragged and not protected also search*/ - else if(proc->types.pointer.drag_in_prog == 0 && + /*If there is last object but it is not scrolled and not protected also search*/ + else if(proc->types.pointer.scroll_obj == NULL && lv_obj_is_protected(indev_obj_act, LV_PROTECT_PRESS_LOST) == false) { indev_obj_act = lv_indev_search_obj(lv_disp_get_layer_sys(disp), &proc->types.pointer.act_point); if(indev_obj_act == NULL) indev_obj_act = lv_indev_search_obj(lv_disp_get_layer_top(disp), @@ -856,15 +826,12 @@ static void indev_proc_press(lv_indev_proc_t * proc) &proc->types.pointer.act_point); new_obj_searched = true; } - /*If a draggable or a protected object was the last then keep it*/ - else { - } - /*The last object might have drag throw. Stop it manually*/ + /*The last object might have scroll throw. Stop it manually*/ if(new_obj_searched && proc->types.pointer.last_obj) { - proc->types.pointer.drag_throw_vect.x = 0; - proc->types.pointer.drag_throw_vect.y = 0; - indev_drag_throw(proc); + proc->types.pointer.scroll_throw_vect.x = 0; + proc->types.pointer.scroll_throw_vect.y = 0; + indev_scroll_throw_handler(proc); } /*Do not use disabled objects*/ @@ -882,11 +849,10 @@ static void indev_proc_press(lv_indev_proc_t * proc) /*Save the obj because in special cases `act_obj` can change in the signal function*/ lv_obj_t * last_obj = proc->types.pointer.act_obj; - last_obj->signal_cb(last_obj, LV_SIGNAL_PRESS_LOST, indev_act); + lv_signal_send(last_obj, LV_SIGNAL_PRESS_LOST, indev_act); if(indev_reset_check(proc)) return; lv_event_send(last_obj, LV_EVENT_PRESS_LOST, NULL); if(indev_reset_check(proc)) return; - } proc->types.pointer.act_obj = indev_obj_act; /*Save the pressed object*/ @@ -896,11 +862,9 @@ static void indev_proc_press(lv_indev_proc_t * proc) /* Save the time when the obj pressed to count long press time.*/ proc->pr_timestamp = lv_tick_get(); proc->long_pr_sent = 0; - proc->types.pointer.drag_limit_out = 0; - proc->types.pointer.drag_in_prog = 0; - proc->types.pointer.drag_sum.x = 0; - proc->types.pointer.drag_sum.y = 0; - proc->types.pointer.drag_dir = LV_DRAG_DIR_BOTH; + proc->types.pointer.scroll_sum.x = 0; + proc->types.pointer.scroll_sum.y = 0; + proc->types.pointer.scroll_dir = LV_SCROLL_DIR_NONE; proc->types.pointer.gesture_sent = 0; proc->types.pointer.gesture_sum.x = 0; proc->types.pointer.gesture_sum.y = 0; @@ -921,7 +885,7 @@ static void indev_proc_press(lv_indev_proc_t * proc) } /*Send a signal about the press*/ - indev_obj_act->signal_cb(indev_obj_act, LV_SIGNAL_PRESSED, indev_act); + lv_signal_send(indev_obj_act, LV_SIGNAL_PRESSED, indev_act); if(indev_reset_check(proc)) return; lv_event_send(indev_obj_act, LV_EVENT_PRESSED, NULL); @@ -936,33 +900,33 @@ static void indev_proc_press(lv_indev_proc_t * proc) } } - /*Calculate the types.pointer.vector*/ + /*Calculate the vector and apply a low pass filter: new value = 0.5 * old_value + 0.5 * new_value*/ proc->types.pointer.vect.x = proc->types.pointer.act_point.x - proc->types.pointer.last_point.x; proc->types.pointer.vect.y = proc->types.pointer.act_point.y - proc->types.pointer.last_point.y; - proc->types.pointer.drag_throw_vect.x = (proc->types.pointer.drag_throw_vect.x * 4) >> 3; - proc->types.pointer.drag_throw_vect.y = (proc->types.pointer.drag_throw_vect.y * 4) >> 3; + proc->types.pointer.scroll_throw_vect.x = (proc->types.pointer.scroll_throw_vect.x * 4) >> 3; + proc->types.pointer.scroll_throw_vect.y = (proc->types.pointer.scroll_throw_vect.y * 4) >> 3; - proc->types.pointer.drag_throw_vect.x += (proc->types.pointer.vect.x * 4) >> 3; - proc->types.pointer.drag_throw_vect.y += (proc->types.pointer.vect.y * 4) >> 3; + proc->types.pointer.scroll_throw_vect.x += (proc->types.pointer.vect.x * 4) >> 3; + proc->types.pointer.scroll_throw_vect.y += (proc->types.pointer.vect.y * 4) >> 3; - /*If there is active object and it can be dragged run the drag*/ - if(indev_obj_act != NULL) { - indev_obj_act->signal_cb(indev_obj_act, LV_SIGNAL_PRESSING, indev_act); + if(indev_obj_act) { + lv_signal_send(indev_obj_act, LV_SIGNAL_PRESSING, indev_act); if(indev_reset_check(proc)) return; lv_event_send(indev_obj_act, LV_EVENT_PRESSING, NULL); if(indev_reset_check(proc)) return; + if(indev_act->proc.wait_until_release) return; - indev_drag(proc); + indev_scroll_handler(proc); indev_gesture(proc); if(indev_reset_check(proc)) return; - /*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 there is no scrolling then check for long press time*/ + if(proc->types.pointer.scroll_obj == NULL && proc->long_pr_sent == 0) { /*Send a signal about the long press if enough time elapsed*/ if(lv_tick_elaps(proc->pr_timestamp) > indev_act->driver.long_press_time) { - indev_obj_act->signal_cb(indev_obj_act, LV_SIGNAL_LONG_PRESS, indev_act); + lv_signal_send(indev_obj_act, LV_SIGNAL_LONG_PRESS, indev_act); if(indev_reset_check(proc)) return; lv_event_send(indev_obj_act, LV_EVENT_LONG_PRESSED, NULL); if(indev_reset_check(proc)) return; @@ -974,11 +938,12 @@ static void indev_proc_press(lv_indev_proc_t * proc) proc->longpr_rep_timestamp = lv_tick_get(); } } + /*Send long press repeated signal*/ - if(proc->types.pointer.drag_in_prog == 0 && proc->long_pr_sent == 1) { + if(proc->types.pointer.scroll_obj == NULL && proc->long_pr_sent == 1) { /*Send a signal about the long press repeat if enough time elapsed*/ if(lv_tick_elaps(proc->longpr_rep_timestamp) > indev_act->driver.long_press_rep_time) { - indev_obj_act->signal_cb(indev_obj_act, LV_SIGNAL_LONG_PRESS_REP, indev_act); + lv_signal_send(indev_obj_act, LV_SIGNAL_LONG_PRESS_REP, indev_act); if(indev_reset_check(proc)) return; lv_event_send(indev_obj_act, LV_EVENT_LONG_PRESSED_REPEAT, NULL); if(indev_reset_check(proc)) return; @@ -1002,73 +967,49 @@ static void indev_proc_release(lv_indev_proc_t * proc) proc->wait_until_release = 0; } indev_obj_act = proc->types.pointer.act_obj; + lv_obj_t * scroll_obj = proc->types.pointer.scroll_obj; /*Forget the act obj and send a released signal */ if(indev_obj_act) { - /* If the object was protected against press lost then it possible that - * the object is already not pressed but still it is the `act_obj`. - * In this case send the `LV_SIGNAL_RELEASED/CLICKED` instead of `LV_SIGNAL_PRESS_LOST` if - * the indev is ON the `types.pointer.act_obj` */ - if(lv_obj_is_protected(indev_obj_act, LV_PROTECT_PRESS_LOST)) { - indev_obj_act->signal_cb(indev_obj_act, LV_SIGNAL_RELEASED, indev_act); - if(indev_reset_check(proc)) return; - - if(proc->types.pointer.drag_in_prog == 0) { - if(proc->long_pr_sent == 0) { - lv_event_send(indev_obj_act, LV_EVENT_SHORT_CLICKED, NULL); - if(indev_reset_check(proc)) return; - } - - lv_event_send(indev_obj_act, LV_EVENT_CLICKED, NULL); - if(indev_reset_check(proc)) return; - } - - lv_event_send(indev_obj_act, LV_EVENT_RELEASED, NULL); - if(indev_reset_check(proc)) return; - } - /* The simple case: `act_obj` was not protected against press lost. - * If it is already not pressed then `indev_proc_press` would set `indev_obj_act = NULL`*/ - else { - indev_obj_act->signal_cb(indev_obj_act, LV_SIGNAL_RELEASED, indev_act); - if(indev_reset_check(proc)) return; - - if(proc->long_pr_sent == 0 && proc->types.pointer.drag_in_prog == 0) { + /*Send CLICK if no scrolling*/ + if(scroll_obj == NULL) { + if(proc->long_pr_sent == 0) { lv_event_send(indev_obj_act, LV_EVENT_SHORT_CLICKED, NULL); if(indev_reset_check(proc)) return; } - if(proc->types.pointer.drag_in_prog == 0) { - lv_event_send(indev_obj_act, LV_EVENT_CLICKED, NULL); - if(indev_reset_check(proc)) return; - } - - lv_event_send(indev_obj_act, LV_EVENT_RELEASED, NULL); + lv_event_send(indev_obj_act, LV_EVENT_CLICKED, NULL); if(indev_reset_check(proc)) return; } - /*Send LV_EVENT_DRAG_THROW_BEGIN if required */ - /*If drag parent is active check recursively the drag_parent attribute*/ - lv_obj_t * drag_obj = get_dragged_obj(indev_obj_act); - if(drag_obj) { - if(lv_obj_get_drag_throw(drag_obj) && proc->types.pointer.drag_in_prog) { - if(drag_obj->signal_cb) drag_obj->signal_cb(drag_obj, LV_SIGNAL_DRAG_THROW_BEGIN, NULL); - if(indev_reset_check(proc)) return; + /*Send RELEASE signal and event*/ + lv_signal_send(indev_obj_act, LV_SIGNAL_RELEASED, indev_act); + if(indev_reset_check(proc)) return; - lv_event_send(drag_obj, LV_EVENT_DRAG_THROW_BEGIN, NULL); - if(indev_reset_check(proc)) return; - } + lv_event_send(indev_obj_act, LV_EVENT_RELEASED, NULL); + if(indev_reset_check(proc)) return; + + + /*Send SCROLL_THROW_BEGIN signal and event*/ + if(scroll_obj) { + lv_signal_send(scroll_obj, LV_SIGNAL_SCROLL_THROW_BEGIN, indev_act); + if(indev_reset_check(proc)) return; + + lv_event_send(indev_obj_act, LV_EVENT_SCROLL_THROW_BEGIN, indev_act); + if(indev_reset_check(proc)) return; } proc->types.pointer.act_obj = NULL; proc->pr_timestamp = 0; proc->longpr_rep_timestamp = 0; + } /*The reset can be set in the signal function. * In case of reset query ignore the remaining parts.*/ - if(proc->types.pointer.last_obj != NULL && proc->reset_query == 0) { - indev_drag_throw(proc); + if(scroll_obj) { + indev_scroll_throw_handler(proc); if(indev_reset_check(proc)) return; } } @@ -1085,17 +1026,15 @@ static void indev_proc_reset_query_handler(lv_indev_t * indev) if(indev->proc.reset_query) { indev->proc.types.pointer.act_obj = NULL; indev->proc.types.pointer.last_obj = NULL; - indev->proc.types.pointer.drag_obj = NULL; - indev->proc.types.pointer.drag_limit_out = 0; - indev->proc.types.pointer.drag_in_prog = 0; + indev->proc.types.pointer.scroll_obj = NULL; indev->proc.long_pr_sent = 0; indev->proc.pr_timestamp = 0; indev->proc.longpr_rep_timestamp = 0; - indev->proc.types.pointer.drag_sum.x = 0; - indev->proc.types.pointer.drag_sum.y = 0; - indev->proc.types.pointer.drag_dir = LV_DRAG_DIR_BOTH; - indev->proc.types.pointer.drag_throw_vect.x = 0; - indev->proc.types.pointer.drag_throw_vect.y = 0; + indev->proc.types.pointer.scroll_sum.x = 0; + indev->proc.types.pointer.scroll_sum.y = 0; + indev->proc.types.pointer.scroll_dir = LV_SCROLL_DIR_NONE; + indev->proc.types.pointer.scroll_throw_vect.x = 0; + indev->proc.types.pointer.scroll_throw_vect.y = 0; indev->proc.types.pointer.gesture_sum.x = 0; indev->proc.types.pointer.gesture_sum.y = 0; indev->proc.reset_query = 0; @@ -1237,42 +1176,30 @@ static void indev_click_focus(lv_indev_proc_t * proc) } /** - * Handle the dragging of indev_proc_p->types.pointer.act_obj + * Handle the scrolling * @param indev pointer to a input device state */ -static void indev_drag(lv_indev_proc_t * proc) +static void indev_scroll_handler(lv_indev_proc_t * proc) { - bool scrollable = true; - - lv_coord_t act_x = 0; - lv_coord_t act_y = 0; lv_obj_t * scroll_candidate_obj = NULL; - lv_drag_dir_t dirs_candidate = LV_DRAG_DIR_NONE; + lv_scroll_dir_t dirs_candidate = LV_SCROLL_DIR_NONE; - /*Count the movement by drag*/ - if(proc->types.pointer.drag_limit_out == 0) { - proc->types.pointer.drag_sum.x += proc->types.pointer.vect.x; - proc->types.pointer.drag_sum.y += proc->types.pointer.vect.y; + /*If there is no scroll object yet try to find one*/ + if(proc->types.pointer.scroll_obj == NULL) { + proc->types.pointer.scroll_sum.x += proc->types.pointer.vect.x; + proc->types.pointer.scroll_sum.y += proc->types.pointer.vect.y; - proc->types.pointer.drag_obj = proc->types.pointer.act_obj; + proc->types.pointer.scroll_obj = proc->types.pointer.act_obj; - /*Go until find the object or parent scrollable in this direction*/ - while(proc->types.pointer.drag_obj) { - /*Get which object to drad/scroll*/ - lv_drag_dir_t dirs = LV_DRAG_DIR_ONE; //scrollable ? lv_obj_get_scroll_dir(target_obj) : lv_obj_get_drag_dir(target_obj); - - /*Enough move?*/ + /*Go until find an scrollable object in the current direction*/ + while(proc->types.pointer.scroll_obj) { bool hor_en = false; bool ver_en = false; - if(dirs == LV_DRAG_DIR_HOR || dirs == LV_DRAG_DIR_BOTH) hor_en = true; - if(dirs == LV_DRAG_DIR_VER || dirs == LV_DRAG_DIR_BOTH) ver_en = true; - if(dirs == LV_DRAG_DIR_ONE) { - if(LV_MATH_ABS(proc->types.pointer.drag_sum.x) > LV_MATH_ABS(proc->types.pointer.drag_sum.y)) { - hor_en = true; - } - else { - ver_en = true; - } + if(LV_MATH_ABS(proc->types.pointer.scroll_sum.x) > LV_MATH_ABS(proc->types.pointer.scroll_sum.y)) { + hor_en = true; + } + else { + ver_en = true; } bool up_en = ver_en; @@ -1280,28 +1207,28 @@ static void indev_drag(lv_indev_proc_t * proc) bool left_en = hor_en; bool right_en = hor_en; - lv_coord_t st = lv_obj_get_scroll_top(proc->types.pointer.drag_obj); - lv_coord_t sb = lv_obj_get_scroll_bottom(proc->types.pointer.drag_obj); - lv_coord_t sl = lv_obj_get_scroll_left(proc->types.pointer.drag_obj); - lv_coord_t sr = lv_obj_get_scroll_right(proc->types.pointer.drag_obj); + lv_coord_t st = lv_obj_get_scroll_top(proc->types.pointer.scroll_obj); + lv_coord_t sb = lv_obj_get_scroll_bottom(proc->types.pointer.scroll_obj); + lv_coord_t sl = lv_obj_get_scroll_left(proc->types.pointer.scroll_obj); + lv_coord_t sr = lv_obj_get_scroll_right(proc->types.pointer.scroll_obj); bool ver_scrollable = st > 0 || sb > 0 ? true : false; bool hor_scrollable = sl > 0 || sr > 0 ? true : false; if(ver_scrollable && - ((up_en && proc->types.pointer.drag_sum.y >= indev_act->driver.drag_limit) || - (down_en && proc->types.pointer.drag_sum.y <= - indev_act->driver.drag_limit))) + ((up_en && proc->types.pointer.scroll_sum.y >= indev_act->driver.scroll_limit) || + (down_en && proc->types.pointer.scroll_sum.y <= - indev_act->driver.scroll_limit))) { - scroll_candidate_obj = proc->types.pointer.drag_obj; - dirs_candidate = LV_DRAG_DIR_VER; + scroll_candidate_obj = proc->types.pointer.scroll_obj; + dirs_candidate = LV_SCROLL_DIR_VER; } if(hor_scrollable && - ((left_en && proc->types.pointer.drag_sum.x >= indev_act->driver.drag_limit) || - (right_en && proc->types.pointer.drag_sum.x <= - indev_act->driver.drag_limit))) + ((left_en && proc->types.pointer.scroll_sum.x >= indev_act->driver.scroll_limit) || + (right_en && proc->types.pointer.scroll_sum.x <= - indev_act->driver.scroll_limit))) { - scroll_candidate_obj = proc->types.pointer.drag_obj; - dirs_candidate = LV_DRAG_DIR_HOR; + scroll_candidate_obj = proc->types.pointer.scroll_obj; + dirs_candidate = LV_SCROLL_DIR_HOR; } if(st <= 0) up_en = false; @@ -1309,236 +1236,106 @@ static void indev_drag(lv_indev_proc_t * proc) if(sl <= 0) left_en = false; if(sr <= 0) right_en = false; - - /*If a move is greater then LV_DRAG_LIMIT then begin the drag*/ - if((left_en && proc->types.pointer.drag_sum.x >= indev_act->driver.drag_limit) || - (right_en && proc->types.pointer.drag_sum.x <= - indev_act->driver.drag_limit) || - (up_en && proc->types.pointer.drag_sum.y >= indev_act->driver.drag_limit) || - (down_en && proc->types.pointer.drag_sum.y <= - indev_act->driver.drag_limit)) + if((left_en && proc->types.pointer.scroll_sum.x >= indev_act->driver.scroll_limit) || + (right_en && proc->types.pointer.scroll_sum.x <= - indev_act->driver.scroll_limit) || + (up_en && proc->types.pointer.scroll_sum.y >= indev_act->driver.scroll_limit) || + (down_en && proc->types.pointer.scroll_sum.y <= - indev_act->driver.scroll_limit)) { - proc->types.pointer.drag_limit_out = 1; - if(dirs == LV_DRAG_DIR_ONE) { - proc->types.pointer.drag_dir = hor_en ? LV_DRAG_DIR_HOR : LV_DRAG_DIR_VER; - } else { - proc->types.pointer.drag_dir = dirs; - } + proc->types.pointer.scroll_dir = hor_en ? LV_SCROLL_DIR_HOR : LV_SCROLL_DIR_VER; - /*The was no move due to drag limit. Compensate it now.*/ - if(!hor_en) proc->types.pointer.drag_sum.x = 0; - if(!ver_en) proc->types.pointer.drag_sum.y = 0; + if(!hor_en) proc->types.pointer.scroll_sum.x = 0; + if(!ver_en) proc->types.pointer.scroll_sum.y = 0; - act_x = lv_obj_get_x(proc->types.pointer.drag_obj) + proc->types.pointer.drag_sum.x; - act_y = lv_obj_get_y(proc->types.pointer.drag_obj) + proc->types.pointer.drag_sum.y; - break; + break; /*It"s good scrollable object, use it*/ } - proc->types.pointer.drag_obj = lv_obj_get_parent(proc->types.pointer.drag_obj); + proc->types.pointer.scroll_obj = lv_obj_get_parent(proc->types.pointer.scroll_obj); } } - /*If the drag/scroll can't be propagated to any parent show an elastic scroll in the original object*/ - if(proc->types.pointer.drag_obj == NULL) { + if(proc->types.pointer.scroll_obj == NULL) { if(scroll_candidate_obj) { - proc->types.pointer.drag_limit_out = 1; - proc->types.pointer.drag_dir = dirs_candidate; - proc->types.pointer.drag_obj = scroll_candidate_obj; + proc->types.pointer.scroll_dir = dirs_candidate; + proc->types.pointer.scroll_obj = scroll_candidate_obj; } else { return; } } - lv_obj_t * obj = proc->types.pointer.drag_obj; + /*If there is no scroll object there is nothing to do*/ + lv_obj_t * scroll_obj = proc->types.pointer.scroll_obj; + if(scroll_obj == NULL) return; - /*If the drag limit is exceeded handle the dragging*/ - if(proc->types.pointer.drag_limit_out != 0) { - /*Set new position or scroll if the vector is not zero*/ - if(proc->types.pointer.vect.x != 0 || proc->types.pointer.vect.y != 0) { - - lv_coord_t prev_x = obj->coords.x1; - lv_coord_t prev_y = obj->coords.y1; - - /*Move the object. `drag_sum` is zerod out for *disabled direction*/ - if(proc->types.pointer.drag_sum.x) act_x += proc->types.pointer.vect.x; - if(proc->types.pointer.drag_sum.y) act_y += proc->types.pointer.vect.y; - - uint16_t inv_buf_size = - lv_disp_get_inv_buf_size(indev_act->driver.disp); /*Get the number of currently invalidated areas*/ - - if(scrollable) { - lv_area_t child_box; - lv_obj_get_children_box(obj, &child_box); - lv_coord_t diff_y = proc->types.pointer.drag_dir == LV_DRAG_DIR_VER ? proc->types.pointer.vect.y : 0; - lv_coord_t diff_x = proc->types.pointer.drag_dir == LV_DRAG_DIR_HOR ? proc->types.pointer.vect.x : 0; - if(obj->scroll.x > 0 && diff_x > 0) { - diff_x = diff_x / 2; - } - if(child_box.y2 < obj->coords.y2 && diff_y < 0) { - diff_y = diff_y / 2; - } - - lv_obj_scroll_by(obj, diff_x, diff_y, LV_ANIM_OFF); - } else { - lv_obj_set_pos(obj, act_x, act_y); - } - - proc->types.pointer.drag_in_prog = 1; -// -// /*If the object didn't moved then clear the invalidated areas*/ -// if(target_obj->coords.x1 == prev_x && target_obj->coords.y1 == prev_y) { -// /*In a special case if the object is moved on a page and -// * the scrollable has fit == true and the object is dragged of the page then -// * while its coordinate is not changing only the parent's size is reduced */ -// lv_coord_t act_par_w = lv_obj_get_width(lv_obj_get_parent(target_obj)); -// lv_coord_t act_par_h = lv_obj_get_height(lv_obj_get_parent(target_obj)); -// if(act_par_w == prev_par_w && act_par_h == prev_par_h) { -// uint16_t new_inv_buf_size = lv_disp_get_inv_buf_size(indev_act->driver.disp); -// _lv_disp_pop_from_inv_buf(indev_act->driver.disp, new_inv_buf_size - inv_buf_size); -// } -// } -// -// /*Set the drag in progress flag*/ -// /*Send the drag begin signal on first move*/ -// if(just_started) { -// target_obj->signal_cb(target_obj, LV_SIGNAL_DRAG_BEGIN, indev_act); -// if(indev_reset_check(proc)) return; -// -// lv_event_send(target_obj, LV_EVENT_DRAG_BEGIN, NULL); -// if(indev_reset_check(proc)) return; -// } + /*Set new position or scroll if the vector is not zero*/ + if(proc->types.pointer.vect.x != 0 || proc->types.pointer.vect.y != 0) { + lv_coord_t diff_x = 0; + lv_coord_t diff_y = 0; + if(proc->types.pointer.scroll_dir == LV_SCROLL_DIR_HOR) { + diff_x = proc->types.pointer.vect.x; + if(lv_obj_get_scroll_right(scroll_obj) < 0) diff_x = diff_x / 2; + if(lv_obj_get_scroll_left(scroll_obj) < 0) diff_x = diff_x / 2; + } else { + diff_y = proc->types.pointer.vect.y; + if(lv_obj_get_scroll_top(scroll_obj) < 0) diff_y = diff_y / 2; + if(lv_obj_get_scroll_bottom(scroll_obj) < 0) diff_y = diff_y / 2; } + lv_obj_scroll_by(scroll_obj, diff_x, diff_y, LV_ANIM_OFF); } } /** - * Handle throwing by drag if the drag is ended + * Handle throwing by after scrolling * @param indev pointer to an input device state */ -static void indev_drag_throw(lv_indev_proc_t * proc) +static void indev_scroll_throw_handler(lv_indev_proc_t * proc) { - if(proc->types.pointer.drag_in_prog == 0) return; + lv_obj_t * scroll_obj = proc->types.pointer.scroll_obj; - - bool scrollable = true; - - /*Get which object to drad/scroll*/ - lv_obj_t * target_obj = proc->types.pointer.drag_obj; - if(target_obj == NULL) return; - - /*Return if the drag throw is not enabled*/ -// if(lv_obj_get_drag_throw(target_obj) == false) { -// proc->types.pointer.drag_in_prog = 0; -// target_obj->signal_cb(target_obj, scrollable ? LV_SIGNAL_SCROLL_END : LV_SIGNAL_DRAG_END, indev_act); -// if(indev_reset_check(proc)) return; -// -// lv_event_send(target_obj, LV_EVENT_DRAG_END, NULL); -// return; -// } + if(scroll_obj == NULL) return; + if(proc->types.pointer.scroll_dir == LV_SCROLL_DIR_NONE) return; /*Reduce the vectors*/ - proc->types.pointer.drag_throw_vect.x = - proc->types.pointer.drag_throw_vect.x * (100 - indev_act->driver.drag_throw) / 100; - proc->types.pointer.drag_throw_vect.y = - proc->types.pointer.drag_throw_vect.y * (100 - indev_act->driver.drag_throw) / 100; + proc->types.pointer.scroll_throw_vect.x = + proc->types.pointer.scroll_throw_vect.x * (100 - indev_act->driver.scroll_throw) / 100; + proc->types.pointer.scroll_throw_vect.y = + proc->types.pointer.scroll_throw_vect.y * (100 - indev_act->driver.scroll_throw) / 100; - switch(proc->types.pointer.drag_dir) { - case LV_DRAG_DIR_HOR: + switch(proc->types.pointer.scroll_dir) { + case LV_SCROLL_DIR_HOR: { - proc->types.pointer.drag_throw_vect.y = 0; - lv_coord_t sl = lv_obj_get_scroll_left(target_obj); - lv_coord_t sr = lv_obj_get_scroll_right(target_obj); + proc->types.pointer.scroll_throw_vect.y = 0; + lv_coord_t sl = lv_obj_get_scroll_left(scroll_obj); + lv_coord_t sr = lv_obj_get_scroll_right(scroll_obj); /*If scrolled inside reduce faster*/ - if(sl < 0 || sr < 0) proc->types.pointer.drag_throw_vect.x = proc->types.pointer.drag_throw_vect.x >> 1; + if(sl < 0 || sr < 0) proc->types.pointer.scroll_throw_vect.x = proc->types.pointer.scroll_throw_vect.x >> 1; break; } - case LV_DRAG_DIR_VER: + case LV_SCROLL_DIR_VER: { - proc->types.pointer.drag_throw_vect.x = 0; - lv_coord_t st = lv_obj_get_scroll_top(target_obj); - lv_coord_t sb = lv_obj_get_scroll_bottom(target_obj); + proc->types.pointer.scroll_throw_vect.x = 0; + lv_coord_t st = lv_obj_get_scroll_top(scroll_obj); + lv_coord_t sb = lv_obj_get_scroll_bottom(scroll_obj); /*If scrolled inside reduce faster*/ - if(st < 0 || sb < 0) proc->types.pointer.drag_throw_vect.y = proc->types.pointer.drag_throw_vect.y >> 1; + if(st < 0 || sb < 0) proc->types.pointer.scroll_throw_vect.y = proc->types.pointer.scroll_throw_vect.y >> 1; break; } } - if((proc->types.pointer.drag_throw_vect.x != 0 || proc->types.pointer.drag_throw_vect.y != 0)) { - /*Get the coordinates and modify them*/ - if(scrollable) { - lv_obj_scroll_by(target_obj, proc->types.pointer.drag_throw_vect.x, proc->types.pointer.drag_throw_vect.y, LV_ANIM_OFF); - } else { - lv_area_t coords_ori; - lv_obj_get_coords(target_obj, &coords_ori); - - lv_coord_t act_x = lv_obj_get_x(target_obj) + proc->types.pointer.drag_throw_vect.x; - lv_coord_t act_y = lv_obj_get_y(target_obj) + proc->types.pointer.drag_throw_vect.y; - lv_obj_set_pos(target_obj, act_x, act_y); - - lv_area_t coords_new; - lv_obj_get_coords(target_obj, &coords_new); - - /*If non of the coordinates are changed then do not continue throwing*/ - if((coords_ori.x1 == coords_new.x1 || proc->types.pointer.drag_throw_vect.x == 0) && - (coords_ori.y1 == coords_new.y1 || proc->types.pointer.drag_throw_vect.y == 0)) { - proc->types.pointer.drag_in_prog = 0; - proc->types.pointer.vect.x = 0; - proc->types.pointer.vect.y = 0; - proc->types.pointer.drag_throw_vect.x = 0; - proc->types.pointer.drag_throw_vect.y = 0; - target_obj->signal_cb(target_obj, LV_SIGNAL_DRAG_END, indev_act); - if(indev_reset_check(proc)) return; - - lv_event_send(target_obj, LV_EVENT_DRAG_END, NULL); - if(indev_reset_check(proc)) return; - } - - } - + if((proc->types.pointer.scroll_throw_vect.x != 0 || proc->types.pointer.scroll_throw_vect.y != 0)) { + lv_obj_scroll_by(scroll_obj, proc->types.pointer.scroll_throw_vect.x, proc->types.pointer.scroll_throw_vect.y, LV_ANIM_OFF); } - /*If the types.pointer.vectors become 0 -> types.pointer.drag_in_prog = 0 and send a drag end + /*If the vectors become 0 then finish scrolling signal*/ else { - proc->types.pointer.drag_in_prog = 0; - proc->types.pointer.drag_obj = NULL; - target_obj->signal_cb(target_obj, scrollable ? LV_SIGNAL_SCROLL_END : LV_SIGNAL_DRAG_END, indev_act); + proc->types.pointer.scroll_dir = LV_SCROLL_DIR_NONE; + proc->types.pointer.scroll_obj = NULL; + lv_signal_send(scroll_obj, LV_SIGNAL_SCROLL_END, indev_act); if(indev_reset_check(proc)) return; - lv_event_send(target_obj, LV_EVENT_DRAG_END, NULL); + lv_event_send(scroll_obj, LV_EVENT_SCROLL_END, indev_act); if(indev_reset_check(proc)) return; } } - -/** - * Get the really dragged object by taking `drag_parent` into account. - * @param obj the start object - * @return the object to really drag - */ -static lv_obj_t * get_dragged_obj(lv_obj_t * obj) -{ - return obj; - - if(indev_act->proc.types.pointer.drag_obj) { - return indev_act->proc.types.pointer.drag_obj; - } else { - lv_area_t child_box; - lv_obj_get_children_box(obj, &child_box); - if(child_box.y2 == obj->coords.y2) indev_act->proc.types.pointer.drag_obj = lv_obj_get_parent(obj); - else indev_act->proc.types.pointer.drag_obj = obj; - } - - return indev_act->proc.types.pointer.drag_obj; - - - if(obj == NULL) return NULL; - lv_obj_t * drag_obj = obj; - while(lv_obj_get_drag_parent(drag_obj) != false && drag_obj != NULL) { - drag_obj = lv_obj_get_parent(drag_obj); - } - - if(lv_obj_get_drag(drag_obj) == false) return NULL; - return drag_obj; -} - - /** * Handle the gesture of indev_proc_p->types.pointer.act_obj * @param indev pointer to a input device state @@ -1546,7 +1343,7 @@ static lv_obj_t * get_dragged_obj(lv_obj_t * obj) static void indev_gesture(lv_indev_proc_t * proc) { - if(proc->types.pointer.drag_in_prog) return; + if(proc->types.pointer.scroll_obj) return; if(proc->types.pointer.gesture_sent) return; lv_obj_t * gesture_obj = proc->types.pointer.act_obj; diff --git a/src/lv_core/lv_indev.h b/src/lv_core/lv_indev.h index 403081f22..ebaf519c0 100644 --- a/src/lv_core/lv_indev.h +++ b/src/lv_core/lv_indev.h @@ -120,36 +120,28 @@ lv_gesture_dir_t lv_indev_get_gesture_dir(const lv_indev_t * indev); uint32_t lv_indev_get_key(const lv_indev_t * indev); /** - * Check if there is dragging with an input device or not (for LV_INDEV_TYPE_POINTER and + * Check the current scroll direction of an input device (for LV_INDEV_TYPE_POINTER and * LV_INDEV_TYPE_BUTTON) * @param indev pointer to an input device - * @return true: drag is in progress + * @return LV_SCROLL_DIR_NONE: no scrolling now + * LV_SCROLL_DIR_HOR/VER */ -bool lv_indev_is_dragging(const lv_indev_t * indev); +lv_scroll_dir_t lv_indev_get_scroll_dir(const lv_indev_t * indev); /** - * Get the vector of dragging of an input device (for LV_INDEV_TYPE_POINTER and + * Get the movement vector of an input device (for LV_INDEV_TYPE_POINTER and * LV_INDEV_TYPE_BUTTON) * @param indev pointer to an input device - * @param point pointer to a point to store the vector + * @param point pointer to a point to store the types.pointer.vector */ void lv_indev_get_vect(const lv_indev_t * indev, lv_point_t * point); -/** - * Manually finish dragging. - * `LV_SIGNAL_DRAG_END` and `LV_EVENT_DRAG_END` will be sent. - * @param indev pointer to an input device - * @return `LV_RES_INV` if the object being dragged was deleted. Else `LV_RES_OK`. - */ -lv_res_t lv_indev_finish_drag(lv_indev_t * indev); - /** * Do nothing until the next release * @param indev pointer to an input device */ void lv_indev_wait_release(lv_indev_t * indev); - /** * Gets a pointer to the currently active object in indev proc functions. * NULL if no object is currently being handled or if groups aren't used. diff --git a/src/lv_core/lv_obj.c b/src/lv_core/lv_obj.c index 5b1c9c068..053775ca9 100644 --- a/src/lv_core/lv_obj.c +++ b/src/lv_core/lv_obj.c @@ -329,10 +329,7 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy) /*Set attributes*/ new_obj->adv_hittest = 0; new_obj->click = 1; - new_obj->drag = 0; - new_obj->drag_throw = 0; - new_obj->drag_parent = 0; - new_obj->drag_dir = LV_DRAG_DIR_BOTH; + new_obj->scroll_mode = LV_SCROLL_MODE_AUTO; new_obj->hidden = 0; new_obj->top = 0; new_obj->protect = LV_PROTECT_NONE; @@ -340,6 +337,8 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy) new_obj->gesture_parent = parent ? 1 : 0; new_obj->focus_parent = 0; new_obj->state = LV_STATE_DEFAULT; + new_obj->scroll.x = 0; + new_obj->scroll.y = 0; new_obj->ext_attr = NULL; @@ -384,10 +383,7 @@ lv_obj_t * lv_obj_create(lv_obj_t * parent, const lv_obj_t * copy) /*Copy attributes*/ new_obj->adv_hittest = copy->adv_hittest; new_obj->click = copy->click; - new_obj->drag = copy->drag; - new_obj->drag_dir = copy->drag_dir; - new_obj->drag_throw = copy->drag_throw; - new_obj->drag_parent = copy->drag_parent; + new_obj->scroll_mode = copy->scroll_mode; new_obj->hidden = copy->hidden; new_obj->top = copy->top; new_obj->parent_event = copy->parent_event; @@ -1613,55 +1609,17 @@ void lv_obj_set_top(lv_obj_t * obj, bool en) } /** - * Enable the dragging of an object + * Set how the scrollbars should behave. * @param obj pointer to an object - * @param en true: make the object draggable + * @param mode: LV_SCROLL_MODE_ON/OFF/AUTO/ACTIVE */ -void lv_obj_set_drag(lv_obj_t * obj, bool en) +void lv_obj_set_scroll_mode(lv_obj_t * obj, lv_scroll_mode_t mode) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - if(en == true) lv_obj_set_click(obj, true); /*Drag is useless without enabled clicking*/ - obj->drag = (en == true ? 1 : 0); -} - -/** - * Set the directions an object can be dragged in - * @param obj pointer to an object - * @param drag_dir bitwise OR of allowed directions an object can be dragged in - */ -void lv_obj_set_drag_dir(lv_obj_t * obj, lv_drag_dir_t drag_dir) -{ - LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - - obj->drag_dir = drag_dir; - - if(obj->drag_dir != 0) lv_obj_set_drag(obj, true); /*Drag direction requires drag*/ -} - -/** - * Enable the throwing of an object after is is dragged - * @param obj pointer to an object - * @param en true: enable the drag throw - */ -void lv_obj_set_drag_throw(lv_obj_t * obj, bool en) -{ - LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - - obj->drag_throw = (en == true ? 1 : 0); -} - -/** - * Enable to use parent for drag related operations. - * If trying to drag the object the parent will be moved instead - * @param obj pointer to an object - * @param en true: enable the 'drag parent' for the object - */ -void lv_obj_set_drag_parent(lv_obj_t * obj, bool en) -{ - LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - - obj->drag_parent = (en == true ? 1 : 0); + if(obj->scroll_mode == mode) return; + obj->scroll_mode = mode; + lv_obj_invalidate(obj); } /** @@ -2944,61 +2902,15 @@ bool lv_obj_get_top(const lv_obj_t * obj) } /** - * Get the drag enable attribute of an object + * Get how the scrollbars should behave. * @param obj pointer to an object - * @return true: the object is draggable + * @return mode: LV_SCROLL_MODE_ON/OFF/AUTO/ACTIVE */ -bool lv_obj_get_drag(const lv_obj_t * obj) +lv_scroll_mode_t lv_obj_get_scroll_mode(lv_obj_t * obj) { LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - return obj->drag == 0 ? false : true; -} - -/** - * Get the directions an object can be dragged - * @param obj pointer to an object - * @return bitwise OR of allowed directions an object can be dragged in - */ -lv_drag_dir_t lv_obj_get_drag_dir(const lv_obj_t * obj) -{ - LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - - return obj->drag_dir; -} - -/** - * Get the directions an object can be scrolled - * @param obj pointer to an object - * @return bitwise OR of allowed directions an object can be dragged in - */ -lv_drag_dir_t lv_obj_get_scroll_dir(const lv_obj_t * obj) -{ - LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - - return obj->scroll_dir; -} - -/** - * Get the drag throw enable attribute of an object - * @param obj pointer to an object - * @return true: drag throw is enabled - */ -bool lv_obj_get_drag_throw(const lv_obj_t * obj) -{ - LV_ASSERT_OBJ(obj, LV_OBJX_NAME); - - return obj->drag_throw == 0 ? false : true; -} - -/** - * Get the drag parent attribute of an object - * @param obj pointer to an object - * @return true: drag parent is enabled - */ -bool lv_obj_get_drag_parent(const lv_obj_t * obj) -{ - return obj->drag_parent == 0 ? false : true; + return obj->scroll_mode; } /** @@ -3022,9 +2934,9 @@ bool lv_obj_get_focus_parent(const lv_obj_t * obj) } /** - * Get the drag parent attribute of an object + * Get the parent event attribute of an object * @param obj pointer to an object - * @return true: drag parent is enabled + * @return true: parent event is enabled */ bool lv_obj_get_parent_event(const lv_obj_t * obj) { diff --git a/src/lv_core/lv_obj.h b/src/lv_core/lv_obj.h index f2e01a33f..87286ec6a 100644 --- a/src/lv_core/lv_obj.h +++ b/src/lv_core/lv_obj.h @@ -85,15 +85,16 @@ enum { LV_EVENT_PRESSED, /**< The object has been pressed*/ LV_EVENT_PRESSING, /**< The object is being pressed (called continuously while pressing)*/ LV_EVENT_PRESS_LOST, /**< User is still pressing but slid cursor/finger off of the object */ - LV_EVENT_SHORT_CLICKED, /**< User pressed object for a short period of time, then released it. Not called if dragged. */ - LV_EVENT_LONG_PRESSED, /**< Object has been pressed for at least `LV_INDEV_LONG_PRESS_TIME`. Not called if dragged.*/ + LV_EVENT_SHORT_CLICKED, /**< User pressed object for a short period of time, then released it. Not called if scrolled. */ + LV_EVENT_LONG_PRESSED, /**< Object has been pressed for at least `LV_INDEV_LONG_PRESS_TIME`. Not called if scrolled.*/ LV_EVENT_LONG_PRESSED_REPEAT, /**< Called after `LV_INDEV_LONG_PRESS_TIME` in every - `LV_INDEV_LONG_PRESS_REP_TIME` ms. Not called if dragged.*/ - LV_EVENT_CLICKED, /**< Called on release if not dragged (regardless to long press)*/ + `LV_INDEV_LONG_PRESS_REP_TIME` ms. Not called if scrolled.*/ + LV_EVENT_CLICKED, /**< Called on release if not scrolled (regardless to long press)*/ LV_EVENT_RELEASED, /**< Called in every cases when the object has been released*/ - LV_EVENT_DRAG_BEGIN, - LV_EVENT_DRAG_END, - LV_EVENT_DRAG_THROW_BEGIN, + LV_EVENT_SCROLL_BEGIN, + LV_EVENT_SCROLL_THROW_BEGIN, + LV_EVENT_SCROLL_END, + LV_EVENT_SCROLL, LV_EVENT_GESTURE, /**< The object has been gesture*/ LV_EVENT_KEY, LV_EVENT_FOCUSED, @@ -136,15 +137,13 @@ enum { LV_SIGNAL_PRESSED, /**< The object has been pressed*/ LV_SIGNAL_PRESSING, /**< The object is being pressed (called continuously while pressing)*/ LV_SIGNAL_PRESS_LOST, /**< User is still pressing but slid cursor/finger off of the object */ - LV_SIGNAL_RELEASED, /**< User pressed object for a short period of time, then released it. Not called if dragged. */ - LV_SIGNAL_LONG_PRESS, /**< Object has been pressed for at least `LV_INDEV_LONG_PRESS_TIME`. Not called if dragged.*/ - LV_SIGNAL_LONG_PRESS_REP, /**< Called after `LV_INDEV_LONG_PRESS_TIME` in every `LV_INDEV_LONG_PRESS_REP_TIME` ms. Not called if dragged.*/ + LV_SIGNAL_RELEASED, /**< User pressed object for a short period of time, then released it. Not called if scrolled. */ + LV_SIGNAL_LONG_PRESS, /**< Object has been pressed for at least `LV_INDEV_LONG_PRESS_TIME`. Not called if scrolled.*/ + LV_SIGNAL_LONG_PRESS_REP, /**< Called after `LV_INDEV_LONG_PRESS_TIME` in every `LV_INDEV_LONG_PRESS_REP_TIME` ms. Not called if scrolled.*/ LV_SIGNAL_SCROLL_BEGIN, /**< The scrolling has just begun */ LV_SIGNAL_SCROLL, /**< The object has been scrolled */ LV_SIGNAL_SCROLL_END, /**< The scrolling has ended */ - LV_SIGNAL_DRAG_BEGIN, - LV_SIGNAL_DRAG_THROW_BEGIN, - LV_SIGNAL_DRAG_END, + LV_SIGNAL_SCROLL_THROW_BEGIN,/**< Scroll throw started*/ LV_SIGNAL_GESTURE, /**< The object has been gesture*/ LV_SIGNAL_LEAVE, /**< Another object is clicked or chosen via an input device */ @@ -196,6 +195,15 @@ enum { typedef uint8_t lv_state_t; +/** Scrollbar modes: shows when should the scrollbars be visible*/ +enum { + LV_SCROLL_MODE_OFF = 0x0, /**< Never show scroll bars*/ + LV_SCROLL_MODE_ON = 0x1, /**< Always show scroll bars*/ + LV_SCROLL_MODE_ACTIVE = 0x2, /**< Show scroll bars when object is being scrolled*/ + LV_SCROLL_MODE_AUTO = 0x3, /**< Show scroll bars when the content is large enough to be scrolled*/ +}; +typedef uint8_t lv_scroll_mode_t; + typedef struct _lv_obj_t { struct _lv_obj_t * parent; /**< Pointer to the parent object*/ lv_ll_t child_ll; /**< Linked list to store the children objects*/ @@ -221,19 +229,13 @@ typedef struct _lv_obj_t { /*Attributes and states*/ uint8_t click : 1; /**< 1: Can be pressed by an input device*/ - uint8_t drag : 1; /**< 1: Enable the dragging*/ - uint8_t drag_throw : 1; /**< 1: Enable throwing with drag*/ - uint8_t drag_parent : 1; /**< 1: Parent will be dragged instead*/ uint8_t hidden : 1; /**< 1: Object is hidden*/ uint8_t top : 1; /**< 1: If the object or its children is clicked it goes to the foreground*/ uint8_t parent_event : 1; /**< 1: Send the object's events to the parent too. */ uint8_t adv_hittest : 1; /**< 1: Use advanced hit-testing (slower) */ uint8_t gesture_parent : 1; /**< 1: Parent will be gesture instead*/ uint8_t focus_parent : 1; /**< 1: Parent will be focused instead*/ - lv_drag_dir_t scroll_elastic : 3; /**< In which directions the object can be scrolled */ - - lv_drag_dir_t drag_dir : 3; /**< In which directions the object can be dragged */ - lv_drag_dir_t scroll_dir : 3; /**< In which directions the object can be scrolled */ + lv_scroll_mode_t scroll_mode :2; /**< How to display scrollbars*/ lv_bidi_dir_t base_dir : 2; /**< Base direction of texts related to this object */ #if LV_USE_GROUP != 0 @@ -781,35 +783,6 @@ void lv_obj_set_click(lv_obj_t * obj, bool en); */ void lv_obj_set_top(lv_obj_t * obj, bool en); -/** - * Enable the dragging of an object - * @param obj pointer to an object - * @param en true: make the object draggable - */ -void lv_obj_set_drag(lv_obj_t * obj, bool en); - -/** - * Set the directions an object can be dragged in - * @param obj pointer to an object - * @param drag_dir bitwise OR of allowed drag directions - */ -void lv_obj_set_drag_dir(lv_obj_t * obj, lv_drag_dir_t drag_dir); - -/** - * Enable the throwing of an object after is is dragged - * @param obj pointer to an object - * @param en true: enable the drag throw - */ -void lv_obj_set_drag_throw(lv_obj_t * obj, bool en); - -/** - * Enable to use parent for drag related operations. - * If trying to drag the object the parent will be moved instead - * @param obj pointer to an object - * @param en true: enable the 'drag parent' for the object - */ -void lv_obj_set_drag_parent(lv_obj_t * obj, bool en); - /** * Enable to use parent for focus state. * When object is focused the parent will get the state instead (visual only) @@ -818,6 +791,13 @@ void lv_obj_set_drag_parent(lv_obj_t * obj, bool en); */ void lv_obj_set_focus_parent(lv_obj_t * obj, bool en); +/** + * Set how the scrollbars should behave. + * @param obj pointer to an object + * @param mode: LV_SCROLL_MODE_ON/OFF/AUTO/ACTIVE + */ +void lv_obj_set_scroll_mode(lv_obj_t * obj, lv_scroll_mode_t mode); + /** * Enable to use parent for gesture related operations. * If trying to gesture the object the parent will be moved instead @@ -1314,42 +1294,6 @@ bool lv_obj_get_click(const lv_obj_t * obj); */ bool lv_obj_get_top(const lv_obj_t * obj); -/** - * Get the drag enable attribute of an object - * @param obj pointer to an object - * @return true: the object is draggable - */ -bool lv_obj_get_drag(const lv_obj_t * obj); - -/** - * Get the directions an object can be dragged - * @param obj pointer to an object - * @return bitwise OR of allowed directions an object can be dragged in - */ -lv_drag_dir_t lv_obj_get_drag_dir(const lv_obj_t * obj); - -/** - * Get the directions an object can be scrolled - * @param obj pointer to an object - * @return bitwise OR of allowed directions an object can be dragged in - */ -lv_drag_dir_t lv_obj_get_scroll_dir(const lv_obj_t * obj); - -/** - * Get the drag throw enable attribute of an object - * @param obj pointer to an object - * @return true: drag throw is enabled - */ -bool lv_obj_get_drag_throw(const lv_obj_t * obj); - -/** - * Get the drag parent attribute of an object - * @param obj pointer to an object - * @return true: drag parent is enabled - */ -bool lv_obj_get_drag_parent(const lv_obj_t * obj); - - /** * Get the focus parent attribute of an object * @param obj pointer to an object @@ -1357,11 +1301,10 @@ bool lv_obj_get_drag_parent(const lv_obj_t * obj); */ bool lv_obj_get_focus_parent(const lv_obj_t * obj); - /** - * Get the drag parent attribute of an object + * Get the parent event attribute of an object * @param obj pointer to an object - * @return true: drag parent is enabled + * @return true: parent event is enabled */ bool lv_obj_get_parent_event(const lv_obj_t * obj); diff --git a/src/lv_hal/lv_hal_indev.c b/src/lv_hal/lv_hal_indev.c index ca4404816..c0f2f4835 100644 --- a/src/lv_hal/lv_hal_indev.c +++ b/src/lv_hal/lv_hal_indev.c @@ -54,8 +54,8 @@ void lv_indev_drv_init(lv_indev_drv_t * driver) _lv_memset_00(driver, sizeof(lv_indev_drv_t)); driver->type = LV_INDEV_TYPE_NONE; - driver->drag_limit = LV_INDEV_DEF_DRAG_LIMIT; - driver->drag_throw = LV_INDEV_DEF_DRAG_THROW; + driver->scroll_limit = LV_INDEV_DEF_DRAG_LIMIT; + driver->scroll_throw = LV_INDEV_DEF_DRAG_THROW; driver->long_press_time = LV_INDEV_DEF_LONG_PRESS_TIME; driver->long_press_rep_time = LV_INDEV_DEF_LONG_PRESS_REP_TIME; driver->gesture_limit = LV_INDEV_DEF_GESTURE_LIMIT; diff --git a/src/lv_hal/lv_hal_indev.h b/src/lv_hal/lv_hal_indev.h index a4af05936..b49080db3 100644 --- a/src/lv_hal/lv_hal_indev.h +++ b/src/lv_hal/lv_hal_indev.h @@ -52,14 +52,12 @@ typedef uint8_t lv_indev_state_t; enum { - LV_DRAG_DIR_NONE = 0x0, /**< Object can't be dragged to any directions. */ - LV_DRAG_DIR_HOR = 0x1, /**< Object can be dragged horizontally. */ - LV_DRAG_DIR_VER = 0x2, /**< Object can be dragged vertically. */ - LV_DRAG_DIR_BOTH = 0x3, /**< Object can be dragged in all directions. */ - LV_DRAG_DIR_ONE = 0x4, /**< Object can be dragged only one direction (the first move). */ + LV_SCROLL_DIR_NONE = 0x0, /**< Object can't be dragged to any directions. */ + LV_SCROLL_DIR_HOR = 0x1, /**< Object can be dragged horizontally. */ + LV_SCROLL_DIR_VER = 0x2, /**< Object can be dragged vertically. */ }; -typedef uint8_t lv_drag_dir_t; +typedef uint8_t lv_scroll_dir_t; enum { LV_GESTURE_DIR_TOP, /**< Gesture dir up. */ @@ -106,10 +104,10 @@ typedef struct _lv_indev_drv_t { lv_task_t * read_task; /**< Number of pixels to slide before actually drag the object*/ - uint8_t drag_limit; + uint8_t scroll_limit; /**< Drag throw slow-down in [%]. Greater value means faster slow-down */ - uint8_t drag_throw; + uint8_t scroll_throw; /**< At least this difference should between two points to evaluate as gesture */ uint8_t gesture_min_velocity; @@ -135,20 +133,18 @@ typedef struct _lv_indev_proc_t { lv_point_t act_point; /**< Current point of input device. */ lv_point_t last_point; /**< Last point of input device. */ lv_point_t vect; /**< Difference between `act_point` and `last_point`. */ - lv_point_t drag_sum; /*Count the dragged pixels to check LV_INDEV_DEF_DRAG_LIMIT*/ - lv_point_t drag_throw_vect; + lv_point_t scroll_sum; /*Count the dragged pixels to check LV_INDEV_DEF_DRAG_LIMIT*/ + lv_point_t scroll_throw_vect; struct _lv_obj_t * act_obj; /*The object being pressed*/ struct _lv_obj_t * last_obj; /*The last object which was pressed (used by drag_throw and other post-release event)*/ - struct _lv_obj_t * drag_obj; /*The object being pressed*/ + struct _lv_obj_t * scroll_obj; /*The object being scrolled*/ struct _lv_obj_t * last_pressed; /*The lastly pressed object*/ lv_gesture_dir_t gesture_dir; lv_point_t gesture_sum; /*Count the gesture pixels to check LV_INDEV_DEF_GESTURE_LIMIT*/ /*Flags*/ - uint8_t drag_limit_out : 1; - uint8_t drag_in_prog : 1; - lv_drag_dir_t drag_dir : 3; + lv_scroll_dir_t scroll_dir : 2; uint8_t gesture_sent : 1; } pointer; struct { diff --git a/src/lv_widgets/lv_btn.c b/src/lv_widgets/lv_btn.c index fa327bd6e..e3d7d9325 100644 --- a/src/lv_widgets/lv_btn.c +++ b/src/lv_widgets/lv_btn.c @@ -273,7 +273,7 @@ static lv_res_t lv_btn_signal(lv_obj_t * btn, lv_signal_t sign, void * param) if(sign == LV_SIGNAL_RELEASED) { /*If not dragged and it was not long press action then *change state and run the action*/ - if(lv_indev_is_dragging(param) == false && tgl) { + if(lv_indev_get_scroll_dir(param) == LV_SCROLL_DIR_NONE && tgl) { uint32_t toggled = 0; if(lv_obj_get_state(btn, LV_BTN_PART_MAIN) & LV_STATE_CHECKED) { lv_btn_set_state(btn, LV_BTN_STATE_RELEASED); diff --git a/src/lv_widgets/lv_cpicker.c b/src/lv_widgets/lv_cpicker.c index d80c9a56c..21d1c09c2 100644 --- a/src/lv_widgets/lv_cpicker.c +++ b/src/lv_widgets/lv_cpicker.c @@ -768,8 +768,8 @@ static lv_res_t lv_cpicker_signal(lv_obj_t * cpicker, lv_signal_t sign, void * p lv_indev_get_point(indev, &p); } - if((LV_MATH_ABS(p.x - ext->last_press_point.x) > indev->driver.drag_limit / 2) || - (LV_MATH_ABS(p.y - ext->last_press_point.y) > indev->driver.drag_limit / 2)) { + if((LV_MATH_ABS(p.x - ext->last_press_point.x) > indev->driver.scroll_limit / 2) || + (LV_MATH_ABS(p.y - ext->last_press_point.y) > indev->driver.scroll_limit / 2)) { ext->last_change_time = lv_tick_get(); ext->last_press_point.x = p.x; ext->last_press_point.y = p.y; diff --git a/src/lv_widgets/lv_dropdown.c b/src/lv_widgets/lv_dropdown.c index c7bbd8746..e6b05eba8 100644 --- a/src/lv_widgets/lv_dropdown.c +++ b/src/lv_widgets/lv_dropdown.c @@ -930,7 +930,7 @@ static lv_res_t lv_dropdown_signal(lv_obj_t * ddlist, lv_signal_t sign, void * p } else if(sign == LV_SIGNAL_RELEASED) { lv_indev_t * indev = lv_indev_get_act(); - if(lv_indev_is_dragging(indev) == false) { + if(lv_indev_is_scrolling(indev) == false) { if(ext->page) { lv_dropdown_close(ddlist); if(ext->sel_opt_id_orig != ext->sel_opt_id) { @@ -1034,7 +1034,7 @@ static lv_res_t lv_dropdown_page_signal(lv_obj_t * page, lv_signal_t sign, void scrl->ext_draw_pad = LV_MATH_MAX3(scrl->ext_draw_pad, left, right); } else if(sign == LV_SIGNAL_RELEASED) { - if(lv_indev_is_dragging(lv_indev_get_act()) == false) { + if(lv_indev_is_scrolling(lv_indev_get_act()) == false) { page_release_handler(page); } } @@ -1071,7 +1071,7 @@ static lv_res_t lv_dropdown_page_scrl_signal(lv_obj_t * scrl, lv_signal_t sign, lv_dropdown_ext_t * ext = lv_obj_get_ext_attr(ddlist); if(sign == LV_SIGNAL_RELEASED) { - if(lv_indev_is_dragging(lv_indev_get_act()) == false) { + if(lv_indev_is_scrolling(lv_indev_get_act()) == false) { page_release_handler(page); } } diff --git a/src/lv_widgets/lv_list.c b/src/lv_widgets/lv_list.c index 76ba666ff..d1d370a87 100644 --- a/src/lv_widgets/lv_list.c +++ b/src/lv_widgets/lv_list.c @@ -688,7 +688,7 @@ static lv_res_t lv_list_signal(lv_obj_t * list, lv_signal_t sign, void * param) res = lv_event_send(ext->act_sel_btn, LV_EVENT_SHORT_CLICKED, NULL); if(res != LV_RES_OK) return res; } - if(lv_indev_is_dragging(indev) == false) { + if(lv_indev_is_scrolling(indev) == false) { res = lv_event_send(ext->act_sel_btn, LV_EVENT_CLICKED, NULL); if(res != LV_RES_OK) return res; } @@ -806,7 +806,7 @@ static lv_res_t lv_list_btn_signal(lv_obj_t * btn, lv_signal_t sign, void * para } } else if(sign == LV_SIGNAL_RELEASED) { - if(lv_indev_is_dragging(lv_indev_get_act()) == false) { + if(lv_indev_is_scrolling(lv_indev_get_act()) == false) { lv_obj_t * list = lv_obj_get_parent(lv_obj_get_parent(btn)); lv_list_focus_btn(list, btn); #if LV_USE_GROUP diff --git a/src/lv_widgets/lv_page.c b/src/lv_widgets/lv_page.c index 89c6c0f0e..f7e1a8e34 100644 --- a/src/lv_widgets/lv_page.c +++ b/src/lv_widgets/lv_page.c @@ -932,7 +932,7 @@ static lv_res_t lv_page_scrollable_signal(lv_obj_t * scrl, lv_signal_t sign, voi if(parent_ext->scroll_prop_obj == NULL) { /*If the dragging just started or scroll is already propagated to this object * enable the scroll propagation if the conditions are met*/ - if((lv_indev_is_dragging(indev) == false || page_ext->scroll_prop_obj) && (drag_sum->y || drag_sum->x)) { + if((lv_indev_is_scrolling(indev) == false || page_ext->scroll_prop_obj) && (drag_sum->y || drag_sum->x)) { /*Propagate vertically?*/ if((drag_sum->y > 0 && lv_page_on_edge(page, LV_PAGE_EDGE_TOP)) || (drag_sum->y < 0 && lv_page_on_edge(page, LV_PAGE_EDGE_BOTTOM))) { diff --git a/src/lv_widgets/lv_roller.c b/src/lv_widgets/lv_roller.c index 46f81221a..9b1672ceb 100644 --- a/src/lv_widgets/lv_roller.c +++ b/src/lv_widgets/lv_roller.c @@ -885,7 +885,7 @@ static lv_res_t release_handler(lv_obj_t * roller) { /*If there was dragging `DRAG_END` signal will refresh the position and update the selected option*/ - if(lv_indev_is_dragging(lv_indev_get_act())) return LV_RES_OK; + if(lv_indev_is_scrolling(lv_indev_get_act())) return LV_RES_OK; lv_roller_ext_t * ext = lv_obj_get_ext_attr(roller); diff --git a/src/lv_widgets/lv_tileview.c b/src/lv_widgets/lv_tileview.c index 0ea0f8133..f5dae125c 100644 --- a/src/lv_widgets/lv_tileview.c +++ b/src/lv_widgets/lv_tileview.c @@ -380,7 +380,7 @@ static lv_res_t lv_tileview_scrl_signal(lv_obj_t * scrl, lv_signal_t sign, void } /*Apply the drag constraints*/ - lv_drag_dir_t drag_dir = indev->proc.types.pointer.drag_dir; + lv_scroll_dir_t drag_dir = indev->proc.types.pointer.drag_dir; if(drag_dir == LV_DRAG_DIR_HOR) lv_obj_set_y(scrl, -ext->act_id.y * lv_obj_get_height(tileview) + top); else if(drag_dir == LV_DRAG_DIR_VER) @@ -406,7 +406,7 @@ static void drag_end_handler(lv_obj_t * tileview) p.x = -(lv_obj_get_x(scrl) - lv_obj_get_width(tileview) / 2); p.y = -(lv_obj_get_y(scrl) - lv_obj_get_height(tileview) / 2); - lv_drag_dir_t drag_dir = indev->proc.types.pointer.drag_dir; + lv_scroll_dir_t drag_dir = indev->proc.types.pointer.drag_dir; /*From the drag vector (drag throw) predict the end position*/ if(drag_dir & LV_DRAG_DIR_HOR) { lv_point_t vect;