(self, item)
return QPolygonF([QPointF(*p) for p in vert])
Return an selection geometry covering item and all its children.
Return an selection geometry covering item and all its children.
Return an selection geometry covering item and all its children .
def _selection_poly(self, item):
        # type: (Tree) -> QPolygonF
        """
        Return an selection geometry covering item and all its children.
        """
        def left(item):
            return [self._items[ch] for ch in item.node.branches[:1]]

        def right(item):
            return [self._items[ch] for ch in item.node.branches[-1:]]

        itemsleft = list(preorder(item, left))[::-1]
        itemsright = list(preorder(item, right))
        # itemsleft + itemsright walks from the leftmost leaf up to the root
        # and down to the rightmost leaf
        assert itemsleft[0].node.is_leaf
        assert itemsright[-1].node.is_leaf

        if item.node.is_leaf:
            # a single anchor point
            vert = [itemsleft[0].element.anchor]
        else:
            vert = []
            for it in itemsleft[1:]:
                vert.extend([it.element.path[0], it.element.path[1],
                             it.element.anchor])
            for it in itemsright[:-1]:
                vert.extend([it.element.anchor,
                             it.element.path[-2], it.element.path[-1]])
            # close the polygon
            vert.append(vert[0])

            def isclose(a, b, rel_tol=1e-6):
                return abs(a - b) < rel_tol * max(abs(a), abs(b))

            def isclose_p(p1, p2, rel_tol=1e-6):
                return isclose(p1.x, p2.x, rel_tol) and \
                       isclose(p1.y, p2.y, rel_tol)

            # merge consecutive vertices that are (too) close
            acc = [vert[0]]
            for v in vert[1:]:
                if not isclose_p(v, acc[-1]):
                    acc.append(v)
            vert = acc

        return QPolygonF([QPointF(*p) for p in vert])
def _selection_poly ( self , item ) : # type: (Tree) -> QPolygonF def left ( item ) : return [ self . _items [ ch ] for ch in item . node . branches [ : 1 ] ] def right ( item ) : return [ self . _items [ ch ] for ch in item . node . branches [ - 1 : ] ] itemsleft = list ( preorder ( item , left ) ) [ : : - 1 ] itemsright = list ( preorder ( item , right ) ) # itemsleft + itemsright walks from the leftmost leaf up to the root # and down to the rightmost leaf assert itemsleft [ 0 ] . node . is_leaf assert itemsright [ - 1 ] . node . is_leaf if item . node . is_leaf : # a single anchor point vert = [ itemsleft [ 0 ] . element . anchor ] else : vert = [ ] for it in itemsleft [ 1 : ] : vert . extend ( [ it . element . path [ 0 ] , it . element . path [ 1 ] , it . element . anchor ] ) for it in itemsright [ : - 1 ] : vert . extend ( [ it . element . anchor , it . element . path [ - 2 ] , it . element . path [ - 1 ] ] ) # close the polygon vert . append ( vert [ 0 ] ) def isclose ( a , b , rel_tol = 1e-6 ) : return abs ( a - b ) < rel_tol * max ( abs ( a ) , abs ( b ) ) def isclose_p ( p1 , p2 , rel_tol = 1e-6 ) : return isclose ( p1 . x , p2 . x , rel_tol ) and isclose ( p1 . y , p2 . y , rel_tol ) # merge consecutive vertices that are (too) close acc = [ vert [ 0 ] ] for v in vert [ 1 : ] : if not isclose_p ( v , acc [ - 1 ] ) : acc . append ( v ) vert = acc return QPolygonF ( [ QPointF ( * p ) for p in vert ] )