Перетащите прокрутку в приложении GTK + - PullRequest
5 голосов
/ 16 февраля 2012

Я работаю над приложением GTK +, которое использует goocanvas для отображения графика на экране.У меня возникают проблемы с хорошим способом реализации перетаскивания.

В настоящее время приложение сохраняет координаты, по которым пользователь щелкнул, а затем в обратном вызове сигнала "движение-уведомление" выполняет goo_canvas_scroll_to () для новогопозиция.Проблема в том, что рисование происходит довольно медленно, и при каждом перемещении мышью каждого пикселя я получаю обратный вызов один раз.Это приводит к отставанию рисования при перетаскивании графика.

Есть ли хороший способ прокрутки с помощью перетаскивания, чтобы он выглядел более плавным, и я мог бы пропустить некоторые перерисовки?

1 Ответ

4 голосов
/ 17 февраля 2012

Мне удалось заставить что-то подобное работать один раз, запустив таймер 5 мс, когда пользователь нажимает кнопку мыши. В таймере я проверяю, где находится мышь, и решаю, какой способ прокручивать, включая более быструю прокрутку по мере приближения к краю. Результатом стала очень плавная прокрутка, по крайней мере, это то, что я помню. Вот его внутренности, его gtkmm / c ++, но вы должны быть в состоянии понять суть этого:

static const int HOT_AREA = 24; 

// convert distance into scroll size.  The larger the 
// value, the faster the scrolling. 
static int accel_fn(int dist) {
    if (dist > HOT_AREA) 
        dist = HOT_AREA; 
    int dif =  dist / (HOT_AREA/4); 
    if (dif <= 0) dif = 1; 
    return dif; 
}


bool scrollerAddin::on_timeout() {
    int ptr_x, ptr_y; 
    o_scroller->get_pointer(ptr_x, ptr_y); 

    int vp_width = o_scroller->get_width(); 
    int vp_height = o_scroller->get_height(); 

    if (o_scroller->get_hscrollbar_visible())
        vp_height -= o_scroller->get_hscrollbar()->get_height(); 
    if (o_scroller->get_vscrollbar_visible())
        vp_width -= o_scroller->get_vscrollbar()->get_width(); 

    if (ptr_x < HOT_AREA)
        scroll_left(accel_fn(HOT_AREA-ptr_x)); 
    else if (ptr_x > vp_width - HOT_AREA)
        scroll_right(accel_fn(ptr_x - (vp_width - HOT_AREA))); 
    if (ptr_y < HOT_AREA)
        scroll_up(accel_fn(HOT_AREA - ptr_y)); 
    else if (ptr_y > vp_height - HOT_AREA)
        scroll_down(accel_fn(ptr_y - (vp_height - HOT_AREA))); 

    return true; 
}

Функции прокрутки просто настраивают соответствующий объект Adjustment по аргументу.

...