开发者

How to do off-screen drawing using Cairo in Gtk+?

I'm trying to do my drawing stuff in an Cairo Image Context. Is there a way to load the content of the Image context to a Cairo Context on expose event?

For example I want to draw a series of dots based on cursor movements over a drawing area, If I want to keep al开发者_StackOverflow社区l the dots I should use an off-screen buffer, so I use an Image Context, but I cannot find a way to draw it to the Cairo Context on expose event...

any solution?


I found the solution myself!

here it is:

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜