diff --git a/MiRCART.py b/MiRCART.py index 28e9d36..c03e793 100755 --- a/MiRCART.py +++ b/MiRCART.py @@ -23,14 +23,13 @@ # from MiRCARTFrame import MiRCARTFrame -from MiRCARTToolRect import MiRCARTToolRect import sys, wx # # Entry point def main(*argv): wxApp = wx.App(False) - MiRCARTFrame(None, canvasTools=[MiRCARTToolRect]) + MiRCARTFrame(None) wxApp.MainLoop() if __name__ == "__main__": main(*sys.argv) diff --git a/MiRCARTCanvas.py b/MiRCARTCanvas.py index 966136b..eb341dd 100644 --- a/MiRCARTCanvas.py +++ b/MiRCARTCanvas.py @@ -31,10 +31,11 @@ class MiRCARTCanvas(wx.Panel): """XXX""" parentFrame = None canvasPos = canvasSize = canvasWinSize = cellSize = None - canvasBitmap = canvasMap = canvasTools = None + canvasBitmap = canvasMap = None brushColours = brushPos = brushSize = None mircBrushes = mircPens = None canvasJournal = canvasStore = None + canvasCurTool = None # {{{ _initBrushesAndPens(self): XXX def _initBrushesAndPens(self): @@ -112,12 +113,12 @@ class MiRCARTCanvas(wx.Panel): tmpDc.SelectObject(self.canvasBitmap) eventPoint = event.GetLogicalPosition(eventDc) mapPoint = self._eventPointToMapPoint(eventPoint) - for tool in self.canvasTools: - mapPatches = tool.onMouseEvent( \ - event, mapPoint, self.brushColours, self.brushSize, \ - event.Dragging(), event.LeftIsDown(), event.RightIsDown()) - self.canvasJournal.merge(mapPatches, eventDc, tmpDc, mapPoint) - self.parentFrame.onCanvasUpdate() + tool = self.canvasCurTool + mapPatches = tool.onMouseEvent( \ + event, mapPoint, self.brushColours, self.brushSize, \ + event.Dragging(), event.LeftIsDown(), event.RightIsDown()) + self.canvasJournal.merge(mapPatches, eventDc, tmpDc, mapPoint) + self.parentFrame.onCanvasUpdate() self.parentFrame.onCanvasMotion(event, mapPoint) # }}} # {{{ onMouseWindowEvent(self, event): XXX @@ -211,17 +212,17 @@ class MiRCARTCanvas(wx.Panel): # }}} # - # _init__(self, parent, parentFrame, canvasPos, cellSize, canvasSize, canvasTools): initialisation method - def __init__(self, parent, parentFrame, canvasPos, canvasSize, canvasTools, cellSize): + # _init__(self, parent, parentFrame, canvasPos, canvasSize, cellSize): initialisation method + def __init__(self, parent, parentFrame, canvasPos, canvasSize, cellSize): self.parentFrame = parentFrame self.canvasPos = canvasPos; self.canvasSize = canvasSize; - self.canvasTools = [canvasTool(self) for canvasTool in canvasTools] self.cellSize = cellSize self.brushColours = [4, 1]; self._initBrushesAndPens(); self.brushPos = [0, 0]; self.brushSize = [1, 1]; self.canvasJournal = MiRCARTCanvasJournal(parentCanvas=self) self.canvasStore = MiRCARTCanvasStore(parentCanvas=self) + self.canvasCurTool = None super().__init__(parent, pos=canvasPos, \ size=[w*h for w,h in zip(canvasSize, cellSize)]) diff --git a/MiRCARTCanvasJournal.py b/MiRCARTCanvasJournal.py index 5bdfbbd..9ac34d2 100644 --- a/MiRCARTCanvasJournal.py +++ b/MiRCARTCanvasJournal.py @@ -46,17 +46,12 @@ class MiRCARTCanvasJournal(): self.patchesUndoLevel = 0 patchesUndo = [] for patch in patches: - absMapPoint = self._relMapPointToAbsMapPoint(patch[0][0], atPoint) - patchesUndo.append([ \ - [absMapPoint, *patch[0][1:]], \ - [absMapPoint, *patch[1][1:]]]) + patchesUndo.append([ \ + [patch[0], *patch[0][1:]], \ + [patch[0], *patch[1][1:]]]) if len(patchesUndo) > 0: self.patchesUndo.insert(0, patchesUndo) # }}} - # {{{ _relMapPointToAbsMapPoint(self, relMapPoint, atPoint): XXX - def _relMapPointToAbsMapPoint(self, relMapPoint, atPoint): - return [a+b for a,b in zip(atPoint, relMapPoint)] - # }}} # {{{ merge(self, mapPatches, eventDc, tmpDc, atPoint): XXX def merge(self, mapPatches, eventDc, tmpDc, atPoint): patchesUndo = [] @@ -65,18 +60,17 @@ class MiRCARTCanvasJournal(): if mapPatchTmp: self._popTmp(eventDc, tmpDc) for patch in mapPatch[1]: - absMapPoint = self._relMapPointToAbsMapPoint(patch[0], atPoint) - if absMapPoint[0] >= self.parentCanvas.canvasSize[0] \ - or absMapPoint[1] >= self.parentCanvas.canvasSize[1]: + if patch[0][0] >= self.parentCanvas.canvasSize[0] \ + or patch[0][1] >= self.parentCanvas.canvasSize[1]: continue elif mapPatchTmp: - self._pushTmp(absMapPoint) - self.parentCanvas.onJournalUpdate(mapPatchTmp, \ - absMapPoint, patch, eventDc, tmpDc, atPoint) + self._pushTmp(patch[0]) + self.parentCanvas.onJournalUpdate(mapPatchTmp, \ + patch[0], patch, eventDc, tmpDc, (0, 0)) else: - patchUndo = \ - self.parentCanvas.onJournalUpdate(mapPatchTmp, \ - absMapPoint, patch, eventDc, tmpDc, atPoint, True) + patchUndo = \ + self.parentCanvas.onJournalUpdate(mapPatchTmp, \ + patch[0], patch, eventDc, tmpDc, (0, 0), True) patchesUndo.append([patchUndo, patch]) if len(patchesUndo) > 0: self._pushUndo(atPoint, patchesUndo) diff --git a/MiRCARTFrame.py b/MiRCARTFrame.py index e377eb1..71372ce 100644 --- a/MiRCARTFrame.py +++ b/MiRCARTFrame.py @@ -26,13 +26,16 @@ from MiRCARTCanvas import MiRCARTCanvas, haveUrllib from MiRCARTColours import MiRCARTColours from MiRCARTGeneralFrame import MiRCARTGeneralFrame, \ TID_ACCELS, TID_COMMAND, TID_LIST, TID_MENU, TID_NOTHING, TID_SELECT, TID_TOOLBAR +from MiRCARTToolCircle import MiRCARTToolCircle +from MiRCARTToolLine import MiRCARTToolLine +from MiRCARTToolRect import MiRCARTToolRect import os, wx class MiRCARTFrame(MiRCARTGeneralFrame): """XXX""" panelCanvas = canvasPathName = None - canvasPos = canvasSize = canvasTools = cellSize = None + canvasPos = canvasSize = cellSize = None # {{{ Commands # Id Type Id Labels Icon bitmap Accelerator [Initial state] @@ -355,11 +358,17 @@ class MiRCARTFrame(MiRCARTGeneralFrame): elif cid == self.CID_SOLID_BRUSH[0]: pass elif cid == self.CID_RECT[0]: - pass + self.menuItemsById[cid].Check(True) + self.panelCanvas.canvasCurTool = \ + MiRCARTToolRect(self.panelCanvas) elif cid == self.CID_CIRCLE[0]: - pass + self.menuItemsById[cid].Check(True) + self.panelCanvas.canvasCurTool = \ + MiRCARTToolCircle(self.panelCanvas) elif cid == self.CID_LINE[0]: - pass + self.menuItemsById[cid].Check(True) + self.panelCanvas.canvasCurTool = \ + MiRCARTToolLine(self.panelCanvas) elif cid >= self.CID_COLOUR00[0] \ and cid <= self.CID_COLOUR15[0]: numColour = cid - self.CID_COLOUR00[0] @@ -376,16 +385,16 @@ class MiRCARTFrame(MiRCARTGeneralFrame): # }}} # - # __init__(self, parent, appSize=(800, 600), canvasPos=(25, 50), cellSize=(7, 14), canvasSize=(100, 30), canvasTools=[]): initialisation method - def __init__(self, parent, appSize=(800, 600), canvasPos=(25, 50), cellSize=(7, 14), canvasSize=(100, 30), canvasTools=[]): + # __init__(self, parent, appSize=(800, 600), canvasPos=(25, 50), canvasSize=(100, 30), cellSize=(7, 14)): initialisation method + def __init__(self, parent, appSize=(800, 600), canvasPos=(25, 50), canvasSize=(100, 30), cellSize=(7, 14)): panelSkin = super().__init__(parent, wx.ID_ANY, "MiRCART", size=appSize) self._setPaletteToolBitmaps() self.canvasPos = canvasPos; self.cellSize = cellSize; self.canvasSize = canvasSize; self.canvasPathName = None - self.canvasTools = canvasTools self.panelCanvas = MiRCARTCanvas(panelSkin, parentFrame=self, \ canvasPos=self.canvasPos, canvasSize=self.canvasSize, \ - canvasTools=self.canvasTools, cellSize=self.cellSize) + cellSize=self.cellSize) + self.panelCanvas.canvasCurTool = MiRCARTToolRect(self.panelCanvas) self.canvasNew() # vim:expandtab foldmethod=marker sw=4 ts=4 tw=120 diff --git a/MiRCARTToolCircle.py b/MiRCARTToolCircle.py new file mode 100644 index 0000000..8218e85 --- /dev/null +++ b/MiRCARTToolCircle.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python3 +# +# MiRCARTToolCircle.py -- XXX +# Copyright (c) 2018 Lucio Andrés Illanes Albornoz +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# + +from MiRCARTTool import MiRCARTTool + +class MiRCARTToolCircle(MiRCARTTool): + """XXX""" + + # + # onMouseEvent(self, event, atPoint, brushColours, brushSize, isDragging, isLeftDown, isRightDown): XXX + def onMouseEvent(self, event, atPoint, brushColours, brushSize, isDragging, isLeftDown, isRightDown): + brushColours = brushColours.copy() + if isLeftDown: + brushColours[1] = brushColours[0] + elif isRightDown: + 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([ \ + [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]] + +# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120 diff --git a/MiRCARTToolLine.py b/MiRCARTToolLine.py new file mode 100644 index 0000000..18652d3 --- /dev/null +++ b/MiRCARTToolLine.py @@ -0,0 +1,100 @@ +#!/usr/bin/env python3 +# +# MiRCARTToolLine.py -- XXX +# Copyright (c) 2018 Lucio Andrés Illanes Albornoz +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# + +from MiRCARTTool import MiRCARTTool + +class MiRCARTToolLine(MiRCARTTool): + """XXX""" + toolOriginPoint = toolState = None + + TS_NONE = 0 + TS_ORIGIN = 1 + + # {{{ _pointDelta(self, a, b): XXX + def _pointDelta(self, a, b): + return [a2-a1 for a1, a2 in zip(a, b)] + # }}} + # {{{ _pointSwap(self, a, b): XXX + def _pointSwap(self, a, b): + return [b, a] + # }}} + # {{{ _getLine(self, brushColours, originPoint, targetPoint): XXX + def _getLine(self, brushColours, originPoint, targetPoint): + originPoint = originPoint.copy(); targetPoint = targetPoint.copy(); + pointDelta = self._pointDelta(originPoint, targetPoint) + lineXSign = 1 if pointDelta[0] > 0 else -1; + lineYSign = 1 if pointDelta[1] > 0 else -1; + pointDelta = [abs(a) for a in pointDelta] + if pointDelta[0] > pointDelta[1]: + lineXX, lineXY, lineYX, lineYY = lineXSign, 0, 0, lineYSign + else: + 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([[ \ + originPoint[0] + lineX*lineXX + lineY*lineYX, \ + originPoint[1] + lineX*lineXY + lineY*lineYY], \ + brushColours, 0, " "]) + 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): + brushColours = brushColours.copy() + if isLeftDown: + brushColours[1] = brushColours[0] + elif isRightDown: + 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]] + elif self.toolState == self.TS_ORIGIN: + targetPoint = list(atPoint) + originPoint = self.toolOriginPoint + brushPatches = self._getLine(brushColours, originPoint, targetPoint) + 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): + super().__init__(*args) + self.toolOriginPoint = None + self.toolState = self.TS_NONE + +# vim:expandtab foldmethod=marker sw=4 ts=4 tw=120 diff --git a/MiRCARTToolRect.py b/MiRCARTToolRect.py index 66a8864..d2452c5 100644 --- a/MiRCARTToolRect.py +++ b/MiRCARTToolRect.py @@ -40,7 +40,9 @@ class MiRCARTToolRect(MiRCARTTool): brushPatches = [] for brushRow in range(brushSize[1]): for brushCol in range(brushSize[0] * 2): - brushPatches.append([[brushCol, brushRow], \ + brushPatches.append([[ \ + atPoint[0] + brushCol, \ + atPoint[1] + brushRow], \ brushColours, 0, " "]) if isLeftDown or isRightDown: return [[False, brushPatches], [True, brushPatches]]