📄 abstracteditor.py
字号:
for shape in forceRedrawShapes:
shape.ForceRedraw()
def OnLeftDoubleClick(self, event):
propertyService = wx.GetApp().GetService(PropertyService.PropertyService)
if propertyService:
propertyService.ShowWindow()
def OnLeftDrag(self, event):
# draw lasso for group select
if self._pt1 and event.LeftIsDown(): # we are in middle of lasso selection
self.EraseRubberBand()
dc = wx.ClientDC(self._canvas)
self._canvas.PrepareDC(dc)
self._pt2 = event.GetLogicalPosition(dc) # this takes into account scrollbar offset
self.DrawRubberBand()
else:
event.Skip()
def OnLeftUp(self, event):
# do group select
if self._needEraseLasso:
self.EraseRubberBand()
dc = wx.ClientDC(self._canvas)
self._canvas.PrepareDC(dc)
x1, y1 = self._pt1
x2, y2 = event.GetLogicalPosition(dc) # this takes into account scrollbar offset
tol = self._diagram.GetMouseTolerance()
if abs(x1 - x2) > tol or abs(y1 - y2) > tol:
# make sure x1 < x2 and y1 < y2 to make comparison test easier
if x1 > x2:
temp = x1
x1 = x2
x2 = temp
if y1 > y2:
temp = y1
y1 = y2
y2 = temp
for shape in self._diagram.GetShapeList():
if not shape.GetParent() and hasattr(shape, "GetModel"): # if part of a composite, don't select it
x, y = shape.GetX(), shape.GetY()
width, height = shape.GetBoundingBoxMax()
selected = x1 < x - width/2 and x2 > x + width/2 and y1 < y - height/2 and y2 > y + height/2
if event.ControlDown() or event.ShiftDown(): # extend select, don't deselect
if selected:
shape.Select(selected, dc)
else: # select items in lasso and deselect items out of lasso
shape.Select(selected, dc)
self._canvas.Redraw(dc)
else:
event.Skip()
else:
event.Skip()
def EraseRubberBand(self):
if self._needEraseLasso:
self._needEraseLasso = False
dc = wx.ClientDC(self._canvas)
self._canvas.PrepareDC(dc)
dc.SetLogicalFunction(wx.XOR)
pen = wx.Pen(wx.Colour(200, 200, 200), 1, wx.SHORT_DASH)
dc.SetPen(pen)
brush = wx.Brush(wx.Colour(255, 255, 255), wx.TRANSPARENT)
dc.SetBrush(brush)
dc.ResetBoundingBox()
dc.BeginDrawing()
x1, y1 = self._pt1
x2, y2 = self._pt2
# make sure x1 < x2 and y1 < y2
# this will make (x1, y1) = upper left corner
if x1 > x2:
temp = x1
x1 = x2
x2 = temp
if y1 > y2:
temp = y1
y1 = y2
y2 = temp
# erase previous outline
dc.SetClippingRegion(x1, y1, x2 - x1, y2 - y1)
dc.DrawRectangle(x1, y1, x2 - x1, y2 - y1)
dc.EndDrawing()
def DrawRubberBand(self):
self._needEraseLasso = True
dc = wx.ClientDC(self._canvas)
self._canvas.PrepareDC(dc)
dc.SetLogicalFunction(wx.XOR)
pen = wx.Pen(wx.Colour(200, 200, 200), 1, wx.SHORT_DASH)
dc.SetPen(pen)
brush = wx.Brush(wx.Colour(255, 255, 255), wx.TRANSPARENT)
dc.SetBrush(brush)
dc.ResetBoundingBox()
dc.BeginDrawing()
x1, y1 = self._pt1
x2, y2 = self._pt2
# make sure x1 < x2 and y1 < y2
# this will make (x1, y1) = upper left corner
if x1 > x2:
temp = x1
x1 = x2
x2 = temp
if y1 > y2:
temp = y1
y1 = y2
y2 = temp
# draw outline
dc.SetClippingRegion(x1, y1, x2 - x1, y2 - y1)
dc.DrawRectangle(x1, y1, x2 - x1, y2 - y1)
dc.EndDrawing()
def SetValetParking(self, enable=True):
""" If valet parking is enabled, remember last parking spot and try for a spot near it """
self._valetParking = enable
if enable:
self._valetPosition = None
def FindParkingSpot(self, width, height, parking=PARKING_HORIZONTAL, x=PARKING_OFFSET, y=PARKING_OFFSET):
"""
Given a width and height, find a upper left corner where shape can be parked without overlapping other shape
"""
if self._valetParking and self._valetPosition:
x, y = self._valetPosition
max = 700 # max distance to the right where we'll place tables
noParkingSpot = True
while noParkingSpot:
point = self.isSpotOccupied(x, y, width, height)
if point:
if parking == PARKING_HORIZONTAL:
x = point[0] + PARKING_OFFSET
if x > max:
x = PARKING_OFFSET
y = point[1] + PARKING_OFFSET
else: # parking == PARKING_VERTICAL:
y = point[1] + PARKING_OFFSET
if y > max:
y = PARKING_OFFSET
x = point[0] + PARKING_OFFSET
else:
noParkingSpot = False
if self._valetParking:
self._valetPosition = (x, y)
return x, y
def isSpotOccupied(self, x, y, width, height):
""" returns None if at x,y,width,height no object occupies that rectangle,
otherwise returns lower right corner of object that occupies given x,y position
"""
x2 = x + width
y2 = y + height
for shape in self._diagram.GetShapeList():
if isinstance(shape, ogl.RectangleShape) or isinstance(shape, ogl.EllipseShape) or isinstance(shape, ogl.PolygonShape):
if shape.GetParent() and isinstance(shape.GetParent(), ogl.CompositeShape):
# skip, part of a composite shape
continue
if hasattr(shape, "GetModel"):
other_x, other_y, other_width, other_height = shape.GetModel().getEditorBounds()
other_x2 = other_x + other_width
other_y2 = other_y + other_height
else:
# shapes x,y are at the center of the shape, need to transform to upper left coordinate
other_width, other_height = shape.GetBoundingBoxMax()
other_x = shape.GetX() - other_width/2
other_y = shape.GetY() - other_height/2
other_x2 = other_x + other_width
other_y2 = other_y + other_height
# intersection check
if ((other_x2 < other_x or other_x2 > x) and
(other_y2 < other_y or other_y2 > y) and
(x2 < x or x2 > other_x) and
(y2 < y or y2 > other_y)):
return (other_x2, other_y2)
return None
#----------------------------------------------------------------------------
# Canvas methods
#----------------------------------------------------------------------------
def AddShape(self, shape, x = None, y = None, pen = None, brush = None, text = None, eventHandler = None, shown=True):
if isinstance(shape, ogl.CompositeShape):
dc = wx.ClientDC(self._canvas)
self._canvas.PrepareDC(dc)
shape.Move(dc, x, y)
else:
shape.SetDraggable(True, True)
shape.SetCanvas(self._canvas)
if x:
shape.SetX(x)
if y:
shape.SetY(y)
shape.SetCentreResize(False)
if pen:
shape.SetPen(pen)
if brush:
shape.SetBrush(brush)
if text:
shape.AddText(text)
shape.SetShadowMode(ogl.SHADOW_NONE)
self._diagram.AddShape(shape)
shape.Show(shown)
if not eventHandler:
eventHandler = EditorCanvasShapeEvtHandler(self)
eventHandler.SetShape(shape)
eventHandler.SetPreviousHandler(shape.GetEventHandler())
shape.SetEventHandler(eventHandler)
return shape
def RemoveShape(self, model = None, shape = None):
if not model and not shape:
return
if not shape:
shape = self.GetShape(model)
if shape:
shape.Select(False)
for line in shape.GetLines():
shape.RemoveLine(line)
self._diagram.RemoveShape(line)
line.Delete()
for obj in self._diagram.GetShapeList():
for line in obj.GetLines():
if self.IsShapeContained(shape, line.GetTo()) or self.IsShapeContained(shape, line.GetFrom()):
obj.RemoveLine(line)
self._diagram.RemoveShape(line)
line.Delete()
if line == shape:
obj.RemoveLine(line)
self._diagram.RemoveShape(line)
line.Delete()
if self._canvas:
shape.RemoveFromCanvas(self._canvas)
self._diagram.RemoveShape(shape)
shape.Delete()
def IsShapeContained(self, parent, shape):
if parent == shape:
return True
elif shape.GetParent():
return self.IsShapeContained(parent, shape.GetParent())
return False
def UpdateShape(self, model):
for shape in self._diagram.GetShapeList():
if hasattr(shape, "GetModel") and shape.GetModel() == model:
oldw, oldh = shape.GetBoundingBoxMax()
oldx = shape.GetX()
oldy = shape.GetY()
x, y, w, h = model.getEditorBounds()
newX = x + w / 2
newY = y + h / 2
if oldw != w or oldh != h or oldx != newX or oldy != newY:
dc = wx.ClientDC(self._canvas)
self._canvas.PrepareDC(dc)
shape.SetSize(w, h, True) # wxBug: SetSize must be before Move because links won't go to the right place
shape.Move(dc, newX, newY) # wxBug: Move must be after SetSize because links won't go to the right place
shape.ResetControlPoints()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -