Ejemplo n.º 1
0
    def redraw_link(self, instance=None, value=None):
        root = App.get_running_app().root

        if root is not None:
            root.canvas.after.remove_group(str(self.uid))

            if self.linked_to_object is not None:

                # find out the vectors for the keyboard (in objects (its) co-ordinates)
                a = Vector(*self.center)
                b = Vector(a[0], a[1]+10)
                v = b-a
                vup = v.rotate(self.rotation)
                #vl = vup.rotate(90)  # rotation is anti-clockwise
                #vr = vup.rotate(-90) # rotation is anti-clockwise
                vup = vup.normalize()
                #vl = vl.normalize()
                #vr = vr.normalize()

                center = a

                up_half = vup*self.size[1]/2*self.scale
                #left_half = vl*self.size[0]/2*self.scale
                #right_half = -left_half

                # positions representing the object, have to use vectors, as otherwise pos, etc. gives back the bounding box instead
                top_center   = center + up_half
                #top_left     = center + left_half  + up_half
                #top_right    = center + right_half + up_half
                #bottom_left  = center + left_half  - up_half
                #bottom_right = center + right_half - up_half

                # figure out the vectors for the linked object (in object co-ordinates)
                la = Vector(*self.linked_to_object.center)
                lb = Vector(la[0], la[1]+10)
                lv = lb-la
                lvup = lv.rotate(self.linked_to_object.rotation)
                lvl = lvup.rotate(90)  # rotation is anti-clockwise
                #lvr = lvup.rotate(-90) # rotation is anti-clockwise
                lvup = lvup.normalize()
                lvl = lvl.normalize()
                #lvr = lvr.normalize()

                lcenter = la

                lup_half = lvup*self.linked_to_object.size[1]/2*self.linked_to_object.scale
                lleft_half = lvl*self.linked_to_object.size[0]/2*self.linked_to_object.scale
                lright_half = -lleft_half

                # positions representing the object, have to use vectors, as otherwise pos, etc. gives back the bounding box instead
                #ltop_center    = lcenter + lup_half
                #lbottom_center = lcenter - lup_half
                #lleft_center   = lcenter + lleft_half
                #lright_center  = lcenter + lright_half
                ltop_left      = lcenter + lleft_half  + lup_half
                ltop_right     = lcenter + lright_half + lup_half
                lbottom_left   = lcenter + lleft_half  - lup_half
                lbottom_right  = lcenter + lright_half - lup_half

                wk_top_center    = self.to_window(*top_center)
                wl_center        = self.linked_to_object.to_window(*lcenter)

                # this is where you can do the code for the intersection testing
                wl_top_left     = self.linked_to_object.to_window(*ltop_left)
                wl_top_right    = self.linked_to_object.to_window(*ltop_right)
                wl_bottom_left  = self.linked_to_object.to_window(*lbottom_left)
                wl_bottom_right = self.linked_to_object.to_window(*lbottom_right)

                # quit when we find the first intersection, else quit when at the end
                shouldDraw = False
                while True:
                    # bottom line
                    intersects, collinear, position = Vector.line_segment_intersection(wk_top_center, wl_center, wl_bottom_left, wl_bottom_right)
                    if intersects and collinear=="not-collinear":
                        x2, y2 = position
                        shouldDraw = True
                        break

                    # top line
                    intersects, collinear, position = Vector.line_segment_intersection(wk_top_center, wl_center, wl_top_left, wl_top_right)
                    if intersects and collinear=="not-collinear":
                        x2, y2 = position
                        shouldDraw = True
                        break

                    # right side
                    intersects, collinear, position = Vector.line_segment_intersection(wk_top_center, wl_center, wl_bottom_right, wl_top_right)
                    if intersects and collinear=="not-collinear":
                        x2, y2 = position
                        shouldDraw = True
                        break

                    # left side
                    intersects, collinear, position = Vector.line_segment_intersection(wk_top_center, wl_center, wl_bottom_left, wl_top_left)
                    if intersects and collinear=="not-collinear":
                        x2, y2 = position
                        shouldDraw = True
                        break

                    # default get out of the loop
                    break

                # only draw, if we have a point to draw to
                if shouldDraw is True:
                    x1, y1 = wk_top_center

                    if self.draw_arrow_head_on_link is False:
                        with root.canvas.after:
                            Color(*self.link_colour)

                            # main line
                            Line(points=(x1, y1, x2, y2),
                                 width=self.link_width,
                                 group=str(self.uid))

                            Color(1,1,1,.1)

                            # main line
                            Line(points=(x1, y1, x2, y2),
                                 width=self.link_width/3.0,
                                 group=str(self.uid))

                    else:
                        _a = Vector(x1, y1)
                        _b = Vector(x2, y2)
                        _v = _b-_a

                        _vl = _v.rotate(140)
                        _vl = _vl.normalize()

                        _vr = _v.rotate(-140)
                        _vr = _vr.normalize()

                        end_point_left  = _b+_vl*20
                        end_point_right = _b+_vr*20

                        with root.canvas.after:
                            Color(*self.link_colour)

                            # main line
                            Line(points=(x1, y1, x2, y2),
                                 width=self.link_width,
                                 group=str(self.uid))

                            # left end point
                            Line(points=(end_point_left.x, end_point_left.y, x2, y2),
                                 width=self.link_width,
                                 group=str(self.uid))

                            # right end point
                            Line(points=(end_point_right.x, end_point_right.y, x2, y2),
                                 width=self.link_width,
                                 group=str(self.uid))

                            Color(1,1,1,.1)

                            # main line
                            Line(points=(x1, y1, x2, y2),
                                 width=self.link_width/3.0,
                                 group=str(self.uid))

                            # left end point
                            Line(points=(end_point_left.x, end_point_left.y, x2, y2),
                                 width=self.link_width/3.0,
                                 group=str(self.uid))

                            # right end point
                            Line(points=(end_point_right.x, end_point_right.y, x2, y2),
                                 width=self.link_width/3.0,
                                 group=str(self.uid))


                # refresh the scene, which adds the line disconnect button
                self.refresh()