Search code examples
python-3.xwxpython

How to return IDs within a wx.Rect in Wxpython PseudoDC


I am making a "Box Select" tool for a program I am developing in Wxpython. I am using the PseudoDC class for the drawing.

The user should able to draw a box to select drawn node objects on the nodegraph by their ID, but I am unable to figure out a good way to get the IDs that are within the Box selection.

So far, I have come up with the following:

    def OnLeftUp(self, event):
            ...
            # This is in the mouse event method which calls the *BoxSelectHitTest* method below.
            self._selectednodes = self.BoxSelectHitTest(
                wx.Point(self._bboxRect[2]/2, 
                    self._bboxRect[3]/2)
                )
            ...

    def BoxSelectHitTest(self, pt):
        # self._bboxRect is the wx.Rect of the Box Select
        average = (self._bboxRect[3] + self._bboxRect[2])/2
        idxs = self._pdc.FindObjects(pt[0], pt[1], int(average))

        hits = [
            idx 
            for idx in idxs
            if idx in self._nodes
        ]
        # Return the node objects from the IDs
        if hits != []:
            nodes = []
            for Id in hits:
                nodes.append(self._nodes[Id])
            return nodes

        else:
            return []

This is obviously not a true box select. It is more like a bad version of a circle select. (The radius by the average is just my attempt at making it "work".)

I couldn't find a method in PseudoDC that would return the IDs of objects within a given wx.Rect. Is there a method that does this or how should this be implemented correctly?

Thank you.


Solution

  • I figured it out by looking through the documentation on wx.Rect, so I thought I would post it here.

    Using wx.Rect.Intersects it checks if the bboxrect intersects with each node's rect and returns them:

        def BoxSelectHitTest(self, bboxrect):
            nodehits = []
            for node in self._nodes.values():
                if bboxrect.Intersects(node.GetRect()) == True:
                    nodehits.append(node)
    
            if nodehits != []:
                return nodehits
    
            else:
                # Make sure we deselect everything
                for node in self._selectednodes:
                    node.SetSelected(False)
                    node.Draw(self._pdc)
                self._selectednodes = []
                return []