Ejemplo n.º 1
0
    def getConnectorLine(self, otherWidget):
        """
        Get the line that would be drawn between this widget and another.
        """
        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())

        return (start, end)
Ejemplo n.º 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])
Ejemplo n.º 3
0
    def getConnectorLine(self, otherWidget, clipped=True):
        """
        Get the line that would be drawn between this widget and another.
        """
        start = self.getCenter()
        end = otherWidget.getCenter()

        #Tweak to make overlapping lines easier to see by shifting the end point
        #Devision by a large constant to so the behavior is not overly noticeable while dragging
        lengthSquared = ((start[0]-end[0])**2+(start[1]-end[1])**2)/1024**2
        end[0] += (0.5 - math.sin(lengthSquared))*PassageWidget.SIZE/8.0
        end[1] += (0.5 - math.cos(lengthSquared))*PassageWidget.SIZE/8.0
        if clipped:
            [start, end] = geometry.clipLineByRects([start, end], otherWidget.getLogicalRect())
        return self.parent.toPixels(start), self.parent.toPixels(end)
Ejemplo n.º 4
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]) 
Ejemplo n.º 5
0
    def getConnectorLine(self, otherWidget, clipped=True):
        """
        Get the line that would be drawn between this widget and another.
        """
        start = self.getCenter()
        end = otherWidget.getCenter()

        #Tweak to make overlapping lines easier to see by shifting the end point
        #Devision by a large constant to so the behavior is not overly noticeable while dragging
        lengthSquared = ((start[0] - end[0])**2 +
                         (start[1] - end[1])**2) / 1024**2
        end[0] += (0.5 - math.sin(lengthSquared)) * PassageWidget.SIZE / 8.0
        end[1] += (0.5 - math.cos(lengthSquared)) * PassageWidget.SIZE / 8.0
        if clipped:
            [start,
             end] = geometry.clipLineByRects([start, end],
                                             otherWidget.getLogicalRect())
        return self.parent.toPixels(start), self.parent.toPixels(end)
Ejemplo n.º 6
0
    def getConnectorLine(self, otherWidget):
        """
        Get the line that would be drawn between this widget and another.
        """
        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())
        
        return (start, end)
Ejemplo n.º 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 = 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])
Ejemplo n.º 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])
Ejemplo n.º 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)
Ejemplo n.º 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)