Marco et.al.
I took a little time to play with this, and generalized the code for
other objects. The trick was that any object you want to move needs a
GetOutlinePoints() method that returns the outline you want drawn while
the object is moving.
I wrote a little mixin that defaults to providing the bounding box of
the object, and that can be overridden if you want a different shape
drawn. I do this for the Triangle example.
However: to really do this right really required more infrastructure.
The Mouse bindings should probably be in a GuiMode, and you may want
each object to have "DrawWhileMoving" call instead of the points --
that would let you draw anything -- it could still default to the
bounding box.
Retief's work is moving towards doing this right.
How can i auto-move the lines with the bitmaps, so two connected
elements could remain connected after the move...
I may work on that a bit later.
-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]
#!/usr/bin/env python2.4
"""
This is a small demo, showing how to make an object that can be moved around.
"""
import wx
ver = 'local'
#ver = 'installed'
if ver == 'installed': ## import the installed version
from wx.lib.floatcanvas import NavCanvas, Resources
from wx.lib.floatcanvas import FloatCanvas as FC
print "using installed version:", wx.lib.floatcanvas.__version__
elif ver == 'local':
## import a local version
import sys
sys.path.append("../")
from floatcanvas import NavCanvas, Resources
from floatcanvas import FloatCanvas as FC
import numpy as N
## here we create a new DrawObject:
## code borrowed and adapted from Werner Bruhin
class MovingObjectMixin(object):
"""
Methods required for a Moving object
"""
# def __init__(self):
# print "in MovingObject __init__"
# self.OutlinePoints = self.BoundingBox
# print self.OutlinePoints
def GetOutlinePoints(self):
BB = self.BoundingBox
OutlinePoints = N.array( ( (BB[0,0], BB[0,1]),
(BB[0,0], BB[1,1]),
(BB[1,0], BB[1,1]),
(BB[1,0], BB[0,1]),
)
)
return OutlinePoints
class MovingBitmap(FC.ScaledBitmap, MovingObjectMixin):
"""
ScaledBitmap Object that can be moved
"""
## All we need to do is is inherit from ScaledBitmap, MovingObjectMixin
pass
class MovingCircle(FC.Circle, MovingObjectMixin):
"""
ScaledBitmap Object that can be moved
"""
## All we need to do is is inherit from Circle, MovingObjectMixin
pass
class TriangleShape1(FC.Polygon, MovingObjectMixin):
def __init__(self, XY, L):
"""
An equalateral triangle object
XY is the middle of the triangle
L is the length of one side of the Triangle
"""
XY = N.asarray(XY)
XY.shape = (2,)
Points = self.CompPoints(XY, L)
FC.Polygon.__init__(self, Points,
LineColor = "Black",
LineStyle = "Solid",
LineWidth = 2,
FillColor = "Red",
FillStyle = "Solid")
## Override the default OutlinePoints
def GetOutlinePoints(self):
return self.Points
def CompPoints(self, XY, L):
c = L/ N.sqrt(3)
Points = N.array(((0, c),
( L/2.0, -c/2.0),
(-L/2.0, -c/2.0)),
N.float_)
Points += XY
return Points
class DrawFrame(wx.Frame):
"""
A frame used for the FloatCanvas Demo
"""
def __init__(self,parent, id,title,position,size):
wx.Frame.__init__(self,parent, id,title,position, size)
self.CreateStatusBar()
# Add the Canvas
Canvas = NavCanvas.NavCanvas(self,-1,(500,500),
ProjectionFun = None,
Debug = 0,
BackgroundColor = "DARK SLATE BLUE",
).Canvas
self.Canvas = Canvas
Canvas.Bind(FC.EVT_MOTION, self.OnMove )
Canvas.Bind(FC.EVT_LEFT_UP, self.OnLeftUp )
Points = N.array(((0,0),
(1,0),
(0.5, 1)),
N.float_)
data = (( (0,0), 1),
( (3,3), 2),
( (-2,3), 2.5 ),
)
for p, L in data:
Tri = TriangleShape1(p, 1)
Canvas.AddObject(Tri)
Tri.Bind(FC.EVT_FC_LEFT_DOWN, self.ObjectHit)
Point = (1, 1)
for Point in ((1,1), (-4,3)):
BitMap = MovingBitmap(Resources.getMondrianImage(), Point, Height = 1)
Canvas.AddObject(BitMap)
BitMap.Bind(FC.EVT_FC_LEFT_DOWN, self.ObjectHit)
Circle = MovingCircle( (1, 3), 2, FillColor="Blue")
Canvas.AddObject(Circle)
Circle.Bind(FC.EVT_FC_LEFT_DOWN, self.ObjectHit)
# Canvas.AddLine([Point,Point1,(0,0),(1,1)],LineWidth=3, LineColor="Red")
self.Show(True)
self.Canvas.ZoomToBB()
self.MoveObject = None
self.Moving = False
return None
def ObjectHit(self, object):
if not self.Moving:
self.Moving = True
self.StartPoint = object.HitCoordsPixel
self.StartObject = self.Canvas.WorldToPixel(object.GetOutlinePoints())
self.MoveObject = None
self.MovingObject = object
def OnMove(self, event):
"""
Updates the status bar with the world coordinates
And moves the triangle it it is clicked on
"""
self.SetStatusText("%.4f, %.4f"%tuple(event.Coords))
if self.Moving:
dxy = event.GetPosition() - self.StartPoint
# Draw the Moving Object:
dc = wx.ClientDC(self.Canvas)
dc.SetPen(wx.Pen('WHITE', 2, wx.SHORT_DASH))
dc.SetBrush(wx.TRANSPARENT_BRUSH)
dc.SetLogicalFunction(wx.XOR)
if self.MoveObject is not None:
dc.DrawPolygon(self.MoveObject)
self.MoveObject = self.StartObject + dxy
dc.DrawPolygon(self.MoveObject)
def OnLeftUp(self, event):
if self.Moving:
self.Moving = False
if self.MoveObject is not None:
dxy = event.GetPosition() - self.StartPoint
dxy = self.Canvas.ScalePixelToWorld(dxy)
self.MovingObject.Move(dxy) ## The Move function has jsut been added
## to the FloatCanvas PointsObject
## It does the next three lines for you.
#self.Tri.Points += dxy
#self.Tri.BoundingBox += dxy
#self.Canvas.BoundingBoxDirty = True
self.MoveTri = None
self.Canvas.Draw(True)
app = wx.PySimpleApp(0)
DrawFrame(None, -1, "FloatCanvas TextBox Test App", wx.DefaultPosition, (700,700) )
app.MainLoop()
_______________________________________________
FloatCanvas mailing list
[email protected]
http://mail.mithis.com/cgi-bin/mailman/listinfo/floatcanvas