cairogtkmm3

How to make Gtk::DrawingArea act incremental?


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?


Solution

  • 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.