2010-11-27 29 views
1

J'essaye de faire mes trucs de dessin dans un Contexte d'Image de Caire. Existe-t-il un moyen de charger le contenu du contexte Image dans un contexte Cairo sur un événement d'exposition? Par exemple, je veux dessiner une série de points basés sur les mouvements du curseur sur une zone de dessin. Si je veux conserver tous les points, je devrais utiliser un tampon hors écran, donc j'utilise un contexte d'image, mais je ne peux pas trouver un moyen de le dessiner au contexte du Caire sur l'événement d'exposition ...Comment faire un dessin hors écran en utilisant Cairo dans Gtk +?

une solution?

Répondre

1

J'ai trouvé la solution moi-même!

ici est:

using Cairo; 
using Gtk; 

public class Canvas : Gtk.DrawingArea{ 
public Canvas(MainWindow mw){ 
    stdout.printf("-> Canvas\n"); 

    main_window = mw; 
    is_pressed_down = false; 

    add_events(Gdk.EventMask.BUTTON_PRESS_MASK | 
       Gdk.EventMask.BUTTON_RELEASE_MASK | 
         Gdk.EventMask.POINTER_MOTION_MASK); 

      set_size_request(400, 300); 
} 

~Canvas(){ 
    stdout.printf("<- Canvas\n"); 
} 

public override void realize(){ 
    base.realize(); 
    stdout.printf("realize\n"); 
} 

protected override bool configure_event(Gdk.EventConfigure event){ 
    int x, y; 

    window.get_size(out x, out y); 
    offscreen_surface = new Cairo.ImageSurface(Cairo.Format.RGB24, x, y); 
    gc = new Cairo.Context(offscreen_surface); 
    gc.set_antialias(Antialias.NONE); 
    gc.set_line_width(1); 
    gc.set_source_rgb(1, 1, 1); 
    gc.paint(); // it will make trouble if user resize the window 

    string msg = "x: " + x.to_string() + ", y: " + y.to_string(); 
    main_window.set_statusbar(msg); 

    return true; 
} 

protected override bool expose_event(Gdk.EventExpose event){ 

    var tgc = Gdk.cairo_create(window); //!!! 
    tgc.set_source_rgb(1, 1, 1); 
    tgc.paint(); 

    tgc.set_source_surface(offscreen_surface, 0, 0); 
    tgc.paint(); 

    return true; 
} 

public override bool motion_notify_event(Gdk.EventMotion event) 
{ 
    string msg = "x: " + event.x.to_string() + ", y: " + event.y.to_string(); 
    main_window.set_statusbar(msg); 

    if(is_pressed_down){ 
     //gc.set_source_rgb(1, 1, 1); 
     //gc.paint(); 
     gc.set_source_rgb(1, 0.5, 0); 

     //gc.move_to(event.x, event.x); 
     gc.arc(event.x, event.y, 1, 0, 360);   
     gc.stroke(); 

     weak Gdk.Region region = this.window.get_clip_region(); 
     this.window.invalidate_region(region, true); 
     this.window.process_updates(true); 
    } 

    return true; 
} 

public override bool button_press_event(Gdk.EventButton event) 
{ 
    stdout.printf("Canvas.button_press_event\n"); 
    is_pressed_down = true; 
    return true; 
} 

public override bool button_release_event(Gdk.EventButton event) 
{ 
    stdout.printf("Canvas.button_release_event\n"); 
    is_pressed_down = false; 
    return true; 
} 

public Cairo.Context get_context(){ 
    return gc; 
} 

private Cairo.Context  gc; 
private weak MainWindow main_window; 
private Cairo.ImageSurface offscreen_surface; 
private bool    is_pressed_down; 
}