Как сделать рисование вне экрана с помощью Cairo в Gtk +? - PullRequest
1 голос
/ 27 ноября 2010

Я пытаюсь рисовать в Cairo Image Context.Есть ли способ загрузить содержимое контекста изображения в Каирский контекст при событии выставления?

Например, я хочу нарисовать серию точек на основе движений курсора над областью рисования, если я хочу сохранитьвсе точки, которые я должен использовать внеэкранный буфер, поэтому я использую контекст изображения, но я не могу найти способ нарисовать его в контексте Cairo при событии выставления ...

любое решение?

1 Ответ

1 голос
/ 27 ноября 2010

Я сам нашел решение!

вот оно:

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