Christopher Barker wrote:
> to get it really smooth, I suppose you could render a larger bitmap off 
> screen, so you could just drag that as you moved, and have floatcanvas 
> fill in the missing bits when they are still off screen.

I've just re-factored it a bit more -- it is now a hybrid method. As you 
move the mouse, it immediately redraws the existing buffer as you move. 
It then sets a timer for 30 microseconds -- when that timer goes off, 
the entire image is re-drawn.

This makes for a slight delay, which is unnecessary for images that are 
fast to draw, but allows it to work OK with images that take a while to 
draw.

I tested it with the Hexagons Demo -- with 100 hexagons, it's very fast, 
with 10,000, it takes over a second to draw on my machine. The current 
GUIMove code works OK for both of these.

Ideally, there would be a way for FloatCanvas to know how complex the 
drawing is, and adjust the timer delay accordingly, but I don't know how 
I'd do that.

It's in SVN, and here's the new GUIMove code:

class GUIMove(GUIBase):
     def __init__(self, canvas=None):
         GUIBase.__init__(self, canvas)
         self.Cursor = self.Cursors.HandCursor
         self.GrabCursor = self.Cursors.GrabHandCursor
         self.StartMove = None
         self.PrevMoveXY = None

         ## timer to give a delay when moving so that buffers aren't 
re-built too many times.
         self.MoveTimer = wx.PyTimer(self.OnMoveTimer)

     def OnLeftDown(self, event):
         self.Canvas.SetCursor(self.GrabCursor)
         self.Canvas.CaptureMouse()
         self.StartMove = N.array( event.GetPosition() )
         self.PrevMoveXY = (0,0)

     def OnLeftUp(self, event):
         self.Canvas.SetCursor(self.Cursor)

     def OnMove(self, event):
         # Always raise the Move event.
         self.Canvas._RaiseMouseEvent(event, FloatCanvas.EVT_FC_MOTION)
         if event.Dragging() and event.LeftIsDown() and not 
self.StartMove is None:
             self.MoveImage(event)
             self.EndMove = N.array(event.GetPosition())
             self.MoveTimer.Start(30, oneShot=True)

     def OnMoveTimer(self, event=None):
         DiffMove = self.StartMove-self.EndMove
         self.Canvas.MoveImage(DiffMove, 'Pixel')
         self.StartMove = self.EndMove

     def MoveImage(self, event):
         xy1 = N.array( event.GetPosition() )
         wh = self.Canvas.PanelSize
         xy_tl = xy1 - self.StartMove
         dc = wx.ClientDC(self.Canvas)
         dc.BeginDrawing()
         x1,y1 = self.PrevMoveXY
         x2,y2 = xy_tl
         w,h = self.Canvas.PanelSize
         ##fixme: This sure could be cleaner!
         ##   This is all to fill in the background with the background 
color
         ##   without flashing as the image moves.
         if x2 > x1 and y2 > y1:
             xa = xb = x1
             ya = yb = y1
             wa = w
             ha = y2 - y1
             wb = x2-  x1
             hb = h
         elif x2 > x1 and y2 <= y1:
             xa = x1
             ya = y1
             wa = x2 - x1
             ha = h
             xb = x1
             yb = y2 + h
             wb = w
             hb = y1 - y2
         elif x2 <= x1 and y2 > y1:
             xa = x1
             ya = y1
             wa = w
             ha = y2 - y1
             xb = x2 + w
             yb = y1
             wb = x1 - x2
             hb = h - y2 + y1
         elif x2 <= x1 and y2 <= y1:
             xa = x2 + w
             ya = y1
             wa = x1 - x2
             ha = h
             xb = x1
             yb = y2 + h
             wb = w
             hb = y1 - y2

         dc.SetPen(wx.TRANSPARENT_PEN)
         dc.SetBrush(self.Canvas.BackgroundBrush)
         dc.DrawRectangle(xa, ya, wa, ha)
         dc.DrawRectangle(xb, yb, wb, hb)
         self.PrevMoveXY = xy_tl
         if self.Canvas._ForeDrawList:
             dc.DrawBitmapPoint(self.Canvas._ForegroundBuffer,xy_tl)
         else:
             dc.DrawBitmapPoint(self.Canvas._Buffer,xy_tl)
         dc.EndDrawing()
         self.Canvas.Update()

     def OnWheel(self, event):
         """
            By default, zoom in/out by a 0.1 factor per Wheel event.
         """
         if event.GetWheelRotation() < 0:
             self.Canvas.Zoom(0.9)
         else:
             self.Canvas.Zoom(1.1)



-Chris




-- 
Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R            (206) 526-6959   voice
7600 Sand Point Way NE   (206) 526-6329   fax
Seattle, WA  98115       (206) 526-6317   main reception

[EMAIL PROTECTED]
_______________________________________________
FloatCanvas mailing list
[email protected]
http://mail.mithis.com/cgi-bin/mailman/listinfo/floatcanvas

Reply via email to