diff --git a/MiRCARTCanvas.py b/MiRCARTCanvas.py index c1855a3..ceef200 100644 --- a/MiRCARTCanvas.py +++ b/MiRCARTCanvas.py @@ -35,88 +35,79 @@ class MiRCARTCanvas(wx.Panel): brushColours = brushPos = brushSize = None canvasBackend = canvasCurTool = canvasJournal = canvasStore = None - # {{{ _commitPatch(self, patch): + # {{{ _commitPatch(self, patch): XXX def _commitPatch(self, patch): self.canvasMap[patch[0][1]][patch[0][0]] = patch[1:] # }}} - # {{{ _dispatchInput(self, eventDc, patches): XXX - def _dispatchInput(self, eventDc, patches): - self.canvasBackend.drawCursorMaskWithJournal( \ - self.canvasJournal, eventDc) - cursorPatches = []; undoPatches = []; newPatches = []; - for patchDescr in patches: - patchIsCursor = patchDescr[0] - for patch in patchDescr[1]: - if self.canvasBackend.drawPatch(eventDc, patch) == False: - continue - else: - patchDeltaCell = self.canvasMap[patch[0][1]][patch[0][0]] - if patchIsCursor == True: - cursorPatches.append([list(patch[0]), *patchDeltaCell.copy()]) - else: - undoPatches.append([list(patch[0]), *patchDeltaCell.copy()]) - newPatches.append(patch) - self._commitPatch(patch) - if len(cursorPatches): - self.canvasJournal.pushCursor(cursorPatches) - if len(undoPatches): - self.canvasJournal.pushDeltas(undoPatches, newPatches) + # {{{ _dispatchDeltaPatches(self, deltaPatches): XXX + def _dispatchDeltaPatches(self, deltaPatches): + eventDc = self.canvasBackend.getDeviceContext(self) + for patch in deltaPatches: + if self.canvasBackend.drawPatch(eventDc, patch): + self._commitPatch(patch) + self.parentFrame.onCanvasUpdate() + # }}} + # {{{ _dispatchPatch(self, eventDc, isCursor, patch): XXX + def _dispatchPatch(self, eventDc, isCursor, patch): + if not self._canvasDirtyCursor: + self.canvasBackend.drawCursorMaskWithJournal( \ + self.canvasJournal, eventDc) + self._canvasDirtyCursor = True + if self.canvasBackend.drawPatch(eventDc, patch): + patchDeltaCell = self.canvasMap[patch[0][1]][patch[0][0]] + patchDelta = [list(patch[0]), *patchDeltaCell.copy()] + if isCursor: + self.canvasJournal.pushCursor(patchDelta) + else: + if not self._canvasDirty: + self.canvasJournal.pushDeltas([], []) + self._canvasDirty = True + self.canvasJournal.updateCurrentDeltas(patchDelta, patch) + self._commitPatch(patch) # }}} # {{{ onPanelClose(self, event): XXX def onPanelClose(self, event): self.Destroy() # }}} - # {{{ onPanelKeyboardInput(self, event): XXX - def onPanelKeyboardInput(self, event): - eventDc = self.canvasBackend.getDeviceContext(self) - tool = self.canvasCurTool; mapPoint = self.brushPos; - keyModifiers = event.GetModifiers() - if keyModifiers != wx.MOD_NONE \ - and keyModifiers != wx.MOD_SHIFT: - event.Skip() - else: - patches = tool.onKeyboardEvent( \ - event, mapPoint, self.brushColours, self.brushSize, \ - chr(event.GetUnicodeKey())) - if len(patches): - self._dispatchInput(eventDc, patches) - self.parentFrame.onCanvasUpdate() - # }}} - # {{{ onPanelMouseInput(self, event): XXX - def onPanelMouseInput(self, event): + # {{{ onPanelInput(self, event): XXX + def onPanelInput(self, event): eventDc = self.canvasBackend.getDeviceContext(self) + eventType = event.GetEventType() + self._canvasDirty = self._canvasDirtyCursor = False tool = self.canvasCurTool - self.brushPos = mapPoint = \ - self.canvasBackend.xlateEventPoint(event, eventDc) - patches = tool.onMouseEvent( \ - event, mapPoint, self.brushColours, self.brushSize, \ - event.Dragging(), event.LeftIsDown(), event.RightIsDown()) - if len(patches): - self._dispatchInput(eventDc, patches) + if eventType == wx.wxEVT_CHAR: + mapPoint = self.brushPos + doSkip = tool.onKeyboardEvent( \ + event, mapPoint, self.brushColours, self.brushSize, \ + chr(event.GetUnicodeKey()), self._dispatchPatch, eventDc) + if doSkip: + event.Skip(); return; + else: + mapPoint = self.canvasBackend.xlateEventPoint(event, eventDc) + self.brushPos = mapPoint + tool.onMouseEvent( \ + event, mapPoint, self.brushColours, self.brushSize, \ + event.Dragging(), event.LeftIsDown(), event.RightIsDown(), \ + self._dispatchPatch, eventDc) + if self._canvasDirty: self.parentFrame.onCanvasUpdate() self.parentFrame.onCanvasMotion(event, mapPoint) # }}} - # {{{ onPanelFocus(self, event): XXX - def onPanelFocus(self, event): - if event.GetEventType() == wx.wxEVT_LEAVE_WINDOW: - eventDc = self.canvasBackend.getDeviceContext(self) - self.canvasBackend.drawCursorMaskWithJournal( \ - self.canvasJournal, eventDc) + # {{{ onPanelLeaveWindow(self, event): XXX + def onPanelLeaveWindow(self, event): + eventDc = self.canvasBackend.getDeviceContext(self) + self.canvasBackend.drawCursorMaskWithJournal( \ + self.canvasJournal, eventDc) self.parentFrame.onCanvasMotion(event) # }}} # {{{ onPanelPaint(self, event): XXX def onPanelPaint(self, event): self.canvasBackend.onPanelPaintEvent(self, event) # }}} - # {{{ onStoreUpdate(self, newCanvasSize, newCanvas=None): + # {{{ onStoreUpdate(self, newCanvasSize, newCanvas=None): XXX def onStoreUpdate(self, newCanvasSize, newCanvas=None): self.resize(newCanvasSize=newCanvasSize) - self.canvasBackend.reset(self.canvasSize, self.canvasBackend.cellSize) - self.canvasJournal.resetCursor(); self.canvasJournal.resetUndo(); - self.canvasMap = [[[(1, 1), 0, " "] \ - for x in range(self.canvasSize[0])] \ - for y in range(self.canvasSize[1])] eventDc = self.canvasBackend.getDeviceContext(self) for numRow in range(self.canvasSize[1]): for numCol in range(self.canvasSize[0]): @@ -130,45 +121,36 @@ class MiRCARTCanvas(wx.Panel): *self.canvasMap[numRow][numCol])) wx.SafeYield() # }}} - # {{{ popRedo(self): + # {{{ popRedo(self): XXX def popRedo(self): - eventDc = self.canvasBackend.getDeviceContext(self) - patches = self.canvasJournal.popRedo() - for patch in patches: - if self.canvasBackend.drawPatch(eventDc, patch) == False: - continue - else: - self._commitPatch(patch) - self.parentFrame.onCanvasUpdate() + self._dispatchDeltaPatches(self.canvasJournal.popRedo()) # }}} - # {{{ popUndo(self): + # {{{ popUndo(self): XXX def popUndo(self): - eventDc = self.canvasBackend.getDeviceContext(self) - patches = self.canvasJournal.popUndo() - for patch in patches: - if self.canvasBackend.drawPatch(eventDc, patch) == False: - continue - else: - self._commitPatch(patch) - self.parentFrame.onCanvasUpdate() + self._dispatchDeltaPatches(self.canvasJournal.popUndo()) # }}} - # {{{ resize(self, newCanvasSize): + # {{{ resize(self, newCanvasSize): XXX def resize(self, newCanvasSize): if newCanvasSize != self.canvasSize: - winSize = [a*b for a,b in \ - zip(newCanvasSize, self.canvasBackend.cellSize)] - self.SetSize(*self.canvasPos, *winSize) - for numRow in range(self.canvasSize[1]): - for numNewCol in range(self.canvasSize[0], newCanvasSize[0]): - self.canvasMap[numRow].append([[1, 1], 0, " "]) - for numNewRow in range(self.canvasSize[1], newCanvasSize[1]): - self.canvasMap.append([]) - for numNewCol in range(newCanvasSize[0]): - self.canvasMap[numNewRow].append([[1, 1], 0, " "]) + if self.canvasMap == None: + self.canvasMap = [[[(1, 1), 0, " "] \ + for x in range(self.canvasSize[0])] \ + for y in range(self.canvasSize[1])] + else: + for numRow in range(self.canvasSize[1]): + for numNewCol in range(self.canvasSize[0], newCanvasSize[0]): + self.canvasMap[numRow].append([[1, 1], 0, " "]) + for numNewRow in range(self.canvasSize[1], newCanvasSize[1]): + self.canvasMap.append([]) + for numNewCol in range(newCanvasSize[0]): + self.canvasMap[numNewRow].append([[1, 1], 0, " "]) self.canvasSize = newCanvasSize - self.canvasBackend.reset(self.canvasSize, \ - self.canvasBackend.cellSize) - self.parentFrame.onCanvasUpdate() + self.SetSize(*self.canvasPos, \ + *[a*b for a,b in zip(self.canvasSize, \ + self.canvasBackend.cellSize)]) + self.canvasBackend.reset(self.canvasSize, self.canvasBackend.cellSize) + self.canvasJournal.resetCursor(); self.canvasJournal.resetUndo(); + self.parentFrame.onCanvasUpdate() # }}} # @@ -187,12 +169,11 @@ class MiRCARTCanvas(wx.Panel): # Bind event handlers self.Bind(wx.EVT_CLOSE, self.onPanelClose) - self.Bind(wx.EVT_ENTER_WINDOW, self.onPanelFocus) - self.Bind(wx.EVT_LEAVE_WINDOW, self.onPanelFocus) - self.parentFrame.Bind(wx.EVT_CHAR, self.onPanelKeyboardInput) + self.Bind(wx.EVT_LEAVE_WINDOW, self.onPanelLeaveWindow) + self.parentFrame.Bind(wx.EVT_CHAR, self.onPanelInput) for eventType in( \ wx.EVT_LEFT_DOWN, wx.EVT_MOTION, wx.EVT_RIGHT_DOWN): - self.Bind(eventType, self.onPanelMouseInput) + self.Bind(eventType, self.onPanelInput) self.Bind(wx.EVT_PAINT, self.onPanelPaint) # vim:expandtab foldmethod=marker sw=4 ts=4 tw=120 diff --git a/MiRCARTCanvasJournal.py b/MiRCARTCanvasJournal.py index 17706e7..d487a60 100644 --- a/MiRCARTCanvasJournal.py +++ b/MiRCARTCanvasJournal.py @@ -55,14 +55,16 @@ class MiRCARTCanvasJournal(): # }}} # {{{ pushCursor(self, patches): XXX def pushCursor(self, patches): - self.patchesCursor += patches + self.patchesCursor.append(patches) # }}} # {{{ pushDeltas(self, undoPatches, redoPatches): XXX def pushDeltas(self, undoPatches, redoPatches): if self.patchesUndoLevel > 0: del self.patchesUndo[0:self.patchesUndoLevel] self.patchesUndoLevel = 0 - self.patchesUndo.insert(0, [undoPatches, redoPatches]) + deltaItem = [undoPatches, redoPatches] + self.patchesUndo.insert(0, deltaItem) + return deltaItem # }}} # {{{ resetCursor(self): XXX def resetCursor(self): @@ -72,6 +74,11 @@ class MiRCARTCanvasJournal(): def resetUndo(self): self.patchesUndo = [None]; self.patchesUndoLevel = 0; # }}} + # {{{ updateCurrentDeltas(self, undoPatches, redoPatches): XXX + def updateCurrentDeltas(self, undoPatches, redoPatches): + self.patchesUndo[0][0].append(undoPatches) + self.patchesUndo[0][1].append(redoPatches) + # }}} # # __init__(self): initialisation method diff --git a/MiRCARTCanvasStore.py b/MiRCARTCanvasStore.py index e41b35a..79b609e 100644 --- a/MiRCARTCanvasStore.py +++ b/MiRCARTCanvasStore.py @@ -235,7 +235,10 @@ class MiRCARTCanvasStore(): # }}} # {{{ importNew(self, newCanvasSize=None): XXX def importNew(self, newCanvasSize=None): - self.parentCanvas.onStoreUpdate(newCanvasSize) + newMap = [[[(1, 1), 0, " "] \ + for x in range(self.parentCanvas.canvasSize[0])] \ + for y in range(self.parentCanvas.canvasSize[1])] + self.parentCanvas.onStoreUpdate(newCanvasSize, newMap) # }}} # diff --git a/MiRCARTTool.py b/MiRCARTTool.py index be8758c..4798ebf 100644 --- a/MiRCARTTool.py +++ b/MiRCARTTool.py @@ -26,12 +26,12 @@ class MiRCARTTool(): """XXX""" parentCanvas = None - # {{{ onKeyboardEvent(self, event, atPoint, brushColours, brushSize, keyChar): - def onKeyboardEvent(self, event, atPoint, brushColours, brushSize, keyChar): - return () + # {{{ onKeyboardEvent(self, event, atPoint, brushColours, brushSize, keyChar, dispatchFn, eventDc): + def onKeyboardEvent(self, event, atPoint, brushColours, brushSize, keyChar, dispatchFn, eventDc): + return True # }}} - # {{{ onMouseEvent(self, event, atPoint, brushColours, brushSize, isDragging, isLeftDown, isRightDown): XXX - def onMouseEvent(self, event, atPoint, brushColours, brushSize, isDragging, isLeftDown, isRightDown): + # {{{ onMouseEvent(self, event, atPoint, brushColours, brushSize, isDragging, isLeftDown, isRightDown, dispatchFn, eventDc): XXX + def onMouseEvent(self, event, atPoint, brushColours, brushSize, isDragging, isLeftDown, isRightDown, dispatchFn, eventDc): return () # }}} diff --git a/MiRCARTToolCircle.py b/MiRCARTToolCircle.py index 8218e85..52497e3 100644 --- a/MiRCARTToolCircle.py +++ b/MiRCARTToolCircle.py @@ -28,8 +28,8 @@ class MiRCARTToolCircle(MiRCARTTool): """XXX""" # - # onMouseEvent(self, event, atPoint, brushColours, brushSize, isDragging, isLeftDown, isRightDown): XXX - def onMouseEvent(self, event, atPoint, brushColours, brushSize, isDragging, isLeftDown, isRightDown): + # onMouseEvent(self, event, atPoint, brushColours, brushSize, isDragging, isLeftDown, isRightDown, dispatchFn, eventDc): XXX + def onMouseEvent(self, event, atPoint, brushColours, brushSize, isDragging, isLeftDown, isRightDown, dispatchFn, eventDc): brushColours = brushColours.copy() if isLeftDown: brushColours[1] = brushColours[0] @@ -37,20 +37,19 @@ class MiRCARTToolCircle(MiRCARTTool): brushColours[0] = brushColours[1] else: brushColours[1] = brushColours[0] - brushPatches = [] _brushSize = brushSize[0]*2 originPoint = (_brushSize/2, _brushSize/2) radius = _brushSize for brushY in range(-radius, radius + 1): for brushX in range(-radius, radius + 1): if ((brushX**2)+(brushY**2) < (((radius**2)+radius)*0.8)): - brushPatches.append([ \ + patch = [ \ [atPoint[0] + int(originPoint[0]+brushX), \ atPoint[1] + int(originPoint[1]+brushY)], \ - brushColours, 0, " "]) - if isLeftDown or isRightDown: - return [[False, brushPatches], [True, brushPatches]] - else: - return [[True, brushPatches]] + brushColours, 0, " "] + if isLeftDown or isRightDown: + dispatchFn(eventDc, False, patch); dispatchFn(eventDc, True, patch); + else: + dispatchFn(eventDc, True, patch) # vim:expandtab foldmethod=marker sw=4 ts=4 tw=120 diff --git a/MiRCARTToolLine.py b/MiRCARTToolLine.py index 18652d3..3180d0d 100644 --- a/MiRCARTToolLine.py +++ b/MiRCARTToolLine.py @@ -39,8 +39,8 @@ class MiRCARTToolLine(MiRCARTTool): def _pointSwap(self, a, b): return [b, a] # }}} - # {{{ _getLine(self, brushColours, originPoint, targetPoint): XXX - def _getLine(self, brushColours, originPoint, targetPoint): + # {{{ _getLine(self, brushColours, eventDc, isCursor, originPoint, targetPoint, dispatchFn): XXX + def _getLine(self, brushColours, eventDc, isCursor, originPoint, targetPoint, dispatchFn): originPoint = originPoint.copy(); targetPoint = targetPoint.copy(); pointDelta = self._pointDelta(originPoint, targetPoint) lineXSign = 1 if pointDelta[0] > 0 else -1; @@ -52,21 +52,23 @@ class MiRCARTToolLine(MiRCARTTool): pointDelta = [pointDelta[1], pointDelta[0]] lineXX, lineXY, lineYX, lineYY = 0, lineYSign, lineXSign, 0 lineD = 2 * pointDelta[1] - pointDelta[0]; lineY = 0; - linePatches = [] for lineX in range(pointDelta[0] + 1): - linePatches.append([[ \ + patch = [[ \ originPoint[0] + lineX*lineXX + lineY*lineYX, \ originPoint[1] + lineX*lineXY + lineY*lineYY], \ - brushColours, 0, " "]) + brushColours, 0, " "] + if isCursor: + dispatchFn(eventDc, False, patch); dispatchFn(eventDc, True, patch); + else: + dispatchFn(eventDc, True, patch) if lineD > 0: lineD -= pointDelta[0]; lineY += 1; lineD += pointDelta[1] - return linePatches # }}} # - # onMouseEvent(self, event, atPoint, brushColours, brushSize, isDragging, isLeftDown, isRightDown): XXX - def onMouseEvent(self, event, atPoint, brushColours, brushSize, isDragging, isLeftDown, isRightDown): + # onMouseEvent(self, event, atPoint, brushColours, brushSize, isDragging, isLeftDown, isRightDown, dispatchFn, eventDc): XXX + def onMouseEvent(self, event, atPoint, brushColours, brushSize, isDragging, isLeftDown, isRightDown, dispatchFn, eventDc): brushColours = brushColours.copy() if isLeftDown: brushColours[1] = brushColours[0] @@ -74,22 +76,19 @@ class MiRCARTToolLine(MiRCARTTool): brushColours[0] = brushColours[1] else: brushColours[1] = brushColours[0] - brushPatches = []; tmpPatches = []; if self.toolState == self.TS_NONE: if isLeftDown or isRightDown: self.toolOriginPoint = list(atPoint) self.toolState = self.TS_ORIGIN - tmpPatches.append([atPoint, brushColours, 0, " "]) - return [[True, tmpPatches]] + dispatchFn(eventDc, True, [atPoint, brushColours, 0, " "]) elif self.toolState == self.TS_ORIGIN: targetPoint = list(atPoint) originPoint = self.toolOriginPoint - brushPatches = self._getLine(brushColours, originPoint, targetPoint) + self._getLine(brushColours, eventDc, \ + isLeftDown or isRightDown, \ + originPoint, targetPoint, dispatchFn) if isLeftDown or isRightDown: self.toolState = self.TS_NONE - return [[False, brushPatches], [True, brushPatches]] - else: - return [[True, brushPatches]] # __init__(self, *args): initialisation method def __init__(self, *args): diff --git a/MiRCARTToolRect.py b/MiRCARTToolRect.py index a4e9662..a1455a3 100644 --- a/MiRCARTToolRect.py +++ b/MiRCARTToolRect.py @@ -28,8 +28,8 @@ class MiRCARTToolRect(MiRCARTTool): """XXX""" # - # onMouseEvent(self, event, atPoint, brushColours, brushSize, isDragging, isLeftDown, isRightDown): XXX - def onMouseEvent(self, event, atPoint, brushColours, brushSize, isDragging, isLeftDown, isRightDown): + # onMouseEvent(self, event, atPoint, brushColours, brushSize, isDragging, isLeftDown, isRightDown, dispatchFn, eventDc): XXX + def onMouseEvent(self, event, atPoint, brushColours, brushSize, isDragging, isLeftDown, isRightDown, dispatchFn, eventDc): brushColours = brushColours.copy() if isLeftDown: brushColours[1] = brushColours[0] @@ -40,16 +40,12 @@ class MiRCARTToolRect(MiRCARTTool): brushSize = brushSize.copy() if brushSize[0] > 1: brushSize[0] *= 2 - brushPatches = [] for brushRow in range(brushSize[1]): for brushCol in range(brushSize[0]): - brushPatches.append([[ \ - atPoint[0] + brushCol, \ - atPoint[1] + brushRow], \ - brushColours, 0, " "]) - if isLeftDown or isRightDown: - return [[False, brushPatches], [True, brushPatches]] - else: - return [[True, brushPatches]] + patch = [[atPoint[0] + brushCol, atPoint[1] + brushRow],brushColours, 0, " "] + if isLeftDown or isRightDown: + dispatchFn(eventDc, False, patch); dispatchFn(eventDc, True, patch); + else: + dispatchFn(eventDc, True, patch) # vim:expandtab foldmethod=marker sw=4 ts=4 tw=120 diff --git a/MiRCARTToolText.py b/MiRCARTToolText.py index 8f1be6d..ca1386a 100644 --- a/MiRCARTToolText.py +++ b/MiRCARTToolText.py @@ -23,23 +23,27 @@ # from MiRCARTTool import MiRCARTTool -import string +import string, wx class MiRCARTToolText(MiRCARTTool): """XXX""" textColours = textPos = None # - # onKeyboardEvent(self, event, atPoint, brushColours, brushSize, keyChar): XXX - def onKeyboardEvent(self, event, atPoint, brushColours, brushSize, keyChar): - if not keyChar in string.printable: - return [] + # onKeyboardEvent(self, event, atPoint, brushColours, brushSize, keyChar, dispatchFn, eventDc): XXX + def onKeyboardEvent(self, event, atPoint, brushColours, brushSize, keyChar, dispatchFn, eventDc): + keyModifiers = event.GetModifiers() + if keyModifiers != wx.MOD_NONE \ + and keyModifiers != wx.MOD_SHIFT: + return True + elif not keyChar in string.printable: + return True else: if self.textColours == None: self.textColours = brushColours.copy() if self.textPos == None: self.textPos = list(atPoint) - patches = [[False, [[self.textPos, self.textColours, 0, keyChar]]]] + dispatchFn(eventDc, False, [self.textPos, self.textColours, 0, keyChar]) if self.textPos[0] < (self.parentCanvas.canvasSize[0] - 1): self.textPos[0] += 1 elif self.textPos[1] < (self.parentCanvas.canvasSize[1] - 1): @@ -47,11 +51,11 @@ class MiRCARTToolText(MiRCARTTool): self.textPos[1] += 1 else: self.textPos = [0, 0] - return patches + return False # - # onMouseEvent(self, event, atPoint, brushColours, brushSize, isDragging, isLeftDown, isRightDown): XXX - def onMouseEvent(self, event, atPoint, brushColours, brushSize, isDragging, isLeftDown, isRightDown): + # onMouseEvent(self, event, atPoint, brushColours, brushSize, isDragging, isLeftDown, isRightDown, dispatchFn, eventDc): XXX + def onMouseEvent(self, event, atPoint, brushColours, brushSize, isDragging, isLeftDown, isRightDown, dispatchFn, eventDc): if isLeftDown: self.textColours = brushColours.copy() self.textPos = list(atPoint) @@ -62,6 +66,6 @@ class MiRCARTToolText(MiRCARTTool): if self.textColours == None: self.textColours = brushColours.copy() self.textPos = list(atPoint) - return [[True, [[self.textPos, self.textColours, 0, "_"]]]] + dispatchFn(eventDc, True, [self.textPos, self.textColours, 0, "_"]) # vim:expandtab foldmethod=marker sw=4 ts=4 tw=120