📄 pysketch.py
字号:
style=wx.SUNKEN_BORDER)
self.drawPanel.SetBackgroundColour(wx.WHITE)
self.drawPanel.EnableScrolling(True, True)
self.drawPanel.SetScrollbars(20, 20, PAGE_WIDTH / 20, PAGE_HEIGHT / 20)
self.drawPanel.Bind(wx.EVT_LEFT_DOWN, self.onMouseEvent)
self.drawPanel.Bind(wx.EVT_LEFT_DCLICK, self.onDoubleClickEvent)
self.drawPanel.Bind(wx.EVT_RIGHT_DOWN, self.onRightClick)
self.drawPanel.Bind(wx.EVT_MOTION, self.onMouseEvent)
self.drawPanel.Bind(wx.EVT_LEFT_UP, self.onMouseEvent)
self.drawPanel.Bind(wx.EVT_PAINT, self.onPaintEvent)
# Position everything in the window.
topSizer = wx.BoxSizer(wx.HORIZONTAL)
topSizer.Add(self.toolPalette, 0)
topSizer.Add(self.drawPanel, 1, wx.EXPAND)
self.topPanel.SetAutoLayout(True)
self.topPanel.SetSizer(topSizer)
self.SetSizeHints(250, 200)
self.SetSize(wx.Size(600, 400))
# Select an initial tool.
self.curTool = None
self._setCurrentTool(self.selectIcon)
# Setup our frame to hold the contents of a sketch document.
self.dirty = False
self.fileName = fileName
self.contents = [] # front-to-back ordered list of DrawingObjects.
self.selection = [] # List of selected DrawingObjects.
self.undoInfo = None # Saved contents for undo.
self.dragMode = drag_NONE # Current mouse-drag mode.
if self.fileName != None:
self.loadContents()
self._adjustMenus()
# Finally, set our initial pen, fill and line options.
self.penColour = wx.BLACK
self.fillColour = wx.WHITE
self.lineSize = 1
# ============================
# == Event Handling Methods ==
# ============================
def onToolIconClick(self, event):
""" Respond to the user clicking on one of our tool icons.
"""
iconID = event.GetEventObject().GetId()
if iconID == id_SELECT: self.doChooseSelectTool()
elif iconID == id_LINE: self.doChooseLineTool()
elif iconID == id_RECT: self.doChooseRectTool()
elif iconID == id_ELLIPSE: self.doChooseEllipseTool()
elif iconID == id_TEXT: self.doChooseTextTool()
else: wx.Bell(); print "1"
def onPenOptionIconClick(self, event):
""" Respond to the user clicking on the "Pen Options" icon.
"""
data = wx.ColourData()
if len(self.selection) == 1:
data.SetColour(self.selection[0].getPenColour())
else:
data.SetColour(self.penColour)
dialog = wx.ColourDialog(self, data)
if dialog.ShowModal() == wx.ID_OK:
c = dialog.GetColourData().GetColour()
self._setPenColour(wx.Colour(c.Red(), c.Green(), c.Blue()))
dialog.Destroy()
def onFillOptionIconClick(self, event):
""" Respond to the user clicking on the "Fill Options" icon.
"""
data = wx.ColourData()
if len(self.selection) == 1:
data.SetColour(self.selection[0].getFillColour())
else:
data.SetColour(self.fillColour)
dialog = wx.ColourDialog(self, data)
if dialog.ShowModal() == wx.ID_OK:
c = dialog.GetColourData().GetColour()
self._setFillColour(wx.Colour(c.Red(), c.Green(), c.Blue()))
dialog.Destroy()
def onLineOptionIconClick(self, event):
""" Respond to the user clicking on the "Line Options" icon.
"""
if len(self.selection) == 1:
menu = self._buildLineSizePopup(self.selection[0].getLineSize())
else:
menu = self._buildLineSizePopup(self.lineSize)
pos = self.lineOptIcon.GetPosition()
pos.y = pos.y + self.lineOptIcon.GetSize().height
self.PopupMenu(menu, pos)
menu.Destroy()
def onKeyEvent(self, event):
""" Respond to a keypress event.
We make the arrow keys move the selected object(s) by one pixel in
the given direction.
"""
if event.GetKeyCode() == wx.WXK_UP:
self._moveObject(0, -1)
elif event.GetKeyCode() == wx.WXK_DOWN:
self._moveObject(0, 1)
elif event.GetKeyCode() == wx.WXK_LEFT:
self._moveObject(-1, 0)
elif event.GetKeyCode() == wx.WXK_RIGHT:
self._moveObject(1, 0)
else:
event.Skip()
def onMouseEvent(self, event):
""" Respond to the user clicking on our main drawing panel.
How we respond depends on the currently selected tool.
"""
if not (event.LeftDown() or event.Dragging() or event.LeftUp()):
return # Ignore mouse movement without click/drag.
if self.curTool == self.selectIcon:
feedbackType = feedback_RECT
action = self.selectByRectangle
actionParam = param_RECT
selecting = True
dashedLine = True
elif self.curTool == self.lineIcon:
feedbackType = feedback_LINE
action = self.createLine
actionParam = param_LINE
selecting = False
dashedLine = False
elif self.curTool == self.rectIcon:
feedbackType = feedback_RECT
action = self.createRect
actionParam = param_RECT
selecting = False
dashedLine = False
elif self.curTool == self.ellipseIcon:
feedbackType = feedback_ELLIPSE
action = self.createEllipse
actionParam = param_RECT
selecting = False
dashedLine = False
elif self.curTool == self.textIcon:
feedbackType = feedback_RECT
action = self.createText
actionParam = param_RECT
selecting = False
dashedLine = True
else:
wx.Bell(); print "2"
return
if event.LeftDown():
mousePt = self._getEventCoordinates(event)
if selecting:
obj, handle = self._getObjectAndSelectionHandleAt(mousePt)
if selecting and (obj != None) and (handle != handle_NONE):
# The user clicked on an object's selection handle. Let the
# user resize the clicked-on object.
self.dragMode = drag_RESIZE
self.resizeObject = obj
if obj.getType() == obj_LINE:
self.resizeFeedback = feedback_LINE
pos = obj.getPosition()
startPt = wx.Point(pos.x + obj.getStartPt().x,
pos.y + obj.getStartPt().y)
endPt = wx.Point(pos.x + obj.getEndPt().x,
pos.y + obj.getEndPt().y)
if handle == handle_START_POINT:
self.resizeAnchor = endPt
self.resizeFloater = startPt
else:
self.resizeAnchor = startPt
self.resizeFloater = endPt
else:
self.resizeFeedback = feedback_RECT
pos = obj.getPosition()
size = obj.getSize()
topLeft = wx.Point(pos.x, pos.y)
topRight = wx.Point(pos.x + size.width, pos.y)
botLeft = wx.Point(pos.x, pos.y + size.height)
botRight = wx.Point(pos.x + size.width, pos.y + size.height)
if handle == handle_TOP_LEFT:
self.resizeAnchor = botRight
self.resizeFloater = topLeft
elif handle == handle_TOP_RIGHT:
self.resizeAnchor = botLeft
self.resizeFloater = topRight
elif handle == handle_BOTTOM_LEFT:
self.resizeAnchor = topRight
self.resizeFloater = botLeft
elif handle == handle_BOTTOM_RIGHT:
self.resizeAnchor = topLeft
self.resizeFloater = botRight
self.curPt = mousePt
self.resizeOffsetX = self.resizeFloater.x - mousePt.x
self.resizeOffsetY = self.resizeFloater.y - mousePt.y
endPt = wx.Point(self.curPt.x + self.resizeOffsetX,
self.curPt.y + self.resizeOffsetY)
self._drawVisualFeedback(self.resizeAnchor, endPt,
self.resizeFeedback, False)
elif selecting and (self._getObjectAt(mousePt) != None):
# The user clicked on an object to select it. If the user
# drags, he/she will move the object.
self.select(self._getObjectAt(mousePt))
self.dragMode = drag_MOVE
self.moveOrigin = mousePt
self.curPt = mousePt
self._drawObjectOutline(0, 0)
else:
# The user is dragging out a selection rect or new object.
self.dragOrigin = mousePt
self.curPt = mousePt
self.drawPanel.SetCursor(wx.CROSS_CURSOR)
self.drawPanel.CaptureMouse()
self._drawVisualFeedback(mousePt, mousePt, feedbackType,
dashedLine)
self.dragMode = drag_DRAG
event.Skip()
return
if event.Dragging():
if self.dragMode == drag_RESIZE:
# We're resizing an object.
mousePt = self._getEventCoordinates(event)
if (self.curPt.x != mousePt.x) or (self.curPt.y != mousePt.y):
# Erase previous visual feedback.
endPt = wx.Point(self.curPt.x + self.resizeOffsetX,
self.curPt.y + self.resizeOffsetY)
self._drawVisualFeedback(self.resizeAnchor, endPt,
self.resizeFeedback, False)
self.curPt = mousePt
# Draw new visual feedback.
endPt = wx.Point(self.curPt.x + self.resizeOffsetX,
self.curPt.y + self.resizeOffsetY)
self._drawVisualFeedback(self.resizeAnchor, endPt,
self.resizeFeedback, False)
elif self.dragMode == drag_MOVE:
# We're moving a selected object.
mousePt = self._getEventCoordinates(event)
if (self.curPt.x != mousePt.x) or (self.curPt.y != mousePt.y):
# Erase previous visual feedback.
self._drawObjectOutline(self.curPt.x - self.moveOrigin.x,
self.curPt.y - self.moveOrigin.y)
self.curPt = mousePt
# Draw new visual feedback.
self._drawObjectOutline(self.curPt.x - self.moveOrigin.x,
self.curPt.y - self.moveOrigin.y)
elif self.dragMode == drag_DRAG:
# We're dragging out a new object or selection rect.
mousePt = self._getEventCoordinates(event)
if (self.curPt.x != mousePt.x) or (self.curPt.y != mousePt.y):
# Erase previous visual feedback.
self._drawVisualFeedback(self.dragOrigin, self.curPt,
feedbackType, dashedLine)
self.curPt = mousePt
# Draw new visual feedback.
self._drawVisualFeedback(self.dragOrigin, self.curPt,
feedbackType, dashedLine)
event.Skip()
return
if event.LeftUp():
if self.dragMode == drag_RESIZE:
# We're resizing an object.
mousePt = self._getEventCoordinates(event)
# Erase last visual feedback.
endPt = wx.Point(self.curPt.x + self.resizeOffsetX,
self.curPt.y + self.resizeOffsetY)
self._drawVisualFeedback(self.resizeAnchor, endPt,
self.resizeFeedback, False)
resizePt = wx.Point(mousePt.x + self.resizeOffsetX,
mousePt.y + self.resizeOffsetY)
if (self.resizeFloater.x != resizePt.x) or \
(self.resizeFloater.y != resizePt.y):
self._resizeObject(self.resizeObject,
self.resizeAnchor,
self.resizeFloater,
resizePt)
else:
self.drawPanel.Refresh() # Clean up after empty resize.
elif self.dragMode == drag_MOVE:
# We're moving a selected object.
mousePt = self._getEventCoordinates(event)
# Erase last visual feedback.
self._drawObjectOutline(self.curPt.x - self.moveOrigin.x,
self.curPt.y - self.moveOrigin.y)
if (self.moveOrigin.x != mousePt.x) or \
(self.moveOrigin.y != mousePt.y):
self._moveObject(mousePt.x - self.moveOrigin.x,
mousePt.y - self.moveOrigin.y)
else:
self.drawPanel.Refresh() # Clean up after empty drag.
elif self.dragMode == drag_DRAG:
# We're dragging out a new object or selection rect.
mousePt = self._getEventCoordinates(event)
# Erase last visual feedback.
self._drawVisualFeedback(self.dragOrigin, self.curPt,
feedbackType, dashedLine)
self.drawPanel.ReleaseMouse()
self.drawPanel.SetCursor(wx.STANDARD_CURSOR)
# Perform the appropriate action for the current tool.
if actionParam == param_RECT:
x1 = min(self.dragOrigin.x, self.curPt.x)
y1 = min(self.dragOrigin.y, self.curPt.y)
x2 = max(self.dragOrigin.x, self.curPt.x)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -