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