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

Reply via email to