MiRCARTCanvas{,Journal,Store}.py: dispatch patches from tool event handlers directly.

MiRCARTTool{,Circle,Line,Rect,Text}.py: updated to new interface.
This commit is contained in:
Lucio Andrés Illanes Albornoz 2018-01-10 00:25:42 +01:00
parent ed8ccab26f
commit cd5ea1fab5
8 changed files with 138 additions and 149 deletions

View File

@ -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

View File

@ -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

View File

@ -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)
# }}}
#

View File

@ -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 ()
# }}}

View File

@ -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

View File

@ -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):

View File

@ -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

View File

@ -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