LVGL-输入设备LV_INDEV_TYPE_POINTER类型

void _lv_indev_read_task(lv_task_t * task)是定时执行的输入设备任务回调函数。会处理输入设备的数据。

按下的处理:

        static void indev_proc_press(lv_indev_proc_t * proc)

        {

        ……

        *首先从layer_sys,layer_top,scr_act按优级查找当前的活动对象

       /* bool lv_obj_is_point_on_coords(lv_obj_t * obj, const lv_point_t * point)*/

        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),
                                                                          &proc->types.pointer.act_point);
        if(indev_obj_act == NULL) indev_obj_act = lv_indev_search_obj(lv_disp_get_scr_act(disp),
                                                                          &proc->types.pointer.act_point);
        new_obj_searched = true;

        ……

        *如果按下时有throw动作手动停止。page drag后一般有throw动作。

            /*The last object might have drag 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.act_obj是上一次的活动  对象,通知上一个活动对象PRESS_LOST(1次)。通知最近的对象被PRESSED(1次),并复位一些寄存器。

    /*If a new object was found reset some variables and send a pressed signal*/
    if(indev_obj_act != proc->types.pointer.act_obj) {
        /*刚选中的活动对象不产生坐标向量值,把last_point与act_point同步*/
        proc->types.pointer.last_point.x = proc->types.pointer.act_point.x;
        proc->types.pointer.last_point.y = proc->types.pointer.act_point.y;

        /*If a new object found the previous was lost, so send a signal*/
        if(proc->types.pointer.act_obj != NULL) {
            /*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);
            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*/
        proc->types.pointer.last_obj = indev_obj_act;

        if(indev_obj_act != NULL) {
            /* 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.gesture_sent   = 0;
            proc->types.pointer.gesture_sum.x  = 0;
            proc->types.pointer.gesture_sum.y  = 0;
            proc->types.pointer.vect.x         = 0;
            proc->types.pointer.vect.y         = 0;

            /*Search for 'top' attribute*/
            lv_obj_t * i        = indev_obj_act;
            lv_obj_t * last_top = NULL;
            while(i != NULL) {
                if(i->top) last_top = i;
                i = lv_obj_get_parent(i);
            }

            if(last_top != NULL) {
                /*Move the last_top object to the foreground*/
                lv_obj_move_foreground(last_top);
            }

            /*Send a signal about the press*/
            indev_obj_act->signal_cb(indev_obj_act, LV_SIGNAL_PRESSED, indev_act);
            if(indev_reset_check(proc)) return;

            lv_event_send(indev_obj_act, LV_EVENT_PRESSED, NULL);
            if(indev_reset_check(proc)) return;

            if(indev_act->proc.wait_until_release) return;

            /*Handle focus*/
            indev_click_focus(&indev_act->proc);
            if(indev_reset_check(proc)) return;

        }
    }

        *构建drag_throw_vect(throw效果的向量)与vect(两次坐标输入向量)的相关性,方便释放时使用。

    ……
    /*Calculate the types.pointer.vector*/
    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 * 5) >> 3;
    proc->types.pointer.drag_throw_vect.y = (proc->types.pointer.drag_throw_vect.y * 5) >> 3;

    if(proc->types.pointer.drag_throw_vect.x < 0)
        proc->types.pointer.drag_throw_vect.x++;
    else if(proc->types.pointer.drag_throw_vect.x > 0)
        proc->types.pointer.drag_throw_vect.x--;

    if(proc->types.pointer.drag_throw_vect.y < 0)
        proc->types.pointer.drag_throw_vect.y++;
    else if(proc->types.pointer.drag_throw_vect.y > 0)
        proc->types.pointer.drag_throw_vect.y--;

    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;
    ……

        *处理拖动、手势、长按、重复长按。PRESSING信号会一直发送。

    /*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_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_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) 
        {
            /*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);
                if(indev_reset_check(proc)) return;
                lv_event_send(indev_obj_act, LV_EVENT_LONG_PRESSED, NULL);
                if(indev_reset_check(proc)) return;

                /*Mark the signal sending to do not send it again*/
                proc->long_pr_sent = 1;

                /*Save the long press time stamp for the long press repeat handler*/
                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) 
        {
            /*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);
                if(indev_reset_check(proc)) return;
                lv_event_send(indev_obj_act, LV_EVENT_LONG_PRESSED_REPEAT, NULL);
                if(indev_reset_check(proc)) return;
                proc->longpr_rep_timestamp = lv_tick_get();
            }
        }
    }

   *indev_drag有两个变量,proc->types.pointer.drag_limit_out全局变量开启拖累后会一直为1,切到新对象才到写0。drag_just_started局部变量与limit_out同时置位控制方向,DRAG_BEGIN信号发送。

static void indev_drag(lv_indev_proc_t * proc)
{
    lv_obj_t * drag_obj    = get_dragged_obj(proc->types.pointer.act_obj);
    bool drag_just_started = false;
    uint8_t drag_dir; //saimen

    if(drag_obj == NULL) return;

    if(lv_obj_get_drag(drag_obj) == false) return;

    lv_drag_dir_t allowed_dirs = lv_obj_get_drag_dir(drag_obj);

    /*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;

        /*Enough move?*/
        bool hor_en = false;
        bool ver_en = false;
        if(allowed_dirs == LV_DRAG_DIR_HOR || allowed_dirs == LV_DRAG_DIR_BOTH) {
            hor_en = true;
        }

        if(allowed_dirs == LV_DRAG_DIR_VER || allowed_dirs == LV_DRAG_DIR_BOTH ||\
           allowed_dirs == LV_DRAG_DIR_VER_ONLY_UP || allowed_dirs == LV_DRAG_DIR_VER_ONLY_DOWN) {
            ver_en = true;
        }

        if(allowed_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;
                drag_dir = 0x10;
            }
            else {
                ver_en = true;
                drag_dir = 0x20;
            }
        }

        /*If a move is greater then LV_DRAG_LIMIT then begin the drag*/
        if((hor_en && LV_MATH_ABS(proc->types.pointer.drag_sum.x) >= indev_act->driver.drag_limit) ||
           (ver_en && LV_MATH_ABS(proc->types.pointer.drag_sum.y) >= indev_act->driver.drag_limit)) {
            proc->types.pointer.drag_limit_out = 1;
            drag_just_started                   = true;
            if(drag_dir==0x10)
            {
                if(proc->types.pointer.drag_sum.x>0)
                {
                    drag_dir |= 1;
                }
                else
                {
                    drag_dir |= 2;
                }
            }
            else
            {
                if(proc->types.pointer.drag_sum.y>0)
                {
                    drag_dir |= 1;
                }
                else
                {
                    drag_dir |= 2;
                }
            }
        }
    }

    /*If the drag limit is exceeded handle the dragging*/
    if(proc->types.pointer.drag_limit_out != 0) {
        /*Set new position if the vector is not zero*/
        if(proc->types.pointer.vect.x != 0 || proc->types.pointer.vect.y != 0) {

            lv_coord_t prev_x     = drag_obj->coords.x1;
            lv_coord_t prev_y     = drag_obj->coords.y1;
            lv_coord_t prev_par_w = lv_obj_get_width(lv_obj_get_parent(drag_obj));
            lv_coord_t prev_par_h = lv_obj_get_height(lv_obj_get_parent(drag_obj));

            /*Get the coordinates of the object and modify them*/
            lv_coord_t act_x = lv_obj_get_x(drag_obj);
            lv_coord_t act_y = lv_obj_get_y(drag_obj);

            if(allowed_dirs == LV_DRAG_DIR_BOTH) {
                if(drag_just_started) {
                    proc->types.pointer.drag_dir = LV_DRAG_DIR_BOTH;
                    act_x += proc->types.pointer.drag_sum.x;
                    act_y += proc->types.pointer.drag_sum.y;
                }
            }
            else if(allowed_dirs == LV_DRAG_DIR_HOR) {
                if(drag_just_started) {
                    proc->types.pointer.drag_dir = LV_DRAG_DIR_HOR;
                    proc->types.pointer.drag_sum.y = 0;
                    act_x += proc->types.pointer.drag_sum.x;
                }
            }
            else if(allowed_dirs == LV_DRAG_DIR_VER) {
                if(drag_just_started) {
                    proc->types.pointer.drag_dir = LV_DRAG_DIR_VER;
                    proc->types.pointer.drag_sum.x = 0;
                    act_y += proc->types.pointer.drag_sum.y;
                }
            }
            else if(allowed_dirs == LV_DRAG_DIR_ONE) {
                if(drag_just_started) {
                    if(LV_MATH_ABS(proc->types.pointer.drag_sum.x) > LV_MATH_ABS(proc->types.pointer.drag_sum.y)) {
                        proc->types.pointer.drag_dir = LV_DRAG_DIR_HOR;
                        proc->types.pointer.drag_sum.y = 0;
                        act_x += proc->types.pointer.drag_sum.x;
                    }
                    else {
                        proc->types.pointer.drag_dir = LV_DRAG_DIR_VER;
                        proc->types.pointer.drag_sum.x = 0;
                        act_y += proc->types.pointer.drag_sum.y;
                    }
                }
            }
            else if (allowed_dirs == LV_DRAG_DIR_VER_ONLY_UP) {
                if (drag_just_started) {
                    proc->types.pointer.drag_dir = LV_DRAG_DIR_VER;
                    proc->types.pointer.drag_sum.x = 0;
                    if (act_y + proc->types.pointer.drag_sum.y <= 0)
                        act_y += proc->types.pointer.drag_sum.y;
                    else
                        proc->types.pointer.drag_sum.y = 0;
                }
            }
            else if (allowed_dirs == LV_DRAG_DIR_VER_ONLY_DOWN) {
                if (drag_just_started) {
                    proc->types.pointer.drag_dir = LV_DRAG_DIR_VER;
                    proc->types.pointer.drag_sum.x = 0;
                    if (act_y + proc->types.pointer.drag_sum.y >= 0)
                        act_y += proc->types.pointer.drag_sum.y;
                    else
                        proc->types.pointer.drag_sum.y = 0;
                }
            }
            

            /*Move the object*/
            if(allowed_dirs == LV_DRAG_DIR_HOR ||
               allowed_dirs == LV_DRAG_DIR_BOTH ||
               (allowed_dirs == LV_DRAG_DIR_ONE &&
                LV_MATH_ABS(proc->types.pointer.drag_sum.x) > LV_MATH_ABS(proc->types.pointer.drag_sum.y))) {
                act_x += proc->types.pointer.vect.x;
            }
            if(allowed_dirs == LV_DRAG_DIR_VER ||
               allowed_dirs == LV_DRAG_DIR_BOTH ||
               (allowed_dirs == LV_DRAG_DIR_ONE &&
                LV_MATH_ABS(proc->types.pointer.drag_sum.x) < LV_MATH_ABS(proc->types.pointer.drag_sum.y))) {
                act_y += proc->types.pointer.vect.y;
            }
            if (allowed_dirs == LV_DRAG_DIR_VER_ONLY_UP)
            {
                if (act_y + proc->types.pointer.vect.y <= 0)
                    act_y += proc->types.pointer.vect.y;
            }
            if (allowed_dirs == LV_DRAG_DIR_VER_ONLY_DOWN)
            {
                if (act_y + proc->types.pointer.vect.y >= 0)
                    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*/

            lv_obj_set_pos(drag_obj, act_x, act_y);
            proc->types.pointer.drag_in_prog = 1;

            /*If the object didn't moved then clear the invalidated areas*/
            if(drag_obj->coords.x1 == prev_x && drag_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(drag_obj));
                lv_coord_t act_par_h = lv_obj_get_height(lv_obj_get_parent(drag_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(drag_just_started) {
                drag_obj->signal_cb(drag_obj, LV_SIGNAL_DRAG_BEGIN, indev_act);
                if(indev_reset_check(proc)) return;

                //lv_event_send(drag_obj, LV_EVENT_DRAG_BEGIN, NULL);
                lv_event_send(drag_obj, LV_EVENT_DRAG_BEGIN, &drag_dir);
                if(indev_reset_check(proc)) return;
            }

        }
    }
}

*indev_drag中的通过调用void lv_obj_set_pos()来改变坐标,触发滚动传输。第次坐标的改变都会通知到父、子对象还有自已。

释放的处理:

static void indev_proc_release(lv_indev_proc_t * proc)

等一下写



 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值