def Draw(self, dc: wx.DC): dc.SetPen(self.__Pen) x = min([self.__X1, self.__X2]) y = min([self.__Y1, self.__Y2]) w = max([self.__X1, self.__X2]) - x h = max([self.__Y1, self.__Y2]) - y dc.DrawRectangle(x, y, w, h)
def Draw(self, dc: DC, withChildren: bool = True): """ Draw the line on the dc. Args: dc: withChildren: """ if self._visible: super().Draw(dc=dc, withChildren=withChildren) line = self.GetSegments() from org.pyut.ogl.sd.OglSDMessage import OglSDMessage if isinstance(self, OglSDMessage): LineShape.clsLogger.debug(f'{self} - {self._selected=}') if self._selected: dc.SetPen(RED_PEN) if self._spline: dc.DrawSpline(line) else: dc.DrawLines(line) for control in self._controls: control.Draw(dc) if self._selected: self._srcAnchor.Draw(dc) self._dstAnchor.Draw(dc) dc.SetPen(BLACK_PEN) if self._drawArrow: u, v = line[-2], line[-1] self.DrawArrow(dc, u, v) if withChildren: # LineShape.clsLogger.debug(f'Call DrawChildren()') self.DrawChildren(dc)
def _drawSourceCardinality(self, dc: DC, sp: OglPosition, dp: OglPosition): dx, dy = self._computeDxDy(srcPosition=sp, destPosition=dp) linkLength: float = self._computeLinkLength(srcPosition=sp, destPosition=dp) srcLblX: int = round((20 * dx / linkLength - dx * 5 / linkLength) + sp.x) srcLblY: int = round((20 * dy / linkLength + dy * 5 / linkLength) + sp.y) if OglAssociation.clsLogger.isEnabledFor(INFO): info = (f'{sp=} ' f'{dp=} ' f'{dx=} ' f'{dy=} ' f'linkLength={linkLength:.2f} ' f'srcLblX={srcLblX:.2f} ' f'srcLblY={srcLblY:.2f}') OglAssociation.clsLogger.info(info) saveFont: Font = dc.GetFont() dc.SetFont(self._defaultFont) sourceCardinalityText: str = self._link.sourceCardinality dc.DrawText(sourceCardinalityText, srcLblX, srcLblY) dc.SetFont(saveFont) self._sourceCardinality = self.__updateAssociationLabel( self._sourceCardinality, x=srcLblX, y=srcLblY, text=sourceCardinalityText)
def Draw(self, dc: DC, withChildren: bool = False): """ Paint handler, draws the content of the shape. Args: dc: device context to draw to withChildren: Redraw children or not """ OglObject.Draw(self, dc) dc.SetFont(self._textFont) w, h = self.GetSize() baseX, baseY = self.GetPosition() dc.SetClippingRegion(baseX, baseY, w, h) noteContent = cast(PyutText, self.getPyutObject()).content lines = LineSplitter().split(noteContent, dc, w - 2 * OglText.MARGIN) x = baseX + OglText.MARGIN y = baseY + OglText.MARGIN for line in range(len(lines)): dc.DrawText(lines[line], x, y + line * (dc.GetCharHeight() + 5)) dc.DestroyClippingRegion()
def Draw(self, dc: DC, withChildren: bool = True): """ Draw the line on the dc. Args: dc: withChildren: """ if self._visible: super().Draw(dc=dc, withChildren=withChildren) line = self.GetSegments() if self._selected: dc.SetPen(RED_PEN) if self._spline: dc.DrawSpline(line) else: dc.DrawLines(line) for control in self._controls: control.Draw(dc) if self._selected: self._srcAnchor.Draw(dc) self._dstAnchor.Draw(dc) dc.SetPen(BLACK_PEN) if self._drawArrow: u, v = line[-2], line[-1] self.DrawArrow(dc, u, v) if withChildren: self.DrawChildren(dc)
def Draw(self, dc: DC, withChildren: bool = True): dc.SetPen(BLACK_PEN) # for some reason PEN is RED xDest, yDest = self._destinationAnchor.GetPosition() attachmentPoint: AttachmentPoint = self._destinationAnchor.attachmentPoint circleX, circleY, xSrc, ySrc = self._calculateWhereToDrawLollipop( attachmentPoint, xDest, yDest) self.logger.debug(f'Source: ({xSrc},{ySrc}) - Dest ({xDest},{yDest})') dc.DrawLine(xSrc, ySrc, xDest, yDest) dc.DrawCircle(circleX, circleY, LollipopLine.LOLLIPOP_CIRCLE_RADIUS)
def _drawCenterLabel(self, dc: DC, sp: OglPosition, dp: OglPosition): midPoint: OglPosition = OglUtils.computeMidPoint(srcPosition=sp, destPosition=dp) saveFont: Font = dc.GetFont() dc.SetFont(self._defaultFont) centerText: str = self._link.getName() dc.DrawText(centerText, midPoint.x, midPoint.y) dc.SetFont(saveFont) self._centerLabel = self.__updateAssociationLabel(self._centerLabel, x=midPoint.x, y=midPoint.y, text=centerText)
def Draw(self, dc: DC, withChildren: bool = False): """ Draw the actor. @param dc : Device context @param withChildren Draw the children or not @since 1.0 @author Philippe Waelti <*****@*****.**> """ OglObject.Draw(self, dc) # Get current font dc.SetFont(self._defaultFont) # Gets the minimum bounding box for the shape width, height = self.GetSize() # Calculate the top center of the shape x, y = self.GetPosition() # drawing is restricted in the specified region of the device dc.SetClippingRegion(x, y, width, height) # Our sweet actor size actorWidth = width actorHeight = 0.8 * (height - 2.0 * MARGIN) # 80 % of total height sizer = min(actorHeight, actorWidth) # Draw our actor head centerX = x + width // 2 centerY = y + height // 2 x = centerX - 0.2 * sizer y += MARGIN dc.DrawEllipse(x, y, 0.4 * sizer, 0.4 * sizer) # Draw body and arms x = centerX y += 0.4 * sizer dc.DrawLine(x, y, x, y + 0.3 * actorHeight) dc.DrawLine(x - 0.25 * actorWidth, y + 0.15 * actorHeight, x + 0.25 * actorWidth, y + 0.15 * actorHeight) # And the feet y += 0.3 * actorHeight dc.DrawLine(x, y, x - 0.25 * actorWidth, y + 0.3 * actorHeight) dc.DrawLine(x, y, x + 0.25 * actorWidth, y + 0.3 * actorHeight) # Draw our buddy name textWidth, textHeight = dc.GetTextExtent( self.getPyutObject().getName()) y = centerY + 0.5 * height - MARGIN - 0.1 * actorHeight dc.DrawText(self.getPyutObject().getName(), x - 0.5 * textWidth, y) dc.DestroyClippingRegion()
def split(self, text: str, dc: DC, textWidth: int) -> List[str]: """ Split the `text` into lines that fit into `textWidth` pixels. Args: text: The text to split dc: Device Context textWidth: The width of the text in pixels Returns: A list of strings that are no wider than the input pixel `width` """ splitLines: List[str] = text.splitlines() newLines: List[str] = [] for line in splitLines: words: List[str] = line.split() lineWidth: int = 0 newLine: str = "" for word in words: word: str = f'{word} ' extentSize: Tuple[int, int] = dc.GetTextExtent(word) # width, height wordWidth: int = extentSize[0] if lineWidth + wordWidth <= textWidth: newLine = f'{newLine}{word}' lineWidth += wordWidth else: newLines.append(newLine[:-1]) # remove last space newLine = word lineWidth = wordWidth newLines.append(newLine[:-1]) return newLines
def DrawArrow(self, dc: DC, u: Tuple[float, float], v: Tuple[float, float]): """ Draw an arrow at the end of the segment uv. @param dc @param u: points of the segment @param v: points of the segment """ from math import pi, atan, cos, sin pi_6 = pi / 6 points = [] x1, y1 = u x2, y2 = v a = x2 - x1 b = y2 - y1 if abs(a) < 0.01: # vertical segment if b > 0: alpha = -pi / 2 else: alpha = pi / 2 else: if a == 0: alpha = pi / 2 # TODO ? else: alpha = atan(b / a) if a > 0: alpha += pi alpha1 = alpha + pi_6 alpha2 = alpha - pi_6 size = self._arrowSize points.append((x2 + size * cos(alpha1), y2 + size * sin(alpha1))) points.append((x2, y2)) points.append((x2 + size * cos(alpha2), y2 + size * sin(alpha2))) dc.DrawPolygon(points)
def drawLosange(self, dc: DC, filled: bool = False): """ Draw an arrow at the beginning of the line. Args: dc: The device context filled: True if the losange must be filled, False otherwise Note: Losange is French for 'diamond' """ pi_6 = pi / 6 points = [] line = self.GetSegments() x1, y1 = line[1] x2, y2 = line[0] a = x2 - x1 b = y2 - y1 if abs(a) < 0.01: # vertical segment if b > 0: alpha = -pi / 2 else: alpha = pi / 2 else: if a == 0: if b > 0: alpha = pi / 2 else: alpha = 3 * pi / 2 else: alpha = atan(b / a) if a > 0: alpha += pi alpha1 = alpha + pi_6 alpha2 = alpha - pi_6 size = 8 points.append((x2 + size * cos(alpha1), y2 + size * sin(alpha1))) points.append((x2, y2)) points.append((x2 + size * cos(alpha2), y2 + size * sin(alpha2))) points.append((x2 + 2 * size * cos(alpha), y2 + 2 * size * sin(alpha))) dc.SetPen(BLACK_PEN) if filled: dc.SetBrush(BLACK_BRUSH) else: dc.SetBrush(WHITE_BRUSH) dc.DrawPolygon(points) dc.SetBrush(WHITE_BRUSH)
def Draw(self, dc: DC, withChildren: bool = True): """ Draw the text on the dc. Args: dc withChildren """ if self._visible: RectangleShape.Draw(self, dc, False) dc.SetTextForeground(self._color) dc.SetBackgroundMode(PENSTYLE_SOLID) dc.SetTextBackground(self._textBack) x, y = self.GetPosition() # to draw the text shape with its own font size saveFont: Font = dc.GetFont() if self.GetFont() is not None: dc.SetFont(self.GetFont()) dc.DrawText(self._text, x, y) dc.SetFont(saveFont) if withChildren: self.DrawChildren(dc)
def _drawVerticalLines(self, memDC: DC, width: int, height: int, startX: int, startY: int): y1: int = 0 y2: int = startY + height stop: int = width + startX step: int = self._prefs.backgroundGridInterval for movingX in range(startX, stop, step): memDC.DrawLine(movingX, y1, movingX, y2)
def _drawHorizontalLines(self, memDC: DC, width: int, height: int, startX: int, startY: int): x1: int = 0 x2: int = startX + width stop: int = height + startY step: int = self._prefs.backgroundGridInterval for movingY in range(startY, stop, step): # self.clsLogger.info(f'{x1=} {movingY=} - {x2=} {movingY=}') memDC.DrawLine(x1, movingY, x2, movingY)
def Draw(self, dc: DC, withChildren: bool = False): """ Called for drawing the contents of links. Args: dc: Device context withChildren: `True` draw the children """ self.updateMessage() srcAnchor, dstAnchor = self.getAnchors() srcX, srcY = srcAnchor.GetPosition() dstX, dstY = dstAnchor.GetPosition() self.clsLogger.debug( f'Draw line from: ({srcX},{srcY}) to: ({dstX},{dstY})') dc.SetPen(GREEN_PEN) dc.DrawLine(srcX, srcY, dstX, dstY) self.DrawArrow(dc, srcAnchor.GetPosition(), dstAnchor.GetPosition()) self.DrawChildren(dc=dc)
def _drawGrid(self, memDC: DC, width: int, height: int, startX: int, startY: int): # self.clsLogger.info(f'{width=} {height=} {startX=} {startY=}') savePen = memDC.GetPen() newPen: Pen = self._getGridPen() memDC.SetPen(newPen) self._drawHorizontalLines(memDC=memDC, width=width, height=height, startX=startX, startY=startY) self._drawVerticalLines(memDC=memDC, width=width, height=height, startX=startX, startY=startY) memDC.SetPen(savePen)
def Draw(self, dc: DC, withChildren: bool = False): """ Paint handler, draws the content of the shape. Args: dc: device context to draw to withChildren: Redraw children or not """ OglObject.Draw(self, dc) dc.SetFont(self._defaultFont) w, h = self.GetSize() try: # lines = LineSplitter().split(self.getPyutObject().getName(), dc, w - 2 * MARGIN) # noteName = self.getPyutObject().getName() noteContent = self.getPyutObject().content lines = LineSplitter().split(noteContent, dc, w - 2 * OglNote.MARGIN) except (ValueError, Exception) as e: self.logger.error(f"Unable to display note - {e}") return baseX, baseY = self.GetPosition() dc.SetClippingRegion(baseX, baseY, w, h) x = baseX + OglNote.MARGIN y = baseY + OglNote.MARGIN for line in range(len(lines)): dc.DrawText(lines[line], x, y + line * (dc.GetCharHeight() + 5)) dc.DrawLine(baseX + w - OglNote.MARGIN, baseY, baseX + w, baseY + OglNote.MARGIN) dc.DestroyClippingRegion()
def Draw(self, dc: DC, withChildren=True): """ Draw the point on the dc. Args: dc: withChildren: """ if self._visible or (self._visibleWhenSelected and self._selected): self.__penSaveColor = dc.GetPen().GetColour() Shape.Draw(self, dc, False) self.__resetPenColor(dc) x, y = self.GetPosition() if not self._selected: dc.DrawRectangle(x - 1, y - 1, 3, 3) else: dc.DrawRectangle(x - 3, y - 3, 7, 7) if withChildren: self.DrawChildren(dc)
def LoadBackground(self, dc: DC, w: int, h: int): """ Load the background image in the given dc. Args: dc: w: h: """ mem = MemoryDC() mem.SelectObject(self.__backgroundBitmap) dc.Blit(0, 0, w, h, mem, 0, 0) mem.SelectObject(NullBitmap)
def Draw(self, dc: DC, withChildren: bool = False): """ Called for drawing the contents of links. Args: dc: Device context withChildren: `True` draw the children """ self.updateMessage() srcAnchor, dstAnchor = self.getAnchors() srcX, srcY = srcAnchor.GetPosition() dstX, dstY = dstAnchor.GetPosition() if self._selected is True: dc.SetPen(RED_PEN) dc.DrawLine(srcX, srcY, dstX, dstY) self.DrawArrow(dc, srcAnchor.GetPosition(), dstAnchor.GetPosition()) self.DrawChildren(dc=dc) dc.SetPen(BLACK_PEN)
def Draw(self, dc: DC, withChildren: bool = True): """ Draw the shape. For a shape, only the anchors are drawn. Nothing is drawn if the shape is set invisible. For children classes, the main classes would normally call it's parent's Draw method, passing withChildren = False, and finally calling itself the DrawChildren method. Args: dc: wxPython device context withChildren: draw the children or not """ if self._visible: dc.SetPen(self._pen) dc.SetBrush(self._brush) if withChildren: self.DrawChildren(dc) if self._selected: dc.SetPen(RED_PEN) self.DrawHandles(dc)
def _drawDestinationCardinality(self, dc: DC, sp: OglPosition, dp: OglPosition): dx, dy = self._computeDxDy(srcPosition=sp, destPosition=dp) linkLength: float = self._computeLinkLength(srcPosition=sp, destPosition=dp) dstLblX: int = round((-20 * dx / linkLength + dy * 5 / linkLength) + dp.x) dstLblY: int = round((-20 * dy / linkLength - dy * 5 / linkLength) + dp.y) saveFont: Font = dc.GetFont() dc.SetFont(self._defaultFont) destinationCardinalityText: str = self._link.destinationCardinality dc.DrawText(destinationCardinalityText, dstLblX, dstLblY) self._destinationCardinality = self.__updateAssociationLabel( self._destinationCardinality, x=dstLblX, y=dstLblY, text=destinationCardinalityText) dc.SetFont(saveFont)
def __drawMethodSignature(self, dc: DC, pyutMethod: PyutMethod, pyutClass: PyutClass, x: float, y: float, h: float): """ If preference is not set at individual class level defer to global; Otherwise, respect the class level preference Args: dc: pyutMethod: pyutClass: x: y: h: """ if pyutClass.displayParameters == PyutDisplayParameters.UNSPECIFIED: dc.DrawText(str(pyutMethod), x + MARGIN, y + h) elif pyutClass.displayParameters == PyutDisplayParameters.DISPLAY: dc.DrawText(pyutMethod.methodWithParameters(), x + MARGIN, y + h) elif pyutClass.displayParameters == PyutDisplayParameters.DO_NOT_DISPLAY: dc.DrawText(pyutMethod.methodWithoutParameters(), x + MARGIN, y + h) else: assert False, 'Internal error unknown pyutMethod parameter display type'
def PaintHandle(self, dc: wx.DC, y_offset, value, left_edge, right_edge): pos = (value - self.min_value) * self._px_per_value + self.X_OFFSET dc.SetBrush(wx.BLACK_BRUSH) dc.DrawPolygon(( wx.Point(pos, y_offset), wx.Point(pos - self.HANDLE_WIDTH / 2, y_offset + self.HANDLE_HEIGHT), wx.Point(pos + self.HANDLE_WIDTH / 2, y_offset + self.HANDLE_HEIGHT), )) label = "{:.3f}".format(value) label_width = dc.GetTextExtent(label).GetWidth() label_pos = pos - label_width / 2 width = self.GetSize().x label_pos = max(min(width - label_width, label_pos), 0) if left_edge != -1: label_pos = max(left_edge, label_pos) edge = label_pos + label_width elif right_edge != -1: label_pos = min(right_edge - label_width, label_pos) edge = label_pos dc.DrawText(label, label_pos, y_offset + self.HANDLE_HEIGHT + self.LABEL_PADDING) return edge
def Draw(self, dc: DC, withChildren: bool = False): """ Draw the rectangle on the dc. Args: dc: withChildren: Returns: """ if self._visible: Shape.Draw(self, dc, False) if self._drawFrame: sx, sy = self.GetPosition() sx, sy = sx - self._ox, sy - self._oy width, height = self.GetSize() dc.DrawRectangle(sx, sy, width, height) if withChildren: self.DrawChildren(dc) if self._topLeftSizer is not None: self._topLeftSizer.Draw(dc, False)
def Draw(self, dc: DC, withChildren: bool = False): """ Called for drawing of interface links. OglLink drew regular lines I need dashed lines for an interface Args: dc: Device context withChildren: Draw the children or not """ self.updateLabels() if self._visible: line = self.GetSegments() if self._selected: dc.SetPen(RED_PEN) if self._spline: dc.DrawSpline(line) else: pen: Pen = dc.GetPen() # pen.SetStyle( PENSTYLE_SHORT_DASH ) # This is what is different from OglLink.Draw(..) dc.SetPen(pen) # dc.DrawLines(line) for control in self._controls: control.Draw(dc) if self._selected: self._srcAnchor.Draw(dc) self._dstAnchor.Draw(dc) dc.SetPen(BLACK_PEN) if self._drawArrow: u, v = line[-2], line[-1] self.DrawArrow(dc, u, v) if withChildren is True: self.DrawChildren(dc)
def Draw(self, dc: DC, withChildren=False): """ Draw the actor. @param dc : Device context @param withChildren @since 1.0 @author Philippe Waelti <*****@*****.**> """ OglObject.Draw(self, dc, withChildren) dc.SetFont(self._defaultFont) # Gets the minimum bounding box for the shape width, height = self.GetSize() # Calculate the top left of the shape x, y = self.GetPosition() # Draw ellipse dc.DrawEllipse(x + 1, y + 1, width - 2, height - 2) # Draw text x += round(0.25 * width) y += round(0.25 * height) textWidth: int = round(0.6 * width) # Text area width space: int = round(1.1 * dc.GetCharHeight()) # Space between lines # Drawing is restricted in the specified region of the device dc.SetClippingRegion(x, y, textWidth, round(0.6 * height)) # Split lines lines = LineSplitter().split(self.pyutObject.getName(), dc, textWidth) # Draw text for line in lines: dc.DrawText(line, x, y) y += space dc.DestroyClippingRegion()
def Redraw(self, dc: DC = None, full: bool = True, saveBackground: bool = False, useBackground: bool = False): """ Refresh the diagram. If a DC is given, use it. Otherwise, use a double buffered DC. Args: dc: If None, a default dc is created full: If False, only draw the shape borders. saveBackground: If True, save the background useBackground: If True, use the background """ needBlit = False w, h = self.GetSize() if dc is None: dc = self.CreateDC(useBackground, w, h) needBlit = True dc.SetFont(self._defaultFont) shapes = self._diagram.GetShapes() if full: # first time, need to create the background if saveBackground: # first, draw every non-moving shapes for shape in shapes: if not shape.IsMoving(): shape.Draw(dc) # save the background self.SaveBackground(dc) # draw every moving shape for shape in shapes: if shape.IsMoving(): shape.Draw(dc) # x, y = self.CalcUnScrolledPosition(0, 0) if useBackground: # draw every moving shapes for shape in shapes: if shape.IsMoving(): shape.Draw(dc) # TODO: This code belongs in OnPaint # if self._prefs.backgroundGridEnabled is True: # self._drawGrid(memDC=dc, width=w, height=h, startX=x, startY=y) else: # don't use background # draw all shapes for shape in shapes: shape.Draw(dc) # TODO: This code belongs in OnPaint # if self._prefs.backgroundGridEnabled is True: # self._drawGrid(memDC=dc, width=w, height=h, startX=x, startY=y) else: # not full for shape in shapes: shape.DrawBorder(dc) shape.DrawAnchors(dc) if needBlit: client = ClientDC(self) x, y = self.CalcUnscrolledPosition(0, 0) client.Blit(0, 0, w, h, dc, x, y)
def DrawClosedArc(dc: wx.DC, shape: Shape): (x, y, w, h) = shape.EnclosingRectangle() dc.Pen = shape.Pen() dc.DrawEllipticArc(x, y, w, h, 0, 360)
def __resetPenColor(self, dc: DC): pen: Pen = dc.GetPen() pen.SetColour(self.__penSaveColor) dc.SetPen(pen)