Question: How to use gtk.snapshot.to_paintable

Hello!

I am using a DrawingArea with a custom snapshot function to create a simple animation program.

I am trying to save the drawing as a Paintable so the currently viewed drawing can be changed and i am trying to use a to_paintable to do so. Whenever the to_paintable function is ran in code the program will crash and i receive this error:

Gtk:ERROR:../gtk/gtksnapshot.c:280:gtk_snapshot_get_current_state: assertion failed: (size > 0)
Bail out! Gtk:ERROR:../gtk/gtksnapshot.c:280:gtk_snapshot_get_current_state: assertion failed: (size > 0)

This is the code i am using to turn it to a paintable:

//image the type Gdk.Paintable?

image = snapshot.to_paintable (null);

I have also tried setting the size myself in code using Graphene.Size but the same thing occurs. The DrawingArea’s size is also set.

Thank you for any help and please tell me if any more information is needed :slight_smile:

Hi!

So first thing’s first: I would recommend against using Gtk.DrawingArea at all, but it clearly doesn’t make sense to use it with a custom snapshot function (as opposed to Cairo drawing). You’re better off just inheriting from Gtk.Widget directly.

Secondly, if you’re doing this:

protected override void snapshot (Gtk.Snapshot snapshot) {
    var image = snapshot.to_paintable (); // WRONG!
}

then that is certainly wrong. to_paintable () is something that whoever created the snapshot can use, after the snapshotting has been completed. In a widget’s snapshot () virtual method, you’re instead supposed just to add your content (i.e. with append_* () methods) to the existing snapshot object, but leave it as-is otherwise.

If you really want to capture your own contents, you can do so by creating your own intermediary snapshot object, like this:

protected override void snapshot (Gtk.Snapshot snapshot) {
    var inner_snapshot = new Gtk.Snapshot ();
    draw_things_on (inner_snapshot);
    Graphene.Size size = { get_width (), get_height () };
    var paintable = inner_snapshot.to_paintable (size); // OK
    store_somehow (paintable);
    // Also append to the original snapshot:
    paintable.snapshot (snapshot, size.width, size.height);
}

But really, you should first get a good idea of how the various pieces fit together here.

Thank you! It worked :^)

I was using a Drawing area because:

  1. Previously drawing was done with cairo.
  2. The set_content_width/height methods are convenient.

I am planning to inherit from Gtk.Widget itself but i am curious why you suggest not using the drawing area at all? would it be better to use snapshot.append_cairo?

Again, thank you for the help.