Sorry, my mistake. Here is the code that I've worked on. What I mean to say is that I can select them and group them to move, but I cant ungroup them or move them individually unless I manually select it.
Cheers
Astan

Astan Chee wrote:
Hi,
In an attempt to modify the MovingElements.py to make group moveable objects (excluding connector lines), I tried to make a similar class but with the ability to select a bunch of objects and they will be grouped together. Using this, I found that I have problems binding the selected objects to be moved or unbind them and select new ones (dynamic binding or unbinding). Also I took the selectionbox code from the floatcanvas.GUI but since the events doubled up on each other, I included it directly. Im not sure how to handle events that double up on each other and my implementation to select is rather crude since I dont know how to get a position of an object in drawcanvas. Also, Chris I think you mentioned that .AddObject returns the reference to the drawobject being added, it seems that it only returns the condition if it added the object or not (i.e. true or false).
I've attached the code of where Im up to.
Cheers
Astan


David Poundall wrote:
Spot on Chris - Thanks, it worked :-)


-----Original Message-----
From: Christopher Barker [mailto:[EMAIL PROTECTED] Sent: 14 December 2007 19:51
To: [EMAIL PROTECTED]
Subject: Re: [fc] How to move a group of objects


David Poundall wrote:
Tried the following but to no avail...
        R = FC.Rectangle((5, 5),(15, 8), FillColor="Red")
        C = FC.Circle( (1, 3), 2, FillColor="Blue")
        self.GroupA = FC.Group((R,C))
        G = MovingGroup(self.GroupA)

MovingGroup is a subclass of Group, but it can't be created from one. This might work:

        G = MovingGroup((R,C))

        Canvas.AddObject(G)
        G.Bind(FC.EVT_FC_LEFT_DOWN, self.FCObjectHit)

-Chris

------------------------------------------------------------------------

_______________________________________________
FloatCanvas mailing list
[email protected]
http://mail.mithis.com/cgi-bin/mailman/listinfo/floatcanvas
#!/usr/bin/env python
"""

This is a small demo, showing how to make an object that can be moved around.

It also contains a simple prototype for a "Connector" object
  -- a line connecting two other objects

"""

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
    from floatcanvas.Utilities import BBox

import numpy as N

## here we create some new mixins:

class MovingObjectMixin:
    """
    Methods required for a Moving object
    
    """

    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 ConnectorObjectMixin:
    """
    Mixin class for DrawObjects that can be connected with lines
    
    NOte that this versionony works for Objects that have an "XY" attribute:
      that is, one that is derived from XHObjectMixin.
    
    """
    
    def GetConnectPoint(self):
        return self.XY
        
class MovingBitmap(FC.ScaledBitmap, MovingObjectMixin, ConnectorObjectMixin):
    """
    ScaledBitmap Object that can be moved
    """
    ## All we need to do is is inherit from:
    ##  ScaledBitmap, MovingObjectMixin and ConnectorObjectMixin
    pass
    
class MovingCircle(FC.Circle, MovingObjectMixin, ConnectorObjectMixin):
    """
    ScaledBitmap Object that can be moved
    """
    ## All we need to do is is inherit from:
    ##  ScaledBitmap, MovingObjectMixin and ConnectorObjectMixin
    pass
    
class MovingArc(FC.Arc, MovingObjectMixin, ConnectorObjectMixin):
    """
    ScaledBitmap Object that can be moved
    """
    ## All we need to do is is inherit from:
    ##  ScaledBitmap, MovingObjectMixin and ConnectorObjectMixin
    pass

class MovingGroup(FC.Group, MovingObjectMixin):
     pass
       
    
class TriangleShape1(FC.Polygon, MovingObjectMixin):

    def __init__(self, XY, L):

        """
        An equilateral 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 simple frame used for the Demo

    """

    def __init__(self, *args, **kwargs):
        wx.Frame.__init__(self, *args, **kwargs)

        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 )
        Canvas.Bind(FC.EVT_LEFT_DOWN, self.OnLeftDown )
        
        self.objects = [] #this contains objects on the canvas

        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)
            self.objects.append(Tri)
            Canvas.AddObject(Tri)
            Tri.Bind(FC.EVT_FC_LEFT_DOWN, self.ObjectHit)

        Circle = MovingCircle( (1, 3), 2, FillColor="Blue")
        self.objects.append(Circle)
        Canvas.AddObject(Circle)
        Circle.Bind(FC.EVT_FC_LEFT_DOWN, self.ObjectHit)

        Bitmaps = []
        ## create the bitmaps first
        for Point in ((1,1), (-4,3)):
            Bitmaps.append(MovingBitmap(Resources.getMondrianImage(),
                                  Point,
                                  Height=1,
                                  Position='cc')
                           )       
        
        ## then add them to the Canvas, so they are on top of the line
        for bmp in Bitmaps:
            self.objects.append(bmp)
            Canvas.AddObject(bmp)
            bmp.Bind(FC.EVT_FC_LEFT_DOWN, self.ObjectHit)

        A = MovingArc((-5, 0),(-2, 2),(-5, 2), LineColor="Red", LineWidth=2)
        self.objects.append(A)
        self.Canvas.AddObject(A)
        A.Bind(FC.EVT_FC_LEFT_DOWN, self.ObjectHit)

        self.Show(True)
        self.Canvas.ZoomToBB()

        self.MoveObject = None
        self.Moving = False
        self.Tol = 5
    
        self.Drawing = False
        self.RBRect = None
        self.StartPointWorld = None


        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 object 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)
            
        if self.Drawing:
            x, y = self.StartPoint
            Cornerx, Cornery = event.GetPosition()
            w, h = ( Cornerx - x, Cornery - y)
            if abs(w) > self.Tol and abs(h) > self.Tol:
                # draw the RB box
                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.RBRect:
                    dc.DrawRectangle(*self.RBRect)
                self.RBRect = (x, y, w, h )
                dc.DrawRectangle(*self.RBRect)
            
    def OnLeftDown(self,event):
        self.Drawing = True
        self.StartPoint = event.GetPosition()
        self.StartPointWorld = event.Coords       
                  
    
    def OnLeftUp(self, event):
        if self.Drawing:
            self.Drawing = False
            if self.RBRect:
                WH = event.Coords - self.StartPointWorld #do I even need this?
                self.selected_objects = []
                for object in self.objects:
                    objp = object.GetOutlinePoints()[0]   #how do i get position of an object?                 
                    if  self.StartPointWorld[0] < objp[0] and self.StartPointWorld[1] > objp[1] and event.Coords[0] > objp[0] and event.Coords[1] < objp[1]:
                        #insert better hitText above
                        self.selected_objects.append(object)            
                        
                G = MovingGroup(self.selected_objects)
                self.Canvas.AddObject(G)
                G.Bind(FC.EVT_FC_LEFT_DOWN, self.ObjectHit)
                    
            self.Canvas.Draw(True)
        self.RBRect = None
        self.StartPointWorld = None   
        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) 
                self.MoveTri = None
            self.Canvas.Draw(True)

            

app = wx.PySimpleApp(0)
DrawFrame(None, -1, "FloatCanvas Moving Group Object 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