在GTK+应用程序中拖动滚动

6
我正在开发一个使用goocanvas显示屏幕上图形的GTK+应用程序。我正在遇到一些在实现拖动滚动的良好方式方面的问题。
目前,该应用程序保存了用户单击的坐标,并在“motion-notify”信号回调中执行goo_canvas_scroll_to()以移动到新位置。问题是,绘制有点慢,每移动鼠标一个像素,就会调用一次回调函数。这使得在拖动图形时绘制落后。
是否有更好的方法来实现拖动滚动,使其显得更加平滑,并且可以跳过一些重绘操作?
1个回答

4
我曾经通过在用户按下鼠标按钮时启动一个5ms定时器来使类似以下的东西工作。在定时器中,我检查鼠标位置并决定滚动的方向,包括越靠近边缘滚动得越快。结果是非常流畅的滚动,至少我记得是这样的。以下是其主要内容,使用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; 
}

滚动功能仅通过参数调整相应的调整对象。

在计时器回调函数中执行是个好主意。这正是我所需要的,谢谢! - Martti Kuosmanen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接