📄 _composit.py
字号:
self.GetEventHandler().OnDrawControlPoints(dc)
if self._canvas and not self._canvas.GetQuickEditMode():
self._canvas.Redraw(dc)
def SetSize(self, w, h, recursive = True):
self._width = w
self._height = h
RectangleShape.SetSize(self, w, h, recursive)
def CalculateSize(self):
pass
# Experimental
def OnRightClick(self, x, y, keys = 0, attachment = 0):
if keys & KEY_CTRL:
self.PopupMenu(x, y)
else:
if self._parent:
hit = self._parent.HitTest(x, y)
if hit:
attachment, dist = hit
self._parent.GetEventHandler().OnRightClick(x, y, keys, attachment)
# Divide wx.HORIZONTALly or wx.VERTICALly
def Divide(self, direction):
"""Divide this division into two further divisions,
horizontally (direction is wxHORIZONTAL) or
vertically (direction is wxVERTICAL).
"""
# Calculate existing top-left, bottom-right
x1 = self.GetX() - self.GetWidth() / 2.0
y1 = self.GetY() - self.GetHeight() / 2.0
compositeParent = self.GetParent()
oldWidth = self.GetWidth()
oldHeight = self.GetHeight()
if self.Selected():
self.Select(False)
dc = wx.ClientDC(self.GetCanvas())
self.GetCanvas().PrepareDC(dc)
if direction == wx.VERTICAL:
# Dividing vertically means notionally putting a horizontal
# line through it.
# Break existing piece into two.
newXPos1 = self.GetX()
newYPos1 = y1 + self.GetHeight() / 4.0
newXPos2 = self.GetX()
newYPos2 = y1 + 3 * self.GetHeight() / 4.0
newDivision = compositeParent.OnCreateDivision()
newDivision.Show(True)
self.Erase(dc)
# Anything adjoining the bottom of this division now adjoins the
# bottom of the new division.
for obj in compositeParent.GetDivisions():
if obj.GetTopSide() == self:
obj.SetTopSide(newDivision)
newDivision.SetTopSide(self)
newDivision.SetBottomSide(self._bottomSide)
newDivision.SetLeftSide(self._leftSide)
newDivision.SetRightSide(self._rightSide)
self._bottomSide = newDivision
compositeParent.GetDivisions().append(newDivision)
# CHANGE: Need to insert this division at start of divisions in the
# object list, because e.g.:
# 1) Add division
# 2) Add contained object
# 3) Add division
# Division is now receiving mouse events _before_ the contained
# object, because it was added last (on top of all others)
# Add after the image that visualizes the container
compositeParent.AddChild(newDivision, compositeParent.FindContainerImage())
self._handleSide = DIVISION_SIDE_BOTTOM
newDivision.SetHandleSide(DIVISION_SIDE_TOP)
self.SetSize(oldWidth, oldHeight / 2.0)
self.Move(dc, newXPos1, newYPos1)
newDivision.SetSize(oldWidth, oldHeight / 2.0)
newDivision.Move(dc, newXPos2, newYPos2)
else:
# Dividing horizontally means notionally putting a vertical line
# through it.
# Break existing piece into two.
newXPos1 = x1 + self.GetWidth() / 4.0
newYPos1 = self.GetY()
newXPos2 = x1 + 3 * self.GetWidth() / 4.0
newYPos2 = self.GetY()
newDivision = compositeParent.OnCreateDivision()
newDivision.Show(True)
self.Erase(dc)
# Anything adjoining the left of this division now adjoins the
# left of the new division.
for obj in compositeParent.GetDivisions():
if obj.GetLeftSide() == self:
obj.SetLeftSide(newDivision)
newDivision.SetTopSide(self._topSide)
newDivision.SetBottomSide(self._bottomSide)
newDivision.SetLeftSide(self)
newDivision.SetRightSide(self._rightSide)
self._rightSide = newDivision
compositeParent.GetDivisions().append(newDivision)
compositeParent.AddChild(newDivision, compositeParent.FindContainerImage())
self._handleSide = DIVISION_SIDE_RIGHT
newDivision.SetHandleSide(DIVISION_SIDE_LEFT)
self.SetSize(oldWidth / 2.0, oldHeight)
self.Move(dc, newXPos1, newYPos1)
newDivision.SetSize(oldWidth / 2.0, oldHeight)
newDivision.Move(dc, newXPos2, newYPos2)
if compositeParent.Selected():
compositeParent.DeleteControlPoints(dc)
compositeParent.MakeControlPoints()
compositeParent.MakeMandatoryControlPoints()
compositeParent.Draw(dc)
return True
def MakeControlPoints(self):
self.MakeMandatoryControlPoints()
def MakeMandatoryControlPoints(self):
maxX, maxY = self.GetBoundingBoxMax()
x = y = 0.0
direction = 0
if self._handleSide == DIVISION_SIDE_LEFT:
x = -maxX / 2.0
direction = CONTROL_POINT_HORIZONTAL
elif self._handleSide == DIVISION_SIDE_TOP:
y = -maxY / 2.0
direction = CONTROL_POINT_VERTICAL
elif self._handleSide == DIVISION_SIDE_RIGHT:
x = maxX / 2.0
direction = CONTROL_POINT_HORIZONTAL
elif self._handleSide == DIVISION_SIDE_BOTTOM:
y = maxY / 2.0
direction = CONTROL_POINT_VERTICAL
if self._handleSide != DIVISION_SIDE_NONE:
control = DivisionControlPoint(self._canvas, self, CONTROL_POINT_SIZE, x, y, direction)
self._canvas.AddShape(control)
self._controlPoints.append(control)
def ResetControlPoints(self):
self.ResetMandatoryControlPoints()
def ResetMandatoryControlPoints(self):
if not self._controlPoints:
return
maxX, maxY = self.GetBoundingBoxMax()
node = self._controlPoints[0]
if self._handleSide == DIVISION_SIDE_LEFT and node:
node._xoffset = -maxX / 2.0
node._yoffset = 0.0
if self._handleSide == DIVISION_SIDE_TOP and node:
node._xoffset = 0.0
node._yoffset = -maxY / 2.0
if self._handleSide == DIVISION_SIDE_RIGHT and node:
node._xoffset = maxX / 2.0
node._yoffset = 0.0
if self._handleSide == DIVISION_SIDE_BOTTOM and node:
node._xoffset = 0.0
node._yoffset = maxY / 2.0
def AdjustLeft(self, left, test):
"""Adjust a side.
Returns FALSE if it's not physically possible to adjust it to
this point.
"""
x2 = self.GetX() + self.GetWidth() / 2.0
if left >= x2:
return False
if test:
return True
newW = x2 - left
newX = left + newW / 2.0
self.SetSize(newW, self.GetHeight())
dc = wx.ClientDC(self.GetCanvas())
self.GetCanvas().PrepareDC(dc)
self.Move(dc, newX, self.GetY())
return True
def AdjustTop(self, top, test):
"""Adjust a side.
Returns FALSE if it's not physically possible to adjust it to
this point.
"""
y2 = self.GetY() + self.GetHeight() / 2.0
if top >= y2:
return False
if test:
return True
newH = y2 - top
newY = top + newH / 2.0
self.SetSize(self.GetWidth(), newH)
dc = wx.ClientDC(self.GetCanvas())
self.GetCanvas().PrepareDC(dc)
self.Move(dc, self.GetX(), newY)
return True
def AdjustRight(self, right, test):
"""Adjust a side.
Returns FALSE if it's not physically possible to adjust it to
this point.
"""
x1 = self.GetX() - self.GetWidth() / 2.0
if right <= x1:
return False
if test:
return True
newW = right - x1
newX = x1 + newW / 2.0
self.SetSize(newW, self.GetHeight())
dc = wx.ClientDC(self.GetCanvas())
self.GetCanvas().PrepareDC(dc)
self.Move(dc, newX, self.GetY())
return True
def AdjustTop(self, top, test):
"""Adjust a side.
Returns FALSE if it's not physically possible to adjust it to
this point.
"""
y1 = self.GetY() - self.GetHeight() / 2.0
if bottom <= y1:
return False
if test:
return True
newH = bottom - y1
newY = y1 + newH / 2.0
self.SetSize(self.GetWidth(), newH)
dc = wx.ClientDC(self.GetCanvas())
self.GetCanvas().PrepareDC(dc)
self.Move(dc, self.GetX(), newY)
return True
# Resize adjoining divisions.
# Behaviour should be as follows:
# If right edge moves, find all objects whose left edge
# adjoins this object, and move left edge accordingly.
# If left..., move ... right.
# If top..., move ... bottom.
# If bottom..., move top.
# If size goes to zero or end position is other side of start position,
# resize to original size and return.
#
def ResizeAdjoining(self, side, newPos, test):
"""Resize adjoining divisions at the given side.
If test is TRUE, just see whether it's possible for each adjoining
region, returning FALSE if it's not.
side can be one of:
* DIVISION_SIDE_NONE
* DIVISION_SIDE_LEFT
* DIVISION_SIDE_TOP
* DIVISION_SIDE_RIGHT
* DIVISION_SIDE_BOTTOM
"""
divisionParent = self.GetParent()
for division in divisionParent.GetDivisions():
if side == DIVISION_SIDE_LEFT:
if division._rightSide == self:
success = division.AdjustRight(newPos, test)
if not success and test:
return false
elif side == DIVISION_SIDE_TOP:
if division._bottomSide == self:
success = division.AdjustBottom(newPos, test)
if not success and test:
return False
elif side == DIVISION_SIDE_RIGHT:
if division._leftSide == self:
success = division.AdjustLeft(newPos, test)
if not success and test:
return False
elif side == DIVISION_SIDE_BOTTOM:
if division._topSide == self:
success = division.AdjustTop(newPos, test)
if not success and test:
return False
return True
def EditEdge(self, side):
print "EditEdge() not implemented."
def PopupMenu(self, x, y):
menu = PopupDivisionMenu()
menu.SetClientData(self)
if self._leftSide:
menu.Enable(DIVISION_MENU_EDIT_LEFT_EDGE, True)
else:
menu.Enable(DIVISION_MENU_EDIT_LEFT_EDGE, False)
if self._topSide:
menu.Enable(DIVISION_MENU_EDIT_TOP_EDGE, True)
else:
menu.Enable(DIVISION_MENU_EDIT_TOP_EDGE, False)
x1, y1 = self._canvas.GetViewStart()
unit_x, unit_y = self._canvas.GetScrollPixelsPerUnit()
dc = wx.ClientDC(self.GetCanvas())
self.GetCanvas().PrepareDC(dc)
mouse_x = dc.LogicalToDeviceX(x - x1 * unit_x)
mouse_y = dc.LogicalToDeviceY(y - y1 * unit_y)
self._canvas.PopupMenu(menu, (mouse_x, mouse_y))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -