I am stuck how to make the Gtk:DrawingArea behave the way I want it to. The reason is I don't want to redraw everything with every call to the on_draw() function. Instead I want to change it incremental (add a line, rectangle, text,...) and don't keep track of the things I added/changed, just pile them on top of each other.
bool drawing_test::on_draw(const Cairo::RefPtr<Cairo::Context>& cr)
{
switch (cmd)
{
case 0: /* initialize background */
cr->set_source_rgba(1, 1, 1, 1); // white
cr->paint();
break;
case 1: /* draw a line */
DrawLine(cr, params);
break;
case 2: /* draw text */
DrawText(cr, params);
break;
default:
break;
}
}
I found the Cairo::Context functions get_target() and set_source(). So I maybe could extract the the necessary information after adding a change and reload it before the next change? But is that the right way to go about this?
So as I have found a working solution, I will answer my own question. Here an abstract code how this can work:
bool drawing_test::on_draw(const Cairo::RefPtr<Cairo::Context>& cr)
{
auto surface = Cairo::ImageSurface::create_from_png_stream(sigc::mem_fun(drawBuffer, &DrawBuffer::read));
cr->set_source(surface, 0, 0);
cr->paint();
switch (cmd)
{
case 0: /* initialize background */
cr->set_source_rgba(1, 1, 1, 1); // white
cr->paint();
break;
case 1: /* draw a line */
DrawLine(cr, params);
break;
case 2: /* draw text */
DrawText(cr, params);
break;
default:
break;
}
Cairo::RefPtr<Cairo::Surface> cs=cr->get_target();
cs->write_to_png_stream(sigc::mem_fun(drawBuffer, &DrawBuffer::write));
}
drawBuffer is a self created class which implements a read and write function and a buffer for a png stream. With this construction its possible to save and restore the contents of a Gtk:DrawingArea.