2012-02-16 15 views
5

Estoy trabajando en una aplicación GTK + que usa goocanvas para mostrar un gráfico en la pantalla. Tengo problemas para encontrar una buena forma de implementar el desplazamiento de arrastre.Desplazamiento por arrastre en una aplicación GTK +

Actualmente la aplicación guarda las coordenadas donde el usuario hizo clic y luego en una devolución de llamada de señal "movimiento notado", hace goo_canvas_scroll_to() a la nueva posición. El problema es que el dibujo es algo lento, y con cada píxel movido por el mouse, obtengo la devolución de llamada invocada una vez. Esto hace que el dibujo se quede atrás al arrastrar el gráfico.

¿Hay una buena manera de hacer arrastre de desplazamiento, por lo que parece más suave y podría omitir algunos de los redibujados?

Respuesta

4

Pude hacer que algo como esto funcionara una vez iniciando un temporizador de 5ms cuando el usuario presiona el botón del mouse. En el temporizador, compruebo dónde se encuentra el mouse y decido por dónde desplazarme, incluido un desplazamiento más rápido cuanto más cerca esté del borde. El resultado fue un desplazamiento muy suave, al menos eso es lo que recuerdo. Aquí las entrañas de la misma, su gtkmm/C++, pero usted debe ser capaz de obtener la esencia de la misma:

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

Las funciones de desplazamiento simplemente ajustar el objeto de ajuste apropiado por el argumento.

+0

Hacerlo en una devolución de llamada con temporizador es una buena idea. Esto es exactamente lo que necesitaba, ¡gracias! –

Cuestiones relacionadas