示例#1
0
    def paintConnectorTo(self, otherWidget, arrowheads, color, width, gc, updateRect = None):
        """
        Paints a connecting line between this widget and another,
        with optional arrowheads. You may pass either a wx.GraphicsContext
        (anti-aliased drawing) or a wx.PaintDC.
        """
        start, end = self.getConnectorLine(otherWidget)

        # does it actually need to be drawn?

        if otherWidget == self:
            return

        if updateRect and not geometry.lineRectIntersection([start, end], updateRect):
            return

        # ok, really draw the line

        lineWidth = max(self.parent.toPixels((width, 0), scaleOnly = True)[0], 1)
        gc.SetPen(wx.Pen(color, lineWidth))

        if isinstance(gc, wx.GraphicsContext):
            gc.StrokeLine(start[0], start[1], end[0], end[1])
        else:
            gc.DrawLine(start[0], start[1], end[0], end[1])

        # arrowheads at end

        if not arrowheads: return

        flat = self.app.config.ReadBool('flatDesign')
        
        arrowheadLength = max(self.parent.toPixels((PassageWidget.ARROWHEAD_LENGTH, 0), scaleOnly = True)[0], 1)
        arrowhead = geometry.endPointProjectedFrom((start, end), angle = PassageWidget.ARROWHEAD_ANGLE, \
                                                   distance = arrowheadLength)

        if flat:
            pass
        elif isinstance(gc, wx.GraphicsContext):
            gc.StrokeLine(end[0], end[1], arrowhead[0], arrowhead[1])
        else:
            gc.DrawLine(end[0], end[1], arrowhead[0], arrowhead[1])

        arrowhead2 = geometry.endPointProjectedFrom((start, end), angle = 0 - PassageWidget.ARROWHEAD_ANGLE, \
                                                   distance = arrowheadLength)

        
        if flat:
            gc.SetBrush(wx.Brush(color))
            if isinstance(gc, wx.GraphicsContext):
                gc.DrawLines([wx.Point2D(*arrowhead2), wx.Point2D(*end), wx.Point2D(*arrowhead) ])
            else:
                gc.DrawPolygon([wx.Point(*arrowhead2), wx.Point(*end), wx.Point(*arrowhead)])
        elif isinstance(gc, wx.GraphicsContext):
            gc.StrokeLine(end[0], end[1], arrowhead2[0], arrowhead2[1])
        else:
            gc.DrawLine(end[0], end[1], arrowhead2[0], arrowhead2[1])
示例#2
0
    def paintConnectorTo(self, otherWidget, arrowheads, gc, updateRect=None):
        """
        Paints a connecting line between this widget and another,
        with optional arrowheads. You may pass either a wx.GraphicsContext
        (anti-aliased drawing) or a wx.PaintDC.
        """
        start = self.parent.toPixels(self.getCenter())
        end = self.parent.toPixels(otherWidget.getCenter())
        start, end = geometry.clipLineByRects([start, end],
                                              otherWidget.getPixelRect())

        # does it actually need to be drawn?

        if updateRect and not geometry.lineRectIntersection([start, end],
                                                            updateRect):
            return

        if otherWidget == self:
            return

        # ok, really draw the line

        lineWidth = max(
            self.parent.toPixels((PassageWidget.CONNECTOR_WIDTH, 0),
                                 scaleOnly=True)[0], 1)
        gc.SetPen(wx.Pen(PassageWidget.CONNECTOR_COLOR, lineWidth))

        if isinstance(gc, wx.GraphicsContext):
            gc.StrokeLine(start[0], start[1], end[0], end[1])
        else:
            gc.DrawLine(start[0], start[1], end[0], end[1])

        # arrowheads at end

        if not arrowheads: return

        arrowheadLength = max(
            self.parent.toPixels((PassageWidget.ARROWHEAD_LENGTH, 0),
                                 scaleOnly=True)[0], 1)
        arrowhead = geometry.endPointProjectedFrom((start, end), angle = PassageWidget.ARROWHEAD_ANGLE, \
                                                   distance = arrowheadLength)

        if isinstance(gc, wx.GraphicsContext):
            gc.StrokeLine(end[0], end[1], arrowhead[0], arrowhead[1])
        else:
            gc.DrawLine(end[0], end[1], arrowhead[0], arrowhead[1])

        arrowhead = geometry.endPointProjectedFrom((start, end), angle = 0 - PassageWidget.ARROWHEAD_ANGLE, \
                                                   distance = arrowheadLength)

        if isinstance(gc, wx.GraphicsContext):
            gc.StrokeLine(end[0], end[1], arrowhead[0], arrowhead[1])
        else:
            gc.DrawLine(end[0], end[1], arrowhead[0], arrowhead[1])
示例#3
0
    def paintConnectorTo (self, otherWidget, arrowheads, color, gc, updateRect = None):
        """
        Paints a connecting line between this widget and another,
        with optional arrowheads. You may pass either a wx.GraphicsContext
        (anti-aliased drawing) or a wx.PaintDC.
        """
        start = self.parent.toPixels(self.getCenter())
        end = self.parent.toPixels(otherWidget.getCenter())
        start, end = geometry.clipLineByRects([start, end], otherWidget.getPixelRect())
                    
        # does it actually need to be drawn?
        
        if updateRect and not geometry.lineRectIntersection([start, end], updateRect):
            return
        
        if otherWidget == self:
            return
            
        # ok, really draw the line
        
        lineWidth = max(self.parent.toPixels((PassageWidget.CONNECTOR_WIDTH, 0), scaleOnly = True)[0], 1)
        gc.SetPen(wx.Pen(color, lineWidth))
        
        if isinstance(gc, wx.GraphicsContext):
            gc.StrokeLine(start[0], start[1], end[0], end[1])
        else:
            gc.DrawLine(start[0], start[1], end[0], end[1])
        
        # arrowheads at end

        if not arrowheads: return
         
        arrowheadLength = max(self.parent.toPixels((PassageWidget.ARROWHEAD_LENGTH, 0), scaleOnly = True)[0], 1)
        arrowhead = geometry.endPointProjectedFrom((start, end), angle = PassageWidget.ARROWHEAD_ANGLE, \
                                                   distance = arrowheadLength)
        
        if isinstance(gc, wx.GraphicsContext):
            gc.StrokeLine(end[0], end[1], arrowhead[0], arrowhead[1])
        else:
            gc.DrawLine(end[0], end[1], arrowhead[0], arrowhead[1])
            
        arrowhead = geometry.endPointProjectedFrom((start, end), angle = 0 - PassageWidget.ARROWHEAD_ANGLE, \
                                                   distance = arrowheadLength)

        if isinstance(gc, wx.GraphicsContext):
            gc.StrokeLine(end[0], end[1], arrowhead[0], arrowhead[1])
        else:
            gc.DrawLine(end[0], end[1], arrowhead[0], arrowhead[1]) 
示例#4
0
    def getConnectorTo(self, otherWidget, arrowheads=False, updateRect=None):
        # does it actually need to be drawn?
        if otherWidget == self:
            return [], []
        start, end = self.getConnectorLine(otherWidget)
        if updateRect and not geometry.lineRectIntersection([start, end], updateRect):
            return [], []

        line = [[start[0], start[1]], [end[0], end[1]]]

        if not arrowheads:
            return line, []
        else:
            length = max(self.parent.toPixels((PassageWidget.ARROWHEAD_LENGTH, 0), scaleOnly=True)[0], 1)
            arrowheadr = geometry.endPointProjectedFrom((start, end), PassageWidget.ARROWHEAD_ANGLE,  length)
            arrowheadl = geometry.endPointProjectedFrom((start, end), 0 - PassageWidget.ARROWHEAD_ANGLE, length)
        return line, [(arrowheadl, end, arrowheadr)]
示例#5
0
    def getConnectorTo(self, otherWidget, arrowheads=False, updateRect=None):
        # does it actually need to be drawn?
        if otherWidget == self:
            return [], []
        start, end = self.getConnectorLine(otherWidget)
        if updateRect and not geometry.lineRectIntersection([start, end],
                                                            updateRect):
            return [], []

        line = [[start[0], start[1]], [end[0], end[1]]]

        if not arrowheads:
            return line, []
        else:
            length = max(
                self.parent.toPixels((PassageWidget.ARROWHEAD_LENGTH, 0),
                                     scaleOnly=True)[0], 1)
            arrowheadr = geometry.endPointProjectedFrom(
                (start, end), PassageWidget.ARROWHEAD_ANGLE, length)
            arrowheadl = geometry.endPointProjectedFrom(
                (start, end), 0 - PassageWidget.ARROWHEAD_ANGLE, length)
        return line, [(arrowheadl, end, arrowheadr)]
示例#6
0
    def paintConnectorTo(self, otherWidget, arrowheads, color, width, gc, updateRect = None):
        """
        Paints a connecting line between this widget and another,
        with optional arrowheads. You may pass either a wx.GraphicsContext
        (anti-aliased drawing) or a wx.PaintDC.
        """
        start = self.parent.toPixels(self.getCenter())
        end = self.parent.toPixels(otherWidget.getCenter())

        # Additional tweak to make overlapping arrows more visible

        length = min(math.sqrt((start[0]-end[0])**2 + (start[1]-end[1])**2)/32, 16)

        if start[1] != end[1]:
            start[0] += length * math.copysign(1, start[1] - end[1]);
            end[0] += length * math.copysign(1, start[1] - end[1]);
        if start[0] != end[0]:
            start[1] += length * math.copysign(1, start[0] - end[0]);
            end[1] += length * math.copysign(1, start[0] - end[0]);

        # Clip the end of the arrow

        start, end = geometry.clipLineByRects([start, end], otherWidget.getPixelRect())

        # does it actually need to be drawn?

        if otherWidget == self:
            return

        if updateRect and not geometry.lineRectIntersection([start, end], updateRect):
            return

        # ok, really draw the line

        lineWidth = max(self.parent.toPixels((width, 0), scaleOnly = True)[0], 1)
        gc.SetPen(wx.Pen(color, lineWidth))

        if isinstance(gc, wx.GraphicsContext):
            gc.StrokeLine(start[0], start[1], end[0], end[1])
        else:
            gc.DrawLine(start[0], start[1], end[0], end[1])

        # arrowheads at end

        if not arrowheads: return

        arrowheadLength = max(self.parent.toPixels((PassageWidget.ARROWHEAD_LENGTH, 0), scaleOnly = True)[0], 1)
        arrowhead = geometry.endPointProjectedFrom((start, end), angle = PassageWidget.ARROWHEAD_ANGLE, \
                                                   distance = arrowheadLength)

        if isinstance(gc, wx.GraphicsContext):
            gc.StrokeLine(end[0], end[1], arrowhead[0], arrowhead[1])
        else:
            gc.DrawLine(end[0], end[1], arrowhead[0], arrowhead[1])

        arrowhead = geometry.endPointProjectedFrom((start, end), angle = 0 - PassageWidget.ARROWHEAD_ANGLE, \
                                                   distance = arrowheadLength)

        if isinstance(gc, wx.GraphicsContext):
            gc.StrokeLine(end[0], end[1], arrowhead[0], arrowhead[1])
        else:
            gc.DrawLine(end[0], end[1], arrowhead[0], arrowhead[1])
示例#7
0
    def paintConnectorTo(self,
                         otherWidget,
                         arrowheads,
                         color,
                         width,
                         gc,
                         updateRect=None):
        """
        Paints a connecting line between this widget and another,
        with optional arrowheads. You may pass either a wx.GraphicsContext
        (anti-aliased drawing) or a wx.PaintDC.
        """
        start, end = self.getConnectorLine(otherWidget)

        # does it actually need to be drawn?

        if otherWidget == self:
            return

        if updateRect and not geometry.lineRectIntersection([start, end],
                                                            updateRect):
            return

        # ok, really draw the line

        lineWidth = max(self.parent.toPixels((width, 0), scaleOnly=True)[0], 1)
        gc.SetPen(wx.Pen(color, lineWidth))

        if isinstance(gc, wx.GraphicsContext):
            gc.StrokeLine(start[0], start[1], end[0], end[1])
        else:
            gc.DrawLine(start[0], start[1], end[0], end[1])

        # arrowheads at end

        if not arrowheads: return

        flat = self.app.config.ReadBool('flatDesign')

        arrowheadLength = max(
            self.parent.toPixels((PassageWidget.ARROWHEAD_LENGTH, 0),
                                 scaleOnly=True)[0], 1)
        arrowhead = geometry.endPointProjectedFrom((start, end), angle = PassageWidget.ARROWHEAD_ANGLE, \
                                                   distance = arrowheadLength)

        if flat:
            pass
        elif isinstance(gc, wx.GraphicsContext):
            gc.StrokeLine(end[0], end[1], arrowhead[0], arrowhead[1])
        else:
            gc.DrawLine(end[0], end[1], arrowhead[0], arrowhead[1])

        arrowhead2 = geometry.endPointProjectedFrom((start, end), angle = 0 - PassageWidget.ARROWHEAD_ANGLE, \
                                                   distance = arrowheadLength)

        if flat:
            gc.SetBrush(wx.Brush(color))
            if isinstance(gc, wx.GraphicsContext):
                gc.DrawLines([
                    wx.Point2D(*arrowhead2),
                    wx.Point2D(*end),
                    wx.Point2D(*arrowhead)
                ])
            else:
                gc.DrawPolygon([
                    wx.Point(*arrowhead2),
                    wx.Point(*end),
                    wx.Point(*arrowhead)
                ])
        elif isinstance(gc, wx.GraphicsContext):
            gc.StrokeLine(end[0], end[1], arrowhead2[0], arrowhead2[1])
        else:
            gc.DrawLine(end[0], end[1], arrowhead2[0], arrowhead2[1])
示例#8
0
    def paintConnectorTo(self,
                         otherWidget,
                         arrowheads,
                         color,
                         width,
                         gc,
                         updateRect=None):
        """
        Paints a connecting line between this widget and another,
        with optional arrowheads. You may pass either a wx.GraphicsContext
        (anti-aliased drawing) or a wx.PaintDC.
        """
        start = self.parent.toPixels(self.getCenter())
        end = self.parent.toPixels(otherWidget.getCenter())

        # Additional tweak to make overlapping arrows more visible

        length = min(
            math.sqrt((start[0] - end[0])**2 + (start[1] - end[1])**2) / 32,
            16)

        if start[1] != end[1]:
            start[0] += length * math.copysign(1, start[1] - end[1])
            end[0] += length * math.copysign(1, start[1] - end[1])
        if start[0] != end[0]:
            start[1] += length * math.copysign(1, start[0] - end[0])
            end[1] += length * math.copysign(1, start[0] - end[0])

        # Clip the end of the arrow

        start, end = geometry.clipLineByRects([start, end],
                                              otherWidget.getPixelRect())

        # does it actually need to be drawn?

        if otherWidget == self:
            return

        if updateRect and not geometry.lineRectIntersection([start, end],
                                                            updateRect):
            return

        # ok, really draw the line

        lineWidth = max(self.parent.toPixels((width, 0), scaleOnly=True)[0], 1)
        gc.SetPen(wx.Pen(color, lineWidth))

        if isinstance(gc, wx.GraphicsContext):
            gc.StrokeLine(start[0], start[1], end[0], end[1])
        else:
            gc.DrawLine(start[0], start[1], end[0], end[1])

        # arrowheads at end

        if not arrowheads: return

        arrowheadLength = max(
            self.parent.toPixels((PassageWidget.ARROWHEAD_LENGTH, 0),
                                 scaleOnly=True)[0], 1)
        arrowhead = geometry.endPointProjectedFrom((start, end), angle = PassageWidget.ARROWHEAD_ANGLE, \
                                                   distance = arrowheadLength)

        if isinstance(gc, wx.GraphicsContext):
            gc.StrokeLine(end[0], end[1], arrowhead[0], arrowhead[1])
        else:
            gc.DrawLine(end[0], end[1], arrowhead[0], arrowhead[1])

        arrowhead = geometry.endPointProjectedFrom((start, end), angle = 0 - PassageWidget.ARROWHEAD_ANGLE, \
                                                   distance = arrowheadLength)

        if isinstance(gc, wx.GraphicsContext):
            gc.StrokeLine(end[0], end[1], arrowhead[0], arrowhead[1])
        else:
            gc.DrawLine(end[0], end[1], arrowhead[0], arrowhead[1])
示例#9
0
 def paint (self, event):
     """Paints marquee selection, widget connectors, and widgets onscreen."""
     
     # do NOT call self.DoPrepareDC() no matter what the docs may say
     # we already take into account our scroll origin in our
     # toPixels() method
     
     # OS X already double buffers drawing for us; if we try to do it
     # ourselves, performance is horrendous
     
     if (sys.platform == 'darwin'):
         gc = wx.GraphicsContext.Create(wx.PaintDC(self))
     else:
         gc = wx.GraphicsContext.Create(wx.BufferedPaintDC(self))
     
     # background
     
     updateRect = self.GetUpdateRegion().GetBox()
     gc.SetBrush(wx.Brush(StoryPanel.BACKGROUND_COLOR))      
     gc.DrawRectangle(updateRect.x, updateRect.y, updateRect.width, updateRect.height)
             
     # connectors
     
     arrowheadLength = max(self.toPixels((StoryPanel.ARROWHEAD_LENGTH, 0), scaleOnly = True)[0], \
                           StoryPanel.MIN_ARROWHEAD_LENGTH)
     
     gc.SetPen(wx.Pen(StoryPanel.CONNECTOR_COLOR, max(self.toPixels((StoryPanel.CONNECTOR_WIDTH, 0), \
                                                                     scaleOnly = True)[0], 1)))
     for widget in self.widgets:
         if widget.dimmed: continue
         start = self.toPixels(widget.getCenter())
         for link in widget.passage.links():
             otherWidget = self.findWidget(link)
             if otherWidget and not otherWidget.dimmed:
                 # connector line
                 
                 end = self.toPixels(otherWidget.getCenter())
                 start, end = geometry.clipLineByRects([start, end], otherWidget.getPixelRect())
                 gc.StrokeLine(start[0], start[1], end[0], end[1])
     
                 # arrowheads at end
     
                 arrowhead = geometry.endPointProjectedFrom((start, end), angle = StoryPanel.ARROWHEAD_ANGLE, \
                                                            distance = arrowheadLength)
                 gc.StrokeLine(end[0], end[1], arrowhead[0], arrowhead[1])
                 arrowhead = geometry.endPointProjectedFrom((start, end), angle = 0 - StoryPanel.ARROWHEAD_ANGLE, \
                                                            distance = arrowheadLength)
                 gc.StrokeLine(end[0], end[1], arrowhead[0], arrowhead[1])                    
             
     # widgets
             
     for widget in self.widgets:
         if updateRect.Intersects(widget.getPixelRect()): widget.paint(gc)
     
     # marquee selection
     # use alpha blending for interior
     
     if self.draggingMarquee:
         marqueeColor = wx.SystemSettings.GetColour(wx.SYS_COLOUR_HIGHLIGHT)
         gc.SetPen(wx.Pen(marqueeColor))
         r, g, b = marqueeColor.Get()
         marqueeColor = wx.Color(r, g, b, StoryPanel.MARQUEE_ALPHA)            
         gc.SetBrush(wx.Brush(marqueeColor))
         gc.DrawRectangle(self.dragRect.x, self.dragRect.y, self.dragRect.width, self.dragRect.height)
示例#10
0
    def paint (self, event):
        """Paints marquee selection, widget connectors, and widgets onscreen."""
        # do NOT call self.DoPrepareDC() no matter what the docs may say
        # we already take into account our scroll origin in our
        # toPixels() method
        
        # in fast drawing, we ask for a standard paint context
        # in slow drawing, we ask for a anti-aliased one
        #
        # OS X already double buffers drawing for us; if we try to do it
        # ourselves, performance is horrendous

        if (sys.platform == 'darwin'):
            gc = wx.PaintDC(self)
        else:
            gc = wx.BufferedPaintDC(self)
        
        if not self.app.config.ReadBool('fastStoryPanel'):
            gc = wx.GraphicsContext.Create(gc)            
                       
        # background
        
        updateRect = self.GetUpdateRegion().GetBox()
        gc.SetBrush(wx.Brush(StoryPanel.BACKGROUND_COLOR))      
        gc.DrawRectangle(updateRect.x - 1, updateRect.y - 1, updateRect.width + 2, updateRect.height + 2)
                
        # connectors
        
        arrowheadLength = max(self.toPixels((StoryPanel.ARROWHEAD_LENGTH, 0), scaleOnly = True)[0], \
                              StoryPanel.MIN_ARROWHEAD_LENGTH)
        
        gc.SetPen(wx.Pen(StoryPanel.CONNECTOR_COLOR, max(self.toPixels((StoryPanel.CONNECTOR_WIDTH, 0), \
                                                                        scaleOnly = True)[0], 1)))
        
        # cache bad links so we don't have to keep doing worst-case lookups
        
        badLinks = []

        for widget in self.widgets:
            if widget.dimmed: continue
            start = self.toPixels(widget.getCenter())
            for link in widget.passage.links():
                if link in badLinks: continue                
                otherWidget = self.findWidget(link)
                if not otherWidget: badLinks.append(link)
                
                if otherWidget and not otherWidget.dimmed:
                    # connector line
                    
                    end = self.toPixels(otherWidget.getCenter())
                    
                    # does it actually need to be drawn?
                    
                    if not geometry.lineRectIntersection([start, end], updateRect):
                        continue
                        
                    # ok, really draw the line
                    
                    if self.scale > StoryPanel.ARROWHEAD_THRESHOLD:
                        start, end = geometry.clipLineByRects([start, end], otherWidget.getPixelRect())
                    
                    if isinstance(gc, wx.GraphicsContext):
                        gc.StrokeLine(start[0], start[1], end[0], end[1])
                    else:
                        gc.DrawLine(start[0], start[1], end[0], end[1])
                    
                    # arrowheads at end
        
                    if self.scale < StoryPanel.ARROWHEAD_THRESHOLD: continue
                        
                    arrowhead = geometry.endPointProjectedFrom((start, end), angle = StoryPanel.ARROWHEAD_ANGLE, \
                                                               distance = arrowheadLength)
                    
                    if isinstance(gc, wx.GraphicsContext):
                        gc.StrokeLine(end[0], end[1], arrowhead[0], arrowhead[1])
                    else:
                        gc.DrawLine(end[0], end[1], arrowhead[0], arrowhead[1])
                        
                    arrowhead = geometry.endPointProjectedFrom((start, end), angle = 0 - StoryPanel.ARROWHEAD_ANGLE, \
                                                               distance = arrowheadLength)

                    if isinstance(gc, wx.GraphicsContext):
                        gc.StrokeLine(end[0], end[1], arrowhead[0], arrowhead[1])
                    else:
                        gc.DrawLine(end[0], end[1], arrowhead[0], arrowhead[1])                    
                     
        # widgets
                
        for widget in self.widgets:
            if updateRect.Intersects(widget.getPixelRect()): widget.paint(gc)
        
        # marquee selection
        # with slow drawing, use alpha blending for interior
        
        if self.draggingMarquee:
            if self.app.config.ReadBool('fastStoryPanel'):
                gc.SetPen(wx.Pen('#ffffff', 1, wx.DOT))
            else:
                marqueeColor = wx.SystemSettings.GetColour(wx.SYS_COLOUR_HIGHLIGHT)
                gc.SetPen(wx.Pen(marqueeColor))
                r, g, b = marqueeColor.Get()
                marqueeColor = wx.Color(r, g, b, StoryPanel.MARQUEE_ALPHA)            
                gc.SetBrush(wx.Brush(marqueeColor))
                
            gc.DrawRectangle(self.dragRect.x, self.dragRect.y, self.dragRect.width, self.dragRect.height)