Re: the right way to draw in a drawingarea



Not at all.

My bad about that method, its actually queue_draw()
http://www.gtkmm.org/docs/gtkmm-2.4/docs/reference/html/classGtk_1_1Widget.html#a153

I can't really explain this too well cause I haven't really read all the specifics on how gtk does its drawing of widgets and the such. Basically, you want to let gtk decide when it needs an update. queue_draw just says, please update now. When you get into repainting the entire screen you'll get the flashes you menitoned.

Oh and just to make sure, you aren't doing anything silly like clearing the widget with something like DrawRectangle( background, 0, 0, WIDTH, HEIGHT ) (obviously not a real function call, just illustrating the point) cause that would
also introduce flickering.

The way to do this is to make your on_expose_event draw the box.

ie:

void on_expose_event( GdkEventExpose ev )
{
   //Draw background pixbuf.
   update_display() ;

   //draw rectangle
   if( left > 0 && top > 0 && right > 0 && bot > 0 )
        Darea->get_window()->draw_rectangle(gc_, 0, left, top,
               right-left, bot-top);
}

Then add ( and connect this to the button press signal obviously. )
on_Darea_button_press_event( GdkEventButton *ev )
{
      if( ev->state & Gdk::BUTTON1_MASK )
      {
         left = ev->x ;
         top = ev->y ;

         right = ev->x ;
         bottom = ev->y ;
      }
      else
      {
            //Erase rectangle.
            left = -1 ;
            top = -1 ;

            right = -1 ;
            bottom = -1 ;
      }

      Darea->queue_draw() ;
}

And then in your
on_Darea_motion_notify_event( GdkEventButton* ev )
{
   right=ev->x;
   if(left>right) swap(left,right);
   bot=ev->y;
   if(top>bot) swap(top,bot);

   Darea->queue_draw() ;
}

If you want to make this as extremely efficient as possible, you could change the calls to queue_draw to queue_draw( left-5, top-5, right-left+10, bot-top+10 ) and make sure that your update_display only redraws the necessary area.

On a side note, what is flickering? The entire image, or just the rectangle? Cuase I might be barking up the wrong tree entirely. If the rectangle is, then this could be a different issue of some sort.

If this doesn't work out, post your entire code somewhere, or a simplified example so I can take a closer look. This shouldn't be that hard of a problem to straighten out.

Anyway, time to watch a movie.

Paul

Amadeus W. M. wrote:

Thanks for the answer. What is this queue_redraw() function? I did a grep
-ri in /usr/include and I didn't find anything. Or is it a user defined
function which simply draws the items that need to be drawn. If so, when
do you call it? Do you not call it from within the mouse motion handler?


My mouse motion handler looks like this:

bool DisplayWindow::on_Darea_motion_notify_event(GdkEventMotion *ev)
{
   // int left,right,top,bot are DisplayWindow members.

   // draw whatever is on already, including pixbuf.
   update_display();

   // get coordinates of bottom right corner.
right=ev->x; if(left>right) swap(left,right); bot=ev->y;
   if(top>bot) swap(top,bot);

   // (continuously) draw a rectangle.
   if(ev->state & Gdk::BUTTON1_MASK)
Darea->get_window()->draw_rectangle(gc_, 0, left, top, right-left, bot-top); }

Is this what you had in mind? The problem stems from my update_display()
which renders the pixbuf into the Darea's window. It has to, because I
only want a single rectangle to be visible at the time. And it flickers.

Rendering only a smaller part of the pixbuf seems like a good idea, I hope
it's worth the trouble.





On Mon, 10 Oct 2005 20:06:46 -0500, Paul Davis wrote:

I've done something similar to this. It was just basic drawing with the mouse.

I did the standard inheriting from a Gtk::DrawingArea and overriding the on_expose_event. In the mouse even signals I just added the notified the drawing area with the necessary information( simple x,y coordinates if I recall )
then just call queue_redraw()

You could probably make this a bit more efficient by only queuing (queueing? ) the redraw in a rectangle of some small area around the mouse event or something. But it worked well without flickering.

If that doesn't make any sense I can try and dig up that code somewhere. But the main idea is to just queue redraws.

Cheers,
Paul

Amadeus W. M. wrote:

I need to draw stuff (shapes rectangles, ellipses, splines, points,
etc), overlayed on top of an image, and I want to update the display in
real time, as the mouse moves. This is similar to doing a selection in
gimp. The way I do this right now is as follows:

The background image is in a Gdk::Pixbuf. I also have a Gtk::DrawingArea
in which I draw my shapes. The display needs to be repainted upon each
expose event, but upon mouse movement as well. So upon each mouse movement
event I render the pixbuf and the shapes into the Darea->get_window(). This works ok, but when the user draws something by dragging the mouse,
the display flickers, even when drawing a simple square.

Now this does not happen in gimp: it does not happen e.g. when a selection
is made, nor when I move the nodes of a path, even though the display must
be re-drawn as the mouse moves, etc. The window is steady and the
drawing smooth.
So I guess there's a better way of overlaying shapes on top of an image,
than the obvious Pixbuf + Darea method. Does anybody know anything about
this?
Thanks!


_______________________________________________
gtkmm-list mailing list
gtkmm-list gnome org
http://mail.gnome.org/mailman/listinfo/gtkmm-list




_______________________________________________
gtkmm-list mailing list
gtkmm-list gnome org
http://mail.gnome.org/mailman/listinfo/gtkmm-list




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]