📄 _basic.py
字号:
"""Assign new ids to this image and its children."""
self._id = wx.NewId()
for child in self._children:
child.AssignNewIds()
def OnDraw(self, dc):
pass
def OnMoveLinks(self, dc):
# Want to set the ends of all attached links
# to point to / from this object
for line in self._lines:
line.GetEventHandler().OnMoveLink(dc)
def OnDrawContents(self, dc):
if not self._regions:
return
bound_x, bound_y = self.GetBoundingBoxMin()
if self._pen:
dc.SetPen(self._pen)
for region in self._regions:
if region.GetFont():
dc.SetFont(region.GetFont())
dc.SetTextForeground(region.GetActualColourObject())
dc.SetBackgroundMode(wx.TRANSPARENT)
if not self._formatted:
CentreText(dc, region.GetFormattedText(), self._xpos, self._ypos, bound_x - 2 * self._textMarginX, bound_y - 2 * self._textMarginY, region.GetFormatMode())
self._formatted = True
if not self.GetDisableLabel():
DrawFormattedText(dc, region.GetFormattedText(), self._xpos, self._ypos, bound_x - 2 * self._textMarginX, bound_y - 2 * self._textMarginY, region.GetFormatMode())
def DrawContents(self, dc):
"""Draw the internal graphic of the shape (such as text).
Do not override this function: override OnDrawContents, which
is called by this function.
"""
self.GetEventHandler().OnDrawContents(dc)
def OnSize(self, x, y):
pass
def OnMovePre(self, dc, x, y, old_x, old_y, display = True):
return True
def OnErase(self, dc):
if not self._visible:
return
# Erase links
for line in self._lines:
line.GetEventHandler().OnErase(dc)
self.GetEventHandler().OnEraseContents(dc)
def OnEraseContents(self, dc):
if not self._visible:
return
xp, yp = self.GetX(), self.GetY()
minX, minY = self.GetBoundingBoxMin()
maxX, maxY = self.GetBoundingBoxMax()
topLeftX = xp - maxX / 2.0 - 2
topLeftY = yp - maxY / 2.0 - 2
penWidth = 0
if self._pen:
penWidth = self._pen.GetWidth()
dc.SetPen(self.GetBackgroundPen())
dc.SetBrush(self.GetBackgroundBrush())
dc.DrawRectangle(topLeftX - penWidth, topLeftY - penWidth, maxX + penWidth * 2 + 4, maxY + penWidth * 2 + 4)
def EraseLinks(self, dc, attachment = -1, recurse = False):
"""Erase links attached to this shape, but do not repair damage
caused to other shapes.
"""
if not self._visible:
return
for line in self._lines:
if attachment == -1 or (line.GetTo() == self and line.GetAttachmentTo() == attachment or line.GetFrom() == self and line.GetAttachmentFrom() == attachment):
line.GetEventHandler().OnErase(dc)
if recurse:
for child in self._children:
child.EraseLinks(dc, attachment, recurse)
def DrawLinks(self, dc, attachment = -1, recurse = False):
"""Draws any lines linked to this shape."""
if not self._visible:
return
for line in self._lines:
if attachment == -1 or (line.GetTo() == self and line.GetAttachmentTo() == attachment or line.GetFrom() == self and line.GetAttachmentFrom() == attachment):
line.Draw(dc)
if recurse:
for child in self._children:
child.DrawLinks(dc, attachment, recurse)
# Returns TRUE if pt1 <= pt2 in the sense that one point comes before
# another on an edge of the shape.
# attachmentPoint is the attachment point (= side) in question.
# This is the default, rectangular implementation.
def AttachmentSortTest(self, attachmentPoint, pt1, pt2):
"""Return TRUE if pt1 is less than or equal to pt2, in the sense
that one point comes before another on an edge of the shape.
attachment is the attachment point (side) in question.
This function is used in Shape.MoveLineToNewAttachment to determine
the new line ordering.
"""
physicalAttachment = self.LogicalToPhysicalAttachment(attachmentPoint)
if physicalAttachment in [0, 2]:
return pt1[0] <= pt2[0]
elif physicalAttachment in [1, 3]:
return pt1[1] <= pt2[1]
return False
def MoveLineToNewAttachment(self, dc, to_move, x, y):
"""Move the given line (which must already be attached to the shape)
to a different attachment point on the shape, or a different order
on the same attachment.
Calls Shape.AttachmentSortTest and then
ShapeEvtHandler.OnChangeAttachment.
"""
if self.GetAttachmentMode() == ATTACHMENT_MODE_NONE:
return False
# Is (x, y) on this object? If so, find the new attachment point
# the user has moved the point to
hit = self.HitTest(x, y)
if not hit:
return False
newAttachment, distance = hit
self.EraseLinks(dc)
if to_move.GetTo() == self:
oldAttachment = to_move.GetAttachmentTo()
else:
oldAttachment = to_move.GetAttachmentFrom()
# The links in a new ordering
# First, add all links to the new list
newOrdering = self._lines[:]
# Delete the line object from the list of links; we're going to move
# it to another position in the list
del newOrdering[newOrdering.index(to_move)]
old_x = -99999.9
old_y = -99999.9
found = False
for line in newOrdering:
if line.GetTo() == self and oldAttachment == line.GetAttachmentTo() or \
line.GetFrom() == self and oldAttachment == line.GetAttachmentFrom():
startX, startY, endX, endY = line.GetEnds()
if line.GetTo() == self:
xp = endX
yp = endY
else:
xp = startX
yp = startY
thisPoint = wx.RealPoint(xp, yp)
lastPoint = wx.RealPoint(old_x, old_y)
newPoint = wx.RealPoint(x, y)
if self.AttachmentSortTest(newAttachment, newPoint, thisPoint) and self.AttachmentSortTest(newAttachment, lastPoint, newPoint):
found = True
newOrdering.insert(newOrdering.index(line), to_move)
old_x = xp
old_y = yp
if found:
break
if not found:
newOrdering.append(to_move)
self.GetEventHandler().OnChangeAttachment(newAttachment, to_move, newOrdering)
return True
def OnChangeAttachment(self, attachment, line, ordering):
if line.GetTo() == self:
line.SetAttachmentTo(attachment)
else:
line.SetAttachmentFrom(attachment)
self.ApplyAttachmentOrdering(ordering)
dc = wx.ClientDC(self.GetCanvas())
self.GetCanvas().PrepareDC(dc)
self.MoveLinks(dc)
if not self.GetCanvas().GetQuickEditMode():
self.GetCanvas().Redraw(dc)
# Reorders the lines according to the given list
def ApplyAttachmentOrdering(self, linesToSort):
"""Apply the line ordering in linesToSort to the shape, to reorder
the way lines are attached.
"""
linesStore = self._lines[:]
self._lines = []
for line in linesToSort:
if line in linesStore:
del linesStore[linesStore.index(line)]
self._lines.append(line)
# Now add any lines that haven't been listed in linesToSort
self._lines += linesStore
def SortLines(self, attachment, linesToSort):
""" Reorder the lines coming into the node image at this attachment
position, in the order in which they appear in linesToSort.
Any remaining lines not in the list will be added to the end.
"""
# This is a temporary store of all the lines at this attachment
# point. We'll tick them off as we've processed them.
linesAtThisAttachment = []
for line in self._lines[:]:
if line.GetTo() == self and line.GetAttachmentTo() == attachment or \
line.GetFrom() == self and line.GetAttachmentFrom() == attachment:
linesAtThisAttachment.append(line)
del self._lines[self._lines.index(line)]
for line in linesToSort:
if line in linesAtThisAttachment:
# Done this one
del linesAtThisAttachment[linesAtThisAttachment.index(line)]
self._lines.append(line)
# Now add any lines that haven't been listed in linesToSort
self._lines += linesAtThisAttachment
def OnHighlight(self, dc):
pass
def OnLeftClick(self, x, y, keys = 0, attachment = 0):
if self._sensitivity & OP_CLICK_LEFT != OP_CLICK_LEFT:
if self._parent:
attachment, dist = self._parent.HitTest(x, y)
self._parent.GetEventHandler().OnLeftClick(x, y, keys, attachment)
def OnRightClick(self, x, y, keys = 0, attachment = 0):
if self._sensitivity & OP_CLICK_RIGHT != OP_CLICK_RIGHT:
attachment, dist = self._parent.HitTest(x, y)
self._parent.GetEventHandler().OnRightClick(x, y, keys, attachment)
def OnDragLeft(self, draw, x, y, keys = 0, attachment = 0):
if self._sensitivity & OP_DRAG_LEFT != OP_DRAG_LEFT:
if self._parent:
hit = self._parent.HitTest(x, y)
if hit:
attachment, dist = hit
self._parent.GetEventHandler().OnDragLeft(draw, x, y, keys, attachment)
return
dc = wx.ClientDC(self.GetCanvas())
self.GetCanvas().PrepareDC(dc)
dc.SetLogicalFunction(OGLRBLF)
dottedPen = wx.Pen(wx.Colour(0, 0, 0), 1, wx.DOT)
dc.SetPen(dottedPen)
dc.SetBrush(wx.TRANSPARENT_BRUSH)
xx = x + DragOffsetX
yy = y + DragOffsetY
xx, yy = self._canvas.Snap(xx, yy)
w, h = self.GetBoundingBoxMax()
self.GetEventHandler().OnDrawOutline(dc, xx, yy, w, h)
def OnBeginDragLeft(self, x, y, keys = 0, attachment = 0):
global DragOffsetX, DragOffsetY
if self._sensitivity & OP_DRAG_LEFT != OP_DRAG_LEFT:
if self._parent:
hit = self._parent.HitTest(x, y)
if hit:
attachment, dist = hit
self._parent.GetEventHandler().OnBeginDragLeft(x, y, keys, attachment)
return
DragOffsetX = self._xpos - x
DragOffsetY = self._ypos - y
dc = wx.ClientDC(self.GetCanvas())
self.GetCanvas().PrepareDC(dc)
# New policy: don't erase shape until end of drag.
# self.Erase(dc)
xx = x + DragOffsetX
yy = y + DragOffsetY
xx, yy = self._canvas.Snap(xx, yy)
dc.SetLogicalFunction(OGLRBLF)
dottedPen = wx.Pen(wx.Colour(0, 0, 0), 1, wx.DOT)
dc.SetPen(dottedPen)
dc.SetBrush(wx.TRANSPARENT_BRUSH)
w, h = self.GetBoundingBoxMax()
self.GetEventHandler().OnDrawOutline(dc, xx, yy, w, h)
self._canvas.CaptureMouse()
def OnEndDragLeft(self, x, y, keys = 0, attachment = 0):
if self._canvas.HasCapture():
self._canvas.ReleaseMouse()
if self._sensitivity & OP_DRAG_LEFT != OP_DRAG_LEFT:
if self._parent:
hit = self._parent.HitTest(x, y)
if hit:
attachment, dist = hit
self._parent.GetEventHandler().OnEndDragLeft(x, y, keys, attachment)
return
dc = wx.ClientDC(self.GetCanvas())
self.GetCanvas().PrepareDC(dc)
dc.SetLogicalFunction(wx.COPY)
xx = x + DragOffsetX
yy = y + DragOffsetY
xx, yy = self._canvas.Snap(xx, yy)
# New policy: erase shape at end of drag.
self.Erase(dc)
self.Move(dc, xx, yy)
if self._canvas and not self._canvas.GetQuickEditMode():
self._canvas.Redraw(dc)
def OnDragRight(self, draw, x, y, keys = 0, attachment = 0):
if self._sensitivity & OP_DRAG_RIGHT != OP_DRAG_RIGHT:
if self._parent:
attachment, dist = self._parent.HitTest(x, y)
self._parent.GetEventHandler().OnDragRight(draw, x, y, keys, attachment)
return
def OnBeginDragRight(self, x, y, keys = 0, attachment = 0):
if self._sensitivity & OP_DRAG_RIGHT != OP_DRAG_RIGHT:
if self._parent:
attachment, dist = self._parent.HitTest(x, y)
self._parent.GetEventHandler().OnBeginDragRight(x, y, keys, attachment)
return
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -